Example #1
0
    /// <summary>
    /// Convert a GroundMesh from a DataGround
    /// </summary>
    /// <param name="dataMesh">Dataground</param>
    /// <returns></returns>
    protected GroundMesh TrianglesToGroundMesh(DataGround dataMesh)
    {
        int        nbTriangle = dataMesh.triangles.Length;
        GroundMesh groundMesh = new GroundMesh(nbTriangle * 3, nbTriangle + 1, dataMesh.center);

        groundMesh.refTriangles = dataMesh.triangles;

        int[]     lTriangles = new int[groundMesh.triangles.Length];
        Vector3[] lVertex    = new Vector3[nbTriangle + 1];
        Vector3[] lNormals   = new Vector3[nbTriangle + 1];
        Vector2[] lUvs       = new Vector2[nbTriangle + 1];

        int ite = 0;

        for (int i = 0; i < nbTriangle; i++)
        {
            for (int j = 0; j < 3; j++)
            {
                int index = CustomGeneric.ArrayContain(lVertex, refVertices[dataMesh.triangles[i].verticesindex[j]]);
                if (index < 0)
                {
                    lVertex[ite]  = refVertices[dataMesh.triangles[i].verticesindex[j]];
                    lNormals[ite] = refNormals[dataMesh.triangles[i].verticesindex[j]];
                    ite++;
                }
            }
        }

        for (int i = 0; i < nbTriangle; i++)
        {
            Vector3 center = groundMesh.centerPosition;
            for (int j = 0; j < 3; j++)
            {
                lTriangles[i * 3 + j] = CustomGeneric.ArrayContain(lVertex, refVertices[dataMesh.triangles[i].verticesindex[j]]);
            }
        }

        groundMesh.vertex    = lVertex;
        groundMesh.normals   = lNormals;
        groundMesh.triangles = lTriangles;

        return(groundMesh);
    }
Example #2
0
 /// <summary>
 /// First init
 /// </summary>
 public void Init(GroundMesh meshObject)
 {
     meshObject.centerIndex = CustomGeneric.ArrayContain(meshObject.smoothVertex, meshObject.centerPosition);
     _indexes             = meshObject.indexes;
     _stateHealth         = 1;
     _walkable            = true;
     _elevation           = 1f;
     _isElevating         = false;
     _neighborElevationID = -1;
     _groundMesh          = meshObject;
     _poluted             = false;
     _deforested          = false;
     _axis              = GetCenterPosition();
     _personnalMesh     = GetComponent <MeshFilter>().mesh;
     _personnalCollider = GetComponents <MeshCollider>();
     _state             = CellState.MOSS;
     UpdateHeight(0);
     InitColor();
 }
