IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    [原]碰撞检测之Ray-Plane检测

    qp120291570发表于 2016-03-01 01:30:37
    love 0

    平面定义


    public class Plane : CuGeometry
    {
        // p satisfies normal.dot(p) + d = 0
        public Plane() : base(GeometryType.Plane) { }
        public Plane(Vector3 _normal, float _d)
            : base(GeometryType.Plane)
        {
            normal = _normal;
            d = _d;
        }
    
        public float distance(Vector3 p)
        {
            return Vector3.Dot(p, normal) + d;
        }
    
        public bool contains(Vector3 p)
        {
            Debug.Log(" Mathf.Abs(distance(p))" + Mathf.Abs(distance(p)));
            return Mathf.Abs(distance(p)) < (1.0e-3f);
        }
    
        public Vector3 normal;		// The normal to the plane
        public float d;			// The distance from the origin
    }
    

    一个平面只需要平面上的一点和平面的法线就可以了。平面上的点可以用一个float来表示法线方向离原点的距离来确定。


    射线检测

    public static bool Raycast(Ray ray, float distance, Plane plane, out RaycastHitInfo hitInfo)
    		{
    			hitInfo = new RaycastHitInfo();
    			float dn = Vector3.Dot(ray.direction, plane.normal);
    			if(-1E-7 < dn && dn < 1E-7)
    				return false; // parallel
    
    			Debug.Log("dIST: " + plane.distance(ray.origin));
    			float dist =  -plane.distance(ray.origin) / dn;
    			if(dist< distance)
    			{
    				hitInfo.distance = dist;
    			}else
    			{
    				return false;
    			}
    
    			hitInfo.point = ray.origin + hitInfo.distance * ray.direction;
    
    			//Inverse to ray direction
    			if (dist < 0F)
    			{
    				return false;
    			}
    
    			return true;
    		}


    很简单,直接向看向量点乘结果,然后根据距离判断一下。


    测试代码

    public class RayPlaneTester : MonoBehaviour {
    
        public GameObject plane;
        NPhysX.Plane _plane;
        Ray ray;
        float castDistance = 10f;
    
        // Use this for initialization
        void Start () {
            ray = new Ray(Vector3.zero, new Vector3(1, 1, 1));
            _plane = new NPhysX.Plane();
        }
    	
    	// Update is called once per frame
    	void Update () {
            _plane.normal = plane.transform.rotation * Vector3.up;
            _plane.d = -Vector3.Dot(plane.transform.position, _plane.normal);
    
            Debug.DrawLine(plane.transform.position, plane.transform.position + 3f * _plane.normal);
    
            RaycastHitInfo hitinfo2 = new RaycastHitInfo();
    
            if (NRaycastTests.Raycast(ray, castDistance, _plane, out hitinfo2))
            {
                Debug.DrawLine(ray.origin, ray.origin + ray.direction * hitinfo2.distance, Color.red, 0, true);
            }
            else
            {
                Debug.DrawLine(ray.origin, ray.origin + ray.direction * castDistance, Color.blue, 0, true);
            }
        }
    }


    结果



    参考 

    PhysX 3.3 source code



沪ICP备19023445号-2号
友情链接