Exemplo n.º 1
0
        internal Displacement(ValveBspFile bsp, DispInfo dispInfo)
        {
            _bspFile  = bsp;
            _dispInfo = dispInfo;
            _corners  = new Vector3[8];

            _min = IntVector2.Zero;
            _max = new IntVector2(Subdivisions, Subdivisions);

            var face             = bsp.FacesHdr[_dispInfo.MapFace];
            var firstCornerDist2 = float.MaxValue;

            Normal = bsp.Planes[face.PlaneNum].Normal;

            for (var i = 0; i < 4; ++i)
            {
                var vert = bsp.GetVertexFromSurfEdgeId(face.FirstEdge + i);
                _corners[i] = vert;

                var dist2 = (_dispInfo.StartPosition - vert).LengthSquared;
                if (dist2 < firstCornerDist2)
                {
                    _firstCorner     = i;
                    firstCornerDist2 = dist2;
                }
            }
        }
Exemplo n.º 2
0
        private void WriteFace(ValveBspFile bsp, int faceIndex, GeometryPage page, List <Face> outFaces)
        {
            const SurfFlags ignoreFlags = SurfFlags.NODRAW | SurfFlags.LIGHT | SurfFlags.SKY | SurfFlags.SKY2D;

            var faceInfo = bsp.Faces[faceIndex];
            var texInfo  = bsp.TextureInfos[faceInfo.TexInfo];

            if ((texInfo.Flags & ignoreFlags) != 0 || texInfo.TexData < 0)
            {
                return;
            }

            var texData = bsp.TextureData[texInfo.TexData];

            var matPath  = bsp.GetTextureString(texData.NameStringTableId);
            var meshData = GetOrCreateMeshData(bsp, page, matPath);

            if (Skip)
            {
                return;
            }

            MeshElement elem;
            Face        face;

            var leafFaceIndex = outFaces.FindIndex(x => x.Material == meshData.MaterialIndex);

            if (leafFaceIndex != -1)
            {
                face = outFaces[leafFaceIndex];
                elem = meshData.Elements[face.Element];
            }
            else
            {
                elem = new MeshElement
                {
                    Mode        = PrimitiveType.Triangles,
                    Material    = 0,
                    IndexOffset = meshData.Indices.Count
                };

                face = new Face
                {
                    Material = meshData.MaterialIndex,
                    Element  = meshData.Elements.Count
                };

                outFaces.Add(face);
                meshData.Elements.Add(elem);
            }

            var texScale = new Vector2(1f / Math.Max(texData.Width, 1), 1f / Math.Max(texData.Height, 1));

            Vector2 lmMin, lmSize;

            bsp.LightmapLayout.GetUvs(faceIndex, out lmMin, out lmSize);

            if (faceInfo.DispInfo != -1)
            {
                var disp = bsp.DisplacementManager[faceInfo.DispInfo];

                SourceUtils.Vector3 c0, c1, c2, c3;
                disp.GetCorners(out c0, out c1, out c2, out c3);

                var uv00 = GetUv(c0, texInfo.TextureUAxis, texInfo.TextureVAxis) * texScale;
                var uv10 = GetUv(c3, texInfo.TextureUAxis, texInfo.TextureVAxis) * texScale;
                var uv01 = GetUv(c1, texInfo.TextureUAxis, texInfo.TextureVAxis) * texScale;
                var uv11 = GetUv(c2, texInfo.TextureUAxis, texInfo.TextureVAxis) * texScale;

                var subDivMul = 1f / disp.Subdivisions;

                for (var y = 0; y < disp.Subdivisions; ++y)
                {
                    meshData.BeginPrimitive();
                    var v0 = (y + 0) * subDivMul;
                    var v1 = (y + 1) * subDivMul;

                    for (var x = 0; x < disp.Size; ++x)
                    {
                        var u = x * subDivMul;

                        meshData.VertexAttribute(VertexAttribute.Position, disp.GetPosition(x, y + 0));
                        meshData.VertexAttribute(VertexAttribute.Normal, disp.GetNormal(x, y + 0));
                        meshData.VertexAttribute(VertexAttribute.Uv,
                                                 (uv00 * (1f - u) + uv10 * u) * (1f - v0) + (uv01 * (1f - u) + uv11 * u) * v0);
                        meshData.VertexAttribute(VertexAttribute.Uv2, new Vector2(u, v0) * lmSize + lmMin);
                        meshData.VertexAttribute(VertexAttribute.Alpha, disp.GetAlpha(x, y + 0));
                        meshData.CommitVertex();

                        meshData.VertexAttribute(VertexAttribute.Position, disp.GetPosition(x, y + 1));
                        meshData.VertexAttribute(VertexAttribute.Normal, disp.GetNormal(x, y + 1));
                        meshData.VertexAttribute(VertexAttribute.Uv,
                                                 (uv00 * (1f - u) + uv10 * u) * (1f - v1) + (uv01 * (1f - u) + uv11 * u) * v1);
                        meshData.VertexAttribute(VertexAttribute.Uv2, new Vector2(u, v1) * lmSize + lmMin);
                        meshData.VertexAttribute(VertexAttribute.Alpha, disp.GetAlpha(x, y + 1));
                        meshData.CommitVertex();
                    }

                    meshData.CommitPrimitive(PrimitiveType.TriangleStrip);
                }
            }
            else
            {
                meshData.BeginPrimitive();

                var plane = bsp.Planes[faceInfo.PlaneNum];

                for (int k = faceInfo.FirstEdge, kEnd = faceInfo.FirstEdge + faceInfo.NumEdges; k < kEnd; ++k)
                {
                    var vert = bsp.GetVertexFromSurfEdgeId(k);
                    var uv   = GetUv(vert, texInfo.TextureUAxis, texInfo.TextureVAxis);
                    var uv2  = GetUv(vert, texInfo.LightmapUAxis, texInfo.LightmapVAxis);

                    uv2.X -= faceInfo.LightMapOffsetX;
                    uv2.Y -= faceInfo.LightMapOffsetY;
                    uv2.X /= Math.Max(faceInfo.LightMapSizeX, 1);
                    uv2.Y /= Math.Max(faceInfo.LightMapSizeY, 1);

                    uv2 *= lmSize;
                    uv2 += lmMin;

                    meshData.VertexAttribute(VertexAttribute.Position, vert);
                    meshData.VertexAttribute(VertexAttribute.Normal, plane.Normal);
                    meshData.VertexAttribute(VertexAttribute.Uv, uv * texScale);
                    meshData.VertexAttribute(VertexAttribute.Uv2, uv2);

                    meshData.CommitVertex();
                }

                var numPrimitives = faceInfo.NumPrimitives & 0x7fff;

                if (numPrimitives == 0)
                {
                    meshData.CommitPrimitive(PrimitiveType.TriangleFan);
                }
                else
                {
                    if (_sIndexBuffer == null)
                    {
                        _sIndexBuffer = new List <int>();
                    }
                    else
                    {
                        _sIndexBuffer.Clear();
                    }

                    var indices = _sIndexBuffer;

                    for (int k = faceInfo.FirstPrimitive, kEnd = faceInfo.FirstPrimitive + numPrimitives;
                         k < kEnd;
                         ++k)
                    {
                        var primitive = bsp.Primitives[k];
                        for (int l = primitive.FirstIndex, lEnd = primitive.FirstIndex + primitive.IndexCount;
                             l < lEnd;
                             ++l)
                        {
                            indices.Add(bsp.PrimitiveIndices[l]);
                        }

                        PrimitiveType mode;
                        switch (primitive.Type)
                        {
                        case ValveBsp.PrimitiveType.TriangleStrip:
                            mode = PrimitiveType.TriangleStrip;
                            break;

                        case ValveBsp.PrimitiveType.TriangleFan:
                            mode = PrimitiveType.TriangleFan;
                            break;

                        case ValveBsp.PrimitiveType.TriangleList:
                            mode = PrimitiveType.Triangles;
                            break;

                        default:
                            throw new NotImplementedException();
                        }

                        meshData.CommitPrimitive(mode, indices);
                        indices.Clear();
                    }
                }
            }

            elem.IndexCount = meshData.Indices.Count - elem.IndexOffset;
        }