Example #3
0
    /// <summary>
    /// Cut the mesh to create a smoothable cell
    /// </summary>
    /// <param name="groundMesh">GroundMesh</param>
    protected void PrepareMeshForSmooth(GroundMesh groundMesh)
    {
        Vector3[] internVertex  = new Vector3[2];
        Vector3   midEdgeVertex = Vector3.zero;

        Vector3[] edgeVertex = new Vector3[2];

        Vector3[] smoothVertex = new Vector3[(groundMesh.triangles.Length * 4) + groundMesh.triangles.Length];
        int       iterator     = 0;

        for (int i = 0; i < groundMesh.computedTriangles.Length / 3; i++)
        {
            if (groundMesh.computedVertex[groundMesh.computedTriangles[i * 3]] == Vector3.zero)
            {
                continue;
            }

            Vector3 ver1 = groundMesh.computedVertex[groundMesh.computedTriangles[(i * 3) + 1]];
            Vector3 ver2 = groundMesh.computedVertex[groundMesh.computedTriangles[(i * 3) + 2]];
            internVertex[0] = (groundMesh.centerPosition + ver1) / 2f;
            internVertex[1] = (groundMesh.centerPosition + ver2) / 2f;

            Vector3 vDir1 = (internVertex[0] - groundMesh.centerPosition);
            Vector3 vDir2 = (internVertex[1] - groundMesh.centerPosition);
            internVertex[0] = internVertex[0] + (vDir1 * CellWidth);
            internVertex[1] = internVertex[1] + (vDir2 * CellWidth);

            float d = Vector3.Distance(internVertex[0], internVertex[1]) / 2f;
            midEdgeVertex = (ver1 + ver2) / 2f;
            edgeVertex[0] = midEdgeVertex + (midEdgeVertex - ver1).normalized * d;
            edgeVertex[1] = midEdgeVertex + (midEdgeVertex - ver2).normalized * d;

            for (int j = 0; j < 5; j++)
            {
                switch (j)
                {
                case 0:
                    smoothVertex[iterator * 3]       = groundMesh.centerPosition;
                    smoothVertex[(iterator * 3) + 1] = internVertex[0];
                    smoothVertex[(iterator * 3) + 2] = internVertex[1];
                    break;

                case 1:
                    smoothVertex[iterator * 3] = internVertex[0];
                    if (Vector3.Distance(ver1, internVertex[0]) > Vector3.Distance(ver2, internVertex[0]))
                    {
                        smoothVertex[iterator * 3 + 1] = ver2;
                    }
                    else
                    {
                        smoothVertex[iterator * 3 + 1] = ver1;
                    }
                    if (Vector3.Distance(edgeVertex[0], internVertex[0]) > Vector3.Distance(edgeVertex[1], internVertex[0]))
                    {
                        smoothVertex[iterator * 3 + 2] = edgeVertex[1];
                    }
                    else
                    {
                        smoothVertex[iterator * 3 + 2] = edgeVertex[0];
                    }
                    break;

                case 2:
                    smoothVertex[iterator * 3] = internVertex[1];
                    if (Vector3.Distance(edgeVertex[0], internVertex[1]) > Vector3.Distance(edgeVertex[1], internVertex[1]))
                    {
                        smoothVertex[iterator * 3 + 1] = edgeVertex[1];
                    }
                    else
                    {
                        smoothVertex[iterator * 3 + 1] = edgeVertex[0];
                    }
                    if (Vector3.Distance(ver1, internVertex[1]) > Vector3.Distance(ver2, internVertex[1]))
                    {
                        smoothVertex[iterator * 3 + 2] = ver2;
                    }
                    else
                    {
                        smoothVertex[iterator * 3 + 2] = ver1;
                    }
                    break;

                case 3:
                    smoothVertex[iterator * 3]     = internVertex[1];
                    smoothVertex[iterator * 3 + 1] = internVertex[0];
                    if (Vector3.Distance(edgeVertex[0], internVertex[1]) > Vector3.Distance(edgeVertex[1], internVertex[1]))
                    {
                        smoothVertex[iterator * 3 + 2] = edgeVertex[1];
                    }
                    else
                    {
                        smoothVertex[iterator * 3 + 2] = edgeVertex[0];
                    }
                    break;

                case 4:
                    smoothVertex[iterator * 3]     = internVertex[0];
                    smoothVertex[iterator * 3 + 1] = edgeVertex[1];
                    smoothVertex[iterator * 3 + 2] = edgeVertex[0];
                    break;
                }

                iterator++;
            }
        }

        iterator = 0;
        int coordNumber = smoothVertex.Length;

        for (int i = 0; i < coordNumber; i++)
        {
            int found = CustomGeneric.ArrayContain(groundMesh.smoothVertex, smoothVertex[i]);
            if (found == -1)
            {
                groundMesh.smoothVertex[iterator]  = smoothVertex[i];
                groundMesh.smoothNormals[iterator] = smoothVertex[i].normalized;
                groundMesh.smoothTriangles[i]      = CustomGeneric.ArrayContain(groundMesh.smoothVertex, smoothVertex[i]);
                iterator++;
            }
            else
            {
                groundMesh.smoothTriangles[i] = found;
            }
        }

        for (int i = 0; i < groundMesh.computedTriangles.Length / 3; i++)
        {
            if (groundMesh.computedVertex[groundMesh.computedTriangles[i * 3]] == Vector3.zero)
            {
                continue;
            }

            Vector3 ver1 = groundMesh.computedVertex[groundMesh.computedTriangles[(i * 3) + 1]];
            Vector3 ver2 = groundMesh.computedVertex[groundMesh.computedTriangles[(i * 3) + 2]];
            internVertex[0] = (groundMesh.centerPosition + ver1) / 2f;
            internVertex[1] = (groundMesh.centerPosition + ver2) / 2f;

            Vector3 vDir1 = (internVertex[0] - groundMesh.centerPosition);
            Vector3 vDir2 = (internVertex[1] - groundMesh.centerPosition);
            internVertex[0] = internVertex[0] + (vDir1 * CellWidth);
            internVertex[1] = internVertex[1] + (vDir2 * CellWidth);

            float d = Vector3.Distance(internVertex[0], internVertex[1]) / 2f;
            midEdgeVertex = (ver1 + ver2) / 2f;
            edgeVertex[0] = midEdgeVertex + (midEdgeVertex - ver1).normalized * d;
            edgeVertex[1] = midEdgeVertex + (midEdgeVertex - ver2).normalized * d;

            int found = CustomGeneric.ArrayContain(groundMesh.smoothVertex, edgeVertex[0]);
            if (found != -1)
            {
                groundMesh.indexes.edgeVertexIndex[i * 2] = found;
            }

            found = CustomGeneric.ArrayContain(groundMesh.smoothVertex, edgeVertex[1]);
            if (found != -1)
            {
                groundMesh.indexes.edgeVertexIndex[i * 2 + 1] = found;
            }

            found = CustomGeneric.ArrayContain(groundMesh.smoothVertex, ver1);
            if (found != -1)
            {
                groundMesh.indexes.cornerVertexIndex[i] = found;
            }

            found = CustomGeneric.ArrayContain(groundMesh.smoothVertex, ver2);
            if (found != -1)
            {
                groundMesh.indexes.cornerVertexIndex[i] = found;
            }

            found = CustomGeneric.ArrayContain(groundMesh.smoothVertex, internVertex[0]);
            if (found != -1)
            {
                groundMesh.indexes.internVertexIndex[i] = found;
            }

            found = CustomGeneric.ArrayContain(groundMesh.smoothVertex, internVertex[1]);
            if (found != -1)
            {
                groundMesh.indexes.internVertexIndex[i] = found;
            }
        }
    }
