Esempio n. 1
0
    private bool AddChunkVisibility(Chunk chunk, MeshLod newLod)
    {
        MeshLod?maybePreviousLod = GetCurrentVisibilityMeshLod(chunk);

        if (maybePreviousLod is MeshLod previousLod)
        {
            if (newLod == previousLod)
            {
                return(true); // Return true if mesh is unchanged
            }
            return(AddVisibleMesh(chunk, newLod));
        }
        else
        {
            return(AddVisibleMesh(chunk, newLod));
        }
    }
Esempio n. 2
0
    // Attempt to add a mesh to the game object mesh collider.
    // Returns true if addition was successful,
    // otherwise returns false (due to mesh not being ready yet)
    private bool AddTangibleMesh(Chunk chunk, MeshLod meshLod)
    {
        Mesh maybeMesh = meshGenerator.RequestMesh(chunk, meshLod, includeCollider: true);

        if (maybeMesh == null)
        {
            return(false);
        }
        GameObject   gameObject   = objectCache.GetTerrainObject(chunk);
        MeshCollider meshCollider = gameObject.GetComponent <MeshCollider>();

        if (meshCollider == null)
        {
            meshCollider = gameObject.AddComponent <MeshCollider>();
        }
        meshCollider.sharedMesh = maybeMesh;
        meshCollider.enabled    = true;
        return(true);
    }
Esempio n. 3
0
        private void ExecuteNewLodCommand()
        {
            if (this.CurrentMeshes.SelectedItem == null)
            {
                return;
            }

            BusyIndicatorService.Run(dispatcher =>
            {
                var mesh = this.CurrentMeshes.SelectedItem;

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

                dispatcher(() => this.UpdateModel());
                dispatcher(() => this.CurrentMeshes.SetSelection(mesh));
                dispatcher(() => this.CurrentLods.SetSelection(lod));
            });
        }
    private MeshLod GetMaxLod(SortedList <MeshLod, float> lodPlanes, Chunk chunk)
    {
        MeshLod maxLod       = lodPlanes.First().Key;
        Point   closestPoint = space.GetPointFromPosition(observer.position);

        foreach (var entry in lodPlanes)
        {
            MeshLod meshLod           = entry.Key;
            float   distanceThreshold = entry.Value;
            if (!space.IsChunkInRange(closestPoint, chunk, distanceThreshold))
            {
                maxLod = meshLod;
            }
            else
            {
                break;
            }
        }
        return(maxLod);
    }
Esempio n. 5
0
 internal MeshLodFace(Mesh mesh, MeshLod lod, FaceGroup face)
 {
     this.Mesh = mesh;
     this.Lod  = lod;
     this.Face = face;
 }
