SO3Engine
OgreNewt_RayCast.cpp
Go to the documentation of this file.
8
9
10namespace OgreNewt
11{
14
15
16 void Raycast::go(const OgreNewt::World* world, const Ogre::Vector3& startpt, const Ogre::Vector3& endpt )
17 {
18 if( world->getDebugger().isRaycastRecording() )
19 {
20 world->getDebugger().addRay(startpt, endpt);
21 }
22
24
25 // perform the raycast!
26 NewtonWorldRayCast( world->getNewtonWorld(), (float*)&startpt, (float*)&endpt, OgreNewt::Raycast::newtonRaycastFilter, this, OgreNewt::Raycast::newtonRaycastPreFilter, 0);
27
29
30 }
31
32 float Raycast::newtonRaycastFilter(const NewtonBody* body, const NewtonCollision* const shapeHit, const dFloat* const hitContact, const dFloat* hitNormal, dLong collisionID, void* userData, dFloat intersectParam)
33 {
34 // get our object!
35 Raycast* me = (Raycast*)userData;
36
37 Body* bod = (Body*)NewtonBodyGetUserData( body );
38 const World* world = bod->getWorld();
39 Ogre::Vector3 normal = Ogre::Vector3( hitNormal[0], hitNormal[1], hitNormal[2] );
40
41
43 return intersectParam;
44
45
47 {
48 world->getDebugger().addHitBody(bod);
49 }
50
51
52 if (me->userCallback( bod, intersectParam, normal, collisionID ))
53 return intersectParam;
54 else
55 return 1.1f;
56
57 }
58
59 unsigned Raycast::newtonRaycastPreFilter(const NewtonBody *body, const NewtonCollision *collision, void* userData)
60 {
61 // get our object!
62 Raycast* me = (Raycast*)userData;
63
64 Body* bod = (Body*)NewtonBodyGetUserData( body );
65 const World* world = bod->getWorld();
66
67
68 me->m_treecollisioncallback_bodyalreadyadded = false;
69 me->m_treecollisioncallback_lastbody = bod;
70
71 if (me->userPreFilterCallback( bod ))
72 return 1;
73 else
74 {
75
76 if( world->getDebugger().isRaycastRecording() && world->getDebugger().isRaycastRecordingHitBodies() )
77 {
78 world->getDebugger().addDiscardedBody(bod);
79 }
80
81 return 0;
82 }
83 }
84
85
86
87 //--------------------------------
89 {
90 mBody = NULL;
91 mDistance = -1.0;
92 mNormal = Ogre::Vector3::ZERO;
93 }
94
96
97
99
100
101 BasicRaycast::BasicRaycast(const OgreNewt::World* world, const Ogre::Vector3& startpt, const Ogre::Vector3& endpt, bool sorted)
102 : Raycast()
103 {
104 go( world, startpt, endpt, sorted );
105 }
106
107
108 void BasicRaycast::go(const OgreNewt::World* world, const Ogre::Vector3& startpt, const Ogre::Vector3& endpt, bool sorted)
109 {
110 // clean the list each time this function is called this way it can be re used for multiple casting.
111 mRayList.clear();
112 Raycast::go( world, startpt, endpt );
113 if( sorted )
114 {
115 std::sort(mRayList.begin(), mRayList.end());
116 }
117 }
118
119
121
122
123 int BasicRaycast::getHitCount() const { return (int)mRayList.size(); }
124
125
127 {
128 //return the closest hit...
130
131 Ogre::Real dist = Ogre::Math::POS_INFINITY;
132
133 RaycastInfoList::const_iterator it;
134 for (it = mRayList.begin(); it != mRayList.end(); it++)
135 {
136 if (it->mDistance < dist)
137 {
138 dist = it->mDistance;
139 ret = (*it);
140 }
141 }
142
143
144 return ret;
145 }
146
147
149 {
150 if (hitnum < mRayList.size())
151 {
152 return mRayList.at(hitnum);
153 }
154 else
155 {
157
158 return emptyInfo;
159 }
160 }
161
162 bool BasicRaycast::userCallback( OgreNewt::Body* body, Ogre::Real distance, const Ogre::Vector3& normal, dLong collisionID )
163 {
164 // create a new infor object.
166
167 newinfo.mBody = body;
168 newinfo.mDistance = distance;
169 newinfo.mNormal = normal;
170 newinfo.mCollisionID = collisionID;
171
172 mRayList.push_back( newinfo );
173
174 return false;
175 }
176
177} // end NAMESPACE OgreNewt
178
simple class that represents a single raycast rigid body intersection.
Ogre::Real mDistance
dist from point1 of the raycast, in range [0,1].
OgreNewt::Body * mBody
pointer to body intersected with
Ogre::Vector3 mNormal
normal of intersection.
dLong mCollisionID
collision ID of the primitive hit by the ray (for compound collision bodies)
bool userCallback(Body *body, Ogre::Real distance, const Ogre::Vector3 &normal, dLong collisionID)
the all-important custom callback function.
BasicRaycastInfo getInfoAt(unsigned int hitnum) const
retrieve the raycast info for a specific hit.
int getHitCount() const
how many bodies did we hit?
BasicRaycastInfo getFirstHit() const
get the closest body hit by the ray.
BasicRaycast()
empty constructor
void go(const OgreNewt::World *world, const Ogre::Vector3 &startpt, const Ogre::Vector3 &endpt, bool sorted)
perform a raycast
main class for all Rigid Bodies in the system.
OgreNewt::World *const getWorld() const
get a pointer to the OgreNewt::World this body belongs to.
bool isRaycastRecording()
returns true, if currently recording raycasts
bool isRaycastRecordingHitBodies()
returns true, if hit bodies are currently recording
void addHitBody(const OgreNewt::Body *body)
this function is used internally
void addDiscardedBody(const OgreNewt::Body *body)
this function is used internally
void addRay(const Ogre::Vector3 &startpt, const Ogre::Vector3 &endpt)
this function is used internally
general raycast
bool m_treecollisioncallback_bodyalreadyadded
save if this body was already added by RayCastCallback from TreeCollision
OgreNewt::Body * m_treecollisioncallback_lastbody
save the last OgreNewt::Body from the newtonRaycastPreFilter to use this for example the TreeCollisio...
virtual ~Raycast()
destuctor.
virtual bool userCallback(OgreNewt::Body *body, Ogre::Real distance, const Ogre::Vector3 &normal, dLong collisionID)=0
user callback filter function
void go(const OgreNewt::World *world, const Ogre::Vector3 &startpt, const Ogre::Vector3 &endpt)
performs the raycast.
represents a physics world.
Debugger & getDebugger() const
get the debugger for this world
NewtonWorld * getNewtonWorld() const
retrieves a pointer to the NewtonWorld