/// <summary> /// Finds the closest point on a mesh given the specified sphere. We can use a sphere /// in order to test for triangles that are in-range of the point. /// </summary> /// <param name="rPoint"></param> /// <param name="rRadius"></param> /// <returns></returns> public Vector3 ClosestPoint(Vector3 rPoint, float rRadius) { if (rRadius == 0f) { return(ClosestPoint(rPoint)); } Vector3 lPoint; Vector3 lClosestPoint = Vector3.zero; lClosestPoint.x = float.MaxValue; // Gather all the triangles that are in range sClosestTrianglesIndexes.Clear(); GetTriangles(rPoint, rRadius, sClosestTrianglesIndexes); // Go through all the triangles and find the closest for (int i = 0; i < sClosestTrianglesIndexes.Count; i++) { int lTriangleIndex = sClosestTrianglesIndexes[i]; Vector3 lVertex1 = MeshVertices[MeshTriangles[lTriangleIndex]]; Vector3 lVertex2 = MeshVertices[MeshTriangles[lTriangleIndex + 1]]; Vector3 lVertex3 = MeshVertices[MeshTriangles[lTriangleIndex + 2]]; MeshExt.ClosestPointOnTriangle(ref rPoint, ref lVertex1, ref lVertex2, ref lVertex3, out lPoint); if (lPoint.x == float.MaxValue) { continue; } if (lClosestPoint.x == float.MaxValue || Vector3.SqrMagnitude(lPoint - rPoint) < Vector3.SqrMagnitude(lClosestPoint - rPoint)) { lClosestPoint = lPoint; ////lVertex1 = MeshExt.DebugTransform.TransformPoint(lVertex1); ////lVertex2 = MeshExt.DebugTransform.TransformPoint(lVertex2); ////lVertex3 = MeshExt.DebugTransform.TransformPoint(lVertex3); ////DebugDraw.DrawLineOverlay(lVertex1, lVertex2, 0.01f, Color.magenta, 1f); ////DebugDraw.DrawLineOverlay(lVertex2, lVertex3, 0.01f, Color.magenta, 1f); ////DebugDraw.DrawLineOverlay(lVertex3, lVertex1, 0.01f, Color.magenta, 1f); } } return(lClosestPoint); }
/// <summary> /// Returns the closest triangle index that the point is positioned at. /// </summary> /// <param name="rPoint">Position (in local space) we are testing</param> /// <returns></returns> public int ClosestTriangle(Vector3 rPoint) { int lClosestIndex = -1; if (rPoint.x + EPSILON < Min.x) { return(lClosestIndex); } if (rPoint.x - EPSILON > Max.x) { return(lClosestIndex); } if (rPoint.y + EPSILON < Min.y) { return(lClosestIndex); } if (rPoint.y - EPSILON > Max.y) { return(lClosestIndex); } if (rPoint.z + EPSILON < Min.z) { return(lClosestIndex); } if (rPoint.z - EPSILON > Max.z) { return(lClosestIndex); } Vector3 lPoint; Vector3 lClosestPoint = Vector3.zero; lClosestPoint.x = float.MaxValue; if (Children == null) { if (TriangleIndexes != null) { for (int i = 0; i < TriangleIndexes.Count; i++) { int lTriangleIndex = TriangleIndexes[i]; Vector3 lVertex1 = MeshVertices[MeshTriangles[lTriangleIndex]]; Vector3 lVertex2 = MeshVertices[MeshTriangles[lTriangleIndex + 1]]; Vector3 lVertex3 = MeshVertices[MeshTriangles[lTriangleIndex + 2]]; MeshExt.ClosestPointOnTriangle(ref rPoint, ref lVertex1, ref lVertex2, ref lVertex3, out lPoint); if (lPoint.x == float.MaxValue) { continue; } if (lClosestPoint.x == float.MaxValue || Vector3.SqrMagnitude(lPoint - rPoint) < Vector3.SqrMagnitude(lClosestPoint - rPoint)) { lClosestIndex = lTriangleIndex; lClosestPoint = lPoint; } } } } else { for (int i = 0; i < 8; i++) { int lTestClosestIndex = Children[i].ClosestTriangle(rPoint); if (lTestClosestIndex >= 0) { lClosestIndex = lTestClosestIndex; } } } return(lClosestIndex); }
/// <summary> /// Finds the closest point on the mesh given the specified point (in local space) /// </summary> /// <param name="rPoint"></param> /// <returns></returns> public Vector3 ClosestPoint(Vector3 rPoint) { Vector3 lPoint; Vector3 lClosestPoint = Vector3.zero; lClosestPoint.x = float.MaxValue; if (rPoint.x + EPSILON < Min.x) { return(lClosestPoint); } if (rPoint.x - EPSILON > Max.x) { return(lClosestPoint); } if (rPoint.y + EPSILON < Min.y) { return(lClosestPoint); } if (rPoint.y - EPSILON > Max.y) { return(lClosestPoint); } if (rPoint.z + EPSILON < Min.z) { return(lClosestPoint); } if (rPoint.z - EPSILON > Max.z) { return(lClosestPoint); } if (Children == null) { if (TriangleIndexes != null) { for (int i = 0; i < TriangleIndexes.Count; i++) { int lTriangleIndex = TriangleIndexes[i]; Vector3 lVertex1 = MeshVertices[MeshTriangles[lTriangleIndex]]; Vector3 lVertex2 = MeshVertices[MeshTriangles[lTriangleIndex + 1]]; Vector3 lVertex3 = MeshVertices[MeshTriangles[lTriangleIndex + 2]]; MeshExt.ClosestPointOnTriangle(ref rPoint, ref lVertex1, ref lVertex2, ref lVertex3, out lPoint); if (lPoint.x == float.MaxValue) { continue; } if (lClosestPoint.x == float.MaxValue || Vector3.SqrMagnitude(lPoint - rPoint) < Vector3.SqrMagnitude(lClosestPoint - rPoint)) { lClosestPoint = lPoint; //lVertex1 = MeshExt.DebugTransform.TransformPoint(lVertex1); //lVertex2 = MeshExt.DebugTransform.TransformPoint(lVertex2); //lVertex3 = MeshExt.DebugTransform.TransformPoint(lVertex3); //DebugDraw.DrawLineOverlay(lVertex1, lVertex2, 0.01f, Color.magenta, 1f); //DebugDraw.DrawLineOverlay(lVertex2, lVertex3, 0.01f, Color.magenta, 1f); //DebugDraw.DrawLineOverlay(lVertex3, lVertex1, 0.01f, Color.magenta, 1f); } } } } else { for (int i = 0; i < 8; i++) { lPoint = Children[i].ClosestPoint(rPoint); if (lPoint.x == float.MaxValue) { continue; } if (lClosestPoint.x == float.MaxValue || Vector3.SqrMagnitude(lPoint - rPoint) < Vector3.SqrMagnitude(lClosestPoint - rPoint)) { lClosestPoint = lPoint; } } } return(lClosestPoint); }