Example #1
0
        public SphFile(IntermediateNode root, ILibFile library)
        {
            if (root == null)
            {
                throw new ArgumentNullException("root");
            }
            if (library == null)
            {
                throw new ArgumentNullException("materialLibrary");
            }

            materialsAccessor = new SphMaterials(this);
            ready             = false;

            this.library      = library;
            sideMaterialNames = new List <string>();

            bool sphereSet = false;

            foreach (Node node in root)
            {
                switch (node.Name.ToLowerInvariant())
                {
                case "sphere":
                    if (sphereSet)
                    {
                        throw new Exception("Multiple sphere nodes");
                    }
                    sphereSet = true;
                    var sphereNode = (IntermediateNode)node;
                    foreach (LeafNode sphereSubNode in sphereNode)
                    {
                        string name = sphereSubNode.Name.ToLowerInvariant();

                        if (name.StartsWith("m", StringComparison.OrdinalIgnoreCase))
                        {
                            sideMaterialNames.Add(sphereSubNode.StringData);
                        }
                        else if (name == "radius")
                        {
                            Radius = sphereSubNode.SingleArrayData[0];
                        }
                        else if (name == "sides")
                        {
                            int count = sphereSubNode.Int32ArrayData[0];
                            if (count != sideMaterialNames.Count)
                            {
                                throw new Exception("Invalid number of sides in " + node.Name + ": " + count);
                            }
                        }
                        else
                        {
                            throw new Exception("Invalid node in " + node.Name + ": " + sphereSubNode.Name);
                        }
                    }
                    break;

                case "vmeshlibrary":
                    IntermediateNode vMeshLibraryNode = node as IntermediateNode;
                    if (VMeshLibrary == null)
                    {
                        VMeshLibrary = new VmsFile(vMeshLibraryNode, library);
                    }
                    else
                    {
                        throw new Exception("Multiple vmeshlibrary nodes in 3db root");
                    }
                    break;

                case "material library":
                    IntermediateNode materialLibraryNode = node as IntermediateNode;
                    if (MaterialLibrary == null)
                    {
                        MaterialLibrary = new MatFile(materialLibraryNode, library);
                    }
                    else
                    {
                        throw new Exception("Multiple material library nodes in 3db root");
                    }
                    break;

                case "texture library":
                    IntermediateNode textureLibraryNode = node as IntermediateNode;
                    if (TextureLibrary == null)
                    {
                        TextureLibrary = new TxmFile(textureLibraryNode);
                    }
                    else
                    {
                        throw new Exception("Multiple texture library nodes in 3db root");
                    }
                    break;
                }
            }
        }
Example #2
0
        public static Material FromNode(IntermediateNode node, ILibFile textureLibrary)
        {
            if (node == null)
            {
                throw new ArgumentNullException("node");
            }
            if (textureLibrary == null)
            {
                throw new ArgumentNullException("textureLibrary");
            }

            LeafNode typeNode = node["Type"] as LeafNode;

            if (typeNode == null)
            {
                throw new Exception("Invalid or missing type node in " + node.Name);
            }


            string type = typeNode.StringData;

            type = MaterialMap.Instance.Get(type) ?? type;
            type = MaterialMap.Instance.Get(node.Name.ToLowerInvariant()) ?? type;

            if (type == "HighGlassMaterial" ||
                type == "HUDAnimMaterial" ||
                type == "HUDIconMaterial" ||
                type == "PlanetWaterMaterial")
            {
                type = "DcDtOcOt";                 //HACK: Should do env mapping
            }
            if (type == "ExclusionZoneMaterial")
            {
                type = "DcDt";                 //HACK: This is handled in NebulaRenderer, not in Material.cs
            }
            var mat = new Material(node, textureLibrary, type);

            if (basicMaterials.Contains(type))
            {
                mat.isBasic = true;
            }
            else
            {
                switch (type)
                {
                case "Nebula":
                case "NebulaTwo":
                case "AtmosphereMaterial":
                case "DetailMapMaterial":
                case "DetailMap2Dm1Msk2PassMaterial":
                case "IllumDetailMapMaterial":
                case "Masked2DetailMapMaterial":
                case "NomadMaterialNoBendy":
                case "NomadMaterial":
                    break;

                default:
                    throw new Exception("Invalid material type: " + type);
                }
            }
            return(mat);
        }
Example #3
0
 public SphFile(string path, ILibFile materialLibrary) : this(parseFile(path), materialLibrary)
 {
 }
Example #4
0
 public CmpFile(string path, ILibFile additionalLibrary) : this(parseFile(path), additionalLibrary)
 {
     Path = path;
 }
