SO3Engine
OgreNewt_RayCastVehicle.cpp
Go to the documentation of this file.
7#include <CustomDGRayCastCar.h>
8
9namespace OgreNewt
10{
11 RaycastVehicle::Tire::Tire(RaycastVehicle* vehicle, Ogre::Node* node, const bool steer, const bool driving, const int id)
12 {
13 m_vehicle = vehicle;
14 m_steer = steer;
15 m_driving = driving;
16 m_tireId = id;
17 m_node = node;
18
19 m_debug.m_node = 0;
20 m_debug.m_visualDebug = 0;
21 }
22
23 RaycastVehicle::Tire::~Tire()
24 {
25 if (m_debug.m_node != 0)
26 {
27 if (m_debug.m_node->getParent())
28 m_debug.m_node->getParent()->removeChild(m_debug.m_node);
29
30 m_debug.m_node->detachAllObjects();
31
32 delete m_debug.m_visualDebug;
33
34 m_debug.m_node = 0;
35 m_debug.m_visualDebug = 0;
36 }
37 }
38
39 void RaycastVehicle::Tire::showDebug(Ogre::SceneNode* debugRootNode)
40 {
41 Body* carBody = m_vehicle->getCarBody();
42 Ogre::Vector3 pos;
43 Ogre::Quaternion orient;
44
45 carBody->getVisualPositionOrientation(pos, orient);
46 dMatrix carMatrix(dQuaternion (orient.w, orient.x, orient.y, orient.z), dVector (pos.x, pos.y, pos.z, 1.0f));
47
48 CustomDGRayCastCar::Tire& tire = m_vehicle->GetTire(m_tireId);
49
50 if (m_debug.m_node == 0)
51 {
52 std::ostringstream oss;
53 oss << "__OgreNewt__Debugger__Lines__" << &tire << "__";
54 m_debug.m_visualDebug = new Ogre::ManualObject(oss.str());
55 m_debug.m_node = debugRootNode->createChildSceneNode();
56 OgreNewt::Debugger& debug(carBody->getWorld()->getDebugger());
57
58 debug.buildDebugObjectFromCollision(m_debug.m_visualDebug, Ogre::ColourValue(0, 0, 1, 1), tire.m_shape);
59
60 m_debug.m_node->attachObject(m_debug.m_visualDebug);
61 }
62
63 dMatrix tireBaseMatrix (m_vehicle->CalculateSuspensionMatrix(m_tireId, tire.m_posit) * m_vehicle->GetChassisMatrixLocal() * carMatrix);
64 Converters::MatrixToQuatPos (&tireBaseMatrix[0][0], orient, pos);
65
66 m_debug.m_node->setPosition(pos);
67 m_debug.m_node->setOrientation(orient);
68 if (!m_debug.m_node->getParent())
69 debugRootNode->addChild(m_debug.m_node);
70 }
71
72 void RaycastVehicle::Tire::getTireMatrix(dMatrix &outMatrix)
73 {
74 outMatrix = m_vehicle->CalculateTireMatrix(m_tireId);
75 }
76
77 void RaycastVehicle::Tire::updateNodePosition()
78 {
79 dMatrix tireMat;
80 getTireMatrix(tireMat);
81
82 Ogre::Quaternion quat;
83 Ogre::Vector3 pos;
84 OgreNewt::Converters::MatrixToQuatPos(&tireMat[0][0], quat, pos);
85
86 // Set position in global terms.
87 Ogre::Node* m_nodeParent = m_node->getParent();
88
89 m_nodeParent->_update(true, true);
90
91 Ogre::Vector3 gscale = m_nodeParent->_getDerivedScale();
92 //if this is a bad scale we ignore the set position
93 if (gscale.x == 0.0f || gscale.y == 0.0f || gscale.z == 0.0f)
94 return;
95
96 m_node->setPosition((m_nodeParent->_getDerivedOrientation().Inverse() * (pos - m_nodeParent->_getDerivedPosition()) / gscale));
97 m_node->setOrientation((m_nodeParent->_getDerivedOrientation().Inverse() * quat));
98 }
99
100 RaycastVehicle::RaycastVehicle(const dMatrix carMatrix, OgreNewt::Body* carBody) : CustomDGRayCastCar(16, carMatrix, carBody->getNewtonBody())
101 {
102 m_body = carBody;
103 m_body->setNodeUpdateJointNotify<RaycastVehicle>(&RaycastVehicle::setTireTransformCallback, this);
104 }
105
107 {
108 m_body->setNodeUpdateNotify(0);
109
110 for (unsigned int i = 0; i < m_lTires.size(); i ++)
111 {
112 Tire* tire = m_lTires.at(i);
113 delete tire;
114 }
115
116 m_lTires.clear();
117 }
118
120 {
121 return m_body;
122 }
123
124 void RaycastVehicle::getTireMatrix(unsigned int index, dMatrix &outMatrix)
125 {
126 if (index < m_lTires.size())
127 m_lTires.at(index)->getTireMatrix(outMatrix);
128 }
129
130 void RaycastVehicle::ApplyTorque(dFloat torque)
131 {
132 for (unsigned int i = 0; i < m_lTires.size(); i ++)
133 {
134 Tire* tire = m_lTires.at(i);
135 if (tire->isDriving())
136 SetTireTorque(tire->getId(), torque);
137 }
138 }
139
141 {
142 for (unsigned int i = 0; i < m_lTires.size(); i ++)
143 {
144 Tire* tire = m_lTires.at(i);
145 if (tire->isSteer())
146 SetTireSteerAngleForce(tire->getId(), angle, 0.5f);
147 }
148 }
149
150 void RaycastVehicle::ApplyBrake(dFloat brakeTorque)
151 {
152 for (unsigned int i = 0; i < m_lTires.size(); i ++)
153 {
154 Tire* tire = m_lTires.at(i);
155 SetTireBrake(tire->getId(), brakeTorque);
156 }
157 }
158
159 void RaycastVehicle::addTire(Ogre::Node* node, const Ogre::Real mass, const Ogre::Real radius, const Ogre::Real width, const Ogre::Real friction, const Ogre::Real susLength, const Ogre::Real susSpring, const Ogre::Real susShock, const bool steer, const bool driving)
160 {
161 //the class use a table of 16 for tires
162 //todo send an exception
163 if (GetTiresCount() > 16)
164 return;
165
166 Ogre::Quaternion quat = node->_getDerivedOrientation();
167 Ogre::Vector3 pos = node->_getDerivedPosition();
168 dMatrix nodeMat;
169 OgreNewt::Converters::QuatPosToMatrix(quat, pos, &nodeMat[0][0]);
170
171 AddSingleSuspensionTire(nodeMat, mass, radius, width, friction, susLength, susSpring, susShock, 1);
172 int tireId = GetTiresCount() - 1;
173
174 Tire* ntire = new Tire(this, node, steer, driving, tireId);
175
176 /*
177 if (steer)
178 {
179 Tire* ltire = 0;
180 //search for an another directionnal tire
181 for (unsigned int i = 0; i < m_lTires.size() && (ltire == 0); i ++)
182 {
183 if (!m_lTires.at(i)->getUsedByDiferencial() && m_lTires.at(i)->isSteer())
184 ltire = m_lTires.at(i);
185 }
186
187 if (ltire != 0)
188 (
189 ltire->setUsedByDiferencial(true);
190 ntire->setUsedByDiferencial(true);
191 AddSlipDifferencial(ltire->getId(), ntire->getId(), 0.5f);
192 );
193 }*/
194
195 m_lTires.push_back(ntire);
196 }
197
198 RaycastVehicle::Tire* RaycastVehicle::getTire(unsigned int index)
199 {
200 if (index < m_lTires.size())
201 return m_lTires[index];
202 else
203 return 0;
204 }
205
206 void RaycastVehicle::setTireTransformCallback(OgreNewt::Body* carBody)
207 {
208 for (unsigned int i = 0; i < m_lTires.size(); i ++)
209 {
210 Tire* tire = m_lTires.at(i);
211 tire->updateNodePosition();
212 }
213 }
214
215 void RaycastVehicle::showDebugData(Ogre::SceneNode* debugRootNode)
216 {
217 for (unsigned int i = 0; i < m_lTires.size(); i ++)
218 {
219 Tire* tire = m_lTires.at(i);
220 tire->showDebug(debugRootNode);
221 }
222 }
223
224 bool RaycastVehicle::getTireOnAir(unsigned int index)
225 {
226 if (index < m_lTires.size())
227 {
228 CustomDGRayCastCar::Tire& tire = GetTire(m_lTires.at(index)->getId());
229 return (tire.m_tireIsOnAir == 1) ? true : false;
230 }
231
232 return true;
233 }
234
235 Ogre::Real RaycastVehicle::getTireAngularVelocity(unsigned int index)
236 {
237 if (index < m_lTires.size())
238 {
239 float omega = 0.0f;
240 CustomDGRayCastCar::Tire& tire = GetTire(m_lTires.at(index)->getId());
241 omega = tire.m_angularVelocity;
242 return omega;
243 }
244
245 return 0.0f;
246 }
247
249 {
250 int index = -1;
251
252 for (unsigned int i = 0; i < m_lTires.size() && (index == -1); i ++)
253 {
254 Tire* tire = m_lTires.at(i);
255 if (tire->getNode() == node)
256 index = i;
257 }
258
259 return index;
260 }
261
262 /*void RaycastVehicle::SubmitConstraints(dFloat timestep, int threadIndex)
263 {
264 }
265
266 void RaycastVehicle::GetInfo(NewtonJointRecord* info)
267 {
268 }*/
269
270} // end NAMESPACE OgreNewt
271
272
273
main class for all Rigid Bodies in the system.
void setNodeUpdateJointNotify(NodeUpdateNotifyCallback callback)
void setNodeUpdateNotify(NodeUpdateNotifyCallback callback)
set a custom node update notify.
For viewing the Newton rigid bodies visually.
RaycastVehicle::Tire * getTire(unsigned int index)
RaycastVehicle(const dMatrix carMatrix, OgreNewt::Body *carBody)
constructor
void getTireMatrix(unsigned int index, dMatrix &outMatrix)
void addTire(Ogre::Node *node, const Ogre::Real mass, const Ogre::Real radius, const Ogre::Real width, const Ogre::Real friction, const Ogre::Real susLength, const Ogre::Real susSpring, const Ogre::Real susShock, const bool steer, const bool driving)
Ogre::Real getTireAngularVelocity(unsigned int index)
void ApplyBrake(dFloat brakeTorque)
int getTireIndexByNode(Ogre::Node *node)
bool getTireOnAir(unsigned int index)
void showDebugData(Ogre::SceneNode *debugRootNode)
show joint visual debugging data
_OgreNewtExport void MatrixToQuatPos(const dFloat *matrix, Ogre::Quaternion &quat, Ogre::Vector3 &pos)
Take a Newton matrix and create a Quaternion + Position_vector.
_OgreNewtExport void QuatPosToMatrix(const Ogre::Quaternion &quat, const Ogre::Vector3 &pos, dFloat *matrix)
Take a Quaternion and Position Matrix and create a Newton-happy float matrix!