예제 #1
0
        public static string TriangleIndexesAsString(this DynamicMeshFile.DynamicMeshBlend dynamicMeshBlend, bool reverse = false)
        {
            var result = new List <int>();

            foreach (var triangle in dynamicMeshBlend.Triangles)
            {
                if (reverse)
                {
                    result.AddRange(new[]
                    {
                        triangle.Index2,
                        triangle.Index1,
                        triangle.Index0
                    });
                }
                else
                {
                    result.AddRange(new[]
                    {
                        triangle.Index0,
                        triangle.Index1,
                        triangle.Index2
                    });
                }
            }
            return(string.Join(" ", result.Select(i => string.Format("{0}", i))));
        }
예제 #2
0
 public static string TexCoordsAsString(this DynamicMeshFile.DynamicMeshBlend dynamicMeshBlend, int index = 0, bool flipV = false)
 {
     return(string.Join(" ", dynamicMeshBlend.TexCoords.Select(tc =>
                                                               string.Format("{0:0.######} {1:0.######}",
                                                                             tc.X,
                                                                             flipV ? (1.0 - tc.Y) : tc.Y))));
 }
예제 #3
0
 public static void ToString(this DynamicMeshFile.DynamicMeshBlend dynamicMeshBlend, TextWriter writer)
 {
     writer.WriteLine("  ShaderFileName: {0}", dynamicMeshBlend.ShaderFileName);
     writer.WriteLine("  PositionIndexes.Count(): {0}", dynamicMeshBlend.PositionIndexes.Count());
     writer.WriteLine("  NormalIndexes.Count(): {0}", dynamicMeshBlend.NormalIndexes.Count());
     writer.WriteLine("  TexCoords.Count(): {0}", dynamicMeshBlend.TexCoords.Count());
     writer.WriteLine("  Triangles.Count(): {0}", dynamicMeshBlend.Triangles.Count());
 }
예제 #4
0
 public static string NormalsAsString(this DynamicMeshFile.DynamicMeshBlend dynamicMeshBlend, bool flipZ = false)
 {
     return(string.Join(" ", dynamicMeshBlend.NormalIndexes.Select(pi =>
     {
         var p = dynamicMeshBlend.Parent.Normals.ElementAt(pi);
         if (flipZ)
         {
             p.Z = -p.Z;
         }
         return p.ToFormatString();
     })));
 }