Example #5
0
        public CmpFile(IntermediateNode rootnode, ILibFile additionalLibrary)
        {
            this.additionalLibrary = additionalLibrary;

            Models     = new Dictionary <string, ModelFile>();
            Cameras    = new Dictionary <string, CmpCameraInfo>();
            Constructs = new ConstructCollection();
            Parts      = new List <Part>();
            List <string> modelNames = new List <string>();

            foreach (Node node in rootnode)
            {
                switch (node.Name.ToLowerInvariant())
                {
                case "exporter version":
                    break;

                case "vmeshlibrary":
                    IntermediateNode vMeshLibraryNode = node as IntermediateNode;
                    if (VMeshLibrary == null)
                    {
                        VMeshLibrary = new VmsFile(vMeshLibraryNode, this);
                    }
                    else
                    {
                        throw new Exception("Multiple vmeshlibrary nodes in cmp root");
                    }
                    break;

                case "animation":
                    IntermediateNode animationNode = node as IntermediateNode;
                    if (Animation == null)
                    {
                        Animation = new AnmFile(animationNode, Constructs);
                    }
                    else
                    {
                        throw new Exception("Multiple animation nodes in cmp root");
                    }
                    break;

                case "material library":
                    IntermediateNode materialLibraryNode = node as IntermediateNode;
                    if (MaterialLibrary == null)
                    {
                        MaterialLibrary = new MatFile(materialLibraryNode, this);
                    }
                    else
                    {
                        throw new Exception("Multiple material library nodes in cmp root");
                    }
                    break;

                case "texture library":
                    IntermediateNode textureLibraryNode = node as IntermediateNode;
                    if (TextureLibrary == null)
                    {
                        TextureLibrary = new TxmFile(textureLibraryNode);
                    }
                    else
                    {
                        throw new Exception("Multiple texture library nodes in cmp root");
                    }
                    break;

                case "cmpnd":
                    IntermediateNode cmpndNode = node as IntermediateNode;
                    foreach (Node SubNode in cmpndNode)
                    {
                        if (SubNode is LeafNode)
                        {
                            continue;
                        }
                        var cmpndSubNode = (IntermediateNode)SubNode;
                        if (cmpndSubNode.Name.Equals("cons", StringComparison.OrdinalIgnoreCase))
                        {
                            Constructs.AddNode(cmpndSubNode);
                        }
                        else if (
                            cmpndSubNode.Name.StartsWith("part_", StringComparison.OrdinalIgnoreCase) ||
                            cmpndSubNode.Name.Equals("root", StringComparison.OrdinalIgnoreCase)
                            )
                        {
                            string objectName = string.Empty, fileName = string.Empty;

                            foreach (LeafNode partNode in cmpndSubNode)
                            {
                                switch (partNode.Name.ToLowerInvariant())
                                {
                                case "object name":
                                    objectName = partNode.StringData;
                                    break;

                                case "file name":
                                    fileName = partNode.StringData;
                                    break;

                                case "index":
                                    break;

                                default:
                                    FLLog.Error("Cmp", "Invalid node in " + cmpndSubNode.Name + ": " + partNode.Name);
                                    break;
                                }
                            }
                            Parts.Add(new Part(objectName, fileName, Models, Cameras, Constructs));
                        }
                        else
                        {
                            throw new Exception("Invalid node in " + cmpndNode.Name + ": " + cmpndSubNode.Name);
                        }
                    }
                    break;

                case "materialanim":
                    MaterialAnim = new MaterialAnimCollection((IntermediateNode)node);
                    break;

                default:
                    if (node is IntermediateNode)
                    {
                        var im = (IntermediateNode)node;
                        if (im.Any(x => x.Name.Equals("vmeshpart", StringComparison.OrdinalIgnoreCase) ||
                                   x.Name.Equals("multilevel", StringComparison.OrdinalIgnoreCase)))
                        {
                            ModelFile m = new ModelFile(im, this);
                            m.Path = node.Name;
                            Models.Add(node.Name, m);
                            modelNames.Add(node.Name);
                            break;
                        }
                        else if (im.Any(x => x.Name.Equals("camera", StringComparison.OrdinalIgnoreCase)))
                        {
                            var cam = new CmpCameraInfo(im);
                            Cameras.Add(im.Name, cam);
                            break;
                        }
                    }
                    FLLog.Error("Cmp", Path ?? "Utf" + ": Invalid Node in cmp root: " + node.Name);
                    break;
                }
            }
            //FL handles cmpnd nodes that point to non-existant models: fix up here
            List <Part> broken = new List <Part>();

            for (int i = 0; i < Parts.Count; i++)
            {
                if (Parts[i].IsBroken())
                {
                    broken.Add(Parts[i]);
                }
            }
            foreach (var b in broken)
            {
                Parts.Remove(b);
            }
        }
Example #6
0
 public MatFile(IntermediateNode materialLibraryNode, ILibFile additionalTextureLibrary)
     : this(additionalTextureLibrary)
 {
     setMaterials(materialLibraryNode);
 }
