| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- #include "Base.h"
- #include "Ray.h"
- #include "Plane.h"
- #include "Frustum.h"
- #include "BoundingSphere.h"
- #include "BoundingBox.h"
- namespace gameplay
- {
- Ray::Ray()
- {
- }
- Ray::Ray(const Vector3& origin, const Vector3& direction)
- {
- set(origin, direction);
- }
- Ray::Ray(const Ray& copy)
- {
- set(copy);
- }
- Ray::~Ray()
- {
- }
- const Vector3& Ray::getOrigin() const
- {
- return _origin;
- }
- void Ray::setOrigin(const Vector3& origin)
- {
- _origin = origin;
- }
- const Vector3& Ray::getDirection() const
- {
- return _direction;
- }
- void Ray::setDirection(const Vector3& direction)
- {
- _direction = direction;
- normalize();
- }
- float Ray::intersects(const BoundingSphere& sphere) const
- {
- return sphere.intersects(*this);
- }
- float Ray::intersects(const BoundingBox& box) const
- {
- return box.intersects(*this);
- }
- float Ray::intersects(const Frustum& frustum) const
- {
- Plane n = frustum.getNear();
- float nD = intersects(n);
- float nOD = n.distance(_origin);
- Plane f = frustum.getFar();
- float fD = intersects(f);
- float fOD = f.distance(_origin);
- Plane l = frustum.getLeft();
- float lD = intersects(l);
- float lOD = l.distance(_origin);
- Plane r = frustum.getRight();
- float rD = intersects(r);
- float rOD = r.distance(_origin);
- Plane b = frustum.getBottom();
- float bD = intersects(b);
- float bOD = b.distance(_origin);
- Plane t = frustum.getTop();
- float tD = intersects(t);
- float tOD = t.distance(_origin);
- // If the ray's origin is in the negative half-space of one of the frustum's planes
- // and it does not intersect that same plane, then it does not intersect the frustum.
- if ( (nOD < 0.0f && nD < 0.0f) || (fOD < 0.0f && fD < 0.0f) ||
- (lOD < 0.0f && lD < 0.0f) || (rOD < 0.0f && rD < 0.0f) ||
- (bOD < 0.0f && bD < 0.0f) || (tOD < 0.0f && tD < 0.0f) )
- {
- return Ray::INTERSECTS_NONE;
- }
- // Otherwise, the intersection distance is the minimum positive intersection distance.
- float d = (nD > 0.0f) ? nD : 0.0f;
- d = (fD > 0.0f) ? ( (d == 0.0f) ? fD : min(fD, d) ) : d;
- d = (lD > 0.0f) ? ( (d == 0.0f) ? lD : min(lD, d) ) : d;
- d = (rD > 0.0f) ? ( (d == 0.0f) ? rD : min(rD, d) ) : d;
- d = (tD > 0.0f) ? ( (d == 0.0f) ? bD : min(bD, d) ) : d;
- d = (bD > 0.0f) ? ( (d == 0.0f) ? tD : min(tD, d) ) : d;
- return d;
- }
- float Ray::intersects(const Plane& plane) const
- {
- const Vector3& normal = plane.getNormal();
- // If the origin of the ray is on the plane then the distance is zero.
- float alpha = (normal.dot(_origin) + plane.getDistance());
- if (fabs(alpha) < MATH_EPSILON)
- {
- return 0.0f;
- }
- float dot = normal.dot(_direction);
-
- // If the dot product of the plane's normal and this ray's direction is zero,
- // then the ray is parallel to the plane and does not intersect it.
- if ( dot == 0.0f )
- {
- return INTERSECTS_NONE;
- }
-
- // Calculate the distance along the ray's direction vector to the point where
- // the ray intersects the plane (if it is negative the plane is behind the ray).
- float d = -alpha / dot;
- if (d < 0.0f)
- {
- return INTERSECTS_NONE;
- }
- return d;
- }
- void Ray::set(const Vector3& origin, const Vector3& direction)
- {
- _origin = origin;
- _direction = direction;
- normalize();
- }
- void Ray::set(const Ray& ray)
- {
- _origin = ray._origin;
- _direction = ray._direction;
- normalize();
- }
- void Ray::transform(const Matrix& matrix)
- {
- matrix.transformPoint(&_origin);
- matrix.transformVector(&_direction);
- _direction.normalize();
- }
- void Ray::normalize()
- {
- if (_direction.isZero())
- return;
- // Normalize the ray's direction vector.
- float normalizeFactor = 1.0f / sqrt(_direction.x * _direction.x + _direction.y * _direction.y + _direction.z * _direction.z);
- if ( normalizeFactor != 1.0f )
- {
- _direction.x *= normalizeFactor;
- _direction.y *= normalizeFactor;
- _direction.z *= normalizeFactor;
- }
- }
- }
|