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
}
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
原文:http://blog.csdn.net/silangquan/article/details/50769482