예제 #1
0
        private RenderGeometryCompression CompressVertexBuffer(VertexBufferDefinition vertexBuffer)
        {
            Debug.Assert(vertexBuffer.Format == VertexBufferFormat.Rigid);

            var compression = new RenderGeometryCompression();

            var rigidVertices = new List <RigidVertex>();

            using (var stream = new MemoryStream(vertexBuffer.Data.Data))
            {
                var vertexStream = VertexStreamFactory.Create(DestCache.Version, stream);
                for (int i = 0; i < vertexBuffer.Count; i++)
                {
                    var vertex = vertexStream.ReadRigidVertex();
                    rigidVertices.Add(vertex);
                }
            }

            var positions = rigidVertices.Select(v => v.Position);
            var texCoords = rigidVertices.Select(v => v.Texcoord);

            if (positions != null && positions.Count() > 0)
            {
                compression.X.Lower = Math.Min(compression.X.Lower, positions.Min(v => v.I));
                compression.Y.Lower = Math.Min(compression.Y.Lower, positions.Min(v => v.J));
                compression.Z.Lower = Math.Min(compression.Z.Lower, positions.Min(v => v.K));
                compression.X.Upper = Math.Max(compression.X.Upper, positions.Max(v => v.I));
                compression.Y.Upper = Math.Max(compression.Y.Upper, positions.Max(v => v.J));
                compression.Z.Upper = Math.Max(compression.Z.Upper, positions.Max(v => v.K));
            }
            if (texCoords != null && texCoords.Count() > 0)
            {
                compression.U.Lower = Math.Min(compression.U.Lower, texCoords.Min(v => v.I));
                compression.V.Lower = Math.Min(compression.V.Lower, texCoords.Min(v => v.J));
                compression.U.Upper = Math.Max(compression.U.Upper, texCoords.Max(v => v.I));
                compression.V.Upper = Math.Max(compression.V.Upper, texCoords.Max(v => v.J));
            }

            var compressor = new VertexCompressor(compression);

            using (var outStream = new MemoryStream())
            {
                var outVertexStream = VertexStreamFactory.Create(DestCache.Version, outStream);
                foreach (var vertex in rigidVertices)
                {
                    vertex.Position = compressor.CompressPosition(vertex.Position);
                    vertex.Texcoord = compressor.CompressUv(vertex.Texcoord);
                    outVertexStream.WriteRigidVertex(vertex);
                }

                vertexBuffer.Data.Data = outStream.ToArray();
            }

            return(compression);
        }
예제 #2
0
        private static List <BMFVertexLighting> ConvertLightingVertices(VertexBufferDefinition vertexBuffer, CacheVersion version, int vertexCount)
        {
            var vertices = new List <BMFVertexLighting>();

            using (var vertexDataStream = new MemoryStream(vertexBuffer.Data.Data))
            {
                var vertexStream = VertexStreamFactory.Create(version, vertexDataStream);

                for (int j = 0; j < vertexCount; j++)
                {
                    var vertex = new BMFVertexLighting();

                    switch (vertexBuffer.Format)
                    {
                    case VertexBufferFormat.AmbientPrt:
                        var ambientPrt = vertexStream.ReadAmbientPrtData();
                        vertex.SHOrder            = 0;
                        vertex.PRTCoefficients[0] = ambientPrt.SHCoefficient;
                        break;

                    case VertexBufferFormat.LinearPrt:
                        var linearPrt = vertexStream.ReadLinearPrtData();
                        vertex.SHOrder            = 1;
                        vertex.PRTCoefficients[0] = linearPrt.SHCoefficients.I;
                        vertex.PRTCoefficients[1] = linearPrt.SHCoefficients.J;
                        vertex.PRTCoefficients[2] = linearPrt.SHCoefficients.K;
                        vertex.PRTCoefficients[3] = linearPrt.SHCoefficients.W;
                        break;

                    case VertexBufferFormat.QuadraticPrt:
                        var quadPrt = vertexStream.ReadQuadraticPrtData();
                        vertex.SHOrder            = 2;
                        vertex.PRTCoefficients[0] = quadPrt.SHCoefficients1.I;
                        vertex.PRTCoefficients[1] = quadPrt.SHCoefficients1.J;
                        vertex.PRTCoefficients[2] = quadPrt.SHCoefficients1.K;
                        vertex.PRTCoefficients[3] = quadPrt.SHCoefficients2.I;
                        vertex.PRTCoefficients[4] = quadPrt.SHCoefficients2.J;
                        vertex.PRTCoefficients[5] = quadPrt.SHCoefficients2.K;
                        vertex.PRTCoefficients[6] = quadPrt.SHCoefficients3.I;
                        vertex.PRTCoefficients[7] = quadPrt.SHCoefficients3.J;
                        vertex.PRTCoefficients[8] = quadPrt.SHCoefficients3.K;
                        break;

                    default:
                        throw new InvalidOperationException("Unsupported vertex buffer type: " + vertexBuffer.Format);
                    }
                    vertices.Add(vertex);
                }

                return(vertices);
            }
        }
