Updated geometry functions to use Eigen instead of custom Celestia vector
and matrix classes.sensor-dev
parent
e2f6953dd2
commit
2427fb8e81
|
@ -30,11 +30,12 @@ template<class T> T distance(const Point3<T>& p, const Ellipsoid<T>& e)
|
|||
|
||||
template<class T> T distance(const Point3<T>& p, const Ray3<T>& r)
|
||||
{
|
||||
T t = ((p - r.origin) * r.direction) / (r.direction * r.direction);
|
||||
Eigen::Matrix<T, 3, 1> p2(p.x, p.y, p.z);
|
||||
T t = ((p2 - r.origin).dot(r.direction)) / r.direction.squaredNorm();
|
||||
if (t <= 0)
|
||||
return p.distanceTo(r.origin);
|
||||
return (p2 - r.origin).norm();
|
||||
else
|
||||
return p.distanceTo(r.point(t));
|
||||
return (p2 - r.point(t)).norm();
|
||||
}
|
||||
|
||||
// Distance between a point and a segment defined by orig+dir*t, 0 <= t <= 1
|
||||
|
|
|
@ -11,57 +11,88 @@
|
|||
#define _CELMATH_ELLIPSOID_H_
|
||||
|
||||
#include "vecmath.h"
|
||||
#include <Eigen/Core>
|
||||
|
||||
template<class T> class Ellipsoid
|
||||
{
|
||||
public:
|
||||
Ellipsoid();
|
||||
Ellipsoid(const Vector3<T>&);
|
||||
Ellipsoid(const Point3<T>&, const Vector3<T>&);
|
||||
|
||||
bool contains(const Point3<T>& p) const;
|
||||
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
|
||||
|
||||
/*! Default Ellipsoid constructor. Create a unit sphere centered
|
||||
* at the origin.
|
||||
*/
|
||||
Ellipsoid() :
|
||||
center(0, 0, 0),
|
||||
axes(1, 1, 1)
|
||||
{
|
||||
}
|
||||
|
||||
/*! Created an ellipsoid with the specified semiaxes, centered
|
||||
* at the origin.
|
||||
*/
|
||||
Ellipsoid(const Eigen::Matrix<T, 3, 1>& _axes) :
|
||||
center(0, 0, 0),
|
||||
axes(_axes)
|
||||
{
|
||||
}
|
||||
|
||||
/*! Create an ellipsoid with the specified center and semiaxes.
|
||||
*/
|
||||
Ellipsoid(const Eigen::Matrix<T, 3, 1>& _center,
|
||||
const Eigen::Matrix<T, 3, 1>& _axes) :
|
||||
center(_center),
|
||||
axes(_axes)
|
||||
{
|
||||
}
|
||||
|
||||
/*! Test whether the point p lies inside the ellipsoid.
|
||||
*/
|
||||
bool contains(const Eigen::Matrix<T, 3, 1>& p) const
|
||||
{
|
||||
Eigen::Matrix<T, 3, 1> v = p - center;
|
||||
v = v.cwise() / axes;
|
||||
return v * v <= (T) 1.0;
|
||||
}
|
||||
|
||||
|
||||
/**** Compatibility with old Celestia vectors ****/
|
||||
|
||||
/*! Created an ellipsoid with the specified semiaxes, centered
|
||||
* at the origin.
|
||||
*/
|
||||
Ellipsoid(const Vector3<T>& _axes) :
|
||||
center(0, 0, 0),
|
||||
axes(_axes.x, _axes.y, _axes.z)
|
||||
{
|
||||
}
|
||||
|
||||
/*! Create an ellipsoid with the specified center and semiaxes.
|
||||
*/
|
||||
Ellipsoid(const Point3<T>& _center,
|
||||
const Vector3<T>& _axes) :
|
||||
center(_center.x, _center.y, _center.z),
|
||||
axes(_axes.x, _axes.y, _axes.z)
|
||||
{
|
||||
}
|
||||
|
||||
/*! Test whether the point p lies inside the ellipsoid.
|
||||
*/
|
||||
bool contains(const Point3<T>& p) const
|
||||
{
|
||||
Vector3<T> v = p - center;
|
||||
v = Vector3<T>(v.x / axes.x, v.y / axes.y, v.z / axes.z);
|
||||
return v * v <= (T) 1.0;
|
||||
}
|
||||
|
||||
public:
|
||||
Point3<T> center;
|
||||
Vector3<T> axes;
|
||||
Eigen::Matrix<T, 3, 1> center;
|
||||
Eigen::Matrix<T, 3, 1> axes;
|
||||
};
|
||||
|
||||
typedef Ellipsoid<float> Ellipsoidf;
|
||||
typedef Ellipsoid<double> Ellipsoidd;
|
||||
|
||||
|
||||
/*! Default Ellipsoid constructor. Create a unit sphere centered
|
||||
* at the origin.
|
||||
*/
|
||||
template<class T> Ellipsoid<T>::Ellipsoid() :
|
||||
center(0, 0, 0), axes(1, 1, 1)
|
||||
{
|
||||
}
|
||||
|
||||
/*! Created an ellipsoid with the specified semiaxes, centered
|
||||
* at the origin.
|
||||
*/
|
||||
template<class T> Ellipsoid<T>::Ellipsoid(const Vector3<T>& _axes) :
|
||||
center(0, 0, 0), axes(_axes)
|
||||
{
|
||||
}
|
||||
|
||||
/*! Create an ellipsoid with the specified center and semiaxes.
|
||||
*/
|
||||
template<class T> Ellipsoid<T>::Ellipsoid(const Point3<T>& _center,
|
||||
const Vector3<T>& _axes) :
|
||||
center(_center), axes(_axes)
|
||||
{
|
||||
}
|
||||
|
||||
/*! Test whether the point p lies inside the ellipsoid.
|
||||
*/
|
||||
template<class T> bool Ellipsoid<T>::contains(const Point3<T>& p) const
|
||||
{
|
||||
Vector3<T> v = p - center;
|
||||
v = Vector3<T>(v.x / axes.x, v.y / axes.y, v.z / axes.z);
|
||||
return v * v <= (T) 1.0;
|
||||
}
|
||||
|
||||
#endif // _CELMATH_ELLIPSOID_H_
|
||||
|
||||
|
|
|
@ -8,6 +8,10 @@
|
|||
// of the License, or (at your option) any later version.
|
||||
|
||||
#include "frustum.h"
|
||||
#include <Eigen/LU>
|
||||
#include <cmath>
|
||||
|
||||
using namespace Eigen;
|
||||
|
||||
|
||||
Frustum::Frustum(float fov, float aspectRatio, float n) :
|
||||
|
@ -26,68 +30,97 @@ Frustum::Frustum(float fov, float aspectRatio, float n, float f) :
|
|||
|
||||
void Frustum::init(float fov, float aspectRatio, float n, float f)
|
||||
{
|
||||
float h = (float) tan(fov / 2.0f);
|
||||
float h = std::tan(fov / 2.0f);
|
||||
float w = h * aspectRatio;
|
||||
|
||||
Vec3f normals[4];
|
||||
normals[Bottom] = Vec3f(0, 1, -h);
|
||||
normals[Top] = Vec3f(0, -1, -h);
|
||||
normals[Left] = Vec3f(1, 0, -w);
|
||||
normals[Right] = Vec3f(-1, 0, -w);
|
||||
for (int i = 0; i < 4; i++)
|
||||
Vector3f normals[4];
|
||||
normals[Bottom] = Vector3f( 0.0f, 1.0f, -h);
|
||||
normals[Top] = Vector3f( 0.0f, -1.0f, -h);
|
||||
normals[Left] = Vector3f( 1.0f, 0.0f, -w);
|
||||
normals[Right] = Vector3f(-1.0f, 0.0f, -w);
|
||||
for (unsigned int i = 0; i < 4; i++)
|
||||
{
|
||||
normals[i].normalize();
|
||||
planes[i] = Planef(normals[i], Point3f(0, 0, 0));
|
||||
planes[i] = Hyperplane<float, 3>(normals[i].normalized(), 0.0f);
|
||||
}
|
||||
|
||||
planes[Near] = Planef(Vec3f(0, 0, -1), -n);
|
||||
planes[Far] = Planef(Vec3f(0, 0, 1), f);
|
||||
planes[Near] = Hyperplane<float, 3>(Vector3f(0.0f, 0.0f, -1.0f), -n);
|
||||
planes[Far] = Hyperplane<float, 3>(Vector3f(0.0f, 0.0f, 1.0f), f);
|
||||
}
|
||||
|
||||
|
||||
Frustum::Aspect
|
||||
Frustum::test(const Eigen::Vector3f& point) const
|
||||
{
|
||||
unsigned int nPlanes = infinite ? 5 : 6;
|
||||
|
||||
for (unsigned int i = 0; i < nPlanes; i++)
|
||||
{
|
||||
if (planes[i].signedDistance(point) < 0.0f)
|
||||
return Outside;
|
||||
}
|
||||
|
||||
return Inside;
|
||||
}
|
||||
|
||||
|
||||
Frustum::Aspect
|
||||
Frustum::testSphere(const Eigen::Vector3f& center, float radius) const
|
||||
{
|
||||
unsigned int nPlanes = infinite ? 5 : 6;
|
||||
unsigned int intersections = 0;
|
||||
|
||||
for (unsigned int i = 0; i < nPlanes; i++)
|
||||
{
|
||||
float distanceToPlane = planes[i].signedDistance(center);
|
||||
if (distanceToPlane < -radius)
|
||||
return Outside;
|
||||
else if (distanceToPlane <= radius)
|
||||
intersections |= (1 << i);
|
||||
}
|
||||
|
||||
return (intersections == 0) ? Inside : Intersect;
|
||||
}
|
||||
|
||||
|
||||
/** Double precision version of testSphere()
|
||||
*/
|
||||
Frustum::Aspect
|
||||
Frustum::testSphere(const Eigen::Vector3d& center, double radius) const
|
||||
{
|
||||
int nPlanes = infinite ? 5 : 6;
|
||||
int intersections = 0;
|
||||
|
||||
// IMPORTANT: Celestia relies on this calculation being peformed at double
|
||||
// precision. Simply converting center to single precision is NOT an
|
||||
// allowable optimization.
|
||||
for (int i = 0; i < nPlanes; i++)
|
||||
{
|
||||
double distanceToPlane = planes[i].cast<double>().signedDistance(center);
|
||||
if (distanceToPlane < -radius)
|
||||
return Outside;
|
||||
else if (distanceToPlane <= radius)
|
||||
intersections |= (1 << i);
|
||||
}
|
||||
|
||||
return (intersections == 0) ? Inside : Intersect;
|
||||
}
|
||||
|
||||
|
||||
Frustum::Aspect Frustum::test(const Point3f& p) const
|
||||
{
|
||||
return testSphere(p, 0);
|
||||
return testSphere(Eigen::Vector3f(p.x, p.y, p.z), 0.0f);
|
||||
}
|
||||
|
||||
|
||||
Frustum::Aspect Frustum::testSphere(const Point3f& center, float radius) const
|
||||
{
|
||||
int nPlanes = infinite ? 5 : 6;
|
||||
int intersections = 0;
|
||||
|
||||
for (int i = 0; i < nPlanes; i++)
|
||||
{
|
||||
float distanceToPlane = planes[i].distanceTo(center);
|
||||
if (distanceToPlane < -radius)
|
||||
return Outside;
|
||||
else if (distanceToPlane <= radius)
|
||||
intersections |= (1 << i);
|
||||
}
|
||||
|
||||
return (intersections == 0) ? Inside : Intersect;
|
||||
return testSphere(Eigen::Vector3f(center.x, center.y, center.z), radius);
|
||||
}
|
||||
|
||||
|
||||
Frustum::Aspect Frustum::testSphere(const Point3d& center, double radius) const
|
||||
{
|
||||
int nPlanes = infinite ? 5 : 6;
|
||||
int intersections = 0;
|
||||
|
||||
for (int i = 0; i < nPlanes; i++)
|
||||
{
|
||||
//TODO: Celestia should incorporate some casting operators overloading to accommodate all this kind of stuff:
|
||||
Vec3f plNormal = planes[i].normal;
|
||||
Vec3d plNormalDbl(plNormal.x, plNormal.y, plNormal.z);
|
||||
|
||||
double distanceToPlane = plNormalDbl.x * center.x + plNormalDbl.y * center.y + plNormalDbl.z * center.z + planes[i].d;
|
||||
if (distanceToPlane < -radius)
|
||||
return Outside;
|
||||
else if (distanceToPlane <= radius)
|
||||
intersections |= (1 << i);
|
||||
}
|
||||
|
||||
return (intersections == 0) ? Inside : Intersect;
|
||||
return testSphere(Eigen::Vector3d(center.x, center.y, center.z), radius);
|
||||
}
|
||||
|
||||
|
||||
|
@ -97,10 +130,15 @@ Frustum::Aspect Frustum::testCapsule(const Capsulef& capsule) const
|
|||
int intersections = 0;
|
||||
float r2 = capsule.radius * capsule.radius;
|
||||
|
||||
// TODO: Unnecessary after Eigen conversion of Capsule class
|
||||
Vector3f capsuleOrigin(capsule.origin.x, capsule.origin.y, capsule.origin.z);
|
||||
Vector3f capsuleAxis(capsule.axis.x, capsule.axis.y, capsule.axis.z);
|
||||
|
||||
for (int i = 0; i < nPlanes; i++)
|
||||
{
|
||||
float signedDist0 = planes[i].normal * Vec3f(capsule.origin.x, capsule.origin.y, capsule.origin.z) + planes[i].d;
|
||||
float signedDist1 = signedDist0 + planes[i].normal * capsule.axis;
|
||||
float signedDist0 = planes[i].signedDistance(capsuleOrigin);
|
||||
float signedDist1 = planes[i].signedDistance(capsuleOrigin + capsuleAxis);
|
||||
//float signedDist1 = signedDist0 + planes[i].normal * capsule.axis;
|
||||
if (signedDist0 * signedDist1 > r2)
|
||||
{
|
||||
// Endpoints of capsule are on same side of plane; test closest endpoint to see if it
|
||||
|
@ -125,58 +163,58 @@ Frustum::Aspect Frustum::testCapsule(const Capsulef& capsule) const
|
|||
// Capsule endpoints are on different sides of the plane, so we have an intersection
|
||||
intersections |= (1 << i);
|
||||
}
|
||||
#if 0
|
||||
Vec3f plNormal = planes[i].normal;
|
||||
Vec3d plNormalDbl(plNormal.x, plNormal.y, plNormal.z);
|
||||
|
||||
double distanceToPlane = planes[i].distanceToSegment(capsule.origin, capsule.axis);
|
||||
if (distanceToPlane < -capsule.radius)
|
||||
return Outside;
|
||||
else if (distanceToPlane <= capsule.radius)
|
||||
intersections |= (1 << i);
|
||||
#endif
|
||||
}
|
||||
|
||||
return (intersections == 0) ? Inside : Intersect;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
// See if the half space defined by the plane intersects the frustum. For the
|
||||
// plane equation p(x, y, z) = ax + by + cz + d = 0, the halfspace is
|
||||
// contains all points p(x, y, z) < 0.
|
||||
Frustum::Aspect Frustum::testHalfSpace(const Planef& plane)
|
||||
void
|
||||
Frustum::transform(const Matrix3f& m)
|
||||
{
|
||||
return Intersect;
|
||||
}
|
||||
#endif
|
||||
unsigned int nPlanes = infinite ? 5 : 6;
|
||||
|
||||
|
||||
void Frustum::transform(const Mat3f& m)
|
||||
{
|
||||
int nPlanes = infinite ? 5 : 6;
|
||||
Mat3f invTranspose = m.inverse().transpose();
|
||||
|
||||
for (int i = 0; i < nPlanes; i++)
|
||||
for (unsigned int i = 0; i < nPlanes; i++)
|
||||
{
|
||||
planes[i] = planes[i] * invTranspose;
|
||||
float s = 1.0f / planes[i].normal.length();
|
||||
planes[i].normal = planes[i].normal * s;
|
||||
planes[i].d *= s;
|
||||
planes[i] = planes[i].transform(m, Eigen::Isometry);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Frustum::transform(const Mat4f& m)
|
||||
void
|
||||
Frustum::transform(const Matrix4f& m)
|
||||
{
|
||||
int nPlanes = infinite ? 5 : 6;
|
||||
Mat4f invTranspose = m.inverse().transpose();
|
||||
unsigned int nPlanes = infinite ? 5 : 6;
|
||||
Matrix4f invTranspose = m.inverse().transpose();
|
||||
|
||||
for (int i = 0; i < nPlanes; i++)
|
||||
for (unsigned int i = 0; i < nPlanes; i++)
|
||||
{
|
||||
planes[i] = planes[i] * invTranspose;
|
||||
float s = 1.0f / planes[i].normal.length();
|
||||
planes[i].normal = planes[i].normal * s;
|
||||
planes[i].d *= s;
|
||||
planes[i].coeffs() = invTranspose * planes[i].coeffs();
|
||||
planes[i].normalize();
|
||||
|
||||
//float s = 1.0f / planes[i].normal().norm();
|
||||
//planes[i].normal() *= s;
|
||||
//planes[i].offset() *= s;
|
||||
|
||||
//planes[i] = planes[i] * invTranspose;
|
||||
//float s = 1.0f / planes[i].normal().norm();
|
||||
//planes[i].normal = planes[i].normal * s;
|
||||
//planes[i].d *= s;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Frustum::transform(const Mat3f& m)
|
||||
{
|
||||
Matrix3f m2 = Map<Matrix3f>(&m[0][0]);
|
||||
transform(m2);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Frustum::transform(const Mat4f& m)
|
||||
{
|
||||
Matrix4f m2 = Map<Matrix4f>(&m[0][0]);
|
||||
transform(m2);
|
||||
}
|
||||
|
|
|
@ -10,20 +10,32 @@
|
|||
#ifndef _CELMATH_FRUSTUM_H_
|
||||
#define _CELMATH_FRUSTUM_H_
|
||||
|
||||
#include <Eigen/Core>
|
||||
#include <Eigen/Geometry>
|
||||
|
||||
// Compatibility
|
||||
#include <celmath/plane.h>
|
||||
|
||||
#include <celmath/capsule.h>
|
||||
|
||||
|
||||
class Frustum
|
||||
{
|
||||
public:
|
||||
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
|
||||
|
||||
typedef Eigen::Hyperplane<float, 3> PlaneType;
|
||||
|
||||
Frustum(float fov, float aspectRatio, float nearDist);
|
||||
Frustum(float fov, float aspectRatio, float nearDist, float farDist);
|
||||
|
||||
void transform(const Mat3f&);
|
||||
void transform(const Mat4f&);
|
||||
inline Eigen::Hyperplane<float, 3> plane(unsigned int which) const
|
||||
{
|
||||
return planes[which];
|
||||
}
|
||||
|
||||
inline Planef getPlane(int) const;
|
||||
void transform(const Eigen::Matrix3f& m);
|
||||
void transform(const Eigen::Matrix4f& m);
|
||||
|
||||
enum {
|
||||
Bottom = 0,
|
||||
|
@ -40,21 +52,28 @@ class Frustum
|
|||
Intersect = 2,
|
||||
};
|
||||
|
||||
Aspect test(const Eigen::Vector3f& point) const;
|
||||
Aspect testSphere(const Eigen::Vector3f& center, float radius) const;
|
||||
Aspect testSphere(const Eigen::Vector3d& center, double radius) const;
|
||||
Aspect testCapsule(const Capsulef&) const;
|
||||
|
||||
// Compatibility
|
||||
inline Planef getPlane(unsigned int which) const
|
||||
{
|
||||
PlaneType p = plane(which);
|
||||
return Planef(Vec3f(p.coeffs().x(), p.coeffs().y(), p.coeffs().z()), p.coeffs().w());
|
||||
}
|
||||
void transform(const Mat3f&);
|
||||
void transform(const Mat4f&);
|
||||
Aspect test(const Point3f&) const;
|
||||
Aspect testSphere(const Point3f& center, float radius) const;
|
||||
Aspect testSphere(const Point3d& center, double radius) const;
|
||||
Aspect testCapsule(const Capsulef&) const;
|
||||
|
||||
private:
|
||||
void init(float, float, float, float);
|
||||
|
||||
Planef planes[6];
|
||||
Eigen::Hyperplane<float, 3> planes[6];
|
||||
bool infinite;
|
||||
};
|
||||
|
||||
Planef Frustum::getPlane(int which) const
|
||||
{
|
||||
return planes[which];
|
||||
}
|
||||
|
||||
#endif // _CELMATH_FRUSTUM_H_
|
||||
|
|
|
@ -15,17 +15,19 @@
|
|||
#include "ray.h"
|
||||
#include "sphere.h"
|
||||
#include "ellipsoid.h"
|
||||
#include <Eigen/Core>
|
||||
#include <Eigen/Array>
|
||||
|
||||
|
||||
template<class T> bool testIntersection(const Ray3<T>& ray,
|
||||
const Sphere<T>& sphere,
|
||||
T& distance)
|
||||
{
|
||||
Vector3<T> diff = ray.origin - sphere.center;
|
||||
Eigen::Matrix<T, 3, 1> diff = ray.origin - sphere.center;
|
||||
T s = (T) 1.0 / square(sphere.radius);
|
||||
T a = ray.direction * ray.direction * s;
|
||||
T b = ray.direction * diff * s;
|
||||
T c = diff * diff * s - (T) 1.0;
|
||||
T a = ray.direction.squaredNorm() * s;
|
||||
T b = ray.direction.dot(diff) * s;
|
||||
T c = diff.squaredNorm() * s - (T) 1.0;
|
||||
T disc = b * b - a * c;
|
||||
if (disc < 0.0)
|
||||
return false;
|
||||
|
@ -61,7 +63,7 @@ template<class T> bool testIntersection(const Ray3<T>& ray,
|
|||
{
|
||||
if (testIntersection(ray, sphere, distanceToTester))
|
||||
{
|
||||
cosAngleToCenter = (sphere.center - ray.origin)*ray.direction/(sphere.center - ray.origin).length();
|
||||
cosAngleToCenter = (sphere.center - ray.origin).dot(ray.direction) / (sphere.center - ray.origin).norm();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -72,17 +74,13 @@ template<class T> bool testIntersection(const Ray3<T>& ray,
|
|||
const Ellipsoid<T>& e,
|
||||
T& distance)
|
||||
{
|
||||
Vector3<T> diff = ray.origin - e.center;
|
||||
Vector3<T> s((T) 1.0 / square(e.axes.x),
|
||||
(T) 1.0 / square(e.axes.y),
|
||||
(T) 1.0 / square(e.axes.z));
|
||||
Vector3<T> sdir(ray.direction.x * s.x,
|
||||
ray.direction.y * s.y,
|
||||
ray.direction.z * s.z);
|
||||
Vector3<T> sdiff(diff.x * s.x, diff.y * s.y, diff.z * s.z);
|
||||
T a = ray.direction * sdir;
|
||||
T b = ray.direction * sdiff;
|
||||
T c = diff * sdiff - (T) 1.0;
|
||||
Eigen::Matrix<T, 3, 1> diff = ray.origin - e.center;
|
||||
Eigen::Matrix<T, 3, 1> s = e.axes.cwise().inverse().cwise().square();
|
||||
Eigen::Matrix<T, 3, 1> sdir = ray.direction.cwise() * s;
|
||||
Eigen::Matrix<T, 3, 1> sdiff = diff.cwise() * s;
|
||||
T a = ray.direction.dot(sdir);
|
||||
T b = ray.direction.dot(sdiff);
|
||||
T c = diff.dot(sdiff) - (T) 1.0;
|
||||
T disc = b * b - a * c;
|
||||
if (disc < 0.0)
|
||||
return false;
|
||||
|
@ -118,7 +116,7 @@ template<class T> bool testIntersection(const Ray3<T>& ray,
|
|||
{
|
||||
if (testIntersection(ray, ellipsoid, distanceToTester))
|
||||
{
|
||||
cosAngleToCenter = (ellipsoid.center - ray.origin)*ray.direction/(ellipsoid.center - ray.origin).length();
|
||||
cosAngleToCenter = (ellipsoid.center - ray.origin).dot(ray.direction) / (ellipsoid.center - ray.origin).norm();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -11,18 +11,28 @@
|
|||
#define _CELMATH_RAY_H_
|
||||
|
||||
#include "vecmath.h"
|
||||
#include <Eigen/Core>
|
||||
|
||||
template<class T> class Ray3
|
||||
{
|
||||
public:
|
||||
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
|
||||
|
||||
Ray3();
|
||||
Ray3(const Eigen::Matrix<T, 3, 1>& origin, const Eigen::Matrix<T, 3, 1>& direction);
|
||||
// Compatibility
|
||||
Ray3(const Point3<T>&, const Vector3<T>&);
|
||||
|
||||
Point3<T> point(T) const;
|
||||
Eigen::Matrix<T, 3, 1> point(T) const;
|
||||
|
||||
Ray3<T> transform(const Eigen::Matrix<T, 3, 3>& m)
|
||||
{
|
||||
return Ray3<T>(m * origin, m * direction);
|
||||
}
|
||||
|
||||
public:
|
||||
Point3<T> origin;
|
||||
Vector3<T> direction;
|
||||
Eigen::Matrix<T, 3, 1> origin;
|
||||
Eigen::Matrix<T, 3, 1> direction;
|
||||
};
|
||||
|
||||
typedef Ray3<float> Ray3f;
|
||||
|
@ -34,26 +44,37 @@ template<class T> Ray3<T>::Ray3() :
|
|||
{
|
||||
}
|
||||
|
||||
template<class T> Ray3<T>::Ray3(const Point3<T>& _origin,
|
||||
const Vector3<T>& _direction) :
|
||||
template<class T> Ray3<T>::Ray3(const Eigen::Matrix<T, 3, 1>& _origin,
|
||||
const Eigen::Matrix<T, 3, 1>& _direction) :
|
||||
origin(_origin), direction(_direction)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
template<class T> Point3<T> Ray3<T>::point(T t) const
|
||||
// Compatibility
|
||||
template<class T> Ray3<T>::Ray3(const Point3<T>& _origin,
|
||||
const Vector3<T>& _direction) :
|
||||
origin(_origin.x, _origin.y, _origin.z),
|
||||
direction(_direction.x, _direction.y, _direction.z)
|
||||
{
|
||||
}
|
||||
|
||||
template<class T> Eigen::Matrix<T, 3, 1> Ray3<T>::point(T t) const
|
||||
{
|
||||
return origin + direction * t;
|
||||
}
|
||||
|
||||
// Compatibility
|
||||
template<class T> Ray3<T> operator*(const Ray3<T>& r, const Matrix3<T>& m)
|
||||
{
|
||||
return Ray3<T>(r.origin * m, r.direction * m);
|
||||
Eigen::Map<Eigen::Matrix<T, 3, 3> > m2(&m[0][0]);
|
||||
return Ray3<T>(m2 * r.origin, m2 * r.direction);
|
||||
}
|
||||
|
||||
// Compatibility
|
||||
template<class T> Ray3<T> operator*(const Ray3<T>& r, const Matrix4<T>& m)
|
||||
{
|
||||
return Ray3<T>(r.origin * m, r.direction * m);
|
||||
Eigen::Map<Eigen::Matrix<T, 4, 4> > m2(&m[0][0]);
|
||||
return Ray3<T>(m2 * r.origin, m2 * r.direction);
|
||||
}
|
||||
|
||||
#endif // _CELMATH_RAY_H_
|
||||
|
|
|
@ -11,37 +11,45 @@
|
|||
#define _CELMATH_SPHERE_H_
|
||||
|
||||
#include "vecmath.h"
|
||||
#include <Eigen/Core>
|
||||
|
||||
template<class T> class Sphere
|
||||
{
|
||||
public:
|
||||
Sphere();
|
||||
Sphere(T);
|
||||
Sphere(const Point3<T>&, T);
|
||||
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
|
||||
|
||||
Sphere() :
|
||||
center(0, 0, 0),
|
||||
radius(1)
|
||||
{
|
||||
}
|
||||
|
||||
Sphere(T _radius) :
|
||||
center(0, 0, 0),
|
||||
radius(_radius)
|
||||
{
|
||||
}
|
||||
|
||||
Sphere(const Eigen::Matrix<T, 3, 1> _center, T _radius) :
|
||||
center(_center),
|
||||
radius(_radius)
|
||||
{
|
||||
}
|
||||
|
||||
// Compatibility
|
||||
Sphere(const Point3<T>& _center, T _radius) :
|
||||
center(_center.x, _center.y, _center.z),
|
||||
radius(_radius)
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
Point3<T> center;
|
||||
Eigen::Matrix<T, 3, 1> center;
|
||||
T radius;
|
||||
};
|
||||
|
||||
typedef Sphere<float> Spheref;
|
||||
typedef Sphere<double> Sphered;
|
||||
|
||||
|
||||
template<class T> Sphere<T>::Sphere() :
|
||||
center(0, 0, 0), radius(1)
|
||||
{
|
||||
}
|
||||
|
||||
template<class T> Sphere<T>::Sphere(T _radius) :
|
||||
center(0, 0, 0), radius(_radius)
|
||||
{
|
||||
}
|
||||
|
||||
template<class T> Sphere<T>::Sphere(const Point3<T>& _center, T _radius) :
|
||||
center(_center), radius(_radius)
|
||||
{
|
||||
}
|
||||
|
||||
#endif // _CELMATH_SPHERE_H_
|
||||
|
||||
|
|
Loading…
Reference in New Issue