ProjectPointOnPlane() public static method

public static ProjectPointOnPlane ( Vector3 planeNormal, Vector3 planePoint, Vector3 point ) : Vector3
planeNormal Vector3
planePoint Vector3
point Vector3
return Vector3
    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);
    }
Example #2
0
    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)
        {
            //filament.transform.position + filament.transform.rotation *
            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;

            //Debug.Log(((360 - 2 * Vector3.Angle(p2 - p1, p3 - p1)) / 2) + "|" + Vector3.Angle(p3 - p1, p2 - p1) + "|" + Vector3.Angle(p1 - p2, p3 - p2) + "|" + Vector3.Angle(p2 - p3, p1 - p3));
            float angleInTriangle1 = Vector3.Angle(p3 - p1, p2 - p1);                                        //(360 - 2 * Vector3.Angle(edge1, edge2)) / 2;
            float angleInTriangle2 = Vector3.Angle(p1 - p2, p3 - p2);                                        //(360 - 2 * Vector3.Angle(edge3, edge1)) / 2;
            float angleInTriangle3 = Vector3.Angle(p2 - p3, p1 - p3);                                        //(360 - 2 * Vector3.Angle(edge2, edge3)) / 2;

            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);

            //Debug.Log("(" + angleInTriangle1 + "|" + angleToPointInPlane1 + ") (" + angleInTriangle2 + "|" +  angleToPointInPlane2 + ") (" + angleInTriangle3 + "|" + angleToPointInPlane3 + ")");
            //Debug.DrawLine(point, pointWithinPlane, Color.black, 100f);

            //Debug.DrawLine(point, p1, Color.red, 100f);
            //Debug.DrawLine(point, p2, Color.green, 100f);
            //Debug.DrawLine(point, p3, Color.blue, 100f);
            //
            //Debug.DrawLine(p1, p1 - normal, Color.red, 100f);
            //Debug.DrawLine(p2, p2 - normal, Color.green, 100f);
            //Debug.DrawLine(p3, p3 - normal, Color.blue, 100f);

            bool outOfTriangle = angleToPointInPlane1 > angleInTriangle1 || angleToPointInPlane2 > angleInTriangle2 || angleToPointInPlane3 > angleInTriangle3;
            //mat.color = !outOfTriangle ? sphereColor[0] : sphereColor[1];

            if (!outOfTriangle)
            {
                newSqrDistance = (centerPoint - pointWithinPlane).sqrMagnitude;

                if (newSqrDistance < sqrShortestDistance)
                {
                    closestPoint        = pointWithinPlane;
                    sqrShortestDistance = newSqrDistance;

                    if (active)
                    {
                        sphereDot[0].transform.position = closestPoint;
                        sphereDot[1].transform.position = new Vector3(10000f, 10000f, 10000f);
                        sphereDot[2].transform.position = new Vector3(10000f, 10000f, 10000f);
                    }

                    //insideFilament = Vector3.Angle(pointWithinPlane - point, normal) > 90;
                    //if (insideFilament)
                    //{
                    //    //  DrawLine(closestPoint, normal * -1, 0);
                    //    //Debug.DrawRay((p1 + p2 + p3) / 3f, normal* -1, Color.green, 10);
                    //}
                }
            }
            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;

                        if (active)
                        {
                            sphereDot[0].transform.position = projectionOnEdge[0];
                            sphereDot[1].transform.position = projectionOnEdge[1];
                            sphereDot[2].transform.position = projectionOnEdge[2];
                        }

                        //insideFilament = Vector3.Angle(pointWithinPlane - point, normal) > 90;
                        //if (insideFilament)
                        //{
                        //    //Debug.Log("p1 " + p1 + " sphere " + transform.position);
                        //    Debug.DrawRay((p1 + p2 + p3) / 3f, normal * -1, Color.yellow, 10);
                        //    // DrawLine(closestPoint, normal * -1, 0);
                        //}
                    }
                }
            }
        }

        distance = Mathf.Sqrt(sqrShortestDistance);
        //mat.color = insideFilament == true ? sphereColor[0] : sphereColor[1];

        if (shortestDistance > biggestRadius && IsInsideMesh)
        {
            biggestRadius = shortestDistance;
            ghostSphere.transform.position = transform.position;
            ScaleSphere(biggestRadius, ghostSphere.transform);
        }

#if UNITY_EDITOR
        if (active)
        {
            if (Input.GetKey(KeyCode.A))
            {
                foreach (UnityEditor.SceneView item in UnityEditor.SceneView.sceneViews)
                {
                    item.LookAtDirect(Vector3.zero, Quaternion.LookRotation(nrml));
                }
            }
        }
#endif

        if (active)
        {
            DrawLine(centerPoint, closestPoint, 1);
        }
    }