public Quad (Triangle triangle1, Triangle triangle2) { row = 0; this.triangles = new Triangle[2]; triangles [0] = triangle1; triangles [0].isLeft = true; triangles [1] = triangle2; for (int t=0; t<2; t++) { area += triangles[t].area; List<Vector3> tpositions = triangles [t].positions; for (int i=0; i<tpositions.Count; i++) { int pointIndex = getPointIndex (tpositions [i]); if (pointIndex == -1) { vertexIndices.Add (positions.Count); positions.Add (tpositions [i]); uvs.Add (triangles [t].uvs [i]); normals.Add(triangles [t].normals [i]); } else { vertexIndices.Add (pointIndex); } } } for (int i=0; i<4; i++) { centerPos += positions [i]; } centerPos /= 4f; base.init (); }
public bool hasSameSharedVertices (Triangle t) { if (t.avgNormal != avgNormal) { return false; } int found = 0; for (int i=0; i<positions.Count; i++) { for (int j=0; j<t.positions.Count; j++) { if (positions [i] == t.positions [j]) { found++; } } } return found == 2; }
public void addTriangle (Triangle t) { if (primitives.Count == 0) { bounds = t.bounds; } else { bounds.Encapsulate(t.bounds); } primitives.Add (t); triangles.Add (t); }
private static CustomMesh buildTriangles (Mesh mesh, string name, Transform transform, bool keep, bool noCompare, int materialIndex) { CustomMesh customMesh = new CustomMesh (); customMesh.mesh = mesh; customMesh.keep = keep; customMesh.noCompare = noCompare; customMesh.name = name; customMesh.materialIndex = materialIndex; for (int triangle = 0; triangle < mesh.triangles.Length/3; triangle++) { int[] vertices = new int[3]; Vector3[] positions = new Vector3[3]; Color[] colors = new Color[3]; Vector2[] uvs = new Vector2[3]; Vector3[] normals = new Vector3[3]; for (int i=0; i<3; i++) { int vertexIndex = mesh.triangles [triangle * 3 + i]; if (transform != null) { positions [i] = transform.TransformPoint (mesh.vertices [vertexIndex]); } else { positions [i] = mesh.vertices [vertexIndex]; } if (mesh.colors.Length > vertexIndex) { colors [i] = mesh.colors [vertexIndex]; } if (transform != null) { normals[i] = transform.TransformDirection (mesh.normals [vertexIndex]); } else { normals[i] = mesh.normals [vertexIndex]; } if(mesh.uv.Length > 0){ uvs [i] = mesh.uv [vertexIndex]; } vertices [i] = vertexIndex; } Triangle tr = new Triangle (positions, colors, uvs, normals); customMesh.addTriangle (tr); } return customMesh; }
private static Triangle findQuadTriangle (Triangle t, List<Triangle> triangles) { for (int i=0; i<triangles.Count; i++) { Triangle t2 = triangles [i]; if (t2 != t && t2.hasSameSharedVertices (t) && !t2.addedToQuad && !t2.removed) { t2.addedToQuad = true; return t2; } } return null; }
private static void buildQuadsFromTriangles (List<CustomMesh> meshes) { for (int mi=0; mi<meshes.Count; mi++) { CustomMesh customMesh = meshes [mi]; List<Triangle> triangles = new List<Triangle>(customMesh.getTriangles ()); customMesh.clear(); for (int t=0; t<triangles.Count; t++) { Triangle t1 = triangles [t]; if(t1.removed){ continue; } if ((customMesh.noCompare || (Mathf.Abs (t1.avgNormal.y)) < 1.0f - MeshUtils.MAX_ROUND_ERROR.x && Mathf.Abs (t1.avgNormal.y) > MeshUtils.MAX_ROUND_ERROR.x)) { t1.addedToQuad = true; customMesh.addTriangle (t1); continue; } if (!t1.addedToQuad) { Triangle t2 = findQuadTriangle (t1, triangles); if (t2 != null) { t1.addedToQuad = true; Quad quad = new Quad (t1, t2); List<Vector3> positions = new List<Vector3> (quad.positions); List<Vector2> uvs = new List<Vector2> (quad.uvs); // Rotate object so the points are always in XY-space Quaternion rot = Quaternion.FromToRotation (quad.avgNormal, new Vector3 (0, 0, -1)); // Move center to origo for (int i=0; i<positions.Count; i++) { positions [i] = rot * (positions [i] - quad.bounds.center); } Bounds quadBounds = createBounds (positions); // After this method quad points are in this order: // // 0 1 // // 3 2 Quad.arrangePositions (ref positions, ref uvs, quadBounds); float x1length = Vector3.Distance (positions [1], positions [0]) - MeshUtils.MAX_ROUND_ERROR.x; float x2length = Vector3.Distance (positions [2], positions [3]) - MeshUtils.MAX_ROUND_ERROR.x; float y1length = Vector3.Distance (positions [0], positions [3]) - MeshUtils.MAX_ROUND_ERROR.x; float y2length = Vector3.Distance (positions [1], positions [2]) - MeshUtils.MAX_ROUND_ERROR.x; bool divide = false;//!customMesh.keep; float xdiff = Mathf.Abs (x1length - x2length); float ydiff = Mathf.Abs (y1length - y2length); if (divide && (x1length > 0 && y1length > 0 && x2length > 0 && y2length > 0 && xdiff < 0.001f && ydiff < 0.001f && (x1length > 1 || y1length > 1))) { Color[] colors = new Color[3]; int ydivisions = (int)Mathf.Ceil (y1length); int xdivisions = (int)Mathf.Ceil (x1length); for (int y=0; y<ydivisions; y++) { Vector3 currentStartPoint = positions [0] + Vector3.Normalize (positions [3] - positions [0]) * y; for (int x=0; x<xdivisions; x++) { Vector3 point1 = currentStartPoint + Vector3.Normalize (positions [1] - positions [0]); Vector3 point2 = point1 + Vector3.Normalize (positions [2] - positions [1]); Vector3 point3 = currentStartPoint + Vector3.Normalize (positions [3] - positions [0]); // Check boundaries if (point1.x > positions [1].x) { point1.x = positions [1].x; } if (point1.y < positions [2].y) { point1.y = positions [1].y; } if (point2.x > positions [2].x) { point2.x = positions [2].x; } if (point2.y < positions [2].y) { point2.y = positions [2].y; } if (point3.y < positions [3].y) { point3.y = positions [3].y; } // Create triangles List<Vector3> trPositions = new List<Vector3> (); trPositions.Add (currentStartPoint); trPositions.Add (point1); trPositions.Add (point3); List<Vector3> tr2Positions = new List<Vector3> (); tr2Positions.Add (point1); tr2Positions.Add (point2); tr2Positions.Add (point3); // Calculate UVs List<Vector2> trUVs = new List<Vector2> (); Vector2 uv0 = Quad.calculateUVForPoint (trPositions [0], positions, uvs); Vector2 uv1 = Quad.calculateUVForPoint (trPositions [1], positions, uvs); Vector2 uv2 = Quad.calculateUVForPoint (tr2Positions [1], positions, uvs); Vector2 uv3 = Quad.calculateUVForPoint (trPositions [2], positions, uvs); trUVs.Add (uv0); trUVs.Add (uv1); trUVs.Add (uv3); List<Vector2> tr2UVs = new List<Vector2> (); tr2UVs.Add (uv1); tr2UVs.Add (uv2); tr2UVs.Add (uv3); // Revert the previous movement for (int i=0; i<trPositions.Count; i++) { // Invert XY-space changes trPositions [i] = Quaternion.Inverse (rot) * trPositions [i]; trPositions [i] += quad.bounds.center; tr2Positions [i] = Quaternion.Inverse (rot) * tr2Positions [i]; tr2Positions [i] += quad.bounds.center; } // Create new Quad List<Vector3> nnormals = new List<Vector3> (); for (int i=0; i<3; i++) { nnormals.Add (quad.avgNormal); } Triangle tr1 = new Triangle (trPositions.ToArray (), colors, trUVs.ToArray (), nnormals.ToArray ()); Triangle tr2 = new Triangle (tr2Positions.ToArray (), colors, tr2UVs.ToArray (), nnormals.ToArray ()); Quad newQuad = new Quad (tr1, tr2); customMesh.addQuad (newQuad); currentStartPoint = point1; } } } else { customMesh.addQuad (quad); } } else { t1.addedToQuad = true; customMesh.addTriangle (t1); } } } } }