/// <summary> /// Recalculate peak to make ground flat /// </summary> /// <param name="groundMesh">GroundMesh</param> protected void RecalculatePeak(GroundMesh groundMesh, Vector3 origin) { int nbVertex = groundMesh.computedVertex.Length; Vector3[] planPoints = new Vector3[3]; int ite = 0; for (int i = 0; i < nbVertex; i++) { if (groundMesh.computedVertex[i] != groundMesh.centerPosition) { planPoints[ite] = groundMesh.computedVertex[i]; ite++; if (ite >= 3) { break; } } } Vector4 groundPlan = MathCustom.GetPlaneValues(planPoints[0], planPoints[1], planPoints[2]); Vector3 newCenterPosition = MathCustom.LineCutPlaneCoordinates(origin, groundMesh.centerPosition * int.MaxValue, groundPlan); for (int i = 0; i < nbVertex; i++) { if (groundMesh.computedVertex[i] == groundMesh.centerPosition) { groundMesh.centerPosition = newCenterPosition; groundMesh.computedVertex[i] = newCenterPosition; } } }
/// <summary> /// Generate UV mapping /// </summary> /// <param name="groundMesh"></param> protected void GenerateTextureMap(GroundMesh groundMesh) { Vector3 cross = Vector3.Cross(Vector3.up, groundMesh.centerPosition); Vector3 py = groundMesh.centerPosition + cross; Vector3 pz = groundMesh.centerPosition + Vector3.Cross(cross, groundMesh.centerPosition); Vector4 cellPlan = MathCustom.GetPlaneValues(groundMesh.centerPosition, py, pz); for (int i = 0; i < groundMesh.smoothVertex.Length; i++) { Vector3 vertex = groundMesh.smoothVertex[i]; if (vertex == groundMesh.centerPosition) { groundMesh.UVs[i] = new Vector2(0.5f, 0.5f); } else { Vector3 planeCoord = MathCustom.LineCutPlaneCoordinates(Vector3.zero, vertex, cellPlan); Vector3 cartesianPos = Quaternion.FromToRotation(groundMesh.centerPosition, Vector3.up) * planeCoord; float lRadius; float lPolar; float lElevation; MathCustom.CartesianToSpherical(cartesianPos, out lRadius, out lPolar, out lElevation); float xAngle = Vector3.SignedAngle(groundMesh.centerPosition, vertex, groundMesh.centerPosition); float yAngle = Vector3.SignedAngle(Vector3.Cross(groundMesh.centerPosition, -Vector3.up), vertex, groundMesh.centerPosition); if (CustomGeneric.IntArrayContain(groundMesh.indexes.internVertexIndex, i) != -1) { groundMesh.UVs[i] = new Vector2(0.5f + (Mathf.Cos(lPolar) * 0.9f), 0.5f + (Mathf.Sin(lPolar) * 0.9f)); } else { groundMesh.UVs[i] = new Vector2(0.5f + Mathf.Cos(lPolar), 0.5f + Mathf.Sin(lPolar)); } } } }
/// <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] = ArrayContain(groundMesh.computedVertex, groundMesh.centerPosition); lTriangles[i * 3 + 1] = ArrayContain(groundMesh.computedVertex, couples[i].vertices[0]); lTriangles[i * 3 + 2] = ArrayContain(groundMesh.computedVertex, couples[i].vertices[1]); } else { lTriangles[i * 3] = ArrayContain(groundMesh.computedVertex, groundMesh.centerPosition); lTriangles[i * 3 + 1] = ArrayContain(groundMesh.computedVertex, couples[i].vertices[1]); lTriangles[i * 3 + 2] = 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] = ArrayContain(groundMesh.computedVertex, Vector3.zero); lTriangles[groundMesh.triangles.Length + i * 3 + 1] = ArrayContain(groundMesh.computedVertex, couples[i].vertices[0]); lTriangles[groundMesh.triangles.Length + i * 3 + 2] = ArrayContain(groundMesh.computedVertex, couples[i].vertices[1]); } else { lTriangles[groundMesh.triangles.Length + i * 3] = ArrayContain(groundMesh.computedVertex, Vector3.zero); lTriangles[groundMesh.triangles.Length + i * 3 + 1] = ArrayContain(groundMesh.computedVertex, couples[i].vertices[1]); lTriangles[groundMesh.triangles.Length + i * 3 + 2] = ArrayContain(groundMesh.computedVertex, couples[i].vertices[0]); } } groundMesh.computedTriangles = lTriangles; }