示例#1
0
 public void WriteWorldVertex(WorldVertex v)
 {
     _stream.WriteFloat3(v.Position.IJK);
     _stream.WriteFloat2(v.Texcoord);
     _stream.WriteFloat3(v.Normal);
     _stream.WriteFloat3(v.Tangent.IJK);
     _stream.WriteFloat3(v.Binormal);
 }
示例#2
0
 public void WriteWorldWaterVertex(WorldVertex v)
 {
     _stream.WriteFloat3(v.Position.IJK);
     _stream.WriteFloat2(v.Texcoord);
     _stream.WriteFloat3(v.Tangent.IJK);
     _stream.WriteFloat3(v.Binormal);
     //Temporary hack to have the right size I have no idea what these 2 values are
     _stream.WriteFloat2(new RealVector2d(1, 1));
 }
示例#3
0
 public void WriteWorldWaterVertex(WorldVertex v)
 {
     throw new NotImplementedException();
 }
        public void ConvertVertexBuffer(RenderGeometryApiResourceDefinition resourceDefinition, Stream inputStream, Stream outputStream, int vertexBufferIndex, int previousVertexBufferCount)
        {
            var vertexBuffer = resourceDefinition.VertexBuffers[vertexBufferIndex].Definition;
            var count        = vertexBuffer.Count;

            var startPos = (int)outputStream.Position;

            vertexBuffer.Data.Address = new CacheAddress(CacheAddressType.Resource, startPos);

            var inVertexStream  = VertexStreamFactory.Create(BlamCache.Version, inputStream);
            var outVertexStream = VertexStreamFactory.Create(CacheContext.Version, outputStream);

            OriginalBufferOffsets.Add(inputStream.Position);

            switch (vertexBuffer.Format)
            {
            case VertexBufferFormat.World:
                ConvertVertices(count, inVertexStream.ReadWorldVertex, (v, i) =>
                {
                    //v.Tangent = new RealQuaternion(-Math.Abs(v.Tangent.I), -Math.Abs(v.Tangent.J), Math.Abs(v.Tangent.K), Math.Abs(v.Tangent.W)); // great results for H3 armors
                    outVertexStream.WriteWorldVertex(v);
                });
                break;

            case VertexBufferFormat.Rigid:
                ConvertVertices(count, inVertexStream.ReadRigidVertex, (v, i) =>
                {
                    //v.Tangent = new RealQuaternion(-Math.Abs(v.Tangent.I), -Math.Abs(v.Tangent.J), Math.Abs(v.Tangent.K), Math.Abs(v.Tangent.W)); // great results for H3 armors
                    outVertexStream.WriteRigidVertex(v);
                });
                break;

            case VertexBufferFormat.Skinned:
                ConvertVertices(count, inVertexStream.ReadSkinnedVertex, (v, i) =>
                {
                    //v.Tangent = new RealQuaternion(-Math.Abs(v.Tangent.I), -Math.Abs(v.Tangent.J), Math.Abs(v.Tangent.K), Math.Abs(v.Tangent.W)); // great results for H3 armors
                    outVertexStream.WriteSkinnedVertex(v);
                });
                break;

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

            case VertexBufferFormat.StaticPerVertex:
                ConvertVertices(count, inVertexStream.ReadStaticPerVertexData, (v, i) =>
                {
                    v.Texcoord1 = ConvertNormal(v.Texcoord1);
                    v.Texcoord2 = ConvertNormal(v.Texcoord2);
                    v.Texcoord3 = ConvertNormal(v.Texcoord3);
                    v.Texcoord4 = ConvertNormal(v.Texcoord4);
                    v.Texcoord5 = ConvertNormal(v.Texcoord5);
                    outVertexStream.WriteStaticPerVertexData(v);
                });
                break;

            case VertexBufferFormat.AmbientPrt:
                ConvertVertices(vertexBuffer.Count = previousVertexBufferCount, inVertexStream.ReadAmbientPrtData, (v, i) => outVertexStream.WriteAmbientPrtData(v));
                break;

            case VertexBufferFormat.LinearPrt:
                ConvertVertices(count, inVertexStream.ReadLinearPrtData, (v, i) =>
                {
                    v.BlendWeight = ConvertNormal(v.BlendWeight);
                    outVertexStream.WriteLinearPrtData(v);
                });
                break;

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

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

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

            case VertexBufferFormat.World2:
                vertexBuffer.Format = VertexBufferFormat.World;
                goto case VertexBufferFormat.World;

            case VertexBufferFormat.Unknown1A:

                var waterData = WaterData[CurrentWaterBuffer];

                // Reformat Vertex Buffer
                vertexBuffer.Format     = VertexBufferFormat.World;
                vertexBuffer.VertexSize = 0x34;
                vertexBuffer.Count      = waterData.IndexBufferLength;

                // Create list of indices for later use.
                Unknown1BIndices = new List <ushort>();

                for (int k = 0; k < waterData.PartData.Count(); k++)
                {
                    Tuple <int, int, bool> currentPartData = waterData.PartData[k];

                    // Not water, add garbage data
                    if (currentPartData.Item3 == false)
                    {
                        for (int j = 0; j < currentPartData.Item2; j++)
                        {
                            WriteUnusedWorldWaterData(outputStream);
                        }
                    }
                    else
                    {
                        ConvertVertices(currentPartData.Item2 / 3, inVertexStream.ReadUnknown1A, (v, i) =>
                        {
                            // Store current stream position
                            var tempStreamPosition = inputStream.Position;

                            // Open previous world buffer (H3)
                            var worldVertexBufferBasePosition = OriginalBufferOffsets[OriginalBufferOffsets.Count() - 3];
                            inputStream.Position = worldVertexBufferBasePosition;

                            for (int j = 0; j < 3; j++)
                            {
                                inputStream.Position = 0x20 * v.Vertices[j] + worldVertexBufferBasePosition;

                                WorldVertex w = inVertexStream.ReadWorldVertex();

                                Unknown1BIndices.Add(v.Indices[j]);

                                // The last 2 floats in WorldWater are unknown.

                                outVertexStream.WriteWorldWaterVertex(w);
                            }

                            // Restore position for reading the next vertex correctly
                            inputStream.Position = tempStreamPosition;
                        });
                    }
                }



                break;

            case VertexBufferFormat.Unknown1B:

                var waterDataB = WaterData[CurrentWaterBuffer];

                // Adjust vertex size to match HO. Set count of vertices

                vertexBuffer.VertexSize = 0x18;

                var originalCount = vertexBuffer.Count;
                vertexBuffer.Count = waterDataB.IndexBufferLength;

                var basePosition      = inputStream.Position;
                var unknown1BPosition = 0;

                for (int k = 0; k < waterDataB.PartData.Count(); k++)
                {
                    Tuple <int, int, bool> currentPartData = waterDataB.PartData[k];

                    // Not water, add garbage data
                    if (currentPartData.Item3 == false)
                    {
                        for (int j = 0; j < currentPartData.Item2; j++)
                        {
                            WriteUnusedUnknown1BData(outputStream);
                        }
                    }
                    else
                    {
                        for (int j = unknown1BPosition; j < Unknown1BIndices.Count() && j - unknown1BPosition < currentPartData.Item2; j++)
                        {
                            inputStream.Position = basePosition + 0x24 * Unknown1BIndices[j];
                            ConvertVertices(1, inVertexStream.ReadUnknown1B, (v, i) => outVertexStream.WriteUnknown1B(v));
                            unknown1BPosition++;
                        }
                    }
                }

                // Get to the end of Unknown1B in H3 data
                inputStream.Position = basePosition + originalCount * 0x24;

                CurrentWaterBuffer++;

                break;

            case VertexBufferFormat.ParticleModel:
                ConvertVertices(count, inVertexStream.ReadParticleModelVertex, (v, i) => outVertexStream.WriteParticleModelVertex(v));
                break;

            case VertexBufferFormat.TinyPosition:
                ConvertVertices(count, inVertexStream.ReadTinyPositionVertex, (v, i) =>
                {
                    v.Position = ConvertPositionShort(v.Position);
                    v.Variant  = (ushort)((v.Variant >> 8) & 0xFF);
                    v.Normal   = ConvertNormal(v.Normal);
                    outVertexStream.WriteTinyPositionVertex(v);
                });
                break;

            default:
                throw new NotSupportedException(vertexBuffer.Format.ToString());
            }

            vertexBuffer.Data.Size  = (int)outputStream.Position - startPos;
            vertexBuffer.VertexSize = (short)(vertexBuffer.Data.Size / vertexBuffer.Count);

            resourceDefinition.VertexBuffers[vertexBufferIndex].DefinitionAddress = 0;
            resourceDefinition.VertexBuffers[vertexBufferIndex].RuntimeAddress    = 0;
        }
示例#5
0
 public void WriteWorldVertex(WorldVertex v)
 {
     _stream.WriteFloat3(v.Position.XYZ);
     _stream.WriteFloat2(v.Texcoord);
     _stream.WriteFloat3(v.Normal);
     _stream.WriteFloat3(v.Tangent.XYZ);
     _stream.WriteFloat3(v.Binormal);
 }
示例#6
0
 public void WriteWorldWaterVertex(WorldVertex v)
 {
     _stream.WriteFloat4(v.Position);
     _stream.WriteFloat2(v.Texcoord);
     _stream.WriteUByte4N(v.Tangent);
 }
示例#7
0
 public void WriteWorldVertex(WorldVertex v)
 {
     _stream.WriteFloat4(v.Position);
     _stream.WriteFloat2(v.Texcoord);
     _stream.WriteUByte4N(v.Tangent);
 }