Example #7
0
        public DfmFile(IntermediateNode root, ILibFile additionalLibrary)
        {
            this.additionalLibrary = additionalLibrary;
            Levels = new Dictionary <int, DfmMesh>();

            Bones      = new Dictionary <string, Bone>();
            Parts      = new Dictionary <int, DfmPart>();
            Constructs = new DfmConstructs();

            foreach (Node node in root)
            {
                switch (node.Name.ToLowerInvariant())
                {
                case "exporter version":
                    break;

                case "material library":
                    IntermediateNode materialLibraryNode = node as IntermediateNode;
                    if (MaterialLibrary == null)
                    {
                        MaterialLibrary = new MatFile(materialLibraryNode, this);
                    }
                    else
                    {
                        throw new Exception("Multiple material library nodes in dfm root");
                    }
                    break;

                case "texture library":
                    IntermediateNode textureLibraryNode = node as IntermediateNode;
                    if (TextureLibrary == null)
                    {
                        TextureLibrary = new TxmFile(textureLibraryNode);
                    }
                    else
                    {
                        throw new Exception("Multiple texture library nodes in dfm root");
                    }
                    break;

                case "multilevel":
                    IntermediateNode multiLevelNode = node as IntermediateNode;
                    foreach (Node multiLevelSubNode in multiLevelNode)
                    {
                        if (multiLevelSubNode.Name.StartsWith("mesh", StringComparison.OrdinalIgnoreCase))
                        {
                            IntermediateNode meshNode = multiLevelSubNode as IntermediateNode;

                            int level = 0;
                            if (!int.TryParse(meshNode.Name.Substring(4), out level))
                            {
                                throw new Exception("");
                            }
                            Levels.Add(level, new DfmMesh(meshNode, this, Parts));
                        }
                        else if (multiLevelSubNode.Name.Equals("fractions", StringComparison.OrdinalIgnoreCase))
                        {
                            LeafNode fractionsNode = multiLevelSubNode as LeafNode;
                            if (Fractions == null)
                            {
                                Fractions = fractionsNode.SingleArrayData;
                            }
                            else
                            {
                                throw new Exception("Multiple fractions nodes in multilevel node");
                            }
                        }
                        else
                        {
                            throw new Exception("Invalid node in " + multiLevelNode.Name + ": " + multiLevelSubNode.Name);
                        }
                    }
                    break;

                case "skeleton":
                    IntermediateNode skeletonNode = node as IntermediateNode;
                    foreach (LeafNode skeletonSubNode in skeletonNode)
                    {
                        switch (skeletonSubNode.Name.ToLowerInvariant())
                        {
                        case "name":
                            if (Skeleton == null)
                            {
                                Skeleton = skeletonSubNode.StringData;
                            }
                            else
                            {
                                throw new Exception("Multiple name nodes in skeleton node");
                            }
                            break;

                        default: throw new Exception("Invalid node in " + skeletonSubNode.Name + ": " + skeletonSubNode.Name);
                        }
                    }
                    break;

                case "cmpnd":
                    IntermediateNode cmpndNode = node as IntermediateNode;
                    foreach (Node cmpndSubNode in cmpndNode)
                    {
                        if (cmpndSubNode.Name.Equals("scale", StringComparison.OrdinalIgnoreCase))
                        {
                            if (Scale == null)
                            {
                                Scale = (cmpndSubNode as LeafNode).SingleData;
                            }
                            else
                            {
                                throw new Exception("Multiple scale nodes in cmpnd node");
                            }
                        }
                        else if (cmpndSubNode.Name.Equals("cons", StringComparison.OrdinalIgnoreCase))
                        {
                            IntermediateNode consNode = cmpndSubNode as IntermediateNode;
                            Constructs.AddNode(consNode);
                        }
                        else if (
                            cmpndSubNode.Name.StartsWith("part_", StringComparison.OrdinalIgnoreCase) ||
                            cmpndSubNode.Name.Equals("root", StringComparison.OrdinalIgnoreCase)
                            )
                        {
                            IntermediateNode partsNode = cmpndSubNode as IntermediateNode;
                            string           objectName = string.Empty, fileName = string.Empty;
                            int index = -1;

                            foreach (LeafNode partNode in partsNode)
                            {
                                switch (partNode.Name.ToLowerInvariant())
                                {
                                case "object name":
                                    objectName = partNode.StringData;
                                    break;

                                case "file name":
                                    fileName = partNode.StringData;
                                    break;

                                case "index":
                                    index = partNode.Int32Data.Value;
                                    break;

                                default: throw new Exception("Invalid node in " + cmpndSubNode.Name + ": " + partNode.Name);
                                }
                            }

                            Parts.Add(index, new DfmPart(objectName, fileName, Bones, null));
                        }
                        else
                        {
                            throw new Exception("Invalid node in " + node.Name + ": " + cmpndSubNode.Name);
                        }
                    }
                    break;

                default:
                    if (node.Name.EndsWith(".3db", StringComparison.OrdinalIgnoreCase))
                    {
                        Bone b = new Bone(node as IntermediateNode);
                        Bones.Add(node.Name, b);
                    }
                    else
                    {
                        throw new Exception("Invalid Node in dfm root: " + node.Name);
                    }
                    break;
                }
            }
        }
