Пример #1
0
        public void AddFace(IEnumerable <Face> faces, FaceMask mask)
        {
            this.WritePadding();
            this.streamWriter.Write("f");
            foreach (Face face in faces)
            {
                this.streamWriter.Write(" ");
                this.streamWriter.Write(face.Vertex.ToString(en_US));

                bool tex = ((mask & FaceMask.Tex) == FaceMask.Tex);
                bool nor = ((mask & FaceMask.Normal) == FaceMask.Normal);
                if (tex || nor)
                {
                    this.streamWriter.Write("/");
                    if (tex)
                    {
                        this.streamWriter.Write(face.Tex.ToString(en_US));
                    }
                    if (nor)
                    {
                        this.streamWriter.Write("/");
                        this.streamWriter.Write(face.Normal.ToString(en_US));
                    }
                }
            }
            this.streamWriter.WriteLine();
        }
Пример #2
0
 /// <summary>Uses the given enabled faces to use <see cref="GameObject.SetActive(bool)"/>.</summary>
 /// <param name="enabled">A <see cref="FaceMask"/> that represents the only faces that should be enabled.</param>
 public void ToggleFaces(FaceMask enabled)
 {
     right.SetActive(enabled.PosX);
     left.SetActive(enabled.NegX);
     top.SetActive(enabled.PosY);
     bottom.SetActive(enabled.NegY);
     front.SetActive(enabled.PosZ);
     back.SetActive(enabled.NegZ);
 }
Пример #3
0
        private string createGeometry(MeshFilter meshFilter)
        {
            Geometry3JS geometry = new Geometry3JS();

            geometry.name = meshFilter.name;
            Mesh mesh = meshFilter.sharedMesh;

            geometry.metadata.vertices = mesh.vertexCount;
            geometry.metadata.normals  = mesh.normals.Length;
            geometry.metadata.uvs      = mesh.uv.Length;
            geometry.metadata.faces    = mesh.triangles.Length / 3;
            FaceMask code = FaceMask.TRIANGLE;

            // Vertices
            geometry.data.vertices = new float[mesh.vertexCount * 3];
            Vector3[] vertices = mesh.vertices;
            for (int i = 0; i < mesh.vertexCount; i++)
            {
                Vector3 vertex = vertices[i];
                // (-1) *
                geometry.data.vertices[i * 3]     = vertex.x;
                geometry.data.vertices[i * 3 + 1] = vertex.y;
                geometry.data.vertices[i * 3 + 2] = (-1) * vertex.z;
            }
            // Normals
            geometry.data.normals = new float[mesh.normals.Length * 3];
            Vector3[] normals = mesh.normals;
            if (normals.Length > 0)
            {
                code = code | FaceMask.VERTEX_NORMAL;
            }
            for (int i = 0; i < normals.Length; i++)
            {
                Vector3 normal = normals[i];
                normal.Normalize();
                // (-1) *
                geometry.data.normals[i * 3]     = normal.x;
                geometry.data.normals[i * 3 + 1] = normal.y;
                geometry.data.normals[i * 3 + 2] = (-1) * normal.z;
            }
            // UV
            geometry.data.uvs = new float[1, mesh.uv.Length * 2];
            Vector2[] uvs = mesh.uv;
            if (uvs.Length > 0)
            {
                code = code | FaceMask.FACE_VERTEX_UV;
            }
            for (int i = 0; i < uvs.Length; i++)
            {
                Vector2 uv = uvs[i];
                geometry.data.uvs[0, i * 2]     = uv.x;
                geometry.data.uvs[0, i * 2 + 1] = uv.y;
            }
            // Colors
            geometry.data.colors = new float[mesh.colors.Length * 3];
            Color[] colors = mesh.colors;
            for (int i = 0; i < colors.Length; i++)
            {
                Color color = colors[i];
                geometry.data.colors[i * 3]     = color.r;
                geometry.data.colors[i * 3 + 1] = color.b;
                geometry.data.colors[i * 3 + 2] = color.g;
            }
            // Faces
            int subMeshCount = mesh.subMeshCount;

            if (subMeshCount > 1)
            {
                code = code | FaceMask.FACE_MATERIAL;
            }
            switch ((int)code)
            {
            case 0:
                // 0, [vertex_index, vertex_index, vertex_index]
                geometry.data.faces = createFaces(mesh);
                break;

            case 2:
                // 2, [vertex_index, vertex_index, vertex_index],
                // [material_index]
                geometry.data.faces = createFacesWithMaterials(mesh);
                break;

            case 8:
                // 8, [vertex_index, vertex_index, vertex_index],
                // [vertex_uv, vertex_uv, vertex_uv]
                geometry.data.faces = createFacesWithUV(mesh);
                break;

            case 10:
                // 10, [vertex_index, vertex_index, vertex_index],
                // [material_index],
                // [vertex_uv, vertex_uv, vertex_uv]
                geometry.data.faces = createFacesWithMaterialsUV(mesh);
                break;

            case 32:
                // 32, [vertex_index, vertex_index, vertex_index],
                // [vertex_normal, vertex_normal, vertex_normal]
                geometry.data.faces = createFacesWithNormals(mesh);
                break;

            case 34:
                // 34, [vertex_index, vertex_index, vertex_index],
                // [material_index],
                // [vertex_normal, vertex_normal, vertex_normal]
                geometry.data.faces = createFacesWithMaterialsNormals(mesh);
                break;

            case 40:
                // 40, [vertex_index, vertex_index, vertex_index],
                // [vertex_uv, vertex_uv, vertex_uv],
                // [vertex_normal, vertex_normal, vertex_normal]
                geometry.data.faces = createFacesWithUVNormals(mesh);
                break;

            case 42:
                // 42, [vertex_index, vertex_index, vertex_index],
                // [material_index],
                // [vertex_uv, vertex_uv, vertex_uv],
                // [vertex_normal, vertex_normal, vertex_normal]
                geometry.data.faces = createFacesWithMaterialsUVNormals(mesh);
                break;
            }
            content.geometries.Add(geometry);
            geometries.Add(geometry.uuid, mesh);
            return(geometry.uuid);
        }
