标签:
这是已知平面上的一个点和平面的法线的情况下,求摄像机在平面看到的视野范围,下图绿色的框框就是了。
效果:
代码:
1 using UnityEngine; 2 using System.Collections; 3 using System; 4 5 public class CameraPlaneView : MonoBehaviour 6 { 7 #region for debug 8 public Camera viewCamera; 9 10 void Update() 11 { 12 Vector3[] corners; 13 if(GetPlaneCorners(Vector3.up, Vector3.zero, viewCamera, out corners)) 14 { 15 Debug.DrawLine(corners[0], corners[1], Color.green); // bottom 16 Debug.DrawLine(corners[1], corners[2], Color.green); // right 17 Debug.DrawLine(corners[2], corners[3], Color.green); // top 18 Debug.DrawLine(corners[3], corners[0], Color.green); // left 19 } 20 } 21 #endregion 22 23 24 /// <summary> 25 /// 获取摄像机在平面上的视野范围的4个角的顶点 26 /// </summary> 27 /// <param name="normal">平面法线</param> 28 /// <param name="planePoint">平面上的一点</param> 29 /// <param name="camera">摄像机</param> 30 /// <param name="corners">返回4个角的顺序:左下、右下、右上、左上</param> 31 /// <returns>摄像机与平面是否完全相交</returns> 32 public static bool GetPlaneCorners(Vector3 normal, Vector3 planePoint,Camera camera, out Vector3[] corners) 33 { 34 Plane plane = new Plane(normal, planePoint); 35 return GetPlaneCorners(ref plane, camera, out corners); 36 } 37 38 /// <summary> 39 /// 获取摄像机在平面上的视野范围的4个角的顶点 40 /// </summary> 41 /// <param name="plane">平面结构体</param> 42 /// <param name="camera">摄像机</param> 43 /// <param name="corners">返回4个角的顺序:左下、右下、右上、左上</param> 44 /// <returns>摄像机与平面是否完全相交</returns> 45 public static bool GetPlaneCorners(ref Plane plane, Camera camera, out Vector3[] corners) 46 { 47 Ray rayBL = camera.ViewportPointToRay(new Vector3(0, 0, 1)); // bottom left 48 Ray rayBR = camera.ViewportPointToRay(new Vector3(1, 0, 1)); // bottom right 49 Ray rayTL = camera.ViewportPointToRay(new Vector3(0, 1, 1)); // top left 50 Ray rayTR = camera.ViewportPointToRay(new Vector3(1, 1, 1)); // top right 51 52 corners = new Vector3[4]; 53 if (!GetRayPlaneIntersection(ref plane, rayBL, out corners[0]) 54 || !GetRayPlaneIntersection(ref plane, rayBR, out corners[1]) 55 || !GetRayPlaneIntersection(ref plane, rayTR, out corners[2]) 56 || !GetRayPlaneIntersection(ref plane, rayTL, out corners[3])) 57 { 58 return false; 59 } 60 else 61 { 62 return true; 63 } 64 } 65 66 /// <summary> 67 /// 获取平面与射线的交点 68 /// </summary> 69 /// <param name="plane">平面结构体</param> 70 /// <param name="ray">射线</param> 71 /// <param name="intersection">返回交点</param> 72 /// <returns>是否相交</returns> 73 public static bool GetRayPlaneIntersection(ref Plane plane, Ray ray, out Vector3 intersection) 74 { 75 float enter; 76 if(!plane.Raycast(ray, out enter)) 77 { 78 intersection = Vector3.zero; 79 return false; 80 } 81 82 // 下面是获取t的公式 83 // 注意,你需要先判断射线与平面是否平行,如果平面和射线平行,那么平面法线和射线方向的点积为0,即除数为0. 84 //float t = (Vector3.Dot(normal, planePoint) - Vector3.Dot(normal, ray.origin)) / Vector3.Dot(normal, ray.direction.normalized); 85 if (enter >= 0) 86 { 87 intersection = ray.origin + enter * ray.direction.normalized; 88 return true; 89 } 90 else 91 { 92 intersection = Vector3.zero; 93 return false; 94 } 95 } 96 97 /// <summary> 98 /// 获取平面与射线的交点 99 /// </summary> 100 /// <param name="normal">平面法线</param> 101 /// <param name="planePoint">平面上的一点</param> 102 /// <param name="ray">射线</param> 103 /// <param name="intersection">返回交点</param> 104 /// <returns>是否相交</returns> 105 public static bool GetRayPlaneIntersection(Vector3 normal, Vector3 planePoint, Ray ray, out Vector3 intersection) 106 { 107 Plane plane = new Plane(normal, planePoint); 108 return GetRayPlaneIntersection(ref plane, ray, out intersection); 109 } 110 }
标签:
原文地址:http://www.cnblogs.com/axsir/p/5636088.html