227 lines
7.6 KiB
C++
227 lines
7.6 KiB
C++
////////////////////////////////////////////////////////////////////
|
|
// Ray.h
|
|
//
|
|
// Copyright 2007 cDc@seacave
|
|
// Distributed under the Boost Software License, Version 1.0
|
|
// (See http://www.boost.org/LICENSE_1_0.txt)
|
|
|
|
#ifndef __SEACAVE_RAY_H__
|
|
#define __SEACAVE_RAY_H__
|
|
|
|
|
|
// I N C L U D E S /////////////////////////////////////////////////
|
|
|
|
|
|
// D E F I N E S ///////////////////////////////////////////////////
|
|
|
|
|
|
namespace SEACAVE {
|
|
|
|
// S T R U C T S ///////////////////////////////////////////////////
|
|
|
|
// Basic triangle class
|
|
template <typename TYPE, int DIMS>
|
|
class TTriangle
|
|
{
|
|
STATIC_ASSERT(DIMS > 1 && DIMS <= 3);
|
|
|
|
public:
|
|
typedef Eigen::Matrix<TYPE,DIMS,1> VECTOR;
|
|
typedef Eigen::Matrix<TYPE,DIMS,1> POINT;
|
|
typedef SEACAVE::TAABB<TYPE,DIMS> AABB;
|
|
typedef SEACAVE::TPlane<TYPE,DIMS> PLANE;
|
|
enum { numScalar = (3*DIMS) };
|
|
|
|
POINT a, b, c; // triangle vertices
|
|
|
|
//---------------------------------------
|
|
|
|
inline TTriangle() {}
|
|
inline TTriangle(const POINT&, const POINT&, const POINT&);
|
|
|
|
inline void Set(const POINT&, const POINT&, const POINT&);
|
|
|
|
inline POINT GetCenter() const;
|
|
inline AABB GetAABB() const;
|
|
inline PLANE GetPlane() const;
|
|
|
|
inline const POINT& operator [] (BYTE i) const { ASSERT(i<3); return (&a)[i]; }
|
|
inline POINT& operator [] (BYTE i) { ASSERT(i<3); return (&a)[i]; }
|
|
}; // class TTriangle
|
|
/*----------------------------------------------------------------*/
|
|
|
|
|
|
// Basic ray class
|
|
template <typename TYPE, int DIMS>
|
|
class TRay
|
|
{
|
|
STATIC_ASSERT(DIMS > 1 && DIMS <= 3);
|
|
|
|
public:
|
|
typedef Eigen::Matrix<TYPE,DIMS+1,DIMS+1,Eigen::RowMajor> MATRIX;
|
|
typedef Eigen::Matrix<TYPE,DIMS,1> VECTOR;
|
|
typedef Eigen::Matrix<TYPE,DIMS,1> POINT;
|
|
typedef SEACAVE::TTriangle<TYPE,DIMS> TRIANGLE;
|
|
typedef SEACAVE::TSphere<TYPE,DIMS> SPHERE;
|
|
typedef SEACAVE::TAABB<TYPE,DIMS> AABB;
|
|
typedef SEACAVE::TOBB<TYPE,DIMS> OBB;
|
|
typedef SEACAVE::TPlane<TYPE,DIMS> PLANE;
|
|
enum { numScalar = (2*DIMS) };
|
|
|
|
VECTOR m_vDir; // ray direction (normalized)
|
|
POINT m_pOrig; // ray origin
|
|
|
|
//---------------------------------------
|
|
|
|
inline TRay() {}
|
|
inline TRay(const POINT& pOrig, const VECTOR& vDir);
|
|
inline TRay(const POINT& pt0, const POINT& pt1, bool bPoints);
|
|
|
|
inline void Set(const POINT& pOrig, const VECTOR& vDir);
|
|
inline void SetFromPoints(const POINT& pt0, const POINT& pt1);
|
|
inline TYPE SetFromPointsLen(const POINT& pt0, const POINT& pt1);
|
|
inline void DeTransform(const MATRIX&); // move to matrix space
|
|
|
|
template <bool bCull>
|
|
bool Intersects(const TRIANGLE&, TYPE *t) const;
|
|
template <bool bCull>
|
|
bool Intersects(const TRIANGLE&, TYPE fL, TYPE *t) const;
|
|
bool Intersects(const PLANE& plane, bool bCull,
|
|
TYPE *t, POINT* pPtHit) const;
|
|
inline TYPE IntersectsDist(const PLANE& plane) const;
|
|
inline POINT Intersects(const PLANE& plane) const;
|
|
bool Intersects(const PLANE& plane, bool bCull,
|
|
TYPE fL, TYPE *t, POINT* pPtHit) const;
|
|
bool Intersects(const SPHERE& sphere) const;
|
|
bool Intersects(const SPHERE& sphere, TYPE& t) const;
|
|
bool Intersects(const AABB& aabb) const;
|
|
bool Intersects(const AABB& aabb, TYPE& t) const;
|
|
bool Intersects(const AABB& aabb, TYPE fL, TYPE *t) const;
|
|
bool Intersects(const OBB& obb) const;
|
|
bool Intersects(const OBB& obb, TYPE &t) const;
|
|
bool Intersects(const OBB& obb, TYPE fL, TYPE *t) const;
|
|
bool Intersects(const TRay& ray, TYPE& s) const;
|
|
bool Intersects(const TRay& ray, POINT& p) const;
|
|
bool Intersects(const TRay& ray, TYPE& s1, TYPE& s2) const;
|
|
bool IntersectsAprox(const TRay& ray, POINT& p) const;
|
|
bool IntersectsAprox2(const TRay& ray, POINT& p) const;
|
|
|
|
inline TYPE CosAngle(const TRay&) const;
|
|
inline bool Coplanar(const TRay&) const;
|
|
inline bool Parallel(const TRay&) const;
|
|
|
|
inline TYPE Classify(const POINT&) const;
|
|
inline POINT ProjectPoint(const POINT&) const;
|
|
bool DistanceSq(const POINT&, TYPE&) const;
|
|
bool Distance(const POINT&, TYPE&) const;
|
|
TYPE DistanceSq(const POINT&) const;
|
|
TYPE Distance(const POINT&) const;
|
|
POINT GetPoint(TYPE) const;
|
|
|
|
TRay operator * (const MATRIX&) const; // matrix multiplication
|
|
inline TRay& operator *= (const MATRIX&); // matrix multiplication
|
|
|
|
inline TYPE& operator [] (BYTE i) { ASSERT(i<6); return m_vDir.data()[i]; }
|
|
inline TYPE operator [] (BYTE i) const { ASSERT(i<6); return m_vDir.data()[i]; }
|
|
}; // class TRay
|
|
/*----------------------------------------------------------------*/
|
|
|
|
|
|
// Basic cylinder class
|
|
template <typename TYPE, int DIMS>
|
|
class TCylinder
|
|
{
|
|
STATIC_ASSERT(DIMS > 1 && DIMS <= 3);
|
|
|
|
public:
|
|
typedef Eigen::Matrix<TYPE,DIMS,1> VECTOR;
|
|
typedef Eigen::Matrix<TYPE,DIMS,1> POINT;
|
|
typedef SEACAVE::TRay<TYPE,DIMS> RAY;
|
|
typedef SEACAVE::TSphere<TYPE,DIMS> SPHERE;
|
|
enum { numScalar = (2*DIMS+2) };
|
|
|
|
RAY ray; // central ray defining starting the point and direction
|
|
TYPE radius; // cylinder radius
|
|
TYPE minHeight; // cylinder heights satisfying:
|
|
TYPE maxHeight; // std::numeric_limits<TYPE>::lowest() <= minHeight <= 0 < maxHeight <= std::numeric_limits<TYPE>::max()
|
|
|
|
//---------------------------------------
|
|
|
|
inline TCylinder() {}
|
|
|
|
inline TCylinder(const RAY& _ray, TYPE _radius, TYPE _minHeight=TYPE(0), TYPE _maxHeight=std::numeric_limits<TYPE>::max())
|
|
: ray(_ray), radius(_radius), minHeight(_minHeight), maxHeight(_maxHeight) { ASSERT(TYPE(0) >= minHeight && minHeight < maxHeight); }
|
|
|
|
inline bool IsFinite() const { return maxHeight < std::numeric_limits<TYPE>::max() && minHeight > std::numeric_limits<TYPE>::lowest(); }
|
|
inline TYPE GetLength() const { return maxHeight - minHeight; }
|
|
|
|
bool Intersects(const SPHERE&) const;
|
|
|
|
inline GCLASS Classify(const POINT&, TYPE& t) const;
|
|
}; // class TCylinder
|
|
/*----------------------------------------------------------------*/
|
|
|
|
|
|
// Basic cone class
|
|
template <typename TYPE, int DIMS>
|
|
class TCone
|
|
{
|
|
STATIC_ASSERT(DIMS > 1 && DIMS <= 3);
|
|
|
|
public:
|
|
typedef Eigen::Matrix<TYPE,DIMS,1> VECTOR;
|
|
typedef Eigen::Matrix<TYPE,DIMS,1> POINT;
|
|
typedef SEACAVE::TRay<TYPE,DIMS> RAY;
|
|
typedef SEACAVE::TSphere<TYPE,DIMS> SPHERE;
|
|
enum { numScalar = (2*DIMS+3) };
|
|
|
|
RAY ray; // ray origin is the cone vertex and ray direction is the cone axis direction
|
|
TYPE angle; // cone angle, in radians, must be inside [0, pi/2]
|
|
TYPE minHeight; // heights satisfying:
|
|
TYPE maxHeight; // 0 <= minHeight < maxHeight <= std::numeric_limits<TYPE>::max()
|
|
|
|
//---------------------------------------
|
|
|
|
inline TCone() {}
|
|
inline TCone(const RAY& _ray, TYPE _angle, TYPE _minHeight=TYPE(0), TYPE _maxHeight=std::numeric_limits<TYPE>::max())
|
|
: ray(_ray), angle(_angle), minHeight(_minHeight), maxHeight(_maxHeight) { ASSERT(TYPE(0) <= minHeight && minHeight < maxHeight); }
|
|
}; // class TCone
|
|
|
|
// Structure used to compute the intersection between a cone and the given sphere/point
|
|
template <typename TYPE, int DIMS>
|
|
class TConeIntersect
|
|
{
|
|
STATIC_ASSERT(DIMS > 1 && DIMS <= 3);
|
|
|
|
public:
|
|
typedef Eigen::Matrix<TYPE,DIMS,1> VECTOR;
|
|
typedef Eigen::Matrix<TYPE,DIMS,1> POINT;
|
|
typedef SEACAVE::TCone<TYPE,DIMS> CONE;
|
|
typedef SEACAVE::TSphere<TYPE,DIMS> SPHERE;
|
|
|
|
const CONE& cone;
|
|
|
|
// cache angle derivatives, to avoid calling trigonometric functions in geometric queries
|
|
const TYPE cosAngle, sinAngle, sinAngleSq, cosAngleSq, invSinAngle;
|
|
|
|
//---------------------------------------
|
|
|
|
inline TConeIntersect(const CONE& _cone)
|
|
: cone(_cone), cosAngle(COS(cone.angle)), sinAngle(SIN(cone.angle)),
|
|
sinAngleSq(SQUARE(sinAngle)), cosAngleSq(SQUARE(cosAngle)),
|
|
invSinAngle(TYPE(1)/sinAngle) {}
|
|
|
|
bool operator()(const SPHERE&) const;
|
|
|
|
GCLASS Classify(const POINT&, TYPE& t) const;
|
|
}; // class TConeIntersect
|
|
/*----------------------------------------------------------------*/
|
|
|
|
|
|
#include "Ray.inl"
|
|
/*----------------------------------------------------------------*/
|
|
|
|
} // namespace SEACAVE
|
|
|
|
#endif // __SEACAVE_RAY_H__
|