public static OptFile FromFile(string path)
        {
            OptFile opt = new OptFile();

            opt.FileName = path;

            OptFileNodes optNodes = OptFileNodes.FromFile(path);

            List<string> globalTexture = null;

            for (int meshId = 0; meshId < optNodes.Nodes.Count; meshId++)
            {
                if (meshId == 0 && optNodes.Nodes[meshId].NodeType == NodeType.Texture)
                {
                    TextureNode textureNode = (TextureNode)optNodes.Nodes[meshId];
                    opt.CreateTexture(textureNode);
                    globalTexture = new List<string>() { textureNode.Name };
                    continue;
                }

                if (optNodes.Nodes[meshId].NodeType != NodeType.NodeGroup)
                {
                    throw new InvalidDataException("invalid mesh");
                }

                NodeGroupNode meshNode = (NodeGroupNode)optNodes.Nodes[meshId];

                var meshNodes = meshNode.Nodes.Union((meshNode.Nodes.Where(t => t.NodeType == NodeType.NodeGroup).FirstOrDefault() ?? new NodeGroupNode()).Nodes).ToList();

                RotationScaleNode rotationScaleNode = (RotationScaleNode)meshNodes.FirstOrDefault(t => t.NodeType == NodeType.RotationScale);
                MeshDescriptorNode descriptorNode = (MeshDescriptorNode)meshNodes.FirstOrDefault(t => t.NodeType == NodeType.MeshDescriptor);
                MeshVerticesNode verticesNode = (MeshVerticesNode)meshNodes.First(t => t.NodeType == NodeType.MeshVertices);
                TextureCoordinatesNode textureVerticesNode = (TextureCoordinatesNode)meshNodes.First(t => t.NodeType == NodeType.TextureCoordinates);
                VertexNormalsNode vertexNormalsNode = (VertexNormalsNode)meshNodes.First(t => t.NodeType == NodeType.VertexNormals);

                var hardpointsNodes = meshNodes.Where(t => t.NodeType == NodeType.Hardpoint).Select(t => (HardpointNode)t).ToList();
                var engineGlowsNodes = meshNodes.Where(t => t.NodeType == NodeType.EngineGlow).Select(t => (EngineGlowNode)t).ToList();

                FaceGroupingNode faceGroupingNode = (FaceGroupingNode)meshNodes.First(t => t.NodeType == NodeType.FaceGrouping);

                Mesh mesh = new Mesh();

                if (rotationScaleNode != null)
                {
                    mesh.RotationScale.Pivot = rotationScaleNode.Pivot;
                    mesh.RotationScale.Look = rotationScaleNode.Look;
                    mesh.RotationScale.Up = rotationScaleNode.Up;
                    mesh.RotationScale.Right = rotationScaleNode.Right;
                }

                if (descriptorNode != null)
                {
                    mesh.Descriptor.MeshType = descriptorNode.MeshType;
                    mesh.Descriptor.ExplosionType = descriptorNode.ExplosionType;
                    mesh.Descriptor.Span = descriptorNode.Span;
                    mesh.Descriptor.Center = descriptorNode.Center;
                    mesh.Descriptor.Min = descriptorNode.Min;
                    mesh.Descriptor.Max = descriptorNode.Max;
                    mesh.Descriptor.TargetId = descriptorNode.TargetId;
                    mesh.Descriptor.Target = descriptorNode.Target;
                }

                foreach (Vector vertex in verticesNode.Vertices)
                {
                    mesh.Vertices.Add(vertex);
                }

                foreach (TextureCoordinates textureVertex in textureVerticesNode.TextureVertices)
                {
                    mesh.TextureCoordinates.Add(textureVertex);
                }

                foreach (Vector normal in vertexNormalsNode.Normals)
                {
                    mesh.VertexNormals.Add(normal);
                }

                foreach (var hardpoint in hardpointsNodes)
                {
                    mesh.Hardpoints.Add(new Hardpoint()
                    {
                        HardpointType = hardpoint.HardpointType,
                        Position = hardpoint.Position
                    });
                }

                foreach (var engineGlow in engineGlowsNodes)
                {
                    mesh.EngineGlows.Add(new EngineGlow()
                    {
                        IsDisabled = engineGlow.IsDisabled,
                        CoreColor = engineGlow.CoreColor,
                        OuterColor = engineGlow.OuterColor,
                        Position = engineGlow.Position,
                        Format = engineGlow.Format,
                        Look = engineGlow.Look,
                        Up = engineGlow.Up,
                        Right = engineGlow.Right
                    });
                }

                if (faceGroupingNode.Distances.Count != faceGroupingNode.Nodes.Count)
                {
                    throw new InvalidDataException("invalid face groups count in face grouping");
                }

                for (int lodId = 0; lodId < faceGroupingNode.Distances.Count; lodId++)
                {
                    List<string> texture = globalTexture;

                    MeshLod lod = new MeshLod();

                    lod.Distance = faceGroupingNode.Distances[lodId];

                    foreach (Node node in faceGroupingNode.Nodes[lodId].Nodes)
                    {
                        switch (node.NodeType)
                        {
                            case NodeType.Texture:
                                {
                                    TextureNode textureNode = (TextureNode)node;

                                    opt.CreateTexture(textureNode);
                                    texture = new List<string>() { textureNode.Name };
                                    break;
                                }

                            case NodeType.NodeReference:
                                texture = new List<string>() { ((NodeReferenceNode)node).Reference };
                                break;

                            case NodeType.NodeSwitch:
                                {
                                    NodeSwitchNode switchNode = (NodeSwitchNode)node;
                                    texture = new List<string>();

                                    foreach (Node nodeSwitch in switchNode.Nodes)
                                    {
                                        switch (nodeSwitch.NodeType)
                                        {
                                            case NodeType.Texture:
                                                {
                                                    TextureNode textureNode = (TextureNode)nodeSwitch;

                                                    opt.CreateTexture(textureNode);
                                                    texture.Add(textureNode.Name);
                                                    break;
                                                }

                                            case NodeType.NodeReference:
                                                texture.Add(((NodeReferenceNode)nodeSwitch).Reference);
                                                break;
                                        }
                                    }

                                    break;
                                }

                            case NodeType.FaceData:
                                {
                                    FaceDataNode faceDataNode = (FaceDataNode)node;

                                    FaceGroup faceGroup = new FaceGroup();

                                    if (texture != null)
                                    {
                                        foreach (var name in texture)
                                        {
                                            faceGroup.Textures.Add(name);
                                        }
                                    }

                                    foreach (var face in faceDataNode.Faces)
                                    {
                                        faceGroup.Faces.Add(new Face()
                                        {
                                            VerticesIndex = face.VerticesIndex,
                                            EdgesIndex = face.EdgesIndex,
                                            TextureCoordinatesIndex = face.TextureCoordinatesIndex,
                                            VertexNormalsIndex = face.VertexNormalsIndex,
                                            Normal = face.Normal,
                                            TexturingDirection = face.TexturingDirection,
                                            TexturingMagniture = face.TexturingMagniture
                                        });
                                    }

                                    foreach (var face in faceGroup.Faces)
                                    {
                                        if (face.VertexNormalsIndex.A >= mesh.VertexNormals.Count)
                                        {
                                            face.VertexNormalsIndex = face.VertexNormalsIndex.SetA(0);
                                        }

                                        if (face.VertexNormalsIndex.B >= mesh.VertexNormals.Count)
                                        {
                                            face.VertexNormalsIndex = face.VertexNormalsIndex.SetB(0);
                                        }

                                        if (face.VertexNormalsIndex.C >= mesh.VertexNormals.Count)
                                        {
                                            face.VertexNormalsIndex = face.VertexNormalsIndex.SetC(0);
                                        }

                                        if (face.VertexNormalsIndex.D >= mesh.VertexNormals.Count)
                                        {
                                            face.VertexNormalsIndex = face.VertexNormalsIndex.SetD(0);
                                        }

                                        if (face.TextureCoordinatesIndex.A >= mesh.TextureCoordinates.Count)
                                        {
                                            face.TextureCoordinatesIndex = face.TextureCoordinatesIndex.SetA(0);
                                        }

                                        if (face.TextureCoordinatesIndex.B >= mesh.TextureCoordinates.Count)
                                        {
                                            face.TextureCoordinatesIndex = face.TextureCoordinatesIndex.SetB(0);
                                        }

                                        if (face.TextureCoordinatesIndex.C >= mesh.TextureCoordinates.Count)
                                        {
                                            face.TextureCoordinatesIndex = face.TextureCoordinatesIndex.SetC(0);
                                        }

                                        if (face.TextureCoordinatesIndex.D >= mesh.TextureCoordinates.Count)
                                        {
                                            face.TextureCoordinatesIndex = face.TextureCoordinatesIndex.SetD(0);
                                        }

                                        if (face.VerticesIndex.A >= 0 && face.TextureCoordinatesIndex.A < 0)
                                        {
                                            face.TextureCoordinatesIndex = face.TextureCoordinatesIndex.SetA(0);
                                        }

                                        if (face.VerticesIndex.B >= 0 && face.TextureCoordinatesIndex.B < 0)
                                        {
                                            face.TextureCoordinatesIndex = face.TextureCoordinatesIndex.SetB(0);
                                        }

                                        if (face.VerticesIndex.C >= 0 && face.TextureCoordinatesIndex.C < 0)
                                        {
                                            face.TextureCoordinatesIndex = face.TextureCoordinatesIndex.SetC(0);
                                        }

                                        if (face.VerticesIndex.D >= 0 && face.TextureCoordinatesIndex.D < 0)
                                        {
                                            face.TextureCoordinatesIndex = face.TextureCoordinatesIndex.SetD(0);
                                        }
                                    }

                                    lod.FaceGroups.Add(faceGroup);

                                    texture = null;
                                    break;
                                }
                        }
                    }

                    mesh.Lods.Add(lod);
                }

                opt.Meshes.Add(mesh);
            }

            opt.SetFaceGroupTextureWhenEmpty();

            return opt;
        }
