Beispiel #1
0
        private void AddFace(Group curGroup, string[] line)
        {
            var fg = new FaceGroup();

            curGroup.fg.Add(fg);
            for (var i = 1; i < line.Length; i++)
            {
                var x    = line[i];
                var arr  = x.Split(new[] { "/" }, StringSplitOptions.None);
                var face = new Face();
                switch (arr.Length)
                {
                case 1:
                    face.v = Convert.ToInt32(arr[0]);
                    break;

                case 2:
                    face.v = Convert.ToInt32(arr[0]);
                    face.t = arr[1] == ""?-1: Convert.ToInt32(arr[1]);
                    break;

                case 3:
                    face.v = Convert.ToInt32(arr[0]);
                    face.t = arr[1] == ""?-1:Convert.ToInt32(arr[1]);
                    face.n = arr[2] == ""?-1:Convert.ToInt32(arr[2]);
                    break;

                default:
                    throw new Exception("Face with too many values");
                }

                fg.f.Add(face);
            }
        }
Beispiel #2
0
        public Soil(FaceGroup geometry, int id, string code, Grid grid, string name)
        {
            ID       = id;
            Geometry = geometry;
            Material = CreateMaterial(Material.DEFAULT_SOIL, code);
            Name     = name ?? "SoilGroup";

            SetMatrix(grid);
        }
Beispiel #3
0
        public Source(FaceGroup geometry, int id, Grid grid, string name = " ")
        {
            ID       = id;
            Geometry = geometry;
            Material = CreateMaterial(Material.DEFAULT_SOURCE);
            Name     = name ?? "SourceGroup";

            SetMatrix(grid);
        }
Beispiel #4
0
        public Plant2d(FaceGroup geometry, int id, string code, Grid grid, string name)
        {
            ID       = id;
            Geometry = geometry;
            Material = CreateMaterial(Material.DEFAULT_PLANT_2D, code);
            Name     = name ?? "PlantGroup";

            SetMatrix(grid);
        }
Beispiel #5
0
        public Building(FaceGroup geometry, int id, Material material, Grid grid, string name = " ")
        {
            ID       = id;
            Geometry = geometry;
            Material = material;
            Name     = name;

            SetMatrix(grid);
        }
Beispiel #6
0
        public Building(Grid grid, FaceGroup geometry, int id, Material material, string name)
        {
            ID       = id;
            Geometry = geometry;
            Material = material ?? CreateMaterial(null, null, null, null);
            Name     = name ?? "Building";

            SetMatrix(grid);
        }
Beispiel #7
0
        public Source(Grid grid, FaceGroup geometry, int id, string code, string name)
        {
            ID       = id;
            Geometry = geometry;
            Material = (code != null) ? CreateMaterial(Material.DEFAULT_SOURCE, code) : CreateMaterial(Material.DEFAULT_SOURCE);
            Name     = name ?? "SourceGroup";

            SetMatrix(grid);
        }
Beispiel #8
0
        public Building(FaceGroup geometry, int id, Grid grid, string name = " ")
        {
            ID       = id;
            Geometry = geometry;
            Material = CreateMaterial(null, null, null, null);
            Name     = name;

            SetMatrix(grid);
        }
        public void AddTriangle(Vector3 v1, Vector3 v2, Vector3 v3, Vector2 uv1, Vector2 uv2, Vector2 uv3, Material m)
        {
            var a    = v1 - v2;
            var b    = v3 - v2;
            var norm = Vector3.Cross(a, b);

            norm.Normalize();
            Normals.Add(norm);
            Normals.Add(norm);
            Normals.Add(norm);
            Positions.Add(v1);
            Positions.Add(v2);
            Positions.Add(v3);
            UV.Add(uv1);
            UV.Add(uv2);
            UV.Add(uv3);

            var facegroup = FaceGroups.Find(x => x.Material == m);

            if (facegroup != null)
            {
                if (facegroup.Indices == null)
                {
                    facegroup.Indices = new List <int>();
                }

                facegroup.Indices.Add(NetIndices.Count);
                NetIndices.Add(NetIndices.Count);
                facegroup.Indices.Add(NetIndices.Count);
                NetIndices.Add(NetIndices.Count);
                facegroup.Indices.Add(NetIndices.Count);
                NetIndices.Add(NetIndices.Count);
                facegroup.Material = m;
            }
            else
            {
                facegroup         = new FaceGroup();
                facegroup.Indices = new List <int>();
                facegroup.Indices.Add(NetIndices.Count);
                NetIndices.Add(NetIndices.Count);
                facegroup.Indices.Add(NetIndices.Count);
                NetIndices.Add(NetIndices.Count);
                facegroup.Indices.Add(NetIndices.Count);
                NetIndices.Add(NetIndices.Count);
                facegroup.Material = m;
                FaceGroups.Add(facegroup);
            }
        }
