碰撞检测之Ray-Plane检测

来源:互联网 发布:java 猜数字游戏 编辑:程序博客网 时间:2024/05/21 14:48

平面定义


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; // parallelDebug.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 directionif (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 framevoid 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

0 0
原创粉丝点击