private BspGeometry BuildGeometry(List<int> list) { if (list == null || list.Count == 0) return null; var res = new BspGeometry() { Faces = new List<BspGeometryFace>() }; foreach (var faceIndex in list) { var face = faces[faceIndex]; if (face.ledge_num == 0) continue; plane_t plane = planes[face.plane_id]; var surf = surfaces[face.texinfo_id]; int texture_id = (int)surf.texture_id; if (textures[texture_id].Name == "aaatrigger") continue; var faceVertices = new BspGeometryVertex[face.ledge_num]; Vector2 minUV0 = new Vector2(float.MaxValue, float.MaxValue); Vector2 minUV1 = new Vector2(float.MaxValue, float.MaxValue); Vector2 maxUV1 = new Vector2(float.MinValue, float.MinValue); for (int j = 0; j < (int)face.ledge_num; ++j) { var listOfEdgesIndex = (int)face.ledge_id + j; if (listOfEdgesIndex >= listOfEdges.Length) throw new ApplicationException(string.Format("Edge list index {0} is out of range [0..{1}]", listOfEdgesIndex, listOfEdges.Length - 1)); var edgeIndex = listOfEdges[listOfEdgesIndex]; if (edgeIndex >= edges.Count) throw new ApplicationException(string.Format("Edge index {0} is out of range [0..{1}]", edgeIndex, edges.Count - 1)); edge_t edge; if (edgeIndex >= 0) { edge = edges[edgeIndex]; } else { var flippedEdge = edges[-edgeIndex]; edge = new edge_t() { vertex0 = flippedEdge.vertex1, vertex1 = flippedEdge.vertex0 }; } var edgesvertex0 = edge.vertex0; if (edgesvertex0 >= vertices.Count) throw new ApplicationException(string.Format("Vertex index {0} is out of range [0..{1}]", edgesvertex0, vertices.Count - 1)); var edgesvertex1 = edge.vertex1; if (edgesvertex1 >= vertices.Count) throw new ApplicationException(string.Format("Vertex index {0} is out of range [0..{1}]", edgesvertex1, vertices.Count - 1)); BspGeometryVertex vertex = BuildVertex(vertices[(short)edgesvertex0], (face.side == 0) ? plane.normal : -plane.normal, ref surf); faceVertices[j] = vertex; if (minUV0.X > vertex.UV0.X) minUV0.X = vertex.UV0.X; if (minUV0.Y > vertex.UV0.Y) minUV0.Y = vertex.UV0.Y; if (minUV1.X > vertex.UV1.X) minUV1.X = vertex.UV1.X; if (minUV1.Y > vertex.UV1.Y) minUV1.Y = vertex.UV1.Y; if (maxUV1.X < vertex.UV1.X) maxUV1.X = vertex.UV1.X; if (maxUV1.Y < vertex.UV1.Y) maxUV1.Y = vertex.UV1.Y; } minUV0.X = (float)System.Math.Floor(minUV0.X); minUV0.Y = (float)System.Math.Floor(minUV0.Y); minUV1.X = (float)System.Math.Floor(minUV1.X); minUV1.Y = (float)System.Math.Floor(minUV1.Y); maxUV1.X = (float)System.Math.Ceiling(maxUV1.X); maxUV1.Y = (float)System.Math.Ceiling(maxUV1.Y); var sizeLightmap = maxUV1 - minUV1 + new Vector2(1, 1); float safeOffset = 0.5f;//0.5f; float safeBorderWidth = 1; for (int j = 0; j < (int)face.ledge_num; ++j) { faceVertices[j].UV0 = faceVertices[j].UV0 - minUV0; faceVertices[j].UV1.X = (faceVertices[j].UV1.X - minUV1.X + safeOffset) / (sizeLightmap.X + safeBorderWidth); faceVertices[j].UV1.Y = (faceVertices[j].UV1.Y - minUV1.Y + safeOffset) / (sizeLightmap.Y + safeBorderWidth); } if (textures[texture_id].Name == "sky") { for (int j = 0; j < (int)face.ledge_num; ++j) faceVertices[j].UV0 = new Vector2(0, 0); } BspTexture lightMap = null; if (face.lightmap != -1) { if (!faceLightmapObjects.TryGetValue(face.lightmap, out lightMap)) { var size2 = (sizeLightmap.X) * (sizeLightmap.Y); Bitmap faceLightmap = BuildFaceLightmap(face.lightmap, (int)sizeLightmap.X, (int)sizeLightmap.Y); faceLightmap = ReaderHelper.BuildSafeLightmap(faceLightmap); lightMap = new BspEmbeddedTexture() { Name = "facelightmap" + face.lightmap, mipMaps = new Bitmap[] { faceLightmap }, Width = faceLightmap.Width, Height = faceLightmap.Height }; faceLightmapObjects[face.lightmap] = lightMap; } } var vert0 = faceVertices[0]; for (int j = 1; j < faceVertices.Length - 1; ++j) { BspGeometryVertex vert1 = faceVertices[j]; BspGeometryVertex vert2 = faceVertices[j + 1]; var geoFace = new BspGeometryFace() { Vertex0 = vert0, Vertex1 = vert1, Vertex2 = vert2, Texture = textures[texture_id], Lightmap = lightMap }; res.Faces.Add(geoFace); } } return res; }
private BspGeometry BuildGeometry(List<int> list) { if (list == null || list.Count == 0) return null; var res = new BspGeometry() { Faces = new List<BspGeometryFace>() }; foreach (var faceIndex in list) { var face = faces[faceIndex]; if (face.numedges == 0) continue; plane_t plane = planes[face.planenum]; var surf = surfaces[face.texinfo]; var texture_id = (int)surf.texdata; var faceVertices = new BspGeometryVertex[face.numedges]; Vector2 minUV0 = new Vector2(float.MaxValue, float.MaxValue); Vector2 minUV1 = new Vector2(float.MaxValue, float.MaxValue); Vector2 maxUV1 = new Vector2(float.MinValue, float.MinValue); for (int j = 0; j < (int)face.numedges; ++j) { var listOfEdgesIndex = (int)face.firstedge + j; if (listOfEdgesIndex >= listOfEdges.Length) throw new ApplicationException(string.Format("Edge list index {0} is out of range [0..{1}]", listOfEdgesIndex, listOfEdges.Length - 1)); var edgeIndex = listOfEdges[listOfEdgesIndex]; if (edgeIndex >= edges.Count) throw new ApplicationException(string.Format("Edge index {0} is out of range [0..{1}]", edgeIndex, edges.Count - 1)); edge_t edge; if (edgeIndex >= 0) { edge = edges[edgeIndex]; } else { var flippedEdge = edges[-edgeIndex]; edge = new edge_t() { vertex0 = flippedEdge.vertex1, vertex1 = flippedEdge.vertex0 }; } var edgesvertex0 = edge.vertex0; if (edgesvertex0 >= vertices.Count) throw new ApplicationException(string.Format("Vertex index {0} is out of range [0..{1}]", edgesvertex0, vertices.Count - 1)); var edgesvertex1 = edge.vertex1; if (edgesvertex1 >= vertices.Count) throw new ApplicationException(string.Format("Vertex index {0} is out of range [0..{1}]", edgesvertex1, vertices.Count - 1)); BspGeometryVertex vertex = BuildVertex(vertices[(short)edgesvertex0], (face.side == 0) ? plane.normal : -plane.normal, face, ref surf); faceVertices[j] = vertex; if (minUV0.X > vertex.UV0.X) minUV0.X = vertex.UV0.X; if (minUV0.Y > vertex.UV0.Y) minUV0.Y = vertex.UV0.Y; if (minUV1.X > vertex.UV1.X) minUV1.X = vertex.UV1.X; if (minUV1.Y > vertex.UV1.Y) minUV1.Y = vertex.UV1.Y; if (maxUV1.X < vertex.UV1.X) maxUV1.X = vertex.UV1.X; if (maxUV1.Y < vertex.UV1.Y) maxUV1.Y = vertex.UV1.Y; } minUV0.X = (float)System.Math.Floor(minUV0.X); minUV0.Y = (float)System.Math.Floor(minUV0.Y); if (textures[texture_id].Name == "TOOLS/TOOLSSKYBOX") { minUV0.X = 0; minUV0.Y = 0; for (int j = 0; j < (int)face.numedges; ++j) faceVertices[j].UV0 = new Vector2(0, 0); } var sizeLightmap = new Vector2(face.LightmapTextureSizeInLuxels[0] + 1, face.LightmapTextureSizeInLuxels[1] + 1); for (int j = 0; j < (int)face.numedges; ++j) { faceVertices[j].UV0 = faceVertices[j].UV0 - minUV0; } BspTexture lightMap = null; if (face.lightmap != -1 && (sizeLightmap.X > 0 && sizeLightmap.Y > 0)) { if (!faceLightmapObjects.TryGetValue(face.lightmap, out lightMap)) { var size2 = (sizeLightmap.X) * (sizeLightmap.Y); Bitmap faceLightmap = BuildFaceLightmap(face.lightmap, (int)sizeLightmap.X, (int)sizeLightmap.Y); faceLightmap = ReaderHelper.BuildSafeLightmap(faceLightmap); //faceLightmap = ReaderHelper.BuildSafeLightmapBothSides(faceLightmap); //Use safeBorderWidth = 2.0f; !!! lightMap = new BspEmbeddedTexture() { Name = "facelightmap" + face.lightmap, mipMaps = new Bitmap[] { faceLightmap }, Width = faceLightmap.Width, Height = faceLightmap.Height }; faceLightmapObjects[face.lightmap] = lightMap; } } else { for (int j = 0; j < (int)face.numedges; ++j) { faceVertices[j].UV1 = Vector2.Zero; } } var vert0 = faceVertices[0]; for (int j = 1; j < faceVertices.Length - 1; ++j) { BspGeometryVertex vert1 = faceVertices[j]; BspGeometryVertex vert2 = faceVertices[j + 1]; var geoFace = new BspGeometryFace() { Vertex0 = vert0, Vertex1 = vert1, Vertex2 = vert2, Texture = textures[texture_id], Lightmap = lightMap }; res.Faces.Add(geoFace); } } return res; }
private void BuildPathFace(BspGeometry res, face_t face) { var texture = (face.texinfo_id>=0)?textures[face.texinfo_id]:null; BspTexture lightMap = (face.lightmapID>=0)?lightmaps[face.lightmapID]:null; var width = face.sizeX; var height = face.sizeY; if (width * height != face.numOfVerts) throw new ApplicationException("wrong patch point count"); for (int i = 0; i < width - 1; i += 1) { for (int j = 0; j < height - 1; j += 1) { var vert0 = BuildVertex((int)(face.vertexIndex + (i) + (j) * width), face); var vert1 = BuildVertex((int)(face.vertexIndex + (i + 1) + (j) * width), face); var vert2 = BuildVertex((int)(face.vertexIndex + (i + 1) + (j + 1) * width), face); var geoFace = new BspGeometryFace() { Vertex0 = vert2, Vertex1 = vert1, Vertex2 = vert0, Texture = texture, Lightmap = lightMap }; res.Faces.Add(geoFace); vert0 = BuildVertex((int)(face.vertexIndex + (i) + (j) * width), face); vert1 = BuildVertex((int)(face.vertexIndex + (i + 1) + (j+1) * width), face); vert2 = BuildVertex((int)(face.vertexIndex + (i) + (j + 1) * width), face); geoFace = new BspGeometryFace() { Vertex0 = vert2, Vertex1 = vert1, Vertex2 = vert0, Texture = texture, Lightmap = lightMap }; res.Faces.Add(geoFace); } } }
private void BuildPolygonFace(BspGeometry res, face_t face) { var texture = (face.texinfo_id >= 0) ? textures[face.texinfo_id] : null; BspTexture lightMap = (face.lightmapID >= 0) ? lightmaps[face.lightmapID] : null; for (uint j = 0; j + 2 < face.numMeshVerts; j+=3) { var vert0 = BuildVertex((int)(face.vertexIndex+listOfVertices[face.meshVertIndex+j]), face); var vert1 = BuildVertex((int)(face.vertexIndex + listOfVertices[face.meshVertIndex + j+1]), face); var vert2 = BuildVertex((int)(face.vertexIndex + listOfVertices[face.meshVertIndex + j + 2]), face); var geoFace = new BspGeometryFace() { Vertex0 = vert0, Vertex1 = vert1, Vertex2 = vert2, Texture = texture, Lightmap = lightMap }; res.Faces.Add(geoFace); } }
private BspGeometry BuildGeometry(List<int> list) { if (list == null || list.Count == 0) return null; var res = new BspGeometry() { Faces = new List<BspGeometryFace>() }; foreach (var faceIndex in list) { var face = faces[faceIndex]; plane_t plane = planes[face.plane]; var surf = texInfos[face.texture_info]; BspTexture texture = null; if (!texturesMap.TryGetValue(surf.name, out texture)) { texture = new BspTextureReference() { Width = 128, Height = 128, Name = surf.name }; texturesMap[surf.name] = texture; } var faceVertices = new BspGeometryVertex[face.ledge_num]; Vector2 minUV0 = new Vector2(float.MaxValue, float.MaxValue); Vector2 minUV1 = new Vector2(float.MaxValue, float.MaxValue); Vector2 maxUV1 = new Vector2(float.MinValue, float.MinValue); for (int j = 0; j < (int)face.ledge_num; ++j) { var listOfEdgesIndex = (int)face.ledge_id + j; if (listOfEdgesIndex >= listOfEdges.Length) throw new ApplicationException(string.Format("Edge list index {0} is out of range [0..{1}]", listOfEdgesIndex, listOfEdges.Length - 1)); var edgeIndex = listOfEdges[listOfEdgesIndex]; if (edgeIndex >= edges.Count) throw new ApplicationException(string.Format("Edge index {0} is out of range [0..{1}]", edgeIndex, edges.Count - 1)); edge_t edge; if (edgeIndex >= 0) { edge = edges[edgeIndex]; } else { var flippedEdge = edges[-edgeIndex]; edge = new edge_t() { vertex0 = flippedEdge.vertex1, vertex1 = flippedEdge.vertex0 }; } var edgesvertex0 = edge.vertex0; if (edgesvertex0 >= vertices.Count) throw new ApplicationException(string.Format("Vertex index {0} is out of range [0..{1}]", edgesvertex0, vertices.Count - 1)); var edgesvertex1 = edge.vertex1; if (edgesvertex1 >= vertices.Count) throw new ApplicationException(string.Format("Vertex index {0} is out of range [0..{1}]", edgesvertex1, vertices.Count - 1)); BspGeometryVertex vertex = BuildVertex(vertices[(short)edgesvertex0], (face.plane_side == 0) ? plane.normal : -plane.normal, ref surf); faceVertices[j] = vertex; if (minUV0.X > vertex.UV0.X) minUV0.X = vertex.UV0.X; if (minUV0.Y > vertex.UV0.Y) minUV0.Y = vertex.UV0.Y; if (minUV1.X > vertex.UV1.X) minUV1.X = vertex.UV1.X; if (minUV1.Y > vertex.UV1.Y) minUV1.Y = vertex.UV1.Y; if (maxUV1.X < vertex.UV1.X) maxUV1.X = vertex.UV1.X; if (maxUV1.Y < vertex.UV1.Y) maxUV1.Y = vertex.UV1.Y; } minUV0.X = (float)System.Math.Floor(minUV0.X); minUV0.Y = (float)System.Math.Floor(minUV0.Y); minUV1.X = (float)System.Math.Floor(minUV1.X); minUV1.Y = (float)System.Math.Floor(minUV1.Y); maxUV1.X = (float)System.Math.Ceiling(maxUV1.X); maxUV1.Y = (float)System.Math.Ceiling(maxUV1.Y); var sizeLightmap = maxUV1 - minUV1 + new Vector2(1, 1); for (int j = 0; j < (int)face.ledge_num; ++j) { faceVertices[j].UV0 = faceVertices[j].UV0 - minUV0; faceVertices[j].UV1.X = (faceVertices[j].UV1.X - minUV1.X + 0.5f) / sizeLightmap.X; faceVertices[j].UV1.Y = (faceVertices[j].UV1.Y - minUV1.Y + 0.5f) / sizeLightmap.Y; } BspTexture lightMap = null; if (face.lightmap != -1) { if (!faceLightmapObjects.TryGetValue(face.lightmap, out lightMap)) { var size2 = (sizeLightmap.X) * (sizeLightmap.Y); lightMap = new BspEmbeddedTexture() { Name = "facelightmap" + face.lightmap, mipMaps = new Bitmap[] { BuildFaceLightmap(face.lightmap, (int)sizeLightmap.X, (int)sizeLightmap.Y) }, Width = (int)sizeLightmap.X, Height = (int)sizeLightmap.Y }; faceLightmapObjects[face.lightmap] = lightMap; } } var vert0 = faceVertices[0]; for (int j = 1; j < faceVertices.Length - 1; ++j) { BspGeometryVertex vert1 = faceVertices[j]; BspGeometryVertex vert2 = faceVertices[j + 1]; var geoFace = new BspGeometryFace() { Vertex0 = vert0, Vertex1 = vert1, Vertex2 = vert2, Texture = texture, Lightmap = lightMap }; res.Faces.Add(geoFace); } } return res; }