Example #2
0
        public static OptFile FromFile(string path)
        {
            OptFile opt = new OptFile();

            opt.FileName = path;

            OptFileNodes optNodes = OptFileNodes.FromFile(path);

            List <string> globalTexture = null;

            for (int meshId = 0; meshId < optNodes.Nodes.Count; meshId++)
            {
                if (meshId == 0 && optNodes.Nodes[meshId].NodeType == NodeType.Texture)
                {
                    TextureNode textureNode = (TextureNode)optNodes.Nodes[meshId];
                    opt.CreateTexture(textureNode);
                    globalTexture = new List <string>()
                    {
                        textureNode.Name
                    };
                    continue;
                }

                if (optNodes.Nodes[meshId].NodeType != NodeType.NodeGroup)
                {
                    throw new InvalidDataException("invalid mesh");
                }

                NodeGroupNode meshNode = (NodeGroupNode)optNodes.Nodes[meshId];

                var meshNodes = meshNode.Nodes.Union((meshNode.Nodes.Where(t => t.NodeType == NodeType.NodeGroup).FirstOrDefault() ?? new NodeGroupNode()).Nodes).ToList();

                RotationScaleNode      rotationScaleNode   = (RotationScaleNode)meshNodes.FirstOrDefault(t => t.NodeType == NodeType.RotationScale);
                MeshDescriptorNode     descriptorNode      = (MeshDescriptorNode)meshNodes.FirstOrDefault(t => t.NodeType == NodeType.MeshDescriptor);
                MeshVerticesNode       verticesNode        = (MeshVerticesNode)meshNodes.First(t => t.NodeType == NodeType.MeshVertices);
                TextureCoordinatesNode textureVerticesNode = (TextureCoordinatesNode)meshNodes.First(t => t.NodeType == NodeType.TextureCoordinates);
                VertexNormalsNode      vertexNormalsNode   = (VertexNormalsNode)meshNodes.First(t => t.NodeType == NodeType.VertexNormals);

                var hardpointsNodes  = meshNodes.Where(t => t.NodeType == NodeType.Hardpoint).Select(t => (HardpointNode)t).ToList();
                var engineGlowsNodes = meshNodes.Where(t => t.NodeType == NodeType.EngineGlow).Select(t => (EngineGlowNode)t).ToList();

                FaceGroupingNode faceGroupingNode = (FaceGroupingNode)meshNodes.First(t => t.NodeType == NodeType.FaceGrouping);

                Mesh mesh = new Mesh();

                if (rotationScaleNode != null)
                {
                    mesh.RotationScale.Pivot = rotationScaleNode.Pivot;
                    mesh.RotationScale.Look  = rotationScaleNode.Look;
                    mesh.RotationScale.Up    = rotationScaleNode.Up;
                    mesh.RotationScale.Right = rotationScaleNode.Right;
                }

                if (descriptorNode != null)
                {
                    mesh.Descriptor.MeshType      = descriptorNode.MeshType;
                    mesh.Descriptor.ExplosionType = descriptorNode.ExplosionType;
                    mesh.Descriptor.Span          = descriptorNode.Span;
                    mesh.Descriptor.Center        = descriptorNode.Center;
                    mesh.Descriptor.Min           = descriptorNode.Min;
                    mesh.Descriptor.Max           = descriptorNode.Max;
                    mesh.Descriptor.TargetId      = descriptorNode.TargetId;
                    mesh.Descriptor.Target        = descriptorNode.Target;
                }

                foreach (Vector vertex in verticesNode.Vertices)
                {
                    mesh.Vertices.Add(vertex);
                }

                foreach (TextureCoordinates textureVertex in textureVerticesNode.TextureVertices)
                {
                    mesh.TextureCoordinates.Add(textureVertex);
                }

                foreach (Vector normal in vertexNormalsNode.Normals)
                {
                    mesh.VertexNormals.Add(normal);
                }

                foreach (var hardpoint in hardpointsNodes)
                {
                    mesh.Hardpoints.Add(new Hardpoint()
                    {
                        HardpointType = hardpoint.HardpointType,
                        Position      = hardpoint.Position
                    });
                }

                foreach (var engineGlow in engineGlowsNodes)
                {
                    mesh.EngineGlows.Add(new EngineGlow()
                    {
                        IsDisabled = engineGlow.IsDisabled,
                        CoreColor  = engineGlow.CoreColor,
                        OuterColor = engineGlow.OuterColor,
                        Position   = engineGlow.Position,
                        Format     = engineGlow.Format,
                        Look       = engineGlow.Look,
                        Up         = engineGlow.Up,
                        Right      = engineGlow.Right
                    });
                }

                if (faceGroupingNode.Distances.Count != faceGroupingNode.Nodes.Count)
                {
                    throw new InvalidDataException("invalid face groups count in face grouping");
                }

                for (int lodId = 0; lodId < faceGroupingNode.Distances.Count; lodId++)
                {
                    List <string> texture = globalTexture;

                    MeshLod lod = new MeshLod();

                    lod.Distance = faceGroupingNode.Distances[lodId];

                    foreach (Node node in faceGroupingNode.Nodes[lodId].Nodes)
                    {
                        switch (node.NodeType)
                        {
                        case NodeType.Texture:
                        {
                            TextureNode textureNode = (TextureNode)node;

                            opt.CreateTexture(textureNode);
                            texture = new List <string>()
                            {
                                textureNode.Name
                            };
                            break;
                        }

                        case NodeType.NodeReference:
                            texture = new List <string>()
                            {
                                ((NodeReferenceNode)node).Reference
                            };
                            break;

                        case NodeType.NodeSwitch:
                        {
                            NodeSwitchNode switchNode = (NodeSwitchNode)node;
                            texture = new List <string>();

                            foreach (Node nodeSwitch in switchNode.Nodes)
                            {
                                switch (nodeSwitch.NodeType)
                                {
                                case NodeType.Texture:
                                {
                                    TextureNode textureNode = (TextureNode)nodeSwitch;

                                    opt.CreateTexture(textureNode);
                                    texture.Add(textureNode.Name);
                                    break;
                                }

                                case NodeType.NodeReference:
                                    texture.Add(((NodeReferenceNode)nodeSwitch).Reference);
                                    break;
                                }
                            }

                            break;
                        }

                        case NodeType.FaceData:
                        {
                            FaceDataNode faceDataNode = (FaceDataNode)node;

                            FaceGroup faceGroup = new FaceGroup();

                            if (texture != null)
                            {
                                foreach (var name in texture)
                                {
                                    faceGroup.Textures.Add(name);
                                }
                            }

                            foreach (var face in faceDataNode.Faces)
                            {
                                faceGroup.Faces.Add(new Face()
                                    {
                                        VerticesIndex           = face.VerticesIndex,
                                        EdgesIndex              = face.EdgesIndex,
                                        TextureCoordinatesIndex = face.TextureCoordinatesIndex,
                                        VertexNormalsIndex      = face.VertexNormalsIndex,
                                        Normal             = face.Normal,
                                        TexturingDirection = face.TexturingDirection,
                                        TexturingMagniture = face.TexturingMagniture
                                    });
                            }

                            foreach (var face in faceGroup.Faces)
                            {
                                if (face.VertexNormalsIndex.A >= mesh.VertexNormals.Count)
                                {
                                    face.VertexNormalsIndex = face.VertexNormalsIndex.SetA(0);
                                }

                                if (face.VertexNormalsIndex.B >= mesh.VertexNormals.Count)
                                {
                                    face.VertexNormalsIndex = face.VertexNormalsIndex.SetB(0);
                                }

                                if (face.VertexNormalsIndex.C >= mesh.VertexNormals.Count)
                                {
                                    face.VertexNormalsIndex = face.VertexNormalsIndex.SetC(0);
                                }

                                if (face.VertexNormalsIndex.D >= mesh.VertexNormals.Count)
                                {
                                    face.VertexNormalsIndex = face.VertexNormalsIndex.SetD(0);
                                }

                                if (face.TextureCoordinatesIndex.A >= mesh.TextureCoordinates.Count)
                                {
                                    face.TextureCoordinatesIndex = face.TextureCoordinatesIndex.SetA(0);
                                }

                                if (face.TextureCoordinatesIndex.B >= mesh.TextureCoordinates.Count)
                                {
                                    face.TextureCoordinatesIndex = face.TextureCoordinatesIndex.SetB(0);
                                }

                                if (face.TextureCoordinatesIndex.C >= mesh.TextureCoordinates.Count)
                                {
                                    face.TextureCoordinatesIndex = face.TextureCoordinatesIndex.SetC(0);
                                }

                                if (face.TextureCoordinatesIndex.D >= mesh.TextureCoordinates.Count)
                                {
                                    face.TextureCoordinatesIndex = face.TextureCoordinatesIndex.SetD(0);
                                }

                                if (face.VerticesIndex.A >= 0 && face.TextureCoordinatesIndex.A < 0)
                                {
                                    face.TextureCoordinatesIndex = face.TextureCoordinatesIndex.SetA(0);
                                }

                                if (face.VerticesIndex.B >= 0 && face.TextureCoordinatesIndex.B < 0)
                                {
                                    face.TextureCoordinatesIndex = face.TextureCoordinatesIndex.SetB(0);
                                }

                                if (face.VerticesIndex.C >= 0 && face.TextureCoordinatesIndex.C < 0)
                                {
                                    face.TextureCoordinatesIndex = face.TextureCoordinatesIndex.SetC(0);
                                }

                                if (face.VerticesIndex.D >= 0 && face.TextureCoordinatesIndex.D < 0)
                                {
                                    face.TextureCoordinatesIndex = face.TextureCoordinatesIndex.SetD(0);
                                }
                            }

                            lod.FaceGroups.Add(faceGroup);

                            texture = null;
                            break;
                        }
                        }
                    }

                    mesh.Lods.Add(lod);
                }

                opt.Meshes.Add(mesh);
            }

            opt.SetFaceGroupTextureWhenEmpty();

            return(opt);
        }