Example #8
0
        public DfmMesh(IntermediateNode root, ILibFile materialLibrary, Dictionary <int, DfmPart> parts)
        {
            this.parts = parts;
            FaceGroups = new List <FaceGroup>();

            foreach (IntermediateNode node in root)
            {
                switch (node.Name.ToLowerInvariant())
                {
                case "face_groups":
                    IntermediateNode faceGroupsNode = node as IntermediateNode;
                    foreach (Node faceGroupNode in faceGroupsNode)
                    {
                        if (faceGroupNode.Name.ToLowerInvariant() == "count")
                        {
                            // ignore
                        }
                        else if (faceGroupNode.Name.StartsWith("group", StringComparison.OrdinalIgnoreCase))
                        {
                            FaceGroups.Add(new FaceGroup(faceGroupNode as IntermediateNode, materialLibrary));
                        }
                        else
                        {
                            throw new Exception("Invalid node in " + faceGroupsNode.Name + ": " + faceGroupNode.Name);
                        }
                    }
                    break;

                case "geometry":
                    foreach (LeafNode geometrySubNode in node)
                    {
                        switch (geometrySubNode.Name.ToLowerInvariant())
                        {
                        case "point_indices":
                            PointIndices = geometrySubNode.Int32ArrayData;
                            break;

                        case "uv0_indices":
                            UV0Indices = geometrySubNode.Int32ArrayData;
                            break;

                        case "uv1_indices":
                            UV1Indices = geometrySubNode.Int32ArrayData;
                            break;

                        case "points":
                            Points = geometrySubNode.Vector3ArrayData;
                            break;

                        case "point_bone_first":
                            PointBoneFirst = geometrySubNode.Int32ArrayData;
                            break;

                        case "point_bone_count":
                            PointBoneCount = geometrySubNode.Int32ArrayData;
                            break;

                        case "bone_id_chain":
                            BoneIdChain = geometrySubNode.Int32ArrayData;
                            break;

                        case "bone_weight_chain":
                            BoneWeightChain = geometrySubNode.SingleArrayData;
                            break;

                        case "vertex_normals":
                            VertexNormals = geometrySubNode.Vector3ArrayData;
                            break;

                        case "uv0":
                            UV0 = geometrySubNode.Vector2ArrayData;
                            break;

                        case "uv1":
                            UV1 = geometrySubNode.Vector2ArrayData;
                            break;

                        case "uv_bone_id":
                            UVBoneId = geometrySubNode;
                            break;

                        case "uv_vertex_count":
                            UVVertexCount = geometrySubNode;
                            break;

                        case "uv_plane_distance":
                            UVPlaneDistance = geometrySubNode;
                            break;

                        case "bone_x_to_u_scale":
                            BoneXToUScale = geometrySubNode;
                            break;

                        case "bone_y_to_v_scale":
                            BoneYToVScale = geometrySubNode;
                            break;

                        case "min_du":
                            MinDU = geometrySubNode;
                            break;

                        case "max_du":
                            MaxDU = geometrySubNode;
                            break;

                        case "min_dv":
                            MinDV = geometrySubNode;
                            break;

                        case "max_dv":
                            MaxDV = geometrySubNode;
                            break;

                        case "uv_vertex_id":
                            UVVertexId = geometrySubNode;
                            break;

                        case "uv_default_list":
                            UVDefaultList = geometrySubNode;
                            break;

                        default: throw new Exception("Invalid node in " + node.Name + ": " + geometrySubNode.Name);
                        }
                    }
                    break;

                default: throw new Exception("Invalid node in " + root.Name + ": " + node.Name);
                }
            }
        }
Example #9
0
        public MatFile(ILibFile additionalTextureLibrary)
        {
            this.additionalTextureLibrary = additionalTextureLibrary;

            Materials = new Dictionary <uint, Material> ();
        }
