示例#1
0
        public void CompactFaceGroups()
        {
            var groups = new List <FaceGroup>(this.FaceGroups.Count);

            foreach (var faceGroup in this.FaceGroups)
            {
                FaceGroup index = null;

                foreach (var group in groups)
                {
                    if (group.Textures.Count != faceGroup.Textures.Count)
                    {
                        continue;
                    }

                    if (group.Textures.Count == 0)
                    {
                        index = group;
                        break;
                    }

                    int t = 0;
                    for (; t < group.Textures.Count; t++)
                    {
                        if (group.Textures[t] != faceGroup.Textures[t])
                        {
                            break;
                        }
                    }

                    if (t == group.Textures.Count)
                    {
                        index = group;
                        break;
                    }
                }

                if (index == null)
                {
                    groups.Add(faceGroup);
                }
                else
                {
                    foreach (var face in faceGroup.Faces)
                    {
                        index.Faces.Add(face);
                    }
                }
            }

            groups.TrimExcess();
            this.FaceGroups = groups;

            foreach (var faceGroup in this.FaceGroups)
            {
                faceGroup.ComputeEdges();
            }
        }
示例#2
0
        public static OptFile An8ToOpt(string an8Path, bool scale)
        {
            string an8Directory = Path.GetDirectoryName(an8Path);

            var an8 = An8File.FromFile(an8Path);
            var opt = new OptFile();

            foreach (var mesh in an8.Objects
                .SelectMany(t => t.Components)
                .SelectMany(t => Converter.EnumMeshes(t)))
            {
                var optMesh = new Mesh();
                opt.Meshes.Add(optMesh);

                if (scale)
                {
                    foreach (var v in mesh.Points)
                    {
                        optMesh.Vertices.Add(new Vector(v.X / OptFile.ScaleFactor, v.Z / OptFile.ScaleFactor, v.Y / OptFile.ScaleFactor));
                    }
                }
                else
                {
                    foreach (var v in mesh.Points)
                    {
                        optMesh.Vertices.Add(new Vector(v.X, v.Z, v.Y));
                    }
                }

                foreach (var v in mesh.TexCoords)
                {
                    optMesh.TextureCoordinates.Add(new TextureCoordinates(v.U, -v.V));
                }

                foreach (var v in mesh.Normals)
                {
                    optMesh.VertexNormals.Add(new Vector(v.X, v.Z, v.Y));
                }

                optMesh.TextureCoordinates.Add(new TextureCoordinates(0, 0));
                optMesh.TextureCoordinates.Add(new TextureCoordinates(1, 0));
                optMesh.TextureCoordinates.Add(new TextureCoordinates(1, 1));
                optMesh.TextureCoordinates.Add(new TextureCoordinates(0, 1));

                var optLod = new MeshLod();
                optMesh.Lods.Add(optLod);

                foreach (var face in mesh.Faces)
                {
                    if (face.PointIndexes.Length < 3)
                    {
                        continue;
                    }

                    bool isQuad = face.PointIndexes.Length > 3;

                    var optFaceGroup = new FaceGroup();
                    optLod.FaceGroups.Add(optFaceGroup);

                    var materialName = mesh.MaterialList.ElementAtOrDefault(face.MaterialIndex);

                    if (!string.IsNullOrEmpty(materialName))
                    {
                        optFaceGroup.Textures.Add(materialName);
                    }

                    Index verticesIndex = new Index(
                        face.PointIndexes[0],
                        face.PointIndexes[1],
                        face.PointIndexes[2],
                        isQuad ? face.PointIndexes[3] : -1);

                    if (verticesIndex.A >= optMesh.Vertices.Count)
                    {
                        verticesIndex.A = 0;
                    }

                    if (verticesIndex.B >= optMesh.Vertices.Count)
                    {
                        verticesIndex.B = 0;
                    }

                    if (verticesIndex.C >= optMesh.Vertices.Count)
                    {
                        verticesIndex.C = 0;
                    }

                    if (verticesIndex.D >= optMesh.Vertices.Count)
                    {
                        verticesIndex.D = 0;
                    }

                    Index textureCoordinatesIndex = new Index(
                        face.TexCoordIndexes[0],
                        face.TexCoordIndexes[1],
                        face.TexCoordIndexes[2],
                        isQuad ? face.TexCoordIndexes[3] : -1);

                    if (textureCoordinatesIndex.A >= optMesh.TextureCoordinates.Count)
                    {
                        textureCoordinatesIndex.A = 0;
                    }

                    if (textureCoordinatesIndex.B >= optMesh.TextureCoordinates.Count)
                    {
                        textureCoordinatesIndex.B = 0;
                    }

                    if (textureCoordinatesIndex.C >= optMesh.TextureCoordinates.Count)
                    {
                        textureCoordinatesIndex.C = 0;
                    }

                    if (textureCoordinatesIndex.D >= optMesh.TextureCoordinates.Count)
                    {
                        textureCoordinatesIndex.D = 0;
                    }

                    Index vertexNormalsIndex = new Index(
                        face.NormalIndexes[0],
                        face.NormalIndexes[1],
                        face.NormalIndexes[2],
                        isQuad ? face.NormalIndexes[3] : -1);

                    if (vertexNormalsIndex.A >= optMesh.VertexNormals.Count)
                    {
                        vertexNormalsIndex.A = 0;
                    }

                    if (vertexNormalsIndex.B >= optMesh.VertexNormals.Count)
                    {
                        vertexNormalsIndex.B = 0;
                    }

                    if (vertexNormalsIndex.C >= optMesh.VertexNormals.Count)
                    {
                        vertexNormalsIndex.C = 0;
                    }

                    if (vertexNormalsIndex.D >= optMesh.VertexNormals.Count)
                    {
                        vertexNormalsIndex.D = 0;
                    }

                    if (textureCoordinatesIndex.A < 0 || textureCoordinatesIndex.B < 0 || textureCoordinatesIndex.C < 0 || (verticesIndex.D >= 0 && textureCoordinatesIndex.D < 0))
                    {
                        textureCoordinatesIndex.A = optMesh.TextureCoordinates.Count - 4;
                        textureCoordinatesIndex.B = optMesh.TextureCoordinates.Count - 3;
                        textureCoordinatesIndex.C = optMesh.TextureCoordinates.Count - 2;
                        textureCoordinatesIndex.D = verticesIndex.D < 0 ? -1 : optMesh.TextureCoordinates.Count - 1;
                    }

                    Vector normal = Vector.Normal(
                        optMesh.Vertices.ElementAtOrDefault(verticesIndex.A),
                        optMesh.Vertices.ElementAtOrDefault(verticesIndex.B),
                        optMesh.Vertices.ElementAtOrDefault(verticesIndex.C));

                    if (vertexNormalsIndex.A < 0 || vertexNormalsIndex.B < 0 || vertexNormalsIndex.C < 0 || (verticesIndex.D >= 0 && vertexNormalsIndex.D < 0))
                    {
                        optMesh.VertexNormals.Add(normal);

                        vertexNormalsIndex.A = optMesh.VertexNormals.Count - 1;
                        vertexNormalsIndex.B = optMesh.VertexNormals.Count - 1;
                        vertexNormalsIndex.C = optMesh.VertexNormals.Count - 1;
                        vertexNormalsIndex.D = verticesIndex.D < 0 ? -1 : optMesh.VertexNormals.Count - 1;
                    }

                    var optFace = new Face()
                    {
                        VerticesIndex = verticesIndex,
                        TextureCoordinatesIndex = textureCoordinatesIndex,
                        VertexNormalsIndex = vertexNormalsIndex,
                        Normal = normal
                    };

                    optFaceGroup.Faces.Add(optFace);
                }
            }

            opt.CompactBuffers();
            opt.ComputeHitzones();

            foreach (var material in an8.Materials
                .Concat(an8.Objects.SelectMany(t => t.Materials))
                .Where(t => t.FrontSurface != null)
                .Select(t => new
                {
                    Name = t.Name,
                    Diffuse = t.FrontSurface.Diffuse,
                    Alpha = t.FrontSurface.Alpha
                }))
            {
                Texture texture;

                var an8Texture = material.Diffuse.TextureName != null ?
                    an8.Textures.FirstOrDefault(t => string.Equals(t.Name, material.Diffuse.TextureName, StringComparison.Ordinal)) :
                    null;

                if (an8Texture == null)
                {
                    byte r = material.Diffuse.Red;
                    byte g = material.Diffuse.Green;
                    byte b = material.Diffuse.Blue;

                    int width = 8;
                    int height = 8;
                    int length = width * height;
                    byte[] data = new byte[length * 4];

                    for (int i = 0; i < length; i++)
                    {
                        data[i * 4 + 0] = b;
                        data[i * 4 + 1] = g;
                        data[i * 4 + 2] = r;
                        data[i * 4 + 3] = 255;
                    }

                    texture = new Texture();
                    texture.Name = material.Name;
                    texture.Width = width;
                    texture.Height = height;
                    texture.ImageData = data;
                }
                else
                {
                    string colorFileName = Path.Combine(an8Directory, Path.GetFileName(an8Texture.Files[0]));

                    texture = Texture.FromFile(colorFileName);
                    texture.Name = material.Name;
                }

                if (material.Alpha > 0 && material.Alpha < 255)
                {
                    byte alpha = (byte)material.Alpha;

                    int length = texture.Width * texture.Height;

                    byte[] alphaData = new byte[length];
                    var data = texture.ImageData;

                    for (int i = 0; i < length; i++)
                    {
                        alphaData[i] = alpha;
                        data[i * 4 + 3] = alpha;
                    }

                    texture.AlphaData = alphaData;
                }

                opt.Textures.Add(texture.Name, texture);
            }

            opt.GenerateTexturesMipmaps();

            return opt;
        }
        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;
        }
