Simple ray casting query: Difference between revisions
From ODE
Jump to navigationJump to search
imported>Jazztickets 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..." |
imported>Jazztickets more clean up |
||
| (One intermediate revision by the same user not shown) | |||
| 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 | ||
dGeomID Ray = dCreateRay(0, Length); | dGeomID Ray = dCreateRay(0, Length); | ||
dGeomRaySet(Ray, Start[0], Start[1], Start[2], Direction[0], Direction[1], Direction[2]); | dGeomRaySet(Ray, Start[0], Start[1], Start[2], Direction[0], Direction[1], Direction[2]); | ||
// Check collisions | // Check collisions | ||
| Line 56: | Line 51: | ||
// Check for hit | // Check for hit | ||
if(HitPosition[3] != dInfinity) { | if(HitPosition[3] != dInfinity) { | ||
End | dCopyVector3(End, HitPosition); | ||
return true; | return true; | ||
Latest revision as of 13:28, 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]);
// 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;
}