Example #4
0
    /// <summary>
    /// Get the dual transformation of a GroundMesh
    /// </summary>
    /// <param name="groundMesh">GroundMesh</param>
    protected void DualTransformation(GroundMesh groundMesh)
    {
        Vector3[] computedVertices = new Vector3[groundMesh.computedVertex.Length];
        Vector3[] computedNormals  = new Vector3[groundMesh.computedVertex.Length];

        for (int i = 0; i < groundMesh.triangles.Length / 3; i++)
        {
            Vector3 addVector = Vector3.zero + groundMesh.centerPosition;
            if (groundMesh.vertex[groundMesh.triangles[i * 3]] != groundMesh.centerPosition)
            {
                addVector += groundMesh.vertex[groundMesh.triangles[i * 3]];
            }
            if (groundMesh.vertex[groundMesh.triangles[i * 3 + 1]] != groundMesh.centerPosition)
            {
                addVector += groundMesh.vertex[groundMesh.triangles[i * 3 + 1]];
            }
            if (groundMesh.vertex[groundMesh.triangles[i * 3 + 2]] != groundMesh.centerPosition)
            {
                addVector += groundMesh.vertex[groundMesh.triangles[i * 3 + 2]];
            }

            computedVertices[i] = addVector.normalized * radius;
            computedNormals[i]  = computedVertices[i].normalized;
        }

        computedVertices[computedVertices.Length - 2] = Vector3.zero;
        computedNormals[computedNormals.Length - 2]   = -groundMesh.centerPosition.normalized;

        computedVertices[computedVertices.Length - 1] = groundMesh.centerPosition;
        computedNormals[computedNormals.Length - 1]   = groundMesh.centerPosition.normalized;

        groundMesh.computedVertex  = computedVertices;
        groundMesh.computedNormals = computedNormals;

        // Creation of the dual triangles array

        int nbTriangle = groundMesh.triangles.Length / 3;

        VertexCouple[] couples = new VertexCouple[nbTriangle];

        for (int i = 0; i < nbTriangle; i++)
        {
            couples[i] = new VertexCouple(Vector3.zero, Vector3.zero);
        }

        int ite = 0;

        for (int j = 0; j < groundMesh.computedVertex.Length; j++)
        {
            for (int k = 0; k < groundMesh.computedVertex.Length; k++)
            {
                if (groundMesh.computedVertex[j] != groundMesh.centerPosition && groundMesh.computedVertex[k] != groundMesh.centerPosition && groundMesh.computedVertex[j] != Vector3.zero && groundMesh.computedVertex[k] != Vector3.zero)
                {
                    float angle = Vector3.Angle(groundMesh.centerPosition - groundMesh.computedVertex[j], groundMesh.centerPosition - groundMesh.computedVertex[k]);
                    if (angle > 2 && angle < 70)
                    {
                        VertexCouple newCouple = new VertexCouple(groundMesh.computedVertex[j], groundMesh.computedVertex[k]);
                        if (!CoupleExist(couples, newCouple))
                        {
                            couples[ite] = newCouple;
                            ite++;
                        }
                    }
                }
            }
        }

        int[] lTriangles = new int[groundMesh.triangles.Length * 2];
        for (int i = 0; i < couples.Length; i++)
        {
            Vector3 surfaceNormal = Vector3.Cross(groundMesh.centerPosition + couples[i].vertices[0], groundMesh.centerPosition + couples[i].vertices[1]);
            float   angle         = Vector3.Angle(gameObject.transform.position + groundMesh.centerPosition, surfaceNormal);

            if (angle < 90)
            {
                lTriangles[i * 3]     = CustomGeneric.ArrayContain(groundMesh.computedVertex, groundMesh.centerPosition);
                lTriangles[i * 3 + 1] = CustomGeneric.ArrayContain(groundMesh.computedVertex, couples[i].vertices[0]);
                lTriangles[i * 3 + 2] = CustomGeneric.ArrayContain(groundMesh.computedVertex, couples[i].vertices[1]);
            }
            else
            {
                lTriangles[i * 3]     = CustomGeneric.ArrayContain(groundMesh.computedVertex, groundMesh.centerPosition);
                lTriangles[i * 3 + 1] = CustomGeneric.ArrayContain(groundMesh.computedVertex, couples[i].vertices[1]);
                lTriangles[i * 3 + 2] = CustomGeneric.ArrayContain(groundMesh.computedVertex, couples[i].vertices[0]);
            }

            Vector4 face = MathCustom.GetPlaneValues(Vector3.zero, couples[i].vertices[1], couples[i].vertices[0]);
            if (MathCustom.GetDistanceToPlane(groundMesh.centerPosition, face) > 0)
            {
                lTriangles[groundMesh.triangles.Length + i * 3]     = CustomGeneric.ArrayContain(groundMesh.computedVertex, Vector3.zero);
                lTriangles[groundMesh.triangles.Length + i * 3 + 1] = CustomGeneric.ArrayContain(groundMesh.computedVertex, couples[i].vertices[0]);
                lTriangles[groundMesh.triangles.Length + i * 3 + 2] = CustomGeneric.ArrayContain(groundMesh.computedVertex, couples[i].vertices[1]);
            }
            else
            {
                lTriangles[groundMesh.triangles.Length + i * 3]     = CustomGeneric.ArrayContain(groundMesh.computedVertex, Vector3.zero);
                lTriangles[groundMesh.triangles.Length + i * 3 + 1] = CustomGeneric.ArrayContain(groundMesh.computedVertex, couples[i].vertices[1]);
                lTriangles[groundMesh.triangles.Length + i * 3 + 2] = CustomGeneric.ArrayContain(groundMesh.computedVertex, couples[i].vertices[0]);
            }
        }
        groundMesh.computedTriangles = lTriangles;
    }