示例#4
0
        public static OptFile ObjToOpt(string objPath, bool scale)
        {
            string objDirectory = Path.GetDirectoryName(objPath);

            var obj = ObjFile.FromFile(objPath);
            var opt = new OptFile();

            foreach (var mesh in obj.Meshes)
            {
                var optMesh = new Mesh();
                opt.Meshes.Add(optMesh);

                if (scale)
                {
                    foreach (var v in obj.Vertices)
                    {
                        optMesh.Vertices.Add(new Vector(v.X / OptFile.ScaleFactor, v.Z / OptFile.ScaleFactor, v.Y / OptFile.ScaleFactor));
                    }
                }
                else
                {
                    foreach (var v in obj.Vertices)
                    {
                        optMesh.Vertices.Add(new Vector(v.X, v.Z, v.Y));
                    }
                }

                foreach (var v in obj.VertexTexCoords)
                {
                    optMesh.TextureCoordinates.Add(new TextureCoordinates(v.U, -v.V));
                }

                foreach (var v in obj.VertexNormals)
                {
                    optMesh.VertexNormals.Add(new Vector(v.X, v.Z, v.Y));
                }

                optMesh.TextureCoordinates.Add(new TextureCoordinates(0, 0));
                optMesh.TextureCoordinates.Add(new TextureCoordinates(1, 0));
                optMesh.TextureCoordinates.Add(new TextureCoordinates(1, 1));
                optMesh.TextureCoordinates.Add(new TextureCoordinates(0, 1));

                var optLod = new MeshLod();
                optMesh.Lods.Add(optLod);

                foreach (var faceGroup in mesh.FaceGroups)
                {
                    var optFaceGroup = new FaceGroup();
                    optLod.FaceGroups.Add(optFaceGroup);

                    if (!string.IsNullOrEmpty(faceGroup.MaterialName))
                    {
                        optFaceGroup.Textures.Add(faceGroup.MaterialName);
                    }

                    foreach (var face in faceGroup.Faces)
                    {
                        Index verticesIndex = new Index(
                                face.VerticesIndex.A,
                                face.VerticesIndex.B,
                                face.VerticesIndex.C,
                                face.VerticesIndex.D);

                        if (verticesIndex.A >= optMesh.Vertices.Count)
                        {
                            verticesIndex.A = 0;
                        }

                        if (verticesIndex.B >= optMesh.Vertices.Count)
                        {
                            verticesIndex.B = 0;
                        }

                        if (verticesIndex.C >= optMesh.Vertices.Count)
                        {
                            verticesIndex.C = 0;
                        }

                        if (verticesIndex.D >= optMesh.Vertices.Count)
                        {
                            verticesIndex.D = 0;
                        }

                        Index textureCoordinatesIndex = new Index(
                                face.VertexTexCoordsIndex.A,
                                face.VertexTexCoordsIndex.B,
                                face.VertexTexCoordsIndex.C,
                                face.VertexTexCoordsIndex.D);

                        if (textureCoordinatesIndex.A >= optMesh.TextureCoordinates.Count)
                        {
                            textureCoordinatesIndex.A = 0;
                        }

                        if (textureCoordinatesIndex.B >= optMesh.TextureCoordinates.Count)
                        {
                            textureCoordinatesIndex.B = 0;
                        }

                        if (textureCoordinatesIndex.C >= optMesh.TextureCoordinates.Count)
                        {
                            textureCoordinatesIndex.C = 0;
                        }

                        if (textureCoordinatesIndex.D >= optMesh.TextureCoordinates.Count)
                        {
                            textureCoordinatesIndex.D = 0;
                        }

                        Index vertexNormalsIndex = new Index(
                                face.VertexNormalsIndex.A,
                                face.VertexNormalsIndex.B,
                                face.VertexNormalsIndex.C,
                                face.VertexNormalsIndex.D);

                        if (vertexNormalsIndex.A >= optMesh.VertexNormals.Count)
                        {
                            vertexNormalsIndex.A = 0;
                        }

                        if (vertexNormalsIndex.B >= optMesh.VertexNormals.Count)
                        {
                            vertexNormalsIndex.B = 0;
                        }

                        if (vertexNormalsIndex.C >= optMesh.VertexNormals.Count)
                        {
                            vertexNormalsIndex.C = 0;
                        }

                        if (vertexNormalsIndex.D >= optMesh.VertexNormals.Count)
                        {
                            vertexNormalsIndex.D = 0;
                        }

                        if (textureCoordinatesIndex.A < 0 || textureCoordinatesIndex.B < 0 || textureCoordinatesIndex.C < 0 || (verticesIndex.D >= 0 && textureCoordinatesIndex.D < 0))
                        {
                            textureCoordinatesIndex.A = optMesh.TextureCoordinates.Count - 4;
                            textureCoordinatesIndex.B = optMesh.TextureCoordinates.Count - 3;
                            textureCoordinatesIndex.C = optMesh.TextureCoordinates.Count - 2;
                            textureCoordinatesIndex.D = verticesIndex.D < 0 ? -1 : optMesh.TextureCoordinates.Count - 1;
                        }

                        Vector normal = Vector.Normal(
                            optMesh.Vertices.ElementAtOrDefault(verticesIndex.A),
                            optMesh.Vertices.ElementAtOrDefault(verticesIndex.B),
                            optMesh.Vertices.ElementAtOrDefault(verticesIndex.C));

                        if (vertexNormalsIndex.A < 0 || vertexNormalsIndex.B < 0 || vertexNormalsIndex.C < 0 || (verticesIndex.D >= 0 && vertexNormalsIndex.D < 0))
                        {
                            optMesh.VertexNormals.Add(normal);

                            vertexNormalsIndex.A = optMesh.VertexNormals.Count - 1;
                            vertexNormalsIndex.B = optMesh.VertexNormals.Count - 1;
                            vertexNormalsIndex.C = optMesh.VertexNormals.Count - 1;
                            vertexNormalsIndex.D = verticesIndex.D < 0 ? -1 : optMesh.VertexNormals.Count - 1;
                        }

                        var optFace = new Face()
                        {
                            VerticesIndex = verticesIndex,
                            TextureCoordinatesIndex = textureCoordinatesIndex,
                            VertexNormalsIndex = vertexNormalsIndex,
                            Normal = normal
                        };

                        optFaceGroup.Faces.Add(optFace);
                    }
                }
            }

            opt.CompactBuffers();
            opt.ComputeHitzones();

            foreach (var material in obj.Materials.Values)
            {
                Texture texture;

                if (material.DiffuseMapFileName == null)
                {
                    var color = material.DiffuseColor;
                    byte r = (byte)(color.X * 255.0f);
                    byte g = (byte)(color.Y * 255.0f);
                    byte b = (byte)(color.Z * 255.0f);

                    int width = 8;
                    int height = 8;
                    int length = width * height;
                    byte[] data = new byte[length * 4];

                    for (int i = 0; i < length; i++)
                    {
                        data[i * 4 + 0] = b;
                        data[i * 4 + 1] = g;
                        data[i * 4 + 2] = r;
                        data[i * 4 + 3] = 255;
                    }

                    texture = new Texture();
                    texture.Name = material.Name;
                    texture.Width = width;
                    texture.Height = height;
                    texture.ImageData = data;
                }
                else
                {
                    string colorFileName = Path.Combine(objDirectory, material.DiffuseMapFileName);

                    texture = Texture.FromFile(colorFileName);
                    texture.Name = material.Name;
                }

                if (material.AlphaMapFileName != null)
                {
                    string alphaFileName = Path.Combine(objDirectory, material.AlphaMapFileName);

                    texture.SetAlphaMap(alphaFileName);
                }
                else if (material.DissolveFactor > 0.0f && material.DissolveFactor < 1.0f)
                {
                    byte alpha = (byte)(material.DissolveFactor * 255.0f);

                    int length = texture.Width * texture.Height;

                    byte[] alphaData = new byte[length];
                    var data = texture.ImageData;

                    for (int i = 0; i < length; i++)
                    {
                        alphaData[i] = alpha;
                        data[i * 4 + 3] = alpha;
                    }

                    texture.AlphaData = alphaData;
                }

                opt.Textures.Add(texture.Name, texture);
            }

            opt.GenerateTexturesMipmaps();

            return opt;
        }
示例#5
0
 internal MeshLodFace(Mesh mesh, MeshLod lod, FaceGroup face)
 {
     this.Mesh = mesh;
     this.Lod = lod;
     this.Face = face;
 }
示例#6
0
        public static OptFile RhinoToOpt(string rhinoPath, bool scale)
        {
            string rhinoDirectory = Path.GetDirectoryName(rhinoPath);

            var opt = new OptFile();

            using (var file = Rhino.FileIO.File3dm.Read(rhinoPath))
            {
                float scaleFactor = scale ? (1.0f / OptFile.ScaleFactor) : 1.0f;

                if (file.Settings.ModelUnitSystem != Rhino.UnitSystem.Meters)
                {
                    scaleFactor *= (float)Rhino.RhinoMath.UnitScale(file.Settings.ModelUnitSystem, Rhino.UnitSystem.Meters);
                    scale = true;
                }

                var groups = file.Objects
                    .Where(t =>
                    {
                        using (var geometry = t.Geometry)
                        {
                            return geometry.ObjectType == Rhino.DocObjects.ObjectType.Mesh;
                        }
                    })
                    .GroupBy(t =>
                    {
                        using (var attributes = t.Attributes)
                        {
                            return attributes.LayerIndex;
                        }
                    })
                    .ToList();

                foreach (var group in groups)
                {
                    var mesh = new Mesh();
                    opt.Meshes.Add(mesh);

                    var lod = new MeshLod();
                    mesh.Lods.Add(lod);

                    foreach (var obj in group)
                    {
                        var faceGroup = new FaceGroup();
                        lod.FaceGroups.Add(faceGroup);

                        int baseIndex = mesh.Vertices.Count;

                        using (var geometry = (Rhino.Geometry.Mesh)obj.Geometry)
                        {
                            if (scale)
                            {
                                foreach (var vertex in geometry.Vertices)
                                {
                                    mesh.Vertices.Add(new Vector(vertex.X * scaleFactor, vertex.Y * scaleFactor, vertex.Z * scaleFactor));
                                }
                            }
                            else
                            {
                                foreach (var vertex in geometry.Vertices)
                                {
                                    mesh.Vertices.Add(new Vector(vertex.X, vertex.Y, vertex.Z));
                                }
                            }

                            foreach (var texCoords in geometry.TextureCoordinates)
                            {
                                mesh.TextureCoordinates.Add(new TextureCoordinates(texCoords.X, -texCoords.Y));
                            }

                            foreach (var normal in geometry.Normals)
                            {
                                mesh.VertexNormals.Add(new Vector(normal.X, normal.Y, normal.Z));
                            }

                            foreach (var geoFace in geometry.Faces)
                            {
                                var face = new Face();
                                faceGroup.Faces.Add(face);

                                Index index = geoFace.IsTriangle ?
                                    new Index(baseIndex + geoFace.C, baseIndex + geoFace.B, baseIndex + geoFace.A) :
                                    new Index(baseIndex + geoFace.D, baseIndex + geoFace.C, baseIndex + geoFace.B, baseIndex + geoFace.A);

                                face.VerticesIndex = index;
                                face.VertexNormalsIndex = index;
                                face.TextureCoordinatesIndex = index;

                                face.Normal = Vector.Normal(mesh.Vertices[index.A], mesh.Vertices[index.B], mesh.Vertices[index.C]);
                            }
                        }

                        using (var attributes = obj.Attributes)
                        {
                            if (attributes.MaterialIndex != -1)
                            {
                                using (var material = file.Materials[attributes.MaterialIndex])
                                {
                                    faceGroup.Textures.Add(material.Name);
                                }
                            }
                        }
                    }
                }

                opt.CompactBuffers();
                opt.ComputeHitzones();

                for (int materialIndex = 0; materialIndex < file.Materials.Count; materialIndex++)
                {
                    using (var material = file.Materials[materialIndex])
                    {
                        if (opt.Textures.ContainsKey(material.Name))
                        {
                            continue;
                        }

                        string colorMap = null;
                        string alphaMap = null;

                        using (var tex = material.GetBitmapTexture())
                        {
                            if (tex != null && !string.IsNullOrEmpty(tex.FileName))
                            {
                                colorMap = Path.GetFileName(tex.FileName);
                            }
                        }

                        using (var tex = material.GetTransparencyTexture())
                        {
                            if (tex != null && !string.IsNullOrEmpty(tex.FileName))
                            {
                                alphaMap = Path.GetFileName(tex.FileName);
                            }
                        }

                        Texture texture;

                        if (colorMap == null)
                        {
                            var color = material.DiffuseColor;
                            byte r = color.R;
                            byte g = color.G;
                            byte b = color.B;

                            int width = 8;
                            int height = 8;
                            int length = width * height;
                            byte[] data = new byte[length * 4];

                            for (int i = 0; i < length; i++)
                            {
                                data[i * 4 + 0] = b;
                                data[i * 4 + 1] = g;
                                data[i * 4 + 2] = r;
                                data[i * 4 + 3] = 255;
                            }

                            texture = new Texture();
                            texture.Name = material.Name;
                            texture.Width = width;
                            texture.Height = height;
                            texture.ImageData = data;
                        }
                        else
                        {
                            string colorFileName = Path.Combine(rhinoDirectory, colorMap);

                            texture = Texture.FromFile(colorFileName);
                            texture.Name = material.Name;
                        }

                        if (alphaMap != null)
                        {
                            string alphaFileName = Path.Combine(rhinoDirectory, alphaMap);

                            texture.SetAlphaMap(alphaFileName);
                        }
                        else if (material.Transparency > 0.0 && material.Transparency < 1.0)
                        {
                            byte alpha = (byte)(material.Transparency * 255.0f);

                            int length = texture.Width * texture.Height;

                            byte[] alphaData = new byte[length];
                            var data = texture.ImageData;

                            for (int i = 0; i < length; i++)
                            {
                                alphaData[i] = alpha;
                                data[i * 4 + 3] = alpha;
                            }

                            texture.AlphaData = alphaData;
                        }

                        opt.Textures.Add(texture.Name, texture);
                    }
                }

                opt.GenerateTexturesMipmaps();
            }

            return opt;
        }
示例#7
0
        public Mesh Duplicate()
        {
            var newMesh = new Mesh();

            foreach (var vertex in this.Vertices)
            {
                newMesh.Vertices.Add(vertex);
            }

            foreach (var textureCoordinate in this.TextureCoordinates)
            {
                newMesh.TextureCoordinates.Add(textureCoordinate);
            }

            foreach (var vertexNormal in this.VertexNormals)
            {
                newMesh.VertexNormals.Add(vertexNormal);
            }

            newMesh.Descriptor.MeshType = this.Descriptor.MeshType;
            newMesh.Descriptor.ExplosionType = this.Descriptor.ExplosionType;
            newMesh.Descriptor.Span = this.Descriptor.Span;
            newMesh.Descriptor.Center = this.Descriptor.Center;
            newMesh.Descriptor.Min = this.Descriptor.Min;
            newMesh.Descriptor.Max = this.Descriptor.Max;
            newMesh.Descriptor.TargetId = this.Descriptor.TargetId;
            newMesh.Descriptor.Target = this.Descriptor.Target;

            newMesh.RotationScale.Pivot = this.RotationScale.Pivot;
            newMesh.RotationScale.Look = this.RotationScale.Look;
            newMesh.RotationScale.Up = this.RotationScale.Up;
            newMesh.RotationScale.Right = this.RotationScale.Right;

            foreach (var lod in this.Lods)
            {
                var newLod = new MeshLod();

                newLod.Distance = lod.Distance;

                foreach (var faceGroup in lod.FaceGroups)
                {
                    var newFaceGroup = new FaceGroup();

                    foreach (var face in faceGroup.Faces)
                    {
                        newFaceGroup.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 texture in faceGroup.Textures)
                    {
                        newFaceGroup.Textures.Add(texture);
                    }

                    newLod.FaceGroups.Add(newFaceGroup);
                }

                newMesh.Lods.Add(newLod);
            }

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

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

            var center = newMesh.Descriptor.Center;
            newMesh.Move(-center.X, -center.Y, -center.Z);

            return newMesh;
        }
示例#8
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);
        }
示例#9
0
        public Mesh Duplicate()
        {
            var newMesh = new Mesh();

            foreach (var vertex in this.Vertices)
            {
                newMesh.Vertices.Add(vertex);
            }

            foreach (var textureCoordinate in this.TextureCoordinates)
            {
                newMesh.TextureCoordinates.Add(textureCoordinate);
            }

            foreach (var vertexNormal in this.VertexNormals)
            {
                newMesh.VertexNormals.Add(vertexNormal);
            }

            newMesh.Descriptor.MeshType      = this.Descriptor.MeshType;
            newMesh.Descriptor.ExplosionType = this.Descriptor.ExplosionType;
            newMesh.Descriptor.Span          = this.Descriptor.Span;
            newMesh.Descriptor.Center        = this.Descriptor.Center;
            newMesh.Descriptor.Min           = this.Descriptor.Min;
            newMesh.Descriptor.Max           = this.Descriptor.Max;
            newMesh.Descriptor.TargetId      = this.Descriptor.TargetId;
            newMesh.Descriptor.Target        = this.Descriptor.Target;

            newMesh.RotationScale.Pivot = this.RotationScale.Pivot;
            newMesh.RotationScale.Look  = this.RotationScale.Look;
            newMesh.RotationScale.Up    = this.RotationScale.Up;
            newMesh.RotationScale.Right = this.RotationScale.Right;

            foreach (var lod in this.Lods)
            {
                var newLod = new MeshLod();

                newLod.Distance = lod.Distance;

                foreach (var faceGroup in lod.FaceGroups)
                {
                    var newFaceGroup = new FaceGroup();

                    foreach (var face in faceGroup.Faces)
                    {
                        newFaceGroup.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 texture in faceGroup.Textures)
                    {
                        newFaceGroup.Textures.Add(texture);
                    }

                    newLod.FaceGroups.Add(newFaceGroup);
                }

                newMesh.Lods.Add(newLod);
            }

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

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

            var center = newMesh.Descriptor.Center;

            newMesh.Move(-center.X, -center.Y, -center.Z);

            return(newMesh);
        }