public TextureBrowserWindow(Window owner, OptFile optFile)
        {
            InitializeComponent();

            this.Owner = owner;
            this.DataContext = optFile;
        }
Example #2
0
 public OptCache(OptFile opt)
 {
     this.file = opt;
     this.BuildTextures(opt);
     this.BuildMeshes(opt);
     this.BuildMeshesWireframes(opt);
 }
Example #3
0
        public static IEnumerable <PlayabilityMessage> CheckTextures(OptFile opt)
        {
            if (opt == null)
            {
                yield break;
            }

            if (opt.Textures.Count != 0 && opt.TexturesBitsPerPixel == 0)
            {
                yield return(new PlayabilityMessage(
                                 PlayabilityMessageLevel.Error,
                                 "Textures",
                                 "All textures have not the same bpp."));
            }

            if (opt.Textures.Count > 200)
            {
                yield return(new PlayabilityMessage(
                                 PlayabilityMessageLevel.Warning,
                                 "Textures",
                                 "This opt requires the textures count patch to work."));
            }

            if (opt.Textures.Values.Any(t => t.Width > 256 || t.Height > 256))
            {
                yield return(new PlayabilityMessage(
                                 PlayabilityMessageLevel.Warning,
                                 "Textures",
                                 "This opt requires the textures size patch to work."));
            }

            if (opt.TexturesBitsPerPixel == 32)
            {
                yield return(new PlayabilityMessage(
                                 PlayabilityMessageLevel.Warning,
                                 "Textures",
                                 "This opt requires the 32-bit textures patch to work."));
            }

            if (opt.TexturesBitsPerPixel == 32)
            {
                if (opt.Textures.Values.Any(t => t.MaximumMipmapsCount != t.MipmapsCount && t.MipmapsCount < 6))
                {
                    yield return(new PlayabilityMessage(
                                     PlayabilityMessageLevel.Error,
                                     "Textures",
                                     "Textures mipmaps have not been generated."));
                }
            }
        }
Example #4
0
        public static IList <PlayabilityMessage> CheckPlayability(OptFile opt)
        {
            var messages = new List <PlayabilityMessage>();

            messages.AddRange(PlayabilityChecker.OptInformations(opt));
            messages.AddRange(PlayabilityChecker.CheckTextures(opt));
            messages.AddRange(PlayabilityChecker.CheckGeometry(opt));
            messages.AddRange(PlayabilityChecker.CheckEngineGlows(opt));
            messages.AddRange(PlayabilityChecker.CheckHardpoints(opt));

            messages.Sort();

            return(messages);
        }
        public static IList<PlayabilityMessage> CheckPlayability(OptFile opt)
        {
            var messages = new List<PlayabilityMessage>();

            messages.AddRange(PlayabilityChecker.OptInformations(opt));
            messages.AddRange(PlayabilityChecker.CheckTextures(opt));
            messages.AddRange(PlayabilityChecker.CheckGeometry(opt));
            messages.AddRange(PlayabilityChecker.CheckEngineGlows(opt));
            messages.AddRange(PlayabilityChecker.CheckHardpoints(opt));

            messages.Sort();

            return messages;
        }
        public static IEnumerable<PlayabilityMessage> CheckTextures(OptFile opt)
        {
            if (opt == null)
            {
                yield break;
            }

            if (opt.Textures.Count != 0 && opt.TexturesBitsPerPixel == 0)
            {
                yield return new PlayabilityMessage(
                    PlayabilityMessageLevel.Error,
                    "Textures",
                    "All textures have not the same bpp.");
            }

            if (opt.Textures.Count > 200)
            {
                yield return new PlayabilityMessage(
                    PlayabilityMessageLevel.Warning,
                    "Textures",
                    "This opt requires the textures count patch to work.");
            }

            if (opt.Textures.Values.Any(t => t.Width > 256 || t.Height > 256))
            {
                yield return new PlayabilityMessage(
                    PlayabilityMessageLevel.Warning,
                    "Textures",
                    "This opt requires the textures size patch to work.");
            }

            if (opt.TexturesBitsPerPixel == 32)
            {
                yield return new PlayabilityMessage(
                    PlayabilityMessageLevel.Warning,
                    "Textures",
                    "This opt requires the 32-bit textures patch to work.");
            }

            if (opt.TexturesBitsPerPixel == 32)
            {
                if (opt.Textures.Values.Any(t => t.MaximumMipmapsCount != t.MipmapsCount && t.MipmapsCount < 6))
                {
                    yield return new PlayabilityMessage(
                        PlayabilityMessageLevel.Error,
                        "Textures",
                        "Textures mipmaps have not been generated.");
                }
            }
        }
Example #7
0
        public static IEnumerable <PlayabilityMessage> CheckHardpoints(OptFile opt)
        {
            if (opt == null)
            {
                yield break;
            }

            if (opt.Meshes.SelectMany(t => t.Hardpoints).Count(t => t.HardpointType == HardpointType.CockpitSparks) > 16)
            {
                yield return(new PlayabilityMessage(
                                 PlayabilityMessageLevel.Error,
                                 "Hardpoints",
                                 "The maximun cockpit sparks count for an opt is 16"));
            }
        }
