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