/** * Get a weighted value for the quality of a quad composed of two triangles. 0 is terrible, 1 is perfect. * normalThreshold will discard any quads where the dot product of their normals is less than the threshold. * @todo Abstract the quad detection to a separate class so it can be applied to pb_Objects. */ static float GetQuadScore(this ProBuilderMesh mesh, WingedEdge left, WingedEdge right, float normalThreshold = .9f) { Vertex[] vertices = mesh.GetVertices(); int[] quad = WingedEdge.MakeQuad(left, right); if (quad == null) { return(0f); } // first check normals Vector3 leftNormal = Math.Normal(vertices[quad[0]].position, vertices[quad[1]].position, vertices[quad[2]].position); Vector3 rightNormal = Math.Normal(vertices[quad[2]].position, vertices[quad[3]].position, vertices[quad[0]].position); float score = Vector3.Dot(leftNormal, rightNormal); if (score < normalThreshold) { return(0f); } // next is right-angle-ness check Vector3 a = (vertices[quad[1]].position - vertices[quad[0]].position); Vector3 b = (vertices[quad[2]].position - vertices[quad[1]].position); Vector3 c = (vertices[quad[3]].position - vertices[quad[2]].position); Vector3 d = (vertices[quad[0]].position - vertices[quad[3]].position); a.Normalize(); b.Normalize(); c.Normalize(); d.Normalize(); float da = Mathf.Abs(Vector3.Dot(a, b)); float db = Mathf.Abs(Vector3.Dot(b, c)); float dc = Mathf.Abs(Vector3.Dot(c, d)); float dd = Mathf.Abs(Vector3.Dot(d, a)); score += 1f - ((da + db + dc + dd) * .25f); // and how close to parallel the opposite sides area score += Mathf.Abs(Vector3.Dot(a, c)) * .5f; score += Mathf.Abs(Vector3.Dot(b, d)) * .5f; // the three tests each contribute 1 return(score * .33f); }