Beispiel #10
0
    public void CloneFace()
    {
        if (initFace == null)
        {
            Debug.Log("缺少初始化脸型");
            return;
        }

        faceGroups.Clear();
        FacePincher initFacePicher = initFace.GetComponent <FacePincher>();

        foreach (FaceGroup faceGroup in initFacePicher.faceGroups)
        {
            // 初始化faceGroup数据
            FaceGroup tempGroup = new FaceGroup();
            faceGroups.Add(tempGroup);
            tempGroup.ResetData(tempGroup);
            foreach (FaceGroupPart faceGroupPart in faceGroup.faceGroupParts)
            {
                // 初始化faceGroupPart数据
                FaceGroupPart tempFaceGroupPart = new FaceGroupPart();
                tempGroup.faceGroupParts.Add(tempFaceGroupPart);
                tempFaceGroupPart.ResetData(faceGroupPart);
                foreach (FaceBone faceBone in faceGroupPart.faceBones)
                {
                    // 初始化faceBone数据
                    FaceBone tempFaceBones = new FaceBone();
                    tempFaceGroupPart.faceBones.Add(tempFaceBones);
                    string    path      = "";
                    Transform tempTrans = faceBone.bone;
                    Transform root      = faceBone.bone.root;
                    while (tempTrans != root)
                    {
                        path = tempTrans.name + path;
                        if (tempTrans.parent != root)
                        {
                            path = "/" + path;
                        }
                        tempTrans = tempTrans.parent;
                    }
                    Transform bone = transform.Find(path);
                    tempFaceBones.ResetData(faceBone, bone, bone);
                }
            }
        }
        OnValidate();
    }
Beispiel #11
0
            LOD readLOD(BinaryReader reader)
            {
                LOD newLOD = new LOD();

                newLOD.relativeDistance = reader.ReadSingle();
                var vertexCount = reader.ReadUInt16();

                newLOD.vertices = new List <Vertex>();

                for (var i = 0; i < vertexCount; i++)
                {
                    Vertex newVertex = new Vertex();
                    newVertex.pos    = ReadVector3(reader);
                    newVertex.normal = ReadVector3(reader);
                    newVertex.uv     = ReadVector2(reader);

                    newLOD.vertices.Add(newVertex);
                }

                var faceGroupCount = reader.ReadByte();

                newLOD.faceGroups = new List <FaceGroup>();

                for (var i = 0; i < faceGroupCount; i++)
                {
                    FaceGroup newFaceGroup = new FaceGroup();
                    newFaceGroup.faces = new List <Face>();

                    var faceCount = reader.ReadUInt16();

                    for (var j = 0; j < faceCount; j++)
                    {
                        Face newFace = new Face();
                        newFace.a = reader.ReadUInt16();
                        newFace.b = reader.ReadUInt16();
                        newFace.c = reader.ReadUInt16();

                        newFaceGroup.faces.Add(newFace);
                    }

                    newFaceGroup.materialID = reader.ReadUInt16();
                    newLOD.faceGroups.Add(newFaceGroup);
                }

                return(newLOD);
            }
Beispiel #12
0
        public static List <Ray> GetRayFromFacegroup(Grid grid, FaceGroup facegroup)
        {
            MorphoGeometry.BoundaryBox box = new MorphoGeometry.BoundaryBox(facegroup);

            Vector minPt = box.MinPoint;
            Vector maxPt = box.MaxPoint;

            var rayXcomponent = Util.FilterByMinMax(grid.Xaxis, maxPt.x, minPt.x);
            var rayYcomponent = Util.FilterByMinMax(grid.Yaxis, maxPt.y, minPt.y);

            List <Ray> rays = new List <Ray>();

            foreach (double y in rayYcomponent)
            {
                foreach (double x in rayXcomponent)
                {
                    rays.Add(new Ray(new Vector((float)x, (float)y, 0), new Vector(0, 0, 1)));
                }
            }

            return(rays);
        }
Beispiel #13
0
 private static Mesh Convert(FaceGroup group, IEnumerable <Face> faces, IEnumerable <Vertex> vertices)
 {
     return(Convert(faces.Skip(group.StartFace).Take(1 + group.EndFace - group.StartFace), vertices));
 }
Beispiel #14
0
 public static IEnumerable <Vector> Raycasting(List <Ray> rays, FaceGroup facegroup, bool reverse = false, bool project = false)
 {
     return(Intersection.RaysFaceGroupIntersect(rays, facegroup, reverse, project));
 }
