public static ProjectPointOnPlane ( Vector3 planeNormal, Vector3 planePoint, Vector3 point ) : Vector3 | ||
planeNormal | Vector3 | |
planePoint | Vector3 | |
point | Vector3 | |
리턴 | 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); }
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); } }