상속: ISWGFile
예제 #1
0
        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
            });
        }
예제 #2
0
 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;
 }
예제 #3
0
        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
            });
        }
예제 #4
0
        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
            });
        }
예제 #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);
        }
예제 #6
0
        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
            });
        }