Beispiel #15
0
        private static Mesh Convert(FaceGroup group, ICollection <Face> faces, ICollection <Vertex> vertices)
        {
            int numFaces = 1 + group.EndFace - group.StartFace;

            return(Convert(faces.Skip(group.StartFace).Take(numFaces), numFaces, vertices, vertices.Count));
        }
Beispiel #16
0
        /// <summary>
        /// Reads a model from a Wavefront OBJ (.obj) model file.
        /// </summary>
        /// <param name="path">File path to the file to parse</param>
        /// <returns>Model parsed from the specified file</returns>
        public static Model FromFile(String path)
        {
            int vertCount = 0, txuvCount = 0, normCount = 0, faceCount = 0;
            var vertGroups = new List<FaceGroup>();
            FaceGroup lastGroup = null;

            // Read all lines from the file and store them as a string array
            var lines = File.ReadAllLines(path);

            // Loop through each line in the array, counting how many vertices,
            // normals, texture UV coordinates, and faces there are. Also, find
            // the start indices and lengths of any face groups.
            foreach (var line in lines) {
                // If the line specifies the start of a face group...
                if (_sREObjc.IsMatch(line)) {
                    // If this isn't the first group in the file...
                    if (lastGroup != null) {
                        // Update the last group to record that the group
                        // ended at the last face read
                        lastGroup.Length = faceCount - lastGroup.StartIndex;
                    }

                    // Start a new face group with the name given by this line, and
                    // with the start index being that of the next face read
                    lastGroup = new FaceGroup(line.Substring(line.IndexOf(' ') + 1)) { StartIndex = faceCount };
                    
                    // Add the face group to the list of groups in this file
                    vertGroups.Add(lastGroup);
                    continue;
                }

                // If the line specifies a vertex position, increment the vertex count
                if (_sREVert.IsMatch(line)) {
                    ++vertCount; continue;
                }

                // If the line specifies a texture coordinate, increment the UV count
                if (_sRETxUV.IsMatch(line)) {
                    ++txuvCount; continue;
                }

                // If the line specifies a vertex normal, increment the normal count
                if (_sRENorm.IsMatch(line)) {
                    ++normCount; continue;
                }

                // If the line specifies a face, increment the face count
                if (_sREFace.IsMatch(line)) {
                    ++faceCount; continue;
                }
            }

            // If there is a face group that has not been completed...
            if (lastGroup != null) {
                // Update the last group to record that the group
                // ended at the last face read
                lastGroup.Length = faceCount - lastGroup.StartIndex;
            }

            // Set up the arrays for vertex positions, UV coordinates, normals, and faces
            var verts = new Vector3[vertCount]; int vi = 0;
            var txuvs = new Vector2[txuvCount]; int ti = 0;
            var norms = new Vector3[normCount]; int ni = 0;
            var faces = new Face[faceCount]; int fi = 0;

            // Create a model instance with these arrays, which will be populated after
            var model = new Model(vertGroups.ToArray(), verts, txuvs, norms, faces);

            // Loop through each line again, but this time actually parsing vertex values
            foreach (var line in lines) {
                // Chop off the identifier token from the start of the string
                var data = line.Substring(line.IndexOf(' ') + 1);

                // If the line is a vertex position, parse it and store it
                if (_sREVert.IsMatch(line)) {
                    verts[vi++] = ParseVector3(data);
                    continue;
                }

                // If the line is a texture UV coordinate, parse it and store it
                if (_sRETxUV.IsMatch(line)) {
                    txuvs[ti++] = ParseVector2(data);
                    continue;
                }

                // If the line is a vertex normal, parse it and store it
                if (_sRENorm.IsMatch(line)) {
                    norms[ni++] = ParseVector3(data);
                    continue;
                }

                // If the line is a face, parse its indices and store it
                if (_sREFace.IsMatch(line)) {
                    faces[fi++] = Face.Parse(data);
                    continue;
                }
            }

            // Update the model's VBO with the newly parsed data, then return it
            model.UpdateVertices();
            return model;
        }
Beispiel #17
0
 public void ResetData(FaceGroup initFaceGroup)
 {
     name = initFaceGroup.name;
 }
Beispiel #18
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);
        }