Exemplo n.º 3
0
        private static void SerializeFace(ValveBspFile bsp, int index, VertexArray verts)
        {
            const SurfFlags ignoreFlags = SurfFlags.NODRAW | SurfFlags.LIGHT;
            const SurfFlags skyFlags    = SurfFlags.SKY2D | SurfFlags.SKY;

            var face    = bsp.FacesHdr[index];
            var texInfo = bsp.TextureInfos[face.TexInfo];
            var plane   = bsp.Planes[face.PlaneNum];

            if ((texInfo.Flags & ignoreFlags) != 0 || texInfo.TexData < 0)
            {
                return;
            }
            var isSky = (texInfo.Flags & skyFlags) != 0;

            if (face.DispInfo != -1)
            {
                SerializeDisplacement(bsp, index, ref face, ref plane, verts);
                return;
            }

            var texData  = bsp.TextureData[texInfo.TexData];
            var texScale = new Vector2(1f / texData.Width, 1f / texData.Height);

            verts.BeginPrimitive();

            for (int i = face.FirstEdge, iEnd = face.FirstEdge + face.NumEdges; i < iEnd; ++i)
            {
                var vert = bsp.GetVertexFromSurfEdgeId(i);
                var uv   = GetUv(vert, texInfo.TextureUAxis, texInfo.TextureVAxis) * texScale;
                var uv2  = GetLightmapUv(bsp, vert, index, ref face, ref texInfo);

                verts.AddVertex(vert, texCoord: uv, lightmapCoord: uv2);
            }

            var numPrimitives  = face.NumPrimitives & 0x7fff;
            var texStringIndex = isSky ? -1 : texData.NameStringTableId;

            if (numPrimitives == 0)
            {
                verts.CommitPrimitive(PrimitiveType.TriangleFan, texStringIndex);
                return;
            }

            if (_sIndicesBuffer == null)
            {
                _sIndicesBuffer = new List <int>();
            }

            for (int i = face.FirstPrimitive, iEnd = face.FirstPrimitive + numPrimitives; i < iEnd; ++i)
            {
                var primitive = bsp.Primitives[i];
                for (int j = primitive.FirstIndex, jEnd = primitive.FirstIndex + primitive.IndexCount; j < jEnd; ++j)
                {
                    _sIndicesBuffer.Add(bsp.PrimitiveIndices[j]);
                }

                verts.CommitPrimitive(primitive.Type, texStringIndex, _sIndicesBuffer);
                _sIndicesBuffer.Clear();
            }
        }