Пример #4
0
 public BoolEnumerator(FaceMask mask) => this.mask = mask;
        /// <summary>
        /// Create the mesh from the current voxel data
        /// </summary>
        public void CreateMesh()
        {
            try
            {
                var vertices  = new List <Vector3>();
                var normals   = new List <Vector3>();
                var colors    = new List <Color>();
                var uv        = new List <Vector2>();
                var uv2       = new List <Vector2>();
                var uv3       = new List <Vector2>();
                var triangles = new List <int>();

                Vector3 offset =
                    new Vector3(
                        _width * _voxelScaleFactor.x,
                        _height * _voxelScaleFactor.y,
                        _depth * _voxelScaleFactor.z) * _levelOfDetailDivisor / 2.0f;

                // GreedyMesh (volume, dims)
                // Sweep over 3-axes
                // dimension = 0 -> y, z
                // dimension = 1 -> z, x
                // dimension = 2 -> x, y
                for (int dimension = 0; dimension < 3; dimension++)
                {
                    // 0 -> x, 1 -> y, 2 -> z
                    int u = (dimension + 1) % 3;
                    int v = (dimension + 2) % 3;

                    int dimensionU   = 0;
                    int dimensionV   = 0;
                    int dimensionMax = 0;

                    switch (dimension)
                    {
                    case 0:
                        dimensionMax = _width / _levelOfDetailDivisor;
                        break;

                    case 1:
                        dimensionMax = _height / _levelOfDetailDivisor;
                        break;

                    case 2:
                        dimensionMax = _depth / _levelOfDetailDivisor;
                        break;
                    }

                    switch (u)
                    {
                    case 0:
                        dimensionU = _width / _levelOfDetailDivisor;
                        break;

                    case 1:
                        dimensionU = _height / _levelOfDetailDivisor;
                        break;

                    case 2:
                        dimensionU = _depth / _levelOfDetailDivisor;
                        break;
                    }

                    switch (v)
                    {
                    case 0:
                        dimensionV = _width / _levelOfDetailDivisor;
                        break;

                    case 1:
                        dimensionV = _height / _levelOfDetailDivisor;
                        break;

                    case 2:
                        dimensionV = _depth / _levelOfDetailDivisor;
                        break;
                    }

                    int maskSize = dimensionU * dimensionV;

                    FaceMask <T>[] mask = new FaceMask <T> [maskSize];

                    int[] x = { 0, 0, 0 };
                    int[] q = { 0, 0, 0 };

                    q[dimension] = 1;
                    x[dimension] = -1;

                    // All normal directions start in the negative direction
                    int[,] normalDirections = new int[dimensionU, dimensionV];

                    for (int normalU = 0; normalU < dimensionU; normalU++)
                    {
                        for (int normalV = 0; normalV < dimensionV; normalV++)
                        {
                            normalDirections[normalU, normalV] = -1;
                        }
                    }

                    while (x[dimension] < dimensionMax)
                    {
                        // Compute mask
                        int maskIndex = 0;
                        for (x[v] = 0; x[v] < dimensionV; x[v]++)
                        {
                            for (x[u] = 0; x[u] < dimensionU; x[u]++)
                            {
                                bool first;
                                if (0 > x[dimension] || _voxels[Utilities.GetIndex(x[0] * _levelOfDetailDivisor, x[1] * _levelOfDetailDivisor, x[2] * _levelOfDetailDivisor, _width, _height, _depth)].Empty)
                                {
                                    first = false;
                                }
                                else
                                {
                                    first = true;
                                }

                                bool second;
                                if (x[dimension] >= dimensionMax - 1 || _voxels[Utilities.GetIndex((x[0] + q[0]) * _levelOfDetailDivisor, (x[1] + q[1]) * _levelOfDetailDivisor, (x[2] + q[2]) * _levelOfDetailDivisor, _width, _height, _depth)].Empty)
                                {
                                    second = false;
                                }
                                else
                                {
                                    second = true;
                                }

                                if (first != second)
                                {
                                    mask[maskIndex].HasFace = true;
                                    if (first)
                                    {
                                        mask[maskIndex].Voxel         = _voxels[Utilities.GetIndex(x[0] * _levelOfDetailDivisor, x[1] * _levelOfDetailDivisor, x[2] * _levelOfDetailDivisor, _width, _height, _depth)];
                                        mask[maskIndex].FirstOrSecond = 1;
                                    }
                                    else
                                    {
                                        mask[maskIndex].Voxel         = _voxels[Utilities.GetIndex((x[0] + q[0]) * _levelOfDetailDivisor, (x[1] + q[1]) * _levelOfDetailDivisor, (x[2] + q[2]) * _levelOfDetailDivisor, _width, _height, _depth)];
                                        mask[maskIndex].FirstOrSecond = 2;
                                    }
                                }
                                else
                                {
                                    mask[maskIndex].HasFace = false;
                                }

                                ++maskIndex;
                            }
                        }

                        //Increment x[dimension]
                        x[dimension]++;

                        //Generate mesh for mask using lexicographic ordering
                        int n = 0;
                        for (int j = 0; j < dimensionV; j++)
                        {
                            int i = 0;
                            while (i < dimensionU)
                            {
                                if (mask[n].HasFace)
                                {
                                    //Compute width
                                    int w = 1;
                                    if (n + w < mask.Length)
                                    {
                                        while (
                                            mask[n].HasFace == mask[n + w].HasFace &&
                                            i + w < dimensionU && mask[n].FirstOrSecond == mask[n + w].FirstOrSecond &&
                                            mask[n].Voxel.Equals(mask[n + w].Voxel)
                                            )
                                        {
                                            w++;

                                            if (n + w >= mask.Length)
                                            {
                                                break;
                                            }
                                        }
                                    }

                                    //Compute height (this is slightly awkward)
                                    bool done = false;
                                    int  h;
                                    for (h = 1; j + h < dimensionV; h++)
                                    {
                                        for (int k = 0; k < w; k++)
                                        {
                                            if (
                                                mask[n].HasFace != mask[n + k + h * dimensionU].HasFace ||
                                                mask[n].FirstOrSecond != mask[n + k + h * dimensionU].FirstOrSecond ||
                                                !mask[n].Voxel.Equals(mask[n + k + h * dimensionU].Voxel)
                                                )
                                            {
                                                done = true;
                                                break;
                                            }
                                        }

                                        if (done)
                                        {
                                            break;
                                        }
                                    }

                                    //Add quad

                                    // Get the starting point
                                    x[u] = i;
                                    x[v] = j;

                                    // Get the change in the dimensions for end point
                                    int[] du = { 0, 0, 0 };
                                    du[u] = w;
                                    int[] dv = { 0, 0, 0 };
                                    dv[v] = h;

                                    // Get mask direction
                                    int maskNormalDirection = normalDirections[i, j];

                                    // +/- represents normal direction
                                    FaceType faceType = FaceType.None;
                                    if (u == 1 && v == 2) // X
                                    {
                                        faceType = maskNormalDirection > 0 ? FaceType.XPositive : FaceType.XNegative;
                                    }
                                    else if (u == 2 && v == 0) // Y
                                    {
                                        faceType = maskNormalDirection > 0 ? FaceType.YPositive : FaceType.YNegative;
                                    }
                                    else if (u == 0 && v == 1) // Z
                                    {
                                        faceType = maskNormalDirection > 0 ? FaceType.ZPositive : FaceType.ZNegative;
                                    }

                                    int baseVerticesNum = vertices.Count;

                                    // If the face is rendered, add it to the triangle list, otherwise skip it
                                    if (mask[n].Voxel.AddVoxelToMesh(faceType, w, h, colors, uv, uv2, uv3))
                                    {
                                        // Vertices
                                        vertices.Add(new Vector3((x[0]) * _voxelScaleFactor.x, (x[1]) * _voxelScaleFactor.y, (x[2]) * _voxelScaleFactor.z) * _levelOfDetailDivisor - offset);                                                 // 0
                                        vertices.Add(new Vector3((x[0] + du[0]) * _voxelScaleFactor.x, (x[1] + du[1]) * _voxelScaleFactor.y, (x[2] + du[2]) * _voxelScaleFactor.z) * _levelOfDetailDivisor - offset);                         // 1
                                        vertices.Add(new Vector3((x[0] + du[0] + dv[0]) * _voxelScaleFactor.x, (x[1] + du[1] + dv[1]) * _voxelScaleFactor.y, (x[2] + du[2] + dv[2]) * _voxelScaleFactor.z) * _levelOfDetailDivisor - offset); // 2
                                        vertices.Add(new Vector3((x[0] + dv[0]) * _voxelScaleFactor.x, (x[1] + dv[1]) * _voxelScaleFactor.y, (x[2] + dv[2]) * _voxelScaleFactor.z) * _levelOfDetailDivisor - offset);                         // 3

                                        // Normals
                                        switch (faceType)
                                        {
                                        case FaceType.XPositive:
                                        case FaceType.XNegative:
                                            normals.Add(new Vector3(maskNormalDirection, 0.0f, 0.0f));
                                            normals.Add(new Vector3(maskNormalDirection, 0.0f, 0.0f));
                                            normals.Add(new Vector3(maskNormalDirection, 0.0f, 0.0f));
                                            normals.Add(new Vector3(maskNormalDirection, 0.0f, 0.0f));
                                            break;

                                        case FaceType.YPositive:
                                        case FaceType.YNegative:
                                            normals.Add(new Vector3(0.0f, maskNormalDirection, 0.0f));
                                            normals.Add(new Vector3(0.0f, maskNormalDirection, 0.0f));
                                            normals.Add(new Vector3(0.0f, maskNormalDirection, 0.0f));
                                            normals.Add(new Vector3(0.0f, maskNormalDirection, 0.0f));
                                            break;

                                        case FaceType.ZPositive:
                                        case FaceType.ZNegative:
                                            normals.Add(new Vector3(0.0f, 0.0f, maskNormalDirection));
                                            normals.Add(new Vector3(0.0f, 0.0f, maskNormalDirection));
                                            normals.Add(new Vector3(0.0f, 0.0f, maskNormalDirection));
                                            normals.Add(new Vector3(0.0f, 0.0f, maskNormalDirection));
                                            break;
                                        }


                                        if (maskNormalDirection == 1)
                                        {
                                            // Triangles
                                            triangles.Add(baseVerticesNum);     // 0
                                            triangles.Add(baseVerticesNum + 1); // 1
                                            triangles.Add(baseVerticesNum + 2); // 2

                                            triangles.Add(baseVerticesNum);     // 0
                                            triangles.Add(baseVerticesNum + 2); // 2
                                            triangles.Add(baseVerticesNum + 3); // 3
                                        }
                                        else
                                        {
                                            // Triangles
                                            triangles.Add(baseVerticesNum);     // 0
                                            triangles.Add(baseVerticesNum + 2); // 2
                                            triangles.Add(baseVerticesNum + 1); // 1


                                            triangles.Add(baseVerticesNum);     // 0
                                            triangles.Add(baseVerticesNum + 3); // 3
                                            triangles.Add(baseVerticesNum + 2); // 2
                                        }
                                    }

                                    // Set covered area to opposite normal direction
                                    for (int normalU = i; normalU < i + w; ++normalU)
                                    {
                                        for (int normalV = j; normalV < j + h; ++normalV)
                                        {
                                            normalDirections[normalU, normalV] *= -1;
                                        }
                                    }

                                    //Zero-out mask
                                    for (int l = 0; l < h; l++)
                                    {
                                        for (int k = 0; k < w; k++)
                                        {
                                            mask[n + k + l * dimensionU].HasFace = false;
                                        }
                                    }

                                    //Increment counters and continue
                                    i += w;
                                    n += w;
                                }
                                else
                                {
                                    i++;
                                    n++;
                                }
                            }
                        }
                    }
                }

                Vertices  = vertices.ToArray();
                Normals   = normals.ToArray();
                Colors    = colors.ToArray();
                UV        = uv.ToArray();
                UV2       = uv2.ToArray();
                UV3       = uv3.ToArray();
                Triangles = triangles.ToArray();

                Utilities.TangentSolver(Triangles, Vertices, Normals, UV);

                Completed = true;
            }
            catch (Exception exception)
            {
                Debug.Log(string.Format("Error creating mesh: {0}", exception.Message));
            }
        }