예제 #5
0
        public static DynamicMeshFile Load(IFFFile iffFile)
        {
            if (iffFile == null)
            {
                throw new ArgumentNullException("iffFile");
            }

            if (!string.Equals(iffFile.Root.Type, "SKMG", StringComparison.InvariantCultureIgnoreCase))
            {
                throw new IOException();
            }

            int skeletonCount;
            int bonesCount;
            int pointsCount;
            int twdtCount;
            int normalsCount;
            int psdtCount;
            int blendsCount;

            var infoNode = iffFile.Root.Children("0004").Children("INFO").First();

            using (var stream = new MemoryStream(infoNode.Data))
            {
                stream.ReadInt32(); // u1?
                stream.ReadInt32(); // u2?
                skeletonCount = stream.ReadInt32();
                bonesCount    = stream.ReadInt32();
                pointsCount   = stream.ReadInt32();
                twdtCount     = stream.ReadInt32();
                normalsCount  = stream.ReadInt32();
                psdtCount     = stream.ReadInt32();
                blendsCount   = stream.ReadInt32();

                stream.ReadInt16(); // u10?
                stream.ReadInt16(); // u11?
                stream.ReadInt16(); // u12? // Something to do with OITL
                stream.ReadInt16(); // u13?
            }

            var skeletonFileNames = iffFile.Root.Children("0004").Children("SKTM").First().Data.ReadStringList();

            var boneNames = iffFile.Root.Children("0004").Children("XFNM").First().Data.ReadStringList();

            if (boneNames.Count() != bonesCount)
            {
                throw new IOException();
            }

            var vertexList = new List <DynamicMeshFile.DynamicMeshVertex>();

            vertexList.AddRange(Enumerable.Range(0, pointsCount).Select(i => new DynamicMeshFile.DynamicMeshVertex()));

            var positionNode = iffFile.Root.Children("0004").Children("POSN").First();

            using (var stream = new MemoryStream(positionNode.Data))
            {
                for (int i = 0; i < pointsCount; i++)
                {
                    vertexList[i].Position = stream.ReadVector3Single();
                }
            }

            var numVertexWeightsNode = iffFile.Root.Children("0004").Children("TWHD").First();

            using (var stream = new MemoryStream(numVertexWeightsNode.Data))
            {
                for (int i = 0; i < pointsCount; i++)
                {
                    int weightsCount = stream.ReadInt32();
                    vertexList[i].BoneWeights = new DynamicMeshFile.DynamicMeshBoneWeight[weightsCount];
                }
            }

            var vertexWeightsNode = iffFile.Root.Children("0004").Children("TWDT").First();

            using (var stream = new MemoryStream(vertexWeightsNode.Data))
            {
                for (int i = 0; i < pointsCount; i++)
                {
                    for (int j = 0; j < vertexList[i].BoneWeights.Count(); j++)
                    {
                        var boneWeight = new DynamicMeshFile.DynamicMeshBoneWeight
                        {
                            BoneIndex = stream.ReadInt32(),
                            Weight    = stream.ReadSingle()
                        };
                        vertexList[i].BoneWeights[j] = boneWeight;
                    }
                }
            }

            var normalsNode = iffFile.Root.Children("0004").Children("NORM").First();
            var normalsList = new List <Vector3>();

            using (var stream = new MemoryStream(normalsNode.Data))
            {
                for (int i = 0; i < normalsCount; i++)
                {
                    var v = stream.ReadVector3Single();
                    normalsList.Add(v);
                }
            }

            var psdtNodes = iffFile.Root.Children("0004").Children("PSDT").ToList();

            if (psdtNodes.Count != psdtCount)
            {
                throw new IOException();
            }
            var meshBlends = new List <DynamicMeshFile.DynamicMeshBlend>();

            foreach (var psdtNode in psdtNodes)
            {
                var shaderFileName = psdtNode.Children("NAME").First().Data.ReadString();

                var positionIndexNode = psdtNode.Children("PIDX").First();
                var positionIndexes   = new List <int>();
                int numIndexes;
                using (var stream = new MemoryStream(positionIndexNode.Data))
                {
                    numIndexes = stream.ReadInt32();
                    for (int i = 0; i < numIndexes; i++)
                    {
                        var pi = stream.ReadInt32();
                        positionIndexes.Add(pi);
                    }
                }

                var normalIndexNode = psdtNode.Children("NIDX").First();
                var normalIndexes   = new List <int>();
                using (var stream = new MemoryStream(normalIndexNode.Data))
                {
                    for (int i = 0; i < numIndexes; i++)
                    {
                        var ni = stream.ReadInt32();
                        normalIndexes.Add(ni);
                    }
                }

                var texureCoordsNode = psdtNode.Children("TCSF").Children("TCSD").First();
                var textureCoords    = new List <Vector2>();
                using (var stream = new MemoryStream(texureCoordsNode.Data))
                {
                    for (int i = 0; i < numIndexes; i++)
                    {
                        var tc = stream.ReadVector2Single();
                        textureCoords.Add(tc);
                    }
                }

                var triangles         = new List <DynamicMeshFile.DynamicMeshTriangle>();
                var triangleNode      = psdtNode.Children("PRIM").Children("ITL").FirstOrDefault();
                var triangleGroupNode = psdtNode.Children("PRIM").Children("OITL").FirstOrDefault();
                if ((triangleNode == null) == (triangleGroupNode == null))
                {
                    throw new IOException();
                }
                if (triangleNode != null)
                {
                    using (var stream = new MemoryStream(triangleNode.Data))
                    {
                        int numTriangles = stream.ReadInt32();
                        for (int i = 0; i < numTriangles; i++)
                        {
                            var triangle = new DynamicMeshFile.DynamicMeshTriangle
                            {
                                Group  = 0,
                                Index0 = stream.ReadInt32(),
                                Index1 = stream.ReadInt32(),
                                Index2 = stream.ReadInt32(),
                            };
                            triangles.Add(triangle);
                        }
                    }
                }
                if (triangleGroupNode != null)
                {
                    using (var stream = new MemoryStream(triangleNode.Data))
                    {
                        int numTriangles = stream.ReadInt32();
                        for (int i = 0; i < numTriangles; i++)
                        {
                            var triangle = new DynamicMeshFile.DynamicMeshTriangle
                            {
                                Group  = stream.ReadInt32(),
                                Index0 = stream.ReadInt32(),
                                Index1 = stream.ReadInt32(),
                                Index2 = stream.ReadInt32(),
                            };
                            triangles.Add(triangle);
                        }
                    }
                }

                var meshBlend = new DynamicMeshFile.DynamicMeshBlend
                {
                    ShaderFileName  = shaderFileName,
                    PositionIndexes = positionIndexes.ToArray(),
                    NormalIndexes   = normalIndexes.ToArray(),
                    TexCoords       = textureCoords.ToArray(),
                    Triangles       = triangles.ToArray()
                };
                meshBlends.Add(meshBlend);
            }

            var result = new DynamicMeshFile
            {
                SkeletonFileNames = skeletonFileNames,
                BoneNames         = boneNames,
                Vertexes          = vertexList.ToArray(),
                Normals           = normalsList.ToArray(),
                MeshBlends        = meshBlends.ToArray()
            };

            foreach (var meshBlend in result.MeshBlends)
            {
                meshBlend.Parent = result;
            }

            return(result);
        }