Exemplo n.º 1
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);
            }
        }