Example #10
0
        public VMeshData(ArraySegment <byte> data, ILibFile materialLibrary, string name)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }
            if (materialLibrary == null)
            {
                throw new ArgumentNullException("materialLibrary");
            }
            vmsname = name;
            ready   = false;

            using (BinaryReader reader = new BinaryReader(data.GetReadStream()))
            {
                // Read the data header.
                MeshType             = reader.ReadUInt32();
                SurfaceType          = reader.ReadUInt32();
                MeshCount            = reader.ReadUInt16();
                IndexCount           = reader.ReadUInt16();
                FlexibleVertexFormat = (D3DFVF)reader.ReadUInt16();
                OriginalFVF          = FlexibleVertexFormat;
                VertexCount          = reader.ReadUInt16();

                // Read the mesh headers.
                Meshes = new List <TMeshHeader>();
                int triangleStartOffset = 0;
                for (int count = 0; count < MeshCount; count++)
                {
                    TMeshHeader item = new TMeshHeader(reader, triangleStartOffset, materialLibrary);
                    if (item.NumRefVertices < 3)
                    {
                        FLLog.Warning("Vms", $"{name} mesh {count} references 0 triangles");
                    }
                    triangleStartOffset += item.NumRefVertices;
                    Meshes.Add(item);
                }

                // Read the triangle data
                Indices = new ushort[IndexCount];
                for (int i = 0; i < IndexCount; i++)
                {
                    Indices[i] = reader.ReadUInt16();
                }

                // Read the vertex data.
                // The FVF defines what fields are included for each vertex.
                switch (FlexibleVertexFormat)
                {
                case D3DFVF.XYZ:     //(D3DFVF)0x0002:
                    verticesVertexPosition = new VertexPosition[VertexCount];
                    for (int i = 0; i < VertexCount; i++)
                    {
                        verticesVertexPosition[i] = new VertexPosition(reader);
                    }
                    break;

                case D3DFVF.XYZ | D3DFVF.NORMAL:     //(D3DFVF)0x0012:
                    verticesVertexPositionNormal = new VertexPositionNormal[VertexCount];
                    for (int i = 0; i < VertexCount; i++)
                    {
                        verticesVertexPositionNormal[i] = new VertexPositionNormal(reader);
                    }
                    break;

                case D3DFVF.XYZ | D3DFVF.TEX1:     //(D3DFVF)0x0102:
                    verticesVertexPositionNormalTexture = new VertexPositionNormalTexture[VertexCount];
                    for (int i = 0; i < VertexCount; i++)
                    {
                        Vector3 position          = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                        Vector2 textureCoordinate = new Vector2(reader.ReadSingle(), 1 - reader.ReadSingle());
                        verticesVertexPositionNormalTexture[i] = new VertexPositionNormalTexture(position, Vector3.One, textureCoordinate);
                    }
                    FlexibleVertexFormat |= D3DFVF.NORMAL;
                    break;

                case D3DFVF.XYZ | D3DFVF.NORMAL | D3DFVF.TEX1:     //(D3DFVF)0x0112:
                    verticesVertexPositionNormalTexture = new VertexPositionNormalTexture[VertexCount];
                    for (int i = 0; i < VertexCount; i++)
                    {
                        Vector3 position          = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                        Vector3 normal            = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                        Vector2 textureCoordinate = new Vector2(reader.ReadSingle(), 1 - reader.ReadSingle());
                        verticesVertexPositionNormalTexture[i] = new VertexPositionNormalTexture(position, normal, textureCoordinate);
                    }
                    break;

                case D3DFVF.XYZ | D3DFVF.DIFFUSE | D3DFVF.TEX1:     //(D3DFVF)0x0142:
                    verticesVertexPositionNormalDiffuseTexture = new VertexPositionNormalDiffuseTexture[VertexCount];
                    Diffuse = new uint[VertexCount];
                    for (int i = 0; i < VertexCount; i++)
                    {
                        Vector3 position = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                        Diffuse[i] = reader.ReadUInt32();
                        Vector2 textureCoordinate = new Vector2(reader.ReadSingle(), 1 - reader.ReadSingle());
                        verticesVertexPositionNormalDiffuseTexture[i] = new VertexPositionNormalDiffuseTexture(position, Vector3.One, Diffuse[i], textureCoordinate);
                    }
                    FlexibleVertexFormat |= D3DFVF.NORMAL;
                    break;

                case D3DFVF.XYZ | D3DFVF.NORMAL | D3DFVF.DIFFUSE | D3DFVF.TEX1:     //(D3DFVF)0x0152:
                    verticesVertexPositionNormalDiffuseTexture = new VertexPositionNormalDiffuseTexture[VertexCount];
                    Diffuse = new uint[VertexCount];
                    for (int i = 0; i < VertexCount; i++)
                    {
                        var position = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                        var normal   = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                        Diffuse[i] = reader.ReadUInt32();
                        Vector2 textureCoordinate = new Vector2(reader.ReadSingle(), 1 - reader.ReadSingle());
                        verticesVertexPositionNormalDiffuseTexture[i] = new VertexPositionNormalDiffuseTexture(position, normal, Diffuse[i], textureCoordinate);
                    }
                    break;

                //TODO: Hacky
                case D3DFVF.XYZ | D3DFVF.NORMAL | D3DFVF.DIFFUSE:
                    verticesVertexPositionNormalDiffuseTexture = new VertexPositionNormalDiffuseTexture[VertexCount];
                    Diffuse = new uint[VertexCount];
                    for (int i = 0; i < VertexCount; i++)
                    {
                        var position = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                        var normal   = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                        Diffuse[i] = reader.ReadUInt32();
                        verticesVertexPositionNormalDiffuseTexture[i] = new VertexPositionNormalDiffuseTexture(position, normal, Diffuse[i], Vector2.Zero);
                    }
                    break;

                case D3DFVF.XYZ | D3DFVF.NORMAL | D3DFVF.TEX2:     //(D3DFVF)0x0212:
                    verticesVertexPositionNormalTextureTwo = new VertexPositionNormalTextureTwo[VertexCount];
                    for (int i = 0; i < VertexCount; i++)
                    {
                        verticesVertexPositionNormalTextureTwo[i] = new VertexPositionNormalTextureTwo(reader);
                    }
                    break;

                case D3DFVF.XYZ | D3DFVF.NORMAL | D3DFVF.DIFFUSE | D3DFVF.TEX2:     //(D3DFVF)0x0252:
                    verticesVertexPositionNormalDiffuseTextureTwo = new VertexPositionNormalDiffuseTextureTwo[VertexCount];
                    for (int i = 0; i < VertexCount; i++)
                    {
                        verticesVertexPositionNormalDiffuseTextureTwo[i] = new VertexPositionNormalDiffuseTextureTwo(reader);
                    }
                    break;

                /*case D3DFVF.XYZ | D3DFVF.NORMAL | D3DFVF.TEX4: //(D3DFVF)0x0412:
                 *  for (int i = 0; i < VertexCount; i++) vertices[i] = new VertexPositionNormalTextureTangentBinormal(reader);
                 *  break;*/
                default:
                    throw new FileContentException("UTF:VMeshData", "FVF 0x" + ((int)FlexibleVertexFormat).ToString("X") + " not supported.");
                }
            }
        }
 public VmsFile(IntermediateNode vMeshLibrary, ILibFile materialLibrary)
     : this()
 {
     setMeshes(vMeshLibrary, materialLibrary);
 }
