87 lines
2.7 KiB
C++
87 lines
2.7 KiB
C++
/**
|
|
* @author Edouard DUPIN
|
|
*
|
|
* @copyright 2011, Edouard DUPIN, all right reserved
|
|
*
|
|
* @license BSD v3 (see license file)
|
|
*/
|
|
#include <etk/types.h>
|
|
#include <ege/Ray.h>
|
|
#include <ege/debug.h>
|
|
#include <ege/elements/Element.h>
|
|
|
|
#include <BulletDynamics/Dynamics/btDynamicsWorld.h>
|
|
#include <BulletCollision/CollisionDispatch/btCollisionWorld.h>
|
|
|
|
#undef __class__
|
|
#define __class__ "Ray"
|
|
|
|
ege::Ray::Ray(const vec3& _origin, const vec3& _direction) :
|
|
m_origin(_origin),
|
|
m_direction(_direction) {
|
|
m_direction.safeNormalize();
|
|
}
|
|
|
|
void ege::Ray::setOrigin(const vec3& _origin) {
|
|
m_origin = _origin;
|
|
}
|
|
|
|
void ege::Ray::setDirection(const vec3& _direction) {
|
|
m_direction = _direction;
|
|
m_direction.safeNormalize();
|
|
}
|
|
|
|
|
|
|
|
std::ostream& ege::operator <<(std::ostream& _os, const ege::Ray& _obj) {
|
|
_os << "{ori=";
|
|
_os << _obj.getOrigin();
|
|
_os << " dir=";
|
|
_os << _obj.getDirection();
|
|
_os << "}";
|
|
return _os;
|
|
}
|
|
|
|
std::pair<vec3,vec3> ege::Ray::testRay(ege::physics::Engine& _engine) {
|
|
vec3 start = m_origin;
|
|
vec3 stop = m_origin+m_direction*1000.0f;
|
|
// Start and End are vectors
|
|
btCollisionWorld::ClosestRayResultCallback rayCallback(start, stop);
|
|
EGE_VERBOSE("Process Raycast :");
|
|
// Perform raycast
|
|
_engine.getDynamicWorld()->rayTest(start, stop, rayCallback);
|
|
if(rayCallback.hasHit()) {
|
|
vec3 end = rayCallback.m_hitPointWorld;
|
|
vec3 normal = rayCallback.m_hitNormalWorld;
|
|
EGE_VERBOSE(" hit at point=" << end << " normal=" << normal);
|
|
return std::pair<vec3,vec3>(end,normal);
|
|
}
|
|
EGE_VERBOSE(" No Hit");
|
|
return std::pair<vec3,vec3>(vec3(0,0,0),vec3(0,0,0));
|
|
}
|
|
|
|
|
|
std::pair<std::shared_ptr<ege::Element>, std::pair<vec3,vec3>> ege::Ray::testRayObject(ege::physics::Engine& _engine) {
|
|
vec3 start = m_origin;
|
|
vec3 stop = m_origin+m_direction*1000.0f;
|
|
// Start and End are vectors
|
|
btCollisionWorld::ClosestRayResultCallback rayCallback(start, stop);
|
|
EGE_VERBOSE("Process Raycast :");
|
|
// Perform raycast
|
|
_engine.getDynamicWorld()->rayTest(start, stop, rayCallback);
|
|
if(rayCallback.hasHit()) {
|
|
vec3 end = rayCallback.m_hitPointWorld;
|
|
vec3 normal = rayCallback.m_hitNormalWorld;
|
|
ege::Element* elem = static_cast<ege::Element*>(rayCallback.m_collisionObject->getUserPointer());
|
|
if (elem != nullptr) {
|
|
EGE_VERBOSE(" hit at point=" << end << " normal=" << normal);
|
|
return std::pair<std::shared_ptr<ege::Element>, std::pair<vec3,vec3>>(elem->shared_from_this(), std::pair<vec3,vec3>(end,normal));
|
|
}
|
|
EGE_VERBOSE(" Can not get the element pointer");
|
|
return std::pair<std::shared_ptr<ege::Element>, std::pair<vec3,vec3>>(nullptr, std::pair<vec3,vec3>(end,normal));
|
|
} else {
|
|
EGE_VERBOSE(" No Hit");
|
|
}
|
|
return std::pair<std::shared_ptr<ege::Element>, std::pair<vec3,vec3>>(nullptr, std::pair<vec3,vec3>(vec3(0,0,0),vec3(0,0,0)));
|
|
}
|