/// <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); }
/// <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(); }
/// <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; } } }
/// <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; }