Example #12
0
        private void load(IntermediateNode root, ILibFile additionalLibrary)
        {
            this.additionalLibrary = additionalLibrary;
            ready = false;

            Hardpoints = new List <HardpointDefinition>();
            var lvls = new Dictionary <int, VMeshRef>();

            foreach (Node node in root)
            {
                switch (node.Name.ToLowerInvariant())
                {
                case "exporter version":
                    break;

                case "vmeshlibrary":
                    IntermediateNode vMeshLibraryNode = node as IntermediateNode;
                    if (VMeshLibrary == null)
                    {
                        VMeshLibrary = new VmsFile(vMeshLibraryNode, this);
                    }
                    else
                    {
                        throw new Exception("Multiple vmeshlibrary nodes in 3db root");
                    }
                    break;

                case "material library":
                    IntermediateNode materialLibraryNode = node as IntermediateNode;
                    if (MaterialLibrary == null)
                    {
                        MaterialLibrary = new MatFile(materialLibraryNode, this);
                    }
                    else
                    {
                        throw new Exception("Multiple material library nodes in 3db root");
                    }
                    break;

                case "texture library":
                    IntermediateNode textureLibraryNode = node as IntermediateNode;
                    if (TextureLibrary == null)
                    {
                        TextureLibrary = new TxmFile(textureLibraryNode);
                    }
                    else
                    {
                        throw new Exception("Multiple texture library nodes in 3db root");
                    }
                    break;

                case "hardpoints":
                    IntermediateNode hardpointsNode = node as IntermediateNode;
                    foreach (Node hpn in hardpointsNode)
                    {
                        if (hpn is LeafNode)
                        {
                            continue;                                     //No nodes here
                        }
                        var hardpointTypeNode = (IntermediateNode)hpn;
                        switch (hardpointTypeNode.Name.ToLowerInvariant())
                        {
                        case "fixed":
                            foreach (IntermediateNode fixedNode in hardpointTypeNode)
                            {
                                Hardpoints.Add(new FixedHardpointDefinition(fixedNode));
                            }
                            break;

                        case "revolute":
                            foreach (IntermediateNode revoluteNode in hardpointTypeNode)
                            {
                                Hardpoints.Add(new RevoluteHardpointDefinition(revoluteNode));
                            }
                            break;

                        default:
                            Hardpoints.Add(new FixedHardpointDefinition(hardpointTypeNode));
                            break;
                        }
                    }
                    break;

                case "vmeshpart":
                {
                    IntermediateNode vMeshPartNode = node as IntermediateNode;
                    if (vMeshPartNode.Count == 1)
                    {
                        LeafNode vMeshRefNode = vMeshPartNode[0] as LeafNode;
                        lvls.Add(0, new VMeshRef(vMeshRefNode.DataSegment, this));
                    }
                    else
                    {
                        throw new Exception("Invalid VMeshPart: More than one child or zero elements");
                    }
                }
                break;

                case "multilevel":
                    IntermediateNode multiLevelNode = node as IntermediateNode;
                    foreach (Node multiLevelSubNode in multiLevelNode)
                    {
                        if (multiLevelSubNode.Name.StartsWith("level", StringComparison.OrdinalIgnoreCase))
                        {
                            if (multiLevelSubNode is LeafNode)
                            {
                                continue;
                            }
                            IntermediateNode levelNode = multiLevelSubNode as IntermediateNode;
                            if (levelNode.Count == 1)
                            {
                                int level = 0;
                                if (!int.TryParse(levelNode.Name.Substring(5), out level))
                                {
                                    throw new Exception("Invalid Level: Missing index");
                                }

                                IntermediateNode vMeshPartNode = levelNode[0] as IntermediateNode;

                                if (vMeshPartNode.Count == 1)
                                {
                                    LeafNode vMeshRefNode = vMeshPartNode[0] as LeafNode;
                                    if (vMeshRefNode != null && vMeshRefNode.Name.Equals("vmeshref",
                                                                                         StringComparison.OrdinalIgnoreCase))
                                    {
                                        lvls.Add(level, new VMeshRef(vMeshRefNode.DataSegment, this));
                                    }
                                }
                                else
                                {
                                    throw new Exception("Invalid VMeshPart: More than one child or zero elements");
                                }
                            }
                            //else throw new Exception("Invalid Level: More than one child or zero elements");
                        }
                        else if (multiLevelSubNode.Name.Equals("switch2", StringComparison.OrdinalIgnoreCase))
                        {
                            LeafNode switch2Node = multiLevelSubNode as LeafNode;
                            Switch2 = switch2Node.SingleArrayData;
                        }
                        else
                        {
                            throw new Exception("Invalid node in " + multiLevelNode.Name + ": " + multiLevelSubNode.Name);
                        }
                    }
                    break;

                case "vmeshwire":
                    VMeshWire = new VMeshWire(node as IntermediateNode, this);
                    break;

                case "mass properties":
                    // TODO 3db Mass Properties
                    break;

                case "extent tree":
                    // TODO 3db Extent Tree
                    break;

                case "materialanim":
                    MaterialAnim = new MaterialAnimCollection((IntermediateNode)node);
                    break;

                default:
                    FLLog.Error("3db", (Path ?? "") + ": Invalid node: " + node.Name);
                    break;
                }
            }

            //Sort levels in order
            var lvl2 = new List <VMeshRef>();

            for (int i = 0; i < 100; i++)
            {
                if (lvls.ContainsKey(i))
                {
                    lvl2.Add(lvls[i]);
                }
                else
                {
                    break;
                }
            }
            Levels = lvl2.ToArray();
        }
Example #13
0
 public ModelFile(IntermediateNode root, ILibFile additionalLibrary)
 {
     Path = root.Name;
     load(root, additionalLibrary);
 }
Example #14
0
 public ModelFile(string path, ILibFile additionalLibrary)
 {
     Path = path;
     load(parseFile(path), additionalLibrary);
 }