Example #8
0
        public static IEnumerable <PlayabilityMessage> CheckEngineGlows(OptFile opt)
        {
            if (opt == null)
            {
                yield break;
            }

            if (opt.EngineGlowsCount > 16)
            {
                yield return(new PlayabilityMessage(
                                 PlayabilityMessageLevel.Error,
                                 "Engine Glows",
                                 "The maximum engine glows count for an opt is 16"));
            }
        }
        private void Execute_Open(object sender, ExecutedRoutedEventArgs e)
        {
            Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
            dlg.Filter = "Xwa OPT files|*.opt";

            if (dlg.ShowDialog() == true)
            {
                try
                {
                    this.OptFile = OptFile.FromFile(dlg.FileName);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, ex.Source, MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
        }
Example #10
0
        public static IEnumerable <PlayabilityMessage> OptInformations(OptFile opt)
        {
            if (opt == null)
            {
                yield break;
            }

            yield return(new PlayabilityMessage(
                             PlayabilityMessageLevel.Information,
                             "Opt",
                             "FileName: {0}",
                             opt.FileName));

            yield return(new PlayabilityMessage(
                             PlayabilityMessageLevel.Information,
                             "Textures",
                             "Textures Bits Per Pixel: {0}",
                             opt.TexturesBitsPerPixel));
        }
        public static IEnumerable<PlayabilityMessage> OptInformations(OptFile opt)
        {
            if (opt == null)
            {
                yield break;
            }

            yield return new PlayabilityMessage(
                PlayabilityMessageLevel.Information,
                "Opt",
                "FileName: {0}",
                opt.FileName);

            yield return new PlayabilityMessage(
                PlayabilityMessageLevel.Information,
                "Textures",
                "Textures Bits Per Pixel: {0}",
                opt.TexturesBitsPerPixel);
        }
Example #12
0
        public static IEnumerable <PlayabilityMessage> CheckGeometry(OptFile opt)
        {
            if (opt == null)
            {
                yield break;
            }

            if (opt.Meshes.Count > 50)
            {
                yield return(new PlayabilityMessage(
                                 PlayabilityMessageLevel.Error,
                                 "Meshes",
                                 "The maximum meshes count for an opt is 50."));
            }

            if (opt.Meshes.Any(t => t.Vertices.Count > 512))
            {
                yield return(new PlayabilityMessage(
                                 PlayabilityMessageLevel.Error,
                                 "Meshes",
                                 "The maximum vertices count for a mesh is 512"));
            }
        }
Example #13
0
        public static void OptToObj(OptFile opt, string objPath, bool scale)
        {
            if (opt == null)
            {
                throw new ArgumentNullException("opt");
            }

            string objDirectory = Path.GetDirectoryName(objPath);
            string objName = Path.GetFileNameWithoutExtension(objPath);

            var objMaterials = new ObjMaterialDictionary();

            foreach (var texture in opt.Textures.Values)
            {
                var material = new ObjMaterial
                {
                    Name = texture.Name,
                    DiffuseMapFileName = string.Format(CultureInfo.InvariantCulture, "{0}.png", texture.Name)
                };

                texture.Save(Path.Combine(objDirectory, material.DiffuseMapFileName));

                if (texture.HasAlpha)
                {
                    material.AlphaMapFileName = string.Format(CultureInfo.InvariantCulture, "{0}_alpha.png", texture.Name);

                    texture.SaveAlphaMap(Path.Combine(objDirectory, material.AlphaMapFileName));
                }

                objMaterials.Add(texture.Name, material);
            }

            objMaterials.Save(Path.ChangeExtension(objPath, "mtl"));

            var distances = opt.Meshes
                .SelectMany(t => t.Lods)
                .Select(t => t.Distance)
                .Distinct()
                .OrderByDescending(t => t)
                .ToArray();

            for (int distance = 0; distance < distances.Length; distance++)
            {
                var obj = new ObjFile();

                int objectsIndex = 0;
                int verticesIndex = 0;
                int verticesTexIndex = 0;
                int verticesNormalIndex = 0;

                foreach (var mesh in opt.Meshes)
                {
                    var lod = mesh.Lods.FirstOrDefault(t => t.Distance <= distances[distance]);

                    if (lod == null)
                    {
                        continue;
                    }

                    var objMesh = new ObjMesh(string.Format(CultureInfo.InvariantCulture, "{0}.{1:D3}", mesh.Descriptor.MeshType, objectsIndex));
                    obj.Meshes.Add(objMesh);
                    objectsIndex++;

                    if (scale)
                    {
                        foreach (var v in mesh.Vertices)
                        {
                            obj.Vertices.Add(new ObjVector3(v.X * OptFile.ScaleFactor, v.Z * OptFile.ScaleFactor, v.Y * OptFile.ScaleFactor));
                        }
                    }
                    else
                    {
                        foreach (var v in mesh.Vertices)
                        {
                            obj.Vertices.Add(new ObjVector3(v.X, v.Z, v.Y));
                        }
                    }

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

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

                    foreach (var faceGroup in lod.FaceGroups)
                    {
                        var objFaceGroup = new ObjFaceGroup();

                        if (faceGroup.Textures.Count > 0)
                        {
                            objFaceGroup.MaterialName = faceGroup.Textures[0];
                        }

                        objMesh.FaceGroups.Add(objFaceGroup);

                        foreach (var face in faceGroup.Faces)
                        {
                            if (face.VerticesIndex.D < 0)
                            {
                                objFaceGroup.Faces.Add(new ObjFace()
                                {
                                    VerticesIndex = new ObjIndex(
                                        verticesIndex + face.VerticesIndex.A,
                                        verticesIndex + face.VerticesIndex.B,
                                        verticesIndex + face.VerticesIndex.C
                                        ),

                                    VertexTexCoordsIndex = new ObjIndex(
                                        verticesTexIndex + face.TextureCoordinatesIndex.A,
                                        verticesTexIndex + face.TextureCoordinatesIndex.B,
                                        verticesTexIndex + face.TextureCoordinatesIndex.C),

                                    VertexNormalsIndex = new ObjIndex(
                                        verticesNormalIndex + face.VertexNormalsIndex.A,
                                        verticesNormalIndex + face.VertexNormalsIndex.B,
                                        verticesNormalIndex + face.VertexNormalsIndex.C)
                                });
                            }
                            else
                            {
                                objFaceGroup.Faces.Add(new ObjFace()
                                {
                                    VerticesIndex = new ObjIndex(
                                        verticesIndex + face.VerticesIndex.A,
                                        verticesIndex + face.VerticesIndex.B,
                                        verticesIndex + face.VerticesIndex.C,
                                        verticesIndex + face.VerticesIndex.D
                                        ),

                                    VertexTexCoordsIndex = new ObjIndex(
                                        verticesTexIndex + face.TextureCoordinatesIndex.A,
                                        verticesTexIndex + face.TextureCoordinatesIndex.B,
                                        verticesTexIndex + face.TextureCoordinatesIndex.C,
                                        verticesTexIndex + face.TextureCoordinatesIndex.D),

                                    VertexNormalsIndex = new ObjIndex(
                                        verticesNormalIndex + face.VertexNormalsIndex.A,
                                        verticesNormalIndex + face.VertexNormalsIndex.B,
                                        verticesNormalIndex + face.VertexNormalsIndex.C,
                                        verticesNormalIndex + face.VertexNormalsIndex.D)
                                });
                            }
                        }
                    }

                    verticesIndex += mesh.Vertices.Count;
                    verticesTexIndex += mesh.TextureCoordinates.Count;
                    verticesNormalIndex += mesh.VertexNormals.Count;
                }

                obj.Save(Path.Combine(objDirectory, string.Format(CultureInfo.InvariantCulture, "{0}_{1}.obj", objName, distance)), objName);
            }
        }
Example #14
0
 public static void OptToObj(OptFile opt, string objPath)
 {
     Converter.OptToObj(opt, objPath, true);
 }
Example #15
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;
        }
Example #16
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);
        }