Beispiel #19
0
        /// <summary>
        /// Reads a model from a Wavefront OBJ (.obj) model file.
        /// </summary>
        /// <param name="path">File path to the file to parse</param>
        /// <returns>Model parsed from the specified file</returns>
        public static Model FromFile(String path)
        {
            int       vertCount = 0, txuvCount = 0, normCount = 0, faceCount = 0;
            var       vertGroups = new List <FaceGroup>();
            FaceGroup lastGroup  = null;

            // Read all lines from the file and store them as a string array
            var lines = File.ReadAllLines(path);

            // Loop through each line in the array, counting how many vertices,
            // normals, texture UV coordinates, and faces there are. Also, find
            // the start indices and lengths of any face groups.
            foreach (var line in lines)
            {
                // If the line specifies the start of a face group...
                if (_sREObjc.IsMatch(line))
                {
                    // If this isn't the first group in the file...
                    if (lastGroup != null)
                    {
                        // Update the last group to record that the group
                        // ended at the last face read
                        lastGroup.Length = faceCount - lastGroup.StartIndex;
                    }

                    // Start a new face group with the name given by this line, and
                    // with the start index being that of the next face read
                    lastGroup = new FaceGroup(line.Substring(line.IndexOf(' ') + 1))
                    {
                        StartIndex = faceCount
                    };

                    // Add the face group to the list of groups in this file
                    vertGroups.Add(lastGroup);
                    continue;
                }

                // If the line specifies a vertex position, increment the vertex count
                if (_sREVert.IsMatch(line))
                {
                    ++vertCount; continue;
                }

                // If the line specifies a texture coordinate, increment the UV count
                if (_sRETxUV.IsMatch(line))
                {
                    ++txuvCount; continue;
                }

                // If the line specifies a vertex normal, increment the normal count
                if (_sRENorm.IsMatch(line))
                {
                    ++normCount; continue;
                }

                // If the line specifies a face, increment the face count
                if (_sREFace.IsMatch(line))
                {
                    ++faceCount; continue;
                }
            }

            // If there is a face group that has not been completed...
            if (lastGroup != null)
            {
                // Update the last group to record that the group
                // ended at the last face read
                lastGroup.Length = faceCount - lastGroup.StartIndex;
            }

            // Set up the arrays for vertex positions, UV coordinates, normals, and faces
            var verts = new Vector3[vertCount]; int vi = 0;
            var txuvs = new Vector2[txuvCount]; int ti = 0;
            var norms = new Vector3[normCount]; int ni = 0;
            var faces = new Face[faceCount]; int fi = 0;

            // Create a model instance with these arrays, which will be populated after
            var model = new Model(vertGroups.ToArray(), verts, txuvs, norms, faces);

            // Loop through each line again, but this time actually parsing vertex values
            foreach (var line in lines)
            {
                // Chop off the identifier token from the start of the string
                var data = line.Substring(line.IndexOf(' ') + 1);

                // If the line is a vertex position, parse it and store it
                if (_sREVert.IsMatch(line))
                {
                    verts[vi++] = ParseVector3(data);
                    continue;
                }

                // If the line is a texture UV coordinate, parse it and store it
                if (_sRETxUV.IsMatch(line))
                {
                    txuvs[ti++] = ParseVector2(data);
                    continue;
                }

                // If the line is a vertex normal, parse it and store it
                if (_sRENorm.IsMatch(line))
                {
                    norms[ni++] = ParseVector3(data);
                    continue;
                }

                // If the line is a face, parse its indices and store it
                if (_sREFace.IsMatch(line))
                {
                    faces[fi++] = Face.Parse(data);
                    continue;
                }
            }

            // Update the model's VBO with the newly parsed data, then return it
            model.UpdateVertices();
            return(model);
        }
Beispiel #20
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);
        }
Beispiel #21
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);
        }
Beispiel #22
0
 internal MeshLodFace(Mesh mesh, MeshLod lod, FaceGroup face)
 {
     this.Mesh = mesh;
     this.Lod  = lod;
     this.Face = face;
 }
Beispiel #23
0
        /// <summary>
        /// Private constructor to create a new instance of Model.
        /// </summary>
        /// <param name="faceGroups">Array of face groups within the model</param>
        /// <param name="verts">Array of vertex positions</param>
        /// <param name="txuvs">Array of texture UV coordinates</param>
        /// <param name="norms">Array of vertex normals</param>
        /// <param name="faces">Array of faces within the model</param>
        private Model(FaceGroup[] faceGroups, Vector3[] verts, Vector2[] txuvs, Vector3[] norms, Face[] faces)
        {
            FaceGroups = faceGroups;

            _verts = verts;
            _txuvs = txuvs;
            _norms = norms;
            _faces = faces;

            // Create a vertex buffer to store the vertex data, with a stride
            // of 8 (position:3 + uv:2 + normal:3)
            _vb = new VertexBuffer(8);
        }