void CalculateDistanceToMesh(Vector3 centerPoint, out float distance)
{
sqrShortestDistance = Mathf.Infinity;
float newSqrDistance;
Vector3 nrml = Vector3.one;
for (int i = 0; i < meshTriangles.Length; i += 3)
{
Vector3 p1 = filament.transform.TransformPoint(meshVertices[meshTriangles[i + 0]]);
Vector3 p2 = filament.transform.TransformPoint(meshVertices[meshTriangles[i + 1]]);
Vector3 p3 = filament.transform.TransformPoint(meshVertices[meshTriangles[i + 2]]);
Vector3 edge1 = p1 - p2;
Vector3 edge2 = p3 - p1;
Vector3 edge3 = p2 - p3;
Vector3 perp = Vector3.Cross(edge1, edge2);
float perpLenght = perp.magnitude;
Vector3 normal = perp / perpLenght;
Vector3 pointWithinPlane = Math3D.ProjectPointOnPlane(normal, p1, centerPoint);
nrml = normal;
float angleInTriangle1 = Vector3.Angle(p3 - p1, p2 - p1);
float angleInTriangle2 = Vector3.Angle(p1 - p2, p3 - p2);
float angleInTriangle3 = Vector3.Angle(p2 - p3, p1 - p3);
float angleToPointInPlane1 = Math3D.SignedVectorAngle(edge2, pointWithinPlane - p1, normal) - 0; //180;
angleToPointInPlane1 = (angleToPointInPlane1 < 0f ? angleToPointInPlane1 + 360f : angleToPointInPlane1);
float angleToPointInPlane2 = Math3D.SignedVectorAngle(edge1, pointWithinPlane - p2, normal) - 0; //180;
angleToPointInPlane2 = (angleToPointInPlane2 < 0f ? angleToPointInPlane2 + 360f : angleToPointInPlane2);
float angleToPointInPlane3 = Math3D.SignedVectorAngle(edge3, pointWithinPlane - p3, normal) - 0; //180;
angleToPointInPlane3 = (angleToPointInPlane3 < 0f ? angleToPointInPlane3 + 360f : angleToPointInPlane3);
bool outOfTriangle = angleToPointInPlane1 > angleInTriangle1 || angleToPointInPlane2 > angleInTriangle2 || angleToPointInPlane3 > angleInTriangle3;
if (!outOfTriangle)
{
newSqrDistance = (centerPoint - pointWithinPlane).sqrMagnitude;
if (newSqrDistance < sqrShortestDistance)
{
closestPoint = pointWithinPlane;
sqrShortestDistance = newSqrDistance;
sphereDot[0].transform.position = closestPoint;
sphereDot[1].transform.position = new Vector3(10000f, 10000f, 10000f);
sphereDot[2].transform.position = new Vector3(10000f, 10000f, 10000f);
}
}
else
{
projectionOnEdge[0] = Math3D.ProjectPointOnLineSegment(p2, p3, pointWithinPlane);
projectionOnEdge[1] = Math3D.ProjectPointOnLineSegment(p3, p1, pointWithinPlane);
projectionOnEdge[2] = Math3D.ProjectPointOnLineSegment(p1, p2, pointWithinPlane);
for (int j = 0; j < 3; j++)
{
newSqrDistance = (centerPoint - (projectionOnEdge[j])).sqrMagnitude;
if (newSqrDistance < sqrShortestDistance)
{
closestPoint = projectionOnEdge[j];
sqrShortestDistance = newSqrDistance;
sphereDot[0].transform.position = projectionOnEdge[0];
sphereDot[1].transform.position = projectionOnEdge[1];
sphereDot[2].transform.position = projectionOnEdge[2];
}
}
}
}
distance = Mathf.Sqrt(sqrShortestDistance);
}