private ShaderFile Load(IFFFile iffFile) { if (iffFile == null) { throw new ArgumentNullException("iffFile"); } var materialNode = iffFile.Root.Descendents("MATS").First(); var materialTag = materialNode.Children().First().Descendents("TAG").First().Data.ReadString(); var materialListNode = materialNode.Children().First().Descendents("MATL").First(); if (materialListNode.Size != 68) { throw new IOException("Expected MATL size to be 68"); } Color a, d, s, e; Single shininess; using (var stream = new MemoryStream(materialListNode.Data)) { a = stream.ReadColorARGBSingle(); d = stream.ReadColorARGBSingle(); s = stream.ReadColorARGBSingle(); e = stream.ReadColorARGBSingle(); shininess = stream.ReadSingle(); } var texureNode = iffFile .Root .Descendents("TXMS") .Descendents("TXM") .FirstOrDefault(node => string.Equals(node.Descendents("DATA").First().Data.ReadString(), "NIAM", StringComparison.InvariantCultureIgnoreCase)); if (texureNode == null) { texureNode = iffFile .Root .Descendents("TXMS") .Descendents("TXM") .First(); } var textureFileName = texureNode.Descendents("NAME").First().Data.ReadString(); return(new ShaderFile { MaterialColorAmbient = a, MaterialColorDiffuse = d, MaterialColorSpecular = s, MaterialColorEmisive = e, MaterialShininess = shininess, TextureFileName = textureFileName }); }
private TreeNode RefreshTreeView(TreeNodeCollection parentNodes, IFFFile.Node item, bool isRoot) { var node = new TreeNode(); node.Text = item.Type; node.Tag = item; node.SelectedImageIndex = node.ImageIndex = item.NodeType == IFFFile.NodeType.Form ? 0 : 1; parentNodes.Add(node); foreach (var childItem in item.Children) RefreshTreeView(node.Nodes, childItem, false); return node; }
private InteriorLayoutFile Load(IFFFile iffFile) { if (iffFile == null) { throw new ArgumentNullException("iffFile"); } var interiorLayoutItems = new List <InteriorLayoutFile.InteriorLayoutItem>(); foreach (var node in iffFile.Root.Descendents("NODE")) { using (var stream = new MemoryStream(node.Data)) { string @object = stream.ReadString(); string cell = stream.ReadString(); var matrix = new Single[3, 3]; var w = new Single[3]; matrix[0, 0] = stream.ReadSingle(); matrix[0, 1] = stream.ReadSingle(); matrix[0, 2] = stream.ReadSingle(); w[0] = stream.ReadSingle(); matrix[1, 0] = stream.ReadSingle(); matrix[1, 1] = stream.ReadSingle(); matrix[1, 2] = stream.ReadSingle(); w[1] = stream.ReadSingle(); matrix[2, 0] = stream.ReadSingle(); matrix[2, 1] = stream.ReadSingle(); matrix[2, 2] = stream.ReadSingle(); w[2] = stream.ReadSingle(); interiorLayoutItems.Add(new InteriorLayoutFile.InteriorLayoutItem { Object = @object, Cell = cell, Matrix = matrix, W = w }); } } return(new InteriorLayoutFile { Items = interiorLayoutItems }); }
public static MeshFile Load(IFFFile iffFile) { if (iffFile == null) { throw new ArgumentNullException("iffFile"); } var rootGeometryNode = iffFile.Root.Descendents("SPS").Children().First(); if (rootGeometryNode == null) { throw new IOException(); } var geometries = new List <MeshFile.MeshGeometry>(); var geometryCount = rootGeometryNode.Children("CNT").First().Data.ReadInt32(); for (int geometryIndex = 0; geometryIndex < geometryCount; geometryIndex++) { var geometryType = (geometryIndex + 1).ToString().PadLeft(4, '0'); var geometryNode = rootGeometryNode.Children(geometryType).First(); var shaderFileName = geometryNode.Descendents("NAME").First().Data.ReadString(); var vertexNode = geometryNode.Descendents("VTXA").First(); var numVertexes = vertexNode.Descendents("INFO").First().Data.ReadInt32(4); var vertexDataNode = vertexNode.Descendents("DATA").First(); var bytesPerVertex = vertexDataNode.Data.Length / numVertexes; if ((vertexDataNode.Data.Length % numVertexes) != 0) { throw new IOException("Invalid mesh geometry"); } var vertexes = new List <MeshFile.MeshVertex>(); using (var stream = new MemoryStream(vertexDataNode.Data)) while (stream.Position < stream.Length) { MeshFile.MeshVertex vertex; int vertexPosition = 0; switch (bytesPerVertex) { case 32: case 40: case 48: case 56: case 64: case 72: vertex = new MeshFile.MeshVertex { Position = stream.ReadVector3Single(), Normal = stream.ReadVector3Single() }; vertexPosition = 24; break; case 36: case 44: case 52: case 60: case 68: vertex = new MeshFile.MeshVertex { Position = stream.ReadVector3Single(), Normal = stream.ReadVector3Single(), Color = stream.ReadColorARGBByte() }; vertexPosition = 28; break; default: throw new IOException("Invalid mesh geometry"); } var textureCoords = new Vector2[(bytesPerVertex - vertexPosition) / 8]; for (int i = 0; i < textureCoords.Length; i++) { textureCoords[i] = stream.ReadVector2Single(); } vertex.TexCoords = textureCoords; vertexes.Add(vertex); } int[] indexes; var vertexIndexNode = geometryNode.Descendents("INDX").First(); using (var stream = new MemoryStream(vertexIndexNode.Data)) { int numIndexes = stream.ReadInt32(); int bytesPerIndex = (vertexIndexNode.Data.Length - 4) / numIndexes; if (((vertexIndexNode.Data.Length - 4) % numIndexes) != 0) { throw new IOException("Invalid mesh geometry"); } indexes = new int[numIndexes]; for (int i = 0; i < indexes.Length; i++) { switch (bytesPerIndex) { case 2: indexes[i] = stream.ReadInt16(); break; case 4: indexes[i] = stream.ReadInt32(); break; default: throw new IOException("Invalid mesh geometry"); } } } geometries.Add(new MeshFile.MeshGeometry { ShaderFileName = shaderFileName, Vertexes = vertexes, Indexes = indexes }); } return(new MeshFile { Geometries = geometries }); }
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); }
private SkeletonFile Load(IFFFile iffFile) { if (iffFile == null) { throw new ArgumentNullException("iffFile"); } // We dont care about whether its a (S)LOD or it just contains just one skeleton (SKTM) var skeletonNodes = string.Equals(iffFile.Root.Type, "SKTM", StringComparison.InvariantCultureIgnoreCase) ? new IFFFile.Node[] { iffFile.Root } : iffFile.Root.Descendents("SKTM").ToArray(); var skeletons = new List <SkeletonFile.Skeleton>(); foreach (var skeletonNode in skeletonNodes) { var bonesCount = skeletonNode.Descendents("INFO").First().Data.ReadInt32(); var boneNames = skeletonNode.Descendents("NAME").First().Data.ReadStringList(); if (boneNames.Count() != bonesCount) { throw new IOException("Invalid # of bone names"); } var boneParents = new List <int>(); using (var stream = new MemoryStream(skeletonNode.Descendents("PRNT").First().Data)) for (int i = 0; i < bonesCount; i++) { boneParents.Add(stream.ReadInt32()); } var bonePreRotations = new List <Quaternion>(); using (var stream = new MemoryStream(skeletonNode.Descendents("RPRE").First().Data)) for (int i = 0; i < bonesCount; i++) { bonePreRotations.Add(stream.ReadQuaternionSingle()); } var bonePostRotations = new List <Quaternion>(); using (var stream = new MemoryStream(skeletonNode.Descendents("RPST").First().Data)) for (int i = 0; i < bonesCount; i++) { bonePostRotations.Add(stream.ReadQuaternionSingle()); } var boneOffsets = new List <Vector3>(); using (var stream = new MemoryStream(skeletonNode.Descendents("BPTR").First().Data)) for (int i = 0; i < bonesCount; i++) { boneOffsets.Add(stream.ReadVector3Single()); } var bones = new List <SkeletonFile.SkeletonBone>(); for (int i = 0; i < bonesCount; i++) { bones.Add(new SkeletonFile.SkeletonBone { Name = boneNames[i], ParentIndex = boneParents[i], PreRotation = bonePreRotations[i], PostRotation = bonePostRotations[i], Offset = boneOffsets[i], }); } foreach (var bone in bones) { if (bone.ParentIndex >= 0) { bone.Parent = bones.ElementAt(bone.ParentIndex); } } skeletons.Add(new SkeletonFile.Skeleton { Bones = bones }); } return(new SkeletonFile { Skeletons = skeletons }); }