Exemple #1
0
        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;
        }
Exemple #2
0
        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;
        }