碰撞检测之Ray-Plane检测

平面定义


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);
        }
    }
}


结果

碰撞检测之Ray-Plane检测_第1张图片

碰撞检测之Ray-Plane检测_第2张图片


参考 

PhysX 3.3 source code

你可能感兴趣的:(unity3d,图形,游戏开发,三维)