Esempio n. 1
0
        public void Save(string path)
        {
            this.CompactBuffers();

            OptFileNodes optNodes = new OptFileNodes();

            Dictionary <string, bool> texturesWriten = this.Textures.Keys.ToDictionary(t => t, t => false);

            foreach (Mesh mesh in this.Meshes)
            {
                mesh.SortLods();

                NodeGroupNode meshNode = new NodeGroupNode();

                RotationScaleNode      rotationScaleNode   = new RotationScaleNode();
                MeshDescriptorNode     descriptorNode      = new MeshDescriptorNode();
                MeshVerticesNode       verticesNode        = new MeshVerticesNode();
                TextureCoordinatesNode textureVerticesNode = new TextureCoordinatesNode();
                VertexNormalsNode      vertexNormalsNode   = new VertexNormalsNode();

                rotationScaleNode.Pivot = mesh.RotationScale.Pivot;
                rotationScaleNode.Look  = mesh.RotationScale.Look;
                rotationScaleNode.Up    = mesh.RotationScale.Up;
                rotationScaleNode.Right = mesh.RotationScale.Right;

                descriptorNode.MeshType      = mesh.Descriptor.MeshType;
                descriptorNode.ExplosionType = mesh.Descriptor.ExplosionType;
                descriptorNode.Span          = mesh.Descriptor.Span;
                descriptorNode.Center        = mesh.Descriptor.Center;
                descriptorNode.Min           = mesh.Descriptor.Min;
                descriptorNode.Max           = mesh.Descriptor.Max;
                descriptorNode.TargetId      = mesh.Descriptor.TargetId;
                descriptorNode.Target        = mesh.Descriptor.Target;

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

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

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

                meshNode.Nodes.Add(verticesNode);
                meshNode.Nodes.Add(textureVerticesNode);
                meshNode.Nodes.Add(vertexNormalsNode);
                meshNode.Nodes.Add(descriptorNode);
                meshNode.Nodes.Add(rotationScaleNode);

                FaceGroupingNode faceGroupingNode = new FaceGroupingNode();

                foreach (var lod in mesh.Lods)
                {
                    NodeGroupNode lodNode = new NodeGroupNode();

                    foreach (var faceGroup in lod.FaceGroups)
                    {
                        if (faceGroup.Textures.Count != 0)
                        {
                            List <Node> texturesNodes = new List <Node>();

                            foreach (var textureName in faceGroup.Textures)
                            {
                                if (!texturesWriten.ContainsKey(textureName) || texturesWriten[textureName])
                                {
                                    NodeReferenceNode textureNode = new NodeReferenceNode()
                                    {
                                        Reference = textureName
                                    };

                                    texturesNodes.Add(textureNode);
                                }
                                else
                                {
                                    var texture = this.Textures[textureName];

                                    TextureNode textureNode = new TextureNode();
                                    textureNode.Name     = texture.Name;
                                    textureNode.UniqueId = 0; // texture.Id
                                    textureNode.Width    = texture.Width;
                                    textureNode.Height   = texture.Height;
                                    textureNode.Palettes = texture.Palette;
                                    textureNode.Bytes    = texture.ImageData;

                                    if (texture.AlphaData != null)
                                    {
                                        TextureAlphaNode alphaNode = new TextureAlphaNode();
                                        alphaNode.Bytes = texture.AlphaData;

                                        textureNode.Nodes.Add(alphaNode);
                                    }

                                    texturesNodes.Add(textureNode);

                                    texturesWriten[textureName] = true;
                                }
                            }

                            if (texturesNodes.Count == 1)
                            {
                                lodNode.Nodes.Add(texturesNodes[0]);
                            }
                            else
                            {
                                NodeSwitchNode switchNode = new NodeSwitchNode();

                                foreach (var textureNode in texturesNodes)
                                {
                                    switchNode.Nodes.Add(textureNode);
                                }

                                lodNode.Nodes.Add(switchNode);
                            }
                        }

                        FaceDataNode faceDataNode = new FaceDataNode();

                        faceDataNode.EdgesCount = faceGroup.EdgesCount;

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

                            faceDataNode.Faces.Add(faceData);
                        }

                        lodNode.Nodes.Add(faceDataNode);
                    }

                    faceGroupingNode.Distances.Add(lod.Distance);
                    faceGroupingNode.Nodes.Add(lodNode);
                }

                NodeGroupNode faceGroupingNodeGroup = new NodeGroupNode();
                faceGroupingNodeGroup.Nodes.Add(Node.Null);
                faceGroupingNodeGroup.Nodes.Add(Node.Null);
                faceGroupingNodeGroup.Nodes.Add(Node.Null);
                faceGroupingNodeGroup.Nodes.Add(faceGroupingNode);

                meshNode.Nodes.Add(faceGroupingNodeGroup);

                foreach (var hardpoint in mesh.Hardpoints)
                {
                    meshNode.Nodes.Add(new HardpointNode()
                    {
                        HardpointType = hardpoint.HardpointType,
                        Position      = hardpoint.Position
                    });
                }

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

                optNodes.Nodes.Add(meshNode);
            }

            foreach (var texture in texturesWriten.Where(t => !t.Value))
            {
                this.Textures.Remove(texture.Key);
            }

            optNodes.Save(path);
            this.FileName = path;
        }
Esempio n. 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);
        }