经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 软件/图像 » unity » 查看文章
unity判断bound是否在摄像机内
来源:cnblogs  作者:McYY丶  时间:2019/8/8 8:38:43  对本文有异议

目前实现了两种方法:

1、将bound的点从世界坐标系转到摄像机视口坐标系vecA,其中摄像机所见视口坐标的范围是vecB(0-1,0-1,0-farClipPlane),比较vecA的xyz是否在vecB中即可

2、将bound的点从世界坐标系转到摄像机投影坐标系vecA,投影坐标系是vector4(x,y,z,w),投影坐标的xyz/w可得到NDC坐标系,摄像机可见的NDC坐标系范围是(-1~1,-1~1,-1~1),那么摄像机可见的投影坐标系范围是vecB(-w~w,-w~w,-w~w),比较vecA的xyz是否在vecB的中即可

 

两种方法大同小异,都是转换到某个容易得到摄像机范围的坐标系,然后进行比较

第二个方法比较优,比第一个方法少了几次坐标系转换

 

代码:

第一种方法:

  1. 1 using System.Collections;
  2. 2 using System.Collections.Generic;
  3. 3 using UnityEngine;
  4. 4
  5. 5 public static class TestExpand
  6. 6 {
  7. 7 /// <summary>
  8. 8 /// 检查一个世界坐标系下的点是否在摄像机可见范围内
  9. 9 /// </summary>
  10. 10 /// <param name="camera"></param>
  11. 11 /// <param name="worldPos"></param>
  12. 12 /// <returns></returns>
  13. 13 public static bool CheckPointIsInCamera(this Camera camera, Vector3 worldPos)
  14. 14 {
  15. 15 Vector3 viewPos = camera.WorldToViewportPoint(worldPos);
  16. 16 //Debug.Log(worldPos+" "+viewPos);
  17. 17 if(viewPos.x<0 || viewPos.x>1 || viewPos.y<0 || viewPos.y > 1 || viewPos.z<0 || viewPos.z>camera.farClipPlane)
  18. 18 {
  19. 19 return false;
  20. 20 }
  21. 21 return true;
  22. 22 }
  23. 23
  24. 24 /// <summary>
  25. 25 /// 检查bound某个点是否在摄像机可见范围内
  26. 26 /// </summary>
  27. 27 /// <param name="bound"></param>
  28. 28 /// <param name="camera"></param>
  29. 29 /// <returns></returns>
  30. 30 public static bool CheckBoundIsInCamera(this Bounds bound, Camera camera)
  31. 31 {
  32. 32 Vector4 worldPos = Vector4.one;
  33. 33 for (int i = -1; i <= 1; i += 2)
  34. 34 {
  35. 35 for (int j = -1; j <= 1; j += 2)
  36. 36 {
  37. 37 for (int k = -1; k <= 1; k += 2)
  38. 38 {
  39. 39 worldPos.x = bound.center.x + i * bound.extents.x;
  40. 40 worldPos.y = bound.center.y + j * bound.extents.y;
  41. 41 worldPos.z = bound.center.z + k * bound.extents.z;
  42. 42 if (camera.CheckPointIsInCamera(worldPos))
  43. 43 {
  44. 44 return true;
  45. 45 }
  46. 46
  47. 47 }
  48. 48 }
  49. 49 }
  50. 50 return false;
  51. 51 }
  52. 52 }
View Code
  1. 1 using System.Collections;
  2. 2 using System.Collections.Generic;
  3. 3 using UnityEngine;
  4. 4
  5. 5
  6. 6 public class Test : MonoBehaviour
  7. 7 {
  8. 8 private GameObject cube;
  9. 9 private Bounds bound;
  10. 10 private Camera mCamera;
  11. 11
  12. 12 void Start()
  13. 13 {
  14. 14 cube = GameObject.Find("Cube");
  15. 15 bound = cube.GetComponent<MeshRenderer>().bounds;
  16. 16 mCamera = GetComponent<Camera>();
  17. 17 }
  18. 18
  19. 19 void Update()
  20. 20 {
  21. 21 if (Input.GetKeyDown(KeyCode.Q))
  22. 22 {
  23. 23 Debug.Log(bound.CheckBoundIsInCamera(mCamera));
  24. 24 }
  25. 25
  26. 26 }
  27. 27
  28. 28 private void OnDrawGizmos()
  29. 29 {
  30. 30 bound.DrawBounds(Color.red);
  31. 31 }
  32. 32 }
View Code

 

第二种方法(和上面代码一样,只是判断点是否在摄像机内的方法改变)

  1. 1 public static bool CheckPointIsInCamera(this Camera camera, Vector4 worldPos)
  2. 2 {
  3. 3 Vector4 projectionPos = camera.projectionMatrix * camera.worldToCameraMatrix * worldPos;
  4. 4 if(projectionPos.x < -projectionPos.w || projectionPos.x > projectionPos.w ||
  5. 5 projectionPos.y < -projectionPos.w || projectionPos.y > projectionPos.w ||
  6. 6 projectionPos.z < -projectionPos.w || projectionPos.z > projectionPos.w)
  7. 7 {
  8. 8 return false;
  9. 9 }
  10. 10 return true;
  11. 11 }
View Code

 

原文链接:http://www.cnblogs.com/McYY/p/11318796.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号