예제 #3
0
        public static void ConvertVertexBuffer(VertexBufferDefinition buffer, MemoryStream inStream, IVertexStream inVertexStream, MemoryStream outStream, IVertexStream outVertexStream)
        {
            if (buffer.Data.Size == 0)
            {
                return;
            }
            var count    = buffer.Count;
            var startPos = (int)outStream.Position;

            inStream.Position   = buffer.Data.Address.Offset;
            buffer.Data.Address = new ResourceAddress(ResourceAddressType.Resource, startPos);
            switch (buffer.Format)
            {
            case VertexBufferFormat.World:
                ConvertVertices(count, inVertexStream.ReadWorldVertex, v =>
                {
                    v.Binormal = new Vector3(v.Position.W, v.Tangent.W, 0);     // Converted shaders use this
                    outVertexStream.WriteWorldVertex(v);
                });
                break;

            case VertexBufferFormat.Rigid:
                ConvertVertices(count, inVertexStream.ReadRigidVertex, v =>
                {
                    v.Binormal = new Vector3(v.Position.W, v.Tangent.W, 0);     // Converted shaders use this
                    outVertexStream.WriteRigidVertex(v);
                });
                break;

            case VertexBufferFormat.Skinned:
                ConvertVertices(count, inVertexStream.ReadSkinnedVertex, v =>
                {
                    v.Binormal = new Vector3(v.Position.W, v.Tangent.W, 0);     // Converted shaders use this
                    outVertexStream.WriteSkinnedVertex(v);
                });
                break;

            case VertexBufferFormat.StaticPerPixel:
                ConvertVertices(count, inVertexStream.ReadStaticPerPixelData, outVertexStream.WriteStaticPerPixelData);
                break;

            case VertexBufferFormat.StaticPerVertex:
                ConvertVertices(count, inVertexStream.ReadStaticPerVertexData, outVertexStream.WriteStaticPerVertexData);
                break;

            case VertexBufferFormat.AmbientPrt:
                ConvertVertices(count, inVertexStream.ReadAmbientPrtData, outVertexStream.WriteAmbientPrtData);
                break;

            case VertexBufferFormat.LinearPrt:
                ConvertVertices(count, inVertexStream.ReadLinearPrtData, outVertexStream.WriteLinearPrtData);
                break;

            case VertexBufferFormat.QuadraticPrt:
                ConvertVertices(count, inVertexStream.ReadQuadraticPrtData, outVertexStream.WriteQuadraticPrtData);
                break;

            case VertexBufferFormat.StaticPerVertexColor:
                ConvertVertices(count, inVertexStream.ReadStaticPerVertexColorData, outVertexStream.WriteStaticPerVertexColorData);
                break;

            case VertexBufferFormat.Decorator:
                ConvertVertices(count, inVertexStream.ReadDecoratorVertex, outVertexStream.WriteDecoratorVertex);
                break;

            case VertexBufferFormat.World2:
                buffer.Format = VertexBufferFormat.World;
                goto default;

            default:
                // Just copy the raw buffer over and pray that it works...
                var bufferData = new byte[buffer.Data.Size];
                inStream.Read(bufferData, 0, bufferData.Length);
                outStream.Write(bufferData, 0, bufferData.Length);
                break;
            }
            buffer.Data.Size  = (int)outStream.Position - startPos;
            buffer.VertexSize = (short)(buffer.Data.Size / buffer.Count);
        }
예제 #4
0
        private static List <BMFVertex> ConvertGeometryVertices(VertexCompressor vertexCompressor, VertexBufferDefinition vertexBuffer, CacheVersion version, int vertexCount, int rigidNodeIndex)
        {
            var vertices = new List <BMFVertex>();

            using (var vertexDataStream = new MemoryStream(vertexBuffer.Data.Data))
            {
                var vertexStream = VertexStreamFactory.Create(version, vertexDataStream);

                for (int j = 0; j < vertexCount; j++)
                {
                    var          vertex = new BMFVertex();
                    RealVector2d texcoordTemp;

                    switch (vertexBuffer.Format)
                    {
                    case VertexBufferFormat.Rigid:
                        var rigid = vertexStream.ReadRigidVertex();

                        vertex.Position = vertexCompressor.DecompressPosition(rigid.Position).IJK;
                        texcoordTemp    = vertexCompressor.DecompressUv(rigid.Texcoord);
                        vertex.Texcoord = new RealVector3d(texcoordTemp.I, texcoordTemp.J, 0.0f);
                        vertex.Normal   = rigid.Normal;
                        vertex.Tangent  = rigid.Tangent.IJK;
                        vertex.Binormal = rigid.Binormal;

                        vertex.Weights[0] = new BMFVertexWeight {
                            NodeIndex = rigidNodeIndex, Weight = 1.0f
                        };

                        for (int i = 1; i < 4; i++)
                        {
                            vertex.Weights[i] = new BMFVertexWeight();
                        }

                        break;

                    case VertexBufferFormat.Skinned:
                        var skinned = vertexStream.ReadSkinnedVertex();

                        vertex.Position = vertexCompressor.DecompressPosition(skinned.Position).IJK;
                        texcoordTemp    = vertexCompressor.DecompressUv(skinned.Texcoord);
                        vertex.Texcoord = new RealVector3d(texcoordTemp.I, texcoordTemp.J, 0.0f);
                        vertex.Normal   = skinned.Normal;
                        vertex.Tangent  = skinned.Tangent.IJK;
                        vertex.Binormal = skinned.Binormal;

                        for (int i = 0; i < 4; i++)
                        {
                            vertex.Weights[i] = new BMFVertexWeight {
                                NodeIndex = skinned.BlendIndices[i], Weight = skinned.BlendWeights[i]
                            };
                        }
                        break;

                    default:
                        throw new InvalidOperationException("Unsupported vertex buffer type: " + vertexBuffer.Format);
                    }
                    vertices.Add(vertex);
                }
            }
            return(vertices);
        }