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); }
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); } }
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); }
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); }