internal static Node ParseNode(byte[] buffer, int globalOffset, int offset)
        {
            NodeType type = (NodeType)BitConverter.ToInt32(buffer, offset + 4);

            Node node = null;

            switch (type)
            {
                case NodeType.NullNode:
                    node = new NullNode();
                    break;
                case NodeType.NodeGroup:
                    node = new NodeGroupNode();
                    break;
                case NodeType.FaceData:
                    node = new FaceDataNode();
                    break;
                case NodeType.MeshVertices:
                    node = new MeshVerticesNode();
                    break;
                case NodeType.NodeReference:
                    node = new NodeReferenceNode();
                    break;
                case NodeType.VertexNormals:
                    node = new VertexNormalsNode();
                    break;
                case NodeType.TextureCoordinates:
                    node = new TextureCoordinatesNode();
                    break;
                case NodeType.Texture:
                    node = new TextureNode();
                    break;
                case NodeType.FaceGrouping:
                    node = new FaceGroupingNode();
                    break;
                case NodeType.Hardpoint:
                    node = new HardpointNode();
                    break;
                case NodeType.RotationScale:
                    node = new RotationScaleNode();
                    break;
                case NodeType.NodeSwitch:
                    node = new NodeSwitchNode();
                    break;
                case NodeType.MeshDescriptor:
                    node = new MeshDescriptorNode();
                    break;
                case NodeType.TextureAlpha:
                    node = new TextureAlphaNode();
                    break;
                case NodeType.EngineGlow:
                    node = new EngineGlowNode();
                    break;
            }

            if (node == null)
            {
                throw new InvalidDataException("invalid node found: " + type);
            }

            node.Parse(buffer, globalOffset, offset);

            return node;
        }
Beispiel #2
0
        internal static Node ParseNode(byte[] buffer, int globalOffset, int offset)
        {
            NodeType type = (NodeType)BitConverter.ToInt32(buffer, offset + 4);

            Node node = null;

            switch (type)
            {
            case NodeType.NullNode:
                node = new NullNode();
                break;

            case NodeType.NodeGroup:
                node = new NodeGroupNode();
                break;

            case NodeType.FaceData:
                node = new FaceDataNode();
                break;

            case NodeType.MeshVertices:
                node = new MeshVerticesNode();
                break;

            case NodeType.NodeReference:
                node = new NodeReferenceNode();
                break;

            case NodeType.VertexNormals:
                node = new VertexNormalsNode();
                break;

            case NodeType.TextureCoordinates:
                node = new TextureCoordinatesNode();
                break;

            case NodeType.Texture:
                node = new TextureNode();
                break;

            case NodeType.FaceGrouping:
                node = new FaceGroupingNode();
                break;

            case NodeType.Hardpoint:
                node = new HardpointNode();
                break;

            case NodeType.RotationScale:
                node = new RotationScaleNode();
                break;

            case NodeType.NodeSwitch:
                node = new NodeSwitchNode();
                break;

            case NodeType.MeshDescriptor:
                node = new MeshDescriptorNode();
                break;

            case NodeType.TextureAlpha:
                node = new TextureAlphaNode();
                break;

            case NodeType.EngineGlow:
                node = new EngineGlowNode();
                break;
            }

            if (node == null)
            {
                throw new InvalidDataException("invalid node found: " + type);
            }

            node.Parse(buffer, globalOffset, offset);

            return(node);
        }
        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;
        }