Esempio n. 6
0
        /// <summary>
        /// Called after construction to initialise the instance.
        /// </summary>
        public virtual void InitInstance()
        {
            // Initialise joint, mesh and shape members

            Root      = CreateAvatarJoint();
            Root.Name = "mRoot";

            foreach (var keyValuePair in AvatarAppearanceDictionary.Instance.MeshEntries)
            {
                AvatarAppearanceDictionary.MeshIndex meshIndex = keyValuePair.Key;
                AvatarAppearanceDictionary.MeshEntry meshEntry = keyValuePair.Value;

                AvatarJoint joint = CreateAvatarJoint();
                joint.Name   = meshEntry.Name;
                joint.MeshId = (int)meshIndex;
                MeshLod.Add(joint);

                for (int lod = 0; lod < meshEntry.Lod; lod++)
                {
                    // TODO: Stopped here!
                    AvatarJointMesh mesh = CreateAvatarJointMesh();

                    //// We pre-pended an m - need to capitalise first character for camelCase
                    char   first    = Char.ToUpper(meshEntry.Name[0]);
                    string meshName = $"m{first}{meshEntry.Name.Substring(1)}{lod}"; // "m" + mesh_dict->mName + boost::lexical_cast < std::string> (lod); // TODO: What is lexical_cast()?
                    mesh.Name   = meshName;
                    mesh.MeshId = (int)meshIndex;
                    //mesh->setPickName(mesh_dict->mPickName);
                    mesh.IsTransparent = false;
                    switch (meshIndex)
                    {
                    case AvatarAppearanceDictionary.MeshIndex.Hair:
                        mesh.IsTransparent = true;
                        break;

                    case AvatarAppearanceDictionary.MeshIndex.Skirt:
                        mesh.IsTransparent = true;
                        break;

                    case AvatarAppearanceDictionary.MeshIndex.EyeBallLeft:
                    case AvatarAppearanceDictionary.MeshIndex.EyeBallRight:
                        mesh.SetSpecular(new Color(1.0f, 1.0f, 1.0f, 1.0f), 1f);
                        break;
                    }

                    joint.MeshParts.Add(mesh);
                }
            }

            // Associate baked textures with meshes
            foreach (KeyValuePair <AvatarAppearanceDictionary.MeshIndex, AvatarAppearanceDictionary.MeshEntry> keyValuePair in AvatarAppearanceDictionary.Instance.MeshEntries)
            {
                AvatarAppearanceDictionary.MeshIndex         meshIndex         = keyValuePair.Key;
                AvatarAppearanceDictionary.MeshEntry         meshEntry         = keyValuePair.Value;
                AvatarAppearanceDictionary.BakedTextureIndex bakedTextureIndex = meshEntry.BakedTextureIndex;

                // Skip it if there's no associated baked texture.
                if (bakedTextureIndex == AvatarAppearanceDictionary.BakedTextureIndex.NumIndices)
                {
                    continue;
                }

                foreach (AvatarJointMesh mesh in MeshLod[(int)meshIndex].MeshParts)
                {
                    BakedTextureDatas[(int)bakedTextureIndex].JointMeshes.Add(mesh);
                }
            }

            BuildCharacter();

            InitFlags |= 1 << 0;
        }
Esempio n. 7
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);
        }
        private void LoadOpt(Mesh mesh, MeshLod lod, int version)
        {
            this.Content = null;
            this.Children.Clear();
            this.ModelToMeshLodFace = new Dictionary <Model3D, MeshLodFace>();

            if (this.Cache == null || this.Cache.file == null)
            {
                return;
            }

            var opt = this.Cache.file;

            if (mesh == null && lod == null)
            {
                if (this.IsSolid)
                {
                    foreach (var model in Enumerable
                             .Range(0, opt.Meshes.Count)
                             .SelectMany(t => CreateMeshModel(opt, t, 0, version))
                             .Where(t => t != null))
                    {
                        this.Children.Add(model);
                    }
                }

                if (this.IsWireframe)
                {
                    foreach (var model in Enumerable
                             .Range(0, opt.Meshes.Count)
                             .SelectMany(t => CreateMeshModelWireframe(opt, t, 0))
                             .Where(t => t != null))
                    {
                        this.Children.Add(model);
                    }
                }
            }
            else if (lod == null)
            {
                int meshIndex = opt.Meshes.IndexOf(mesh);

                if (meshIndex == -1)
                {
                    return;
                }

                if (this.IsSolid)
                {
                    foreach (var model in CreateMeshModel(opt, meshIndex, 0, version)
                             .Where(t => t != null))
                    {
                        this.Children.Add(model);
                    }
                }

                if (this.IsWireframe)
                {
                    foreach (var model in CreateMeshModelWireframe(opt, meshIndex, 0)
                             .Where(t => t != null))
                    {
                        this.Children.Add(model);
                    }
                }
            }
            else
            {
                int meshIndex = opt.Meshes.IndexOf(mesh);

                if (meshIndex == -1)
                {
                    return;
                }

                int lodIndex = mesh.Lods.IndexOf(lod);

                if (lodIndex == -1)
                {
                    return;
                }

                if (this.IsSolid)
                {
                    foreach (var model in CreateMeshModel(opt, meshIndex, lodIndex, version)
                             .Where(t => t != null))
                    {
                        this.Children.Add(model);
                    }
                }

                if (this.IsWireframe)
                {
                    foreach (var model in CreateMeshModelWireframe(opt, meshIndex, lodIndex)
                             .Where(t => t != null))
                    {
                        this.Children.Add(model);
                    }
                }
            }
        }
Esempio n. 9
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);
        }
Esempio n. 10
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);
        }
Esempio n. 11
0
 public void Draw(IBlockEffect effect)
 {
     MeshLod.Draw(effect);
 }