Example #15
0
        public CmpFile(IntermediateNode rootnode, ILibFile additionalLibrary)
        {
            this.additionalLibrary = additionalLibrary;

            Models     = new Dictionary <string, ModelFile>();
            Constructs = new ConstructCollection();
            Parts      = new Dictionary <int, Part>();

            foreach (Node node in rootnode)
            {
                switch (node.Name.ToLowerInvariant())
                {
                case "exporter version":
                    break;

                case "vmeshlibrary":
                    IntermediateNode vMeshLibraryNode = node as IntermediateNode;
                    if (VMeshLibrary == null)
                    {
                        VMeshLibrary = new VmsFile(vMeshLibraryNode, this);
                    }
                    else
                    {
                        throw new Exception("Multiple vmeshlibrary nodes in cmp root");
                    }
                    break;

                case "animation":
                    IntermediateNode animationNode = node as IntermediateNode;
                    if (Animation == null)
                    {
                        Animation = new AnmFile(animationNode, Constructs);
                    }
                    else
                    {
                        throw new Exception("Multiple animation nodes in cmp root");
                    }
                    break;

                case "material library":
                    IntermediateNode materialLibraryNode = node as IntermediateNode;
                    if (MaterialLibrary == null)
                    {
                        MaterialLibrary = new MatFile(materialLibraryNode, this);
                    }
                    else
                    {
                        throw new Exception("Multiple material library nodes in cmp root");
                    }
                    break;

                case "texture library":
                    IntermediateNode textureLibraryNode = node as IntermediateNode;
                    if (TextureLibrary == null)
                    {
                        TextureLibrary = new TxmFile(textureLibraryNode);
                    }
                    else
                    {
                        throw new Exception("Multiple texture library nodes in cmp root");
                    }
                    break;

                case "cmpnd":
                    IntermediateNode cmpndNode = node as IntermediateNode;
                    int maxIndices             = int.MaxValue;
                    foreach (Node SubNode in cmpndNode)
                    {
                        if (SubNode is LeafNode)
                        {
                            continue;
                        }
                        var cmpndSubNode = (IntermediateNode)SubNode;
                        if (cmpndSubNode.Name.Equals("cons", StringComparison.OrdinalIgnoreCase))
                        {
                            Constructs.AddNode(cmpndSubNode);
                        }
                        else if (
                            cmpndSubNode.Name.StartsWith("part_", StringComparison.OrdinalIgnoreCase) ||
                            cmpndSubNode.Name.Equals("root", StringComparison.OrdinalIgnoreCase)
                            )
                        {
                            string objectName = string.Empty, fileName = string.Empty;
                            int    index = -1;

                            foreach (LeafNode partNode in cmpndSubNode)
                            {
                                switch (partNode.Name.ToLowerInvariant())
                                {
                                case "object name":
                                    objectName = partNode.StringData;
                                    break;

                                case "file name":
                                    fileName = partNode.StringData;
                                    break;

                                case "index":
                                    if (partNode.Int32Data != null)
                                    {
                                        index = partNode.Int32Data.Value;
                                    }
                                    else
                                    {
                                        index = partNode.Int32ArrayData [0];
                                    }
                                    break;

                                default: throw new Exception("Invalid node in " + cmpndSubNode.Name + ": " + partNode.Name);
                                }
                            }
                            if (Parts.ContainsKey(index))
                            {
                                FLLog.Error("Cmp", "Duplicate index");
                                Parts.Add(maxIndices--, new Part(objectName, fileName, Models, Constructs));
                            }
                            else
                            {
                                Parts.Add(index, new Part(objectName, fileName, Models, Constructs));
                            }
                        }
                        else
                        {
                            throw new Exception("Invalid node in " + cmpndNode.Name + ": " + cmpndSubNode.Name);
                        }
                    }
                    break;

                case "materialanim":
                    MaterialAnim = new MaterialAnimCollection((IntermediateNode)node);
                    break;

                default:
                    if (node.Name.EndsWith(".3db", StringComparison.OrdinalIgnoreCase))
                    {
                        ModelFile m = new ModelFile(node as IntermediateNode, this);
                        m.Path = node.Name;
                        Models.Add(node.Name, m);
                    }
                    else
                    {
                        FLLog.Error("Cmp", Path ?? "Utf" + ": Invalid Node in cmp root: " + node.Name);
                    }
                    break;
                }
            }
        }
Example #16
0
        public VMeshData(byte[] data, ILibFile materialLibrary, string name)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }
            if (materialLibrary == null)
            {
                throw new ArgumentNullException("materialLibrary");
            }
            vmsname = name;
            ready   = false;

            using (BinaryReader reader = new BinaryReader(new MemoryStream(data)))
            {
                // Read the data header.
                MeshType             = reader.ReadUInt32();
                SurfaceType          = reader.ReadUInt32();
                MeshCount            = reader.ReadUInt16();
                IndexCount           = reader.ReadUInt16();
                FlexibleVertexFormat = (D3DFVF)reader.ReadUInt16();
                VertexCount          = reader.ReadUInt16();

                // Read the mesh headers.
                Meshes = new List <TMeshHeader>();
                int triangleStartOffset = 0;
                for (int count = 0; count < MeshCount; count++)
                {
                    TMeshHeader item = new TMeshHeader(reader, triangleStartOffset, materialLibrary);
                    triangleStartOffset += item.NumRefVertices;
                    Meshes.Add(item);
                }

                // Read the triangle data
                Indices = new ushort[IndexCount];
                for (int i = 0; i < IndexCount; i++)
                {
                    Indices[i] = reader.ReadUInt16();
                }

                // Read the vertex data.
                // The FVF defines what fields are included for each vertex.
                switch (FlexibleVertexFormat)
                {
                case D3DFVF.XYZ:     //(D3DFVF)0x0002:
                    verticesVertexPosition = new VertexPosition[VertexCount];
                    for (int i = 0; i < VertexCount; i++)
                    {
                        verticesVertexPosition[i] = new VertexPosition(reader);
                    }
                    break;

                case D3DFVF.XYZ | D3DFVF.NORMAL:     //(D3DFVF)0x0012:
                    verticesVertexPositionNormal = new VertexPositionNormal[VertexCount];
                    for (int i = 0; i < VertexCount; i++)
                    {
                        verticesVertexPositionNormal[i] = new VertexPositionNormal(reader);
                    }
                    break;

                case D3DFVF.XYZ | D3DFVF.TEX1:     //(D3DFVF)0x0102:
                    verticesVertexPositionNormalTexture = new VertexPositionNormalTexture[VertexCount];
                    for (int i = 0; i < VertexCount; i++)
                    {
                        Vector3 position          = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                        Vector2 textureCoordinate = new Vector2(reader.ReadSingle(), 1 - reader.ReadSingle());
                        verticesVertexPositionNormalTexture[i] = new VertexPositionNormalTexture(position, Vector3.Zero, textureCoordinate);
                    }
                    CalculateNormals(verticesVertexPositionNormalTexture);
                    FlexibleVertexFormat |= D3DFVF.NORMAL;
                    break;

                case D3DFVF.XYZ | D3DFVF.NORMAL | D3DFVF.TEX1:     //(D3DFVF)0x0112:
                    verticesVertexPositionNormalTexture = new VertexPositionNormalTexture[VertexCount];
                    for (int i = 0; i < VertexCount; i++)
                    {
                        Vector3 position          = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                        Vector3 normal            = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                        Vector2 textureCoordinate = new Vector2(reader.ReadSingle(), 1 - reader.ReadSingle());
                        verticesVertexPositionNormalTexture[i] = new VertexPositionNormalTexture(position, normal, textureCoordinate);
                    }
                    break;

                case D3DFVF.XYZ | D3DFVF.DIFFUSE | D3DFVF.TEX1:     //(D3DFVF)0x0142:
                    verticesVertexPositionNormalColorTexture = new VertexPositionNormalColorTexture[VertexCount];
                    for (int i = 0; i < VertexCount; i++)
                    {
                        Vector3 position          = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                        int     r                 = reader.ReadByte();
                        int     g                 = reader.ReadByte();
                        int     b                 = reader.ReadByte();
                        int     a                 = reader.ReadByte();
                        Color4  diffuse           = new Color4(r / 255f, g / 255f, b / 255f, a / 255f);
                        Vector2 textureCoordinate = new Vector2(reader.ReadSingle(), 1 - reader.ReadSingle());
                        verticesVertexPositionNormalColorTexture[i] = new VertexPositionNormalColorTexture(position, Vector3.Zero, diffuse, textureCoordinate);
                    }
                    FlexibleVertexFormat |= D3DFVF.NORMAL;
                    CalculateNormals(verticesVertexPositionNormalColorTexture);
                    break;

                case D3DFVF.XYZ | D3DFVF.NORMAL | D3DFVF.DIFFUSE | D3DFVF.TEX1:     //(D3DFVF)0x0152:
                    verticesVertexPositionNormalColorTexture = new VertexPositionNormalColorTexture[VertexCount];
                    for (int i = 0; i < VertexCount; i++)
                    {
                        //verticesVertexPositionNormalDiffuseTexture[i] = new VertexPositionNormalDiffuseTexture(reader);
                        var     position          = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                        var     normal            = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                        int     r                 = reader.ReadByte();
                        int     g                 = reader.ReadByte();
                        int     b                 = reader.ReadByte();
                        int     a                 = reader.ReadByte();
                        Color4  diffuse           = new Color4(r / 255f, g / 255f, b / 255f, a / 255f);
                        Vector2 textureCoordinate = new Vector2(reader.ReadSingle(), 1 - reader.ReadSingle());
                        verticesVertexPositionNormalColorTexture[i] = new VertexPositionNormalColorTexture(position, normal, diffuse, textureCoordinate);
                    }
                    break;

                case D3DFVF.XYZ | D3DFVF.NORMAL | D3DFVF.TEX2:     //(D3DFVF)0x0212:
                    verticesVertexPositionNormalTextureTwo = new VertexPositionNormalTextureTwo[VertexCount];
                    for (int i = 0; i < VertexCount; i++)
                    {
                        verticesVertexPositionNormalTextureTwo[i] = new VertexPositionNormalTextureTwo(reader);
                    }
                    break;

                case D3DFVF.XYZ | D3DFVF.NORMAL | D3DFVF.DIFFUSE | D3DFVF.TEX2:     //(D3DFVF)0x0252:
                    verticesVertexPositionNormalDiffuseTextureTwo = new VertexPositionNormalDiffuseTextureTwo[VertexCount];
                    for (int i = 0; i < VertexCount; i++)
                    {
                        verticesVertexPositionNormalDiffuseTextureTwo[i] = new VertexPositionNormalDiffuseTextureTwo(reader);
                    }
                    break;

                /*case D3DFVF.XYZ | D3DFVF.NORMAL | D3DFVF.TEX4: //(D3DFVF)0x0412:
                 *  for (int i = 0; i < VertexCount; i++) vertices[i] = new VertexPositionNormalTextureTangentBinormal(reader);
                 *  break;*/
                default:
                    throw new FileContentException("UTF:VMeshData", "FVF 0x" + FlexibleVertexFormat + " not supported.");
                }
            }
        }