Difference between revisions of "Simple ray casting query"
Jazztickets (talk | contribs) (Created page with "Unlike most physics engines, ODE has no built-in ray casting query function. However, you can easily create one using dSpaceCollide2. Other modifications could be made to incl...") |
Jazztickets (talk | contribs) (cleaned up code) |
||
Line 1: | Line 1: | ||
Unlike most physics engines, ODE has no built-in ray casting query function. However, you can easily create one using dSpaceCollide2. Other modifications could be made to include the hit geometry, for example. | Unlike most physics engines, ODE has no built-in ray casting query function. However, you can easily create one using dSpaceCollide2. Other modifications could be made to include the hit geometry, for example. | ||
− | + | #include <ode/odemath.h> | |
+ | #include <ode/collision.h> | ||
+ | #include <ode/objects.h> | ||
+ | |||
const int MAX_CONTACTS = 32; | const int MAX_CONTACTS = 32; | ||
Line 14: | Line 17: | ||
// Check depth against current closest hit | // Check depth against current closest hit | ||
if(Contacts[i].geom.depth < HitPosition[3]) { | if(Contacts[i].geom.depth < HitPosition[3]) { | ||
− | HitPosition | + | dCopyVector3(HitPosition, Contacts[i].geom.pos); |
− | |||
− | |||
HitPosition[3] = Contacts[i].geom.depth; | HitPosition[3] = Contacts[i].geom.depth; | ||
} | } | ||
} | } | ||
} | } | ||
− | + | ||
// Performs raycasting on a space and returns the point of collision. Return false for no hit. | // Performs raycasting on a space and returns the point of collision. Return false for no hit. | ||
bool RaycastQuery(dSpaceID Space, const dVector3 Start, dVector3 End) { | bool RaycastQuery(dSpaceID Space, const dVector3 Start, dVector3 End) { | ||
Line 27: | Line 28: | ||
// Calculate direction | // Calculate direction | ||
dVector3 Direction; | dVector3 Direction; | ||
− | Direction | + | dSubtractVectors3(Direction, End, Start); |
− | |||
− | |||
// Get length | // Get length | ||
− | dReal Length = | + | dReal Length = dCalcVectorLength3(Direction); |
dReal InverseLength = dRecip(Length); | dReal InverseLength = dRecip(Length); | ||
// Normalize | // Normalize | ||
− | Direction | + | dScaleVector3(Direction, InverseLength); |
− | |||
− | |||
// Create ray | // Create ray | ||
Line 56: | Line 53: | ||
// Check for hit | // Check for hit | ||
if(HitPosition[3] != dInfinity) { | if(HitPosition[3] != dInfinity) { | ||
− | End | + | dCopyVector3(End, HitPosition); |
− | |||
− | |||
return true; | return true; |
Revision as of 12:27, 24 March 2019
Unlike most physics engines, ODE has no built-in ray casting query function. However, you can easily create one using dSpaceCollide2. Other modifications could be made to include the hit geometry, for example.
#include <ode/odemath.h> #include <ode/collision.h> #include <ode/objects.h> const int MAX_CONTACTS = 32; // Check ray collision against a space void RayCallback(void *Data, dGeomID Geometry1, dGeomID Geometry2) { dReal *HitPosition = (dReal *)Data; // Check collisions dContact Contacts[MAX_CONTACTS]; int Count = dCollide(Geometry1, Geometry2, MAX_CONTACTS, &Contacts[0].geom, sizeof(dContact)); for(int i = 0; i < Count; i++) { // Check depth against current closest hit if(Contacts[i].geom.depth < HitPosition[3]) { dCopyVector3(HitPosition, Contacts[i].geom.pos); HitPosition[3] = Contacts[i].geom.depth; } } } // Performs raycasting on a space and returns the point of collision. Return false for no hit. bool RaycastQuery(dSpaceID Space, const dVector3 Start, dVector3 End) { // Calculate direction dVector3 Direction; dSubtractVectors3(Direction, End, Start); // Get length dReal Length = dCalcVectorLength3(Direction); dReal InverseLength = dRecip(Length); // Normalize dScaleVector3(Direction, InverseLength); // Create ray dGeomID Ray = dCreateRay(0, Length); dGeomRaySet(Ray, Start[0], Start[1], Start[2], Direction[0], Direction[1], Direction[2]); dGeomSetCategoryBits(Ray, 0); dGeomSetCollideBits(Ray, _Physics::FILTER_CAMERA); // Check collisions dVector4 HitPosition; HitPosition[3] = dInfinity; dSpaceCollide2(Ray, (dGeomID)Space, HitPosition, &RayCallback); // Cleanup dGeomDestroy(Ray); // Check for hit if(HitPosition[3] != dInfinity) { dCopyVector3(End, HitPosition); return true; } return false; }