Example #17
0
        public OptModel()
        {
            this.PlayabilityMessages = new ObservableCollection<PlayabilityMessage>();

            this.file = new OptFile();
        }
        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;
        }
        public static IEnumerable<PlayabilityMessage> CheckEngineGlows(OptFile opt)
        {
            if (opt == null)
            {
                yield break;
            }

            if (opt.EngineGlowsCount > 16)
            {
                yield return new PlayabilityMessage(
                    PlayabilityMessageLevel.Error,
                    "Engine Glows",
                    "The maximum engine glows count for an opt is 16");
            }
        }
Example #20
0
 public static void OptToAn8(OptFile opt, string an8Path)
 {
     Converter.OptToAn8(opt, an8Path, true);
 }
 public TextureBrowserMessage(OptFile optFile)
 {
     this.OptFile = optFile;
 }
Example #22
0
        private static BitmapSource CreateTexture(OptFile opt, string name)
        {
            if (!opt.Textures.ContainsKey(name))
            {
                return null;
            }

            var texture = opt.Textures[name];

            int size = texture.Width * texture.Height;
            int bpp = texture.BitsPerPixel;

            if (bpp == 8)
            {
                var palette = new BitmapPalette(Enumerable.Range(0, 256)
                    .Select(i =>
                    {
                        ushort c = BitConverter.ToUInt16(texture.Palette, 8 * 512 + i * 2);

                        byte r = (byte)((c & 0xF800) >> 11);
                        byte g = (byte)((c & 0x7E0) >> 5);
                        byte b = (byte)(c & 0x1F);

                        r = (byte)((r * (0xffU * 2) + 0x1fU) / (0x1fU * 2));
                        g = (byte)((g * (0xffU * 2) + 0x3fU) / (0x3fU * 2));
                        b = (byte)((b * (0xffU * 2) + 0x1fU) / (0x1fU * 2));

                        return Color.FromRgb(r, g, b);
                    })
                    .ToList());

                if (texture.AlphaData == null)
                {
                    byte[] imageData = new byte[size];
                    Array.Copy(texture.ImageData, imageData, size);

                    return BitmapSource.Create(texture.Width, texture.Height, 96, 96, PixelFormats.Indexed8, palette, imageData, texture.Width);
                }
                else
                {
                    byte[] imageData = new byte[size * 4];

                    for (int i = 0; i < size; i++)
                    {
                        int colorIndex = texture.ImageData[i];

                        imageData[i * 4 + 0] = palette.Colors[colorIndex].B;
                        imageData[i * 4 + 1] = palette.Colors[colorIndex].G;
                        imageData[i * 4 + 2] = palette.Colors[colorIndex].R;
                        imageData[i * 4 + 3] = texture.AlphaData[i];
                    }

                    return BitmapSource.Create(texture.Width, texture.Height, 96, 96, PixelFormats.Bgra32, null, imageData, texture.Width * 4);
                }
            }
            else if (bpp == 32)
            {
                byte[] imageData = new byte[size * 4];
                Array.Copy(texture.ImageData, imageData, size * 4);

                return BitmapSource.Create(texture.Width, texture.Height, 96, 96, PixelFormats.Bgra32, null, imageData, texture.Width * 4);
            }
            else
            {
                return null;
            }
        }
        public static IEnumerable<PlayabilityMessage> CheckHardpoints(OptFile opt)
        {
            if (opt == null)
            {
                yield break;
            }

            if (opt.Meshes.SelectMany(t => t.Hardpoints).Count(t => t.HardpointType == HardpointType.CockpitSparks) > 16)
            {
                yield return new PlayabilityMessage(
                    PlayabilityMessageLevel.Error,
                    "Hardpoints",
                    "The maximun cockpit sparks count for an opt is 16");
            }
        }
Example #24
0
        private void BuildMeshes(OptFile opt)
        {
            this.meshes = null;

            if (opt == null)
            {
                return;
            }

            this.meshes = new MeshGeometry3D[opt.Meshes.Count][][][];

            for (int meshIndex = 0; meshIndex < opt.Meshes.Count; meshIndex++)
            {
                var mesh = opt.Meshes[meshIndex];

                var positions = new Point3DCollection(
                    mesh.Vertices
                    .Select(t => new Point3D(-t.Y, -t.X, t.Z)));

                var normals = new Vector3DCollection(
                    mesh.VertexNormals
                    .Select(t => new Vector3D(-t.Y, -t.X, t.Z)));

                var textureCoordinates = new PointCollection(
                    mesh.TextureCoordinates
                    .Select(t => new Point(t.U, t.V)));

                this.meshes[meshIndex] = new MeshGeometry3D[mesh.Lods.Count][][];

                for (int lodIndex = 0; lodIndex < mesh.Lods.Count; lodIndex++)
                {
                    var lod = mesh.Lods[lodIndex];

                    this.meshes[meshIndex][lodIndex] = new MeshGeometry3D[lod.FaceGroups.Count][];

                    for (int faceGroupIndex = 0; faceGroupIndex < lod.FaceGroups.Count; faceGroupIndex++)
                    {
                        var faceGroup = lod.FaceGroups[faceGroupIndex];

                        MeshGeometry3D[] geometries = new MeshGeometry3D[faceGroup.Faces.Count + 1];

                        for (int faceIndex = 0; faceIndex < faceGroup.Faces.Count; faceIndex++)
                        {
                            var face = faceGroup.Faces[faceIndex];

                            MeshGeometry3D geometry = new MeshGeometry3D();
                            int index = 0;

                            Index positionsIndex = face.VerticesIndex;
                            Index normalsIndex = face.VertexNormalsIndex;
                            Index textureCoordinatesIndex = face.TextureCoordinatesIndex;

                            geometry.Positions.Add(positions.ElementAtOrDefault(positionsIndex.A));
                            geometry.Normals.Add(normals.ElementAtOrDefault(normalsIndex.A));
                            geometry.TextureCoordinates.Add(textureCoordinates.ElementAtOrDefault(textureCoordinatesIndex.A));
                            geometry.TriangleIndices.Add(index);
                            index++;

                            geometry.Positions.Add(positions.ElementAtOrDefault(positionsIndex.B));
                            geometry.Normals.Add(normals.ElementAtOrDefault(normalsIndex.B));
                            geometry.TextureCoordinates.Add(textureCoordinates.ElementAtOrDefault(textureCoordinatesIndex.B));
                            geometry.TriangleIndices.Add(index);
                            index++;

                            geometry.Positions.Add(positions.ElementAtOrDefault(positionsIndex.C));
                            geometry.Normals.Add(normals.ElementAtOrDefault(normalsIndex.C));
                            geometry.TextureCoordinates.Add(textureCoordinates.ElementAtOrDefault(textureCoordinatesIndex.C));
                            geometry.TriangleIndices.Add(index);
                            index++;

                            if (positionsIndex.D >= 0)
                            {
                                geometry.TriangleIndices.Add(index - 3);
                                geometry.TriangleIndices.Add(index - 1);

                                geometry.Positions.Add(positions.ElementAtOrDefault(positionsIndex.D));
                                geometry.Normals.Add(normals.ElementAtOrDefault(normalsIndex.D));
                                geometry.TextureCoordinates.Add(textureCoordinates.ElementAtOrDefault(textureCoordinatesIndex.D));
                                geometry.TriangleIndices.Add(index);
                                index++;
                            }

                            geometry.Freeze();
                            geometries[1 + faceIndex] = geometry;
                        }

                        MeshGeometry3D geometryGroup = new MeshGeometry3D();

                        for (int i = 1; i < geometries.Length; i++)
                        {
                            MergeGeometry(geometryGroup, geometries[i]);
                        }

                        geometryGroup.Freeze();
                        geometries[0] = geometryGroup;

                        this.meshes[meshIndex][lodIndex][faceGroupIndex] = geometries;
                    }
                }
            }
        }
Example #25
0
        private void BuildMeshesWireframes(OptFile opt)
        {
            this.meshesWireframes = null;

            if (opt == null)
            {
                return;
            }

            this.meshesWireframes = opt.Meshes
                .AsParallel()
                .AsOrdered()
                .Select(mesh =>
                {
                    var positions = new Point3DCollection(
                        mesh.Vertices
                        .Select(t => new Point3D(-t.Y, -t.X, t.Z)));

                    var wireframes = new IList<Point3D>[mesh.Lods.Count];

                    for (int lodIndex = 0; lodIndex < mesh.Lods.Count; lodIndex++)
                    {
                        var lod = mesh.Lods[lodIndex];

                        var lines = new List<Tuple<int, int>>(lod.TrianglesCount * 3);

                        var addLine = new Action<int, int>((a, b) =>
                        {
                            if (a < b)
                            {
                                lines.Add(new Tuple<int, int>(a, b));
                            }
                            else
                            {
                                lines.Add(new Tuple<int, int>(b, a));
                            }
                        });

                        for (int faceGroupIndex = 0; faceGroupIndex < lod.FaceGroups.Count; faceGroupIndex++)
                        {
                            var faceGroup = lod.FaceGroups[faceGroupIndex];

                            for (int faceIndex = 0; faceIndex < faceGroup.Faces.Count; faceIndex++)
                            {
                                var face = faceGroup.Faces[faceIndex];

                                Index positionsIndex = face.VerticesIndex;

                                addLine(positionsIndex.A, positionsIndex.B);
                                addLine(positionsIndex.B, positionsIndex.C);

                                if (positionsIndex.D < 0)
                                {
                                    addLine(positionsIndex.C, positionsIndex.A);
                                }
                                else
                                {
                                    addLine(positionsIndex.C, positionsIndex.D);
                                    addLine(positionsIndex.D, positionsIndex.A);
                                }
                            }
                        }

                        var points = lines
                            .Distinct()
                            .SelectMany(t => new List<Point3D>
                        {
                            positions.ElementAtOrDefault(t.Item1),
                            positions.ElementAtOrDefault(t.Item2)
                        })
                            .ToList();

                        wireframes[lodIndex] = points;
                    }

                    return wireframes;
                })
                .ToArray();
        }
Example #26
0
        private List<ModelVisual3D> CreateMeshModelWireframe(OptFile opt, int meshIndex, int lodIndex)
        {
            if (opt == null ||
                opt.Meshes.ElementAtOrDefault(meshIndex) == null ||
                opt.Meshes[meshIndex].Lods.ElementAtOrDefault(lodIndex) == null)
            {
                return new List<ModelVisual3D>();
            }

            var cache = this.Cache;

            if (meshIndex >= cache.meshesWireframes.Length || lodIndex >= cache.meshesWireframes[meshIndex].Length)
            {
                return new List<ModelVisual3D>();
            }

            return new List<ModelVisual3D>
            {
                new LinesVisual3D
                {
                    Points = new Point3DCollection(cache.meshesWireframes[meshIndex][lodIndex]),
                    DepthOffset = 0.0001,
                    Color = Colors.White
                }
            };
        }
Example #27
0
        private void BuildTextures(OptFile opt)
        {
            this.nullTexture = null;
            this.textures = null;

            if (opt == null)
            {
                return;
            }

            this.nullTexture = new DiffuseMaterial(Brushes.White);

            this.textures = new Dictionary<string, Material>();

            foreach (var texture in opt.Textures.Values)
            {
                var image = CreateTexture(opt, texture.Name);
                image.Freeze();

                var brush = new ImageBrush(image)
                {
                    ViewportUnits = BrushMappingMode.Absolute,
                    Stretch = Stretch.Fill,
                    TileMode = TileMode.Tile,
                    Opacity = texture.HasAlpha ? 0.999 : 1.0
                };

                brush.Freeze();

                var material = new DiffuseMaterial(brush);
                material.Freeze();

                this.textures.Add(texture.Name, material);
            }
        }
        public static IEnumerable<PlayabilityMessage> CheckGeometry(OptFile opt)
        {
            if (opt == null)
            {
                yield break;
            }

            if (opt.Meshes.Count > 50)
            {
                yield return new PlayabilityMessage(
                    PlayabilityMessageLevel.Error,
                    "Meshes",
                    "The maximum meshes count for an opt is 50.");
            }

            if (opt.Meshes.Any(t => t.Vertices.Count > 512))
            {
                yield return new PlayabilityMessage(
                    PlayabilityMessageLevel.Error,
                    "Meshes",
                    "The maximum vertices count for a mesh is 512");
            }
        }
Example #29
0
 public static void OptToRhino(OptFile opt, string rhinoPath)
 {
     Converter.OptToRhino(opt, rhinoPath, true);
 }
Example #30
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;
        }
Example #31
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;
        }
Example #32
0
        public static void OptToRhino(OptFile opt, string rhinoPath, bool scale)
        {
            if (opt == null)
            {
                throw new ArgumentNullException("opt");
            }

            string rhinoDirectory = Path.GetDirectoryName(rhinoPath);
            string rhinoName = Path.GetFileNameWithoutExtension(rhinoPath);

            var distances = opt.Meshes
                .SelectMany(t => t.Lods)
                .Select(t => t.Distance)
                .Distinct()
                .OrderByDescending(t => t)
                .ToArray();

            for (int distance = 0; distance < distances.Length; distance++)
            {
                using (var file = new Rhino.FileIO.File3dm())
                {
                    file.Settings.ModelUnitSystem = Rhino.UnitSystem.Meters;

                    int objectsIndex = 0;
                    List<string> textureNames = new List<string>();

                    foreach (var mesh in opt.Meshes)
                    {
                        var lod = mesh.Lods.FirstOrDefault(t => t.Distance <= distances[distance]);

                        if (lod == null)
                        {
                            continue;
                        }

                        foreach (var textureName in lod.FaceGroups
                            .Where(t => t.Textures.Count > 0)
                            .Select(t => t.Textures[0]))
                        {
                            if (!textureNames.Contains(textureName))
                            {
                                textureNames.Add(textureName);
                            }
                        }

                        string meshName = string.Format(CultureInfo.InvariantCulture, "{0}.{1:D3}", mesh.Descriptor.MeshType, objectsIndex);

                        using (var layer = new Rhino.DocObjects.Layer())
                        {
                            layer.Name = meshName;

                            file.Layers.Add(layer);
                        }

                        foreach (var faceGroup in lod.FaceGroups)
                        {
                            using (var rhinoMesh = new Rhino.Geometry.Mesh())
                            using (var rhinoAttributes = new Rhino.DocObjects.ObjectAttributes())
                            {
                                rhinoAttributes.Name = meshName;
                                rhinoAttributes.LayerIndex = objectsIndex;

                                if (faceGroup.Textures.Count > 0)
                                {
                                    rhinoAttributes.MaterialIndex = textureNames.IndexOf(faceGroup.Textures[0]);
                                }

                                Action<Vector> addVertex;

                                if (scale)
                                {
                                    addVertex = vertex => rhinoMesh.Vertices.Add(vertex.X * OptFile.ScaleFactor, vertex.Y * OptFile.ScaleFactor, vertex.Z * OptFile.ScaleFactor);
                                }
                                else
                                {
                                    addVertex = vertex => rhinoMesh.Vertices.Add(vertex.X, vertex.Y, vertex.Z);
                                }

                                Action<TextureCoordinates> addTexCoords = texCoords => rhinoMesh.TextureCoordinates.Add(texCoords.U, -texCoords.V);

                                Action<Vector> addNormal = normal => rhinoMesh.Normals.Add(normal.X, normal.Y, normal.Z);

                                int facesIndex = 0;

                                foreach (var face in faceGroup.Faces)
                                {
                                    var verticesIndex = face.VerticesIndex;
                                    var texCoordsIndex = face.TextureCoordinatesIndex;
                                    var normalsIndex = face.VertexNormalsIndex;

                                    addVertex(mesh.Vertices[verticesIndex.A]);
                                    addTexCoords(mesh.TextureCoordinates[texCoordsIndex.A]);
                                    addNormal(mesh.VertexNormals[normalsIndex.A]);
                                    facesIndex++;

                                    addVertex(mesh.Vertices[verticesIndex.B]);
                                    addTexCoords(mesh.TextureCoordinates[texCoordsIndex.B]);
                                    addNormal(mesh.VertexNormals[normalsIndex.B]);
                                    facesIndex++;

                                    addVertex(mesh.Vertices[verticesIndex.C]);
                                    addTexCoords(mesh.TextureCoordinates[texCoordsIndex.C]);
                                    addNormal(mesh.VertexNormals[normalsIndex.C]);
                                    facesIndex++;

                                    if (verticesIndex.D >= 0)
                                    {
                                        addVertex(mesh.Vertices[verticesIndex.D]);
                                        addTexCoords(mesh.TextureCoordinates[texCoordsIndex.D]);
                                        addNormal(mesh.VertexNormals[normalsIndex.D]);
                                        facesIndex++;
                                    }

                                    if (verticesIndex.D < 0)
                                    {
                                        rhinoMesh.Faces.AddFace(facesIndex - 1, facesIndex - 2, facesIndex - 3);
                                    }
                                    else
                                    {
                                        rhinoMesh.Faces.AddFace(facesIndex - 1, facesIndex - 2, facesIndex - 3, facesIndex - 4);
                                    }
                                }

                                rhinoMesh.Compact();

                                file.Objects.AddMesh(rhinoMesh, rhinoAttributes);
                            }
                        }

                        objectsIndex++;
                    }

                    foreach (var textureName in textureNames)
                    {
                        Texture texture;
                        opt.Textures.TryGetValue(textureName, out texture);

                        using (var material = new Rhino.DocObjects.Material())
                        {
                            material.Name = textureName;

                            if (texture == null)
                            {
                                material.DiffuseColor = System.Drawing.Color.White;
                            }
                            else
                            {
                                texture.Save(Path.Combine(rhinoDirectory, textureName + ".png"));
                                material.SetBitmapTexture(textureName + ".png");

                                if (texture.HasAlpha)
                                {
                                    texture.SaveAlphaMap(Path.Combine(rhinoDirectory, textureName + "_alpha.png"));
                                    material.SetTransparencyTexture(textureName + "_alpha.png");
                                }
                            }

                            file.Materials.Add(material);
                        }
                    }

                    file.Write(Path.Combine(rhinoDirectory, string.Format(CultureInfo.InvariantCulture, "{0}_{1}.3dm", rhinoName, distance)), 4);
                }
            }
        }
Example #33
0
        public static void OptToAn8(OptFile opt, string an8Path, bool scale)
        {
            if (opt == null)
            {
                throw new ArgumentNullException("opt");
            }

            string an8Directory = Path.GetDirectoryName(an8Path);
            string an8Name = Path.GetFileNameWithoutExtension(an8Path);

            foreach (var texture in opt.Textures.Values)
            {
                texture.Save(Path.Combine(an8Directory, string.Concat(texture.Name, ".png")));
            }

            var distances = opt.Meshes
                .SelectMany(t => t.Lods)
                .Select(t => t.Distance)
                .Distinct()
                .OrderByDescending(t => t)
                .ToArray();

            for (int distance = 0; distance < distances.Length; distance++)
            {
                var an8 = new An8File();

                foreach (var texture in opt.Textures.Values)
                {
                    var an8Texture = new An8Texture();
                    an8Texture.Name = texture.Name;
                    an8Texture.Files.Add(string.Concat(texture.Name, ".png"));
                    an8.Textures.Add(an8Texture);

                    var an8Material = new An8Material();
                    an8Material.Name = texture.Name;
                    an8Material.FrontSurface = new An8Surface();
                    an8Material.FrontSurface.Diffuse = new An8MaterialColor
                    {
                        TextureName = texture.Name,
                        TextureParams = new An8TextureParams
                        {
                            AlphaMode = texture.HasAlpha ? An8AlphaMode.Final : An8AlphaMode.None,
                            BlendMode = An8BlendMode.Darken
                        }
                    };

                    an8.Materials.Add(an8Material);
                }

                var an8Object = new An8Object();
                an8Object.Name = Path.GetFileNameWithoutExtension(opt.FileName);
                an8.Objects.Add(an8Object);

                int objectsIndex = 0;

                foreach (var mesh in opt.Meshes)
                {
                    var lod = mesh.Lods.FirstOrDefault(t => t.Distance <= distances[distance]);

                    if (lod == null)
                    {
                        continue;
                    }

                    var an8Mesh = new An8Mesh();
                    an8Mesh.Name = string.Format(CultureInfo.InvariantCulture, "{0}.{1:D3}", mesh.Descriptor.MeshType, objectsIndex);
                    an8Object.Components.Add(an8Mesh);
                    objectsIndex++;

                    foreach (var texture in mesh.Lods
                        .SelectMany(t => t.FaceGroups)
                        .SelectMany(t => t.Textures)
                        .Distinct())
                    {
                        an8Mesh.MaterialList.Add(texture);
                    }

                    if (scale)
                    {
                        foreach (var v in mesh.Vertices)
                        {
                            an8Mesh.Points.Add(new An8Point
                            {
                                X = v.X * OptFile.ScaleFactor,
                                Y = v.Z * OptFile.ScaleFactor,
                                Z = v.Y * OptFile.ScaleFactor
                            });
                        }
                    }
                    else
                    {
                        foreach (var v in mesh.Vertices)
                        {
                            an8Mesh.Points.Add(new An8Point
                            {
                                X = v.X,
                                Y = v.Z,
                                Z = v.Y
                            });
                        }
                    }

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

                    foreach (var v in mesh.VertexNormals)
                    {
                        an8Mesh.Normals.Add(new An8Point
                        {
                            X = v.X,
                            Y = v.Z,
                            Z = v.Y
                        });
                    }

                    int verticesIndex = 0;
                    int verticesTexIndex = 0;
                    int verticesNormalIndex = 0;

                    foreach (var faceGroup in lod.FaceGroups)
                    {
                        int materialIndex = 0;

                        if (faceGroup.Textures.Count > 0)
                        {
                            materialIndex = an8Mesh.MaterialList.IndexOf(faceGroup.Textures[0]);
                        }

                        foreach (var face in faceGroup.Faces)
                        {
                            if (face.VerticesIndex.D < 0)
                            {
                                var an8Face = new An8Face
                                {
                                    MaterialIndex = materialIndex,
                                    FlatNormalIndex = -1
                                };

                                an8Face.PointIndexes = new int[]
                                {
                                    verticesIndex + face.VerticesIndex.A,
                                    verticesIndex + face.VerticesIndex.B,
                                    verticesIndex + face.VerticesIndex.C
                                };

                                an8Face.TexCoordIndexes = new int[]
                                {
                                    verticesTexIndex + face.TextureCoordinatesIndex.A,
                                    verticesTexIndex + face.TextureCoordinatesIndex.B,
                                    verticesTexIndex + face.TextureCoordinatesIndex.C
                                };

                                an8Face.NormalIndexes = new int[]
                                {
                                    verticesNormalIndex + face.VertexNormalsIndex.A,
                                    verticesNormalIndex + face.VertexNormalsIndex.B,
                                    verticesNormalIndex + face.VertexNormalsIndex.C
                                };

                                an8Mesh.Faces.Add(an8Face);
                            }
                            else
                            {
                                var an8Face = new An8Face
                                {
                                    MaterialIndex = materialIndex,
                                    FlatNormalIndex = -1
                                };

                                an8Face.PointIndexes = new int[]
                                {
                                    verticesIndex + face.VerticesIndex.A,
                                    verticesIndex + face.VerticesIndex.B,
                                    verticesIndex + face.VerticesIndex.C,
                                    verticesIndex + face.VerticesIndex.D
                                };

                                an8Face.TexCoordIndexes = new int[]
                                {
                                    verticesTexIndex + face.TextureCoordinatesIndex.A,
                                    verticesTexIndex + face.TextureCoordinatesIndex.B,
                                    verticesTexIndex + face.TextureCoordinatesIndex.C,
                                    verticesTexIndex + face.TextureCoordinatesIndex.D
                                };

                                an8Face.NormalIndexes = new int[]
                                {
                                    verticesNormalIndex + face.VertexNormalsIndex.A,
                                    verticesNormalIndex + face.VertexNormalsIndex.B,
                                    verticesNormalIndex + face.VertexNormalsIndex.C,
                                    verticesNormalIndex + face.VertexNormalsIndex.D
                                };

                                an8Mesh.Faces.Add(an8Face);
                            }
                        }
                    }

                    verticesIndex += mesh.Vertices.Count;
                    verticesTexIndex += mesh.TextureCoordinates.Count;
                    verticesNormalIndex += mesh.VertexNormals.Count;
                }

                an8.Save(Path.Combine(an8Directory, string.Format(CultureInfo.InvariantCulture, "{0}_{1}.an8", an8Name, distance)));
            }
        }
Example #34
0
        private List<ModelVisual3D> CreateMeshModel(OptFile opt, int meshIndex, int lodIndex, int version)
        {
            if (opt == null ||
                opt.Meshes.ElementAtOrDefault(meshIndex) == null ||
                opt.Meshes[meshIndex].Lods.ElementAtOrDefault(lodIndex) == null)
            {
                return new List<ModelVisual3D>();
            }

            var cache = this.Cache;

            var mesh = opt.Meshes[meshIndex];
            var lod = mesh.Lods[lodIndex];

            if (meshIndex >= cache.meshes.Length || lodIndex >= cache.meshes[meshIndex].Length || lod.FaceGroups.Count > cache.meshes[meshIndex][lodIndex].Length)
            {
                return new List<ModelVisual3D>();
            }

            List<ModelVisual3D> group = new List<ModelVisual3D>();

            for (int faceGroupIndex = 0; faceGroupIndex < lod.FaceGroups.Count; faceGroupIndex++)
            {
                var faceGroup = lod.FaceGroups[faceGroupIndex];

                Material texture = null;
                bool alpha = false;

                if (faceGroup.Textures.Count != 0)
                {
                    int currentVersion = version;

                    if (version < 0 || version >= faceGroup.Textures.Count)
                    {
                        currentVersion = faceGroup.Textures.Count - 1;
                    }

                    string textureName = faceGroup.Textures[currentVersion];

                    if (cache.textures.ContainsKey(textureName))
                    {
                        texture = cache.textures[textureName];
                        alpha = opt.Textures[textureName].HasAlpha;
                    }
                }

                var geometries = cache.meshes[meshIndex][lodIndex][faceGroupIndex];

                if (alpha)
                {
                    for (int i = 1; i < geometries.Length; i++)
                    {
                        GeometryModel3D model = new GeometryModel3D();

                        model.Geometry = geometries[i];
                        model.Material = texture == null ? cache.nullTexture : texture;
                        model.BackMaterial = texture == null ? cache.nullTexture : texture;

                        model.Freeze();

                        group.Add(new ModelVisual3D() { Content = model });

                        this.ModelToMeshLodFace.Add(model, new MeshLodFace(opt.Meshes[meshIndex], opt.Meshes[meshIndex].Lods[lodIndex], faceGroup));
                    }
                }
                else
                {
                    GeometryModel3D model = new GeometryModel3D();

                    model.Geometry = geometries[0];
                    model.Material = texture == null ? cache.nullTexture : texture;

                    model.Freeze();

                    group.Add(new ModelVisual3D() { Content = model });

                    this.ModelToMeshLodFace.Add(model, new MeshLodFace(opt.Meshes[meshIndex], opt.Meshes[meshIndex].Lods[lodIndex], faceGroup));
                }
            }

            return group;
        }