RaycastVehicle.cpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775
  1. //
  2. // Copyright (c) 2008-2020 the Urho3D project.
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to deal
  6. // in the Software without restriction, including without limitation the rights
  7. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. // copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. // THE SOFTWARE.
  21. //
  22. #include "../Core/Context.h"
  23. #include "../Physics/PhysicsUtils.h"
  24. #include "../Physics/RigidBody.h"
  25. #include "../Physics/PhysicsWorld.h"
  26. #include "../Scene/Scene.h"
  27. #include "../IO/Log.h"
  28. #include "../Physics/RaycastVehicle.h"
  29. #include <Bullet/BulletDynamics/Vehicle/btRaycastVehicle.h>
  30. #include <Bullet/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h>
  31. namespace Urho3D
  32. {
  33. const IntVector3 RaycastVehicle::RIGHT_UP_FORWARD(0, 1, 2);
  34. const IntVector3 RaycastVehicle::RIGHT_FORWARD_UP(0, 2, 1);
  35. const IntVector3 RaycastVehicle::UP_FORWARD_RIGHT(1, 2, 0);
  36. const IntVector3 RaycastVehicle::UP_RIGHT_FORWARD(1, 0, 2);
  37. const IntVector3 RaycastVehicle::FORWARD_RIGHT_UP(2, 0, 1);
  38. const IntVector3 RaycastVehicle::FORWARD_UP_RIGHT(2, 1, 0);
  39. struct RaycastVehicleData
  40. {
  41. RaycastVehicleData()
  42. {
  43. vehicleRayCaster_ = nullptr;
  44. vehicle_ = nullptr;
  45. added_ = false;
  46. }
  47. ~RaycastVehicleData()
  48. {
  49. delete vehicleRayCaster_;
  50. vehicleRayCaster_ = nullptr;
  51. if (vehicle_)
  52. {
  53. if (physWorld_ && added_)
  54. {
  55. btDynamicsWorld* pbtDynWorld = physWorld_->GetWorld();
  56. if (pbtDynWorld)
  57. pbtDynWorld->removeAction(vehicle_);
  58. added_ = false;
  59. }
  60. delete vehicle_;
  61. }
  62. vehicle_ = nullptr;
  63. }
  64. btRaycastVehicle* Get()
  65. {
  66. return vehicle_;
  67. }
  68. void Init(Scene* scene, RigidBody* body, bool enabled, const IntVector3& coordinateSystem)
  69. {
  70. auto* pPhysWorld = scene->GetComponent<PhysicsWorld>();
  71. btDynamicsWorld* pbtDynWorld = pPhysWorld->GetWorld();
  72. if (!pbtDynWorld)
  73. return;
  74. // Delete old vehicle & action first
  75. delete vehicleRayCaster_;
  76. if (vehicle_)
  77. {
  78. if (added_)
  79. pbtDynWorld->removeAction(vehicle_);
  80. delete vehicle_;
  81. }
  82. vehicleRayCaster_ = new btDefaultVehicleRaycaster(pbtDynWorld);
  83. btRigidBody* bthullBody = body->GetBody();
  84. vehicle_ = new btRaycastVehicle(tuning_, bthullBody, vehicleRayCaster_);
  85. if (enabled)
  86. {
  87. pbtDynWorld->addAction(vehicle_);
  88. added_ = true;
  89. }
  90. SetCoordinateSystem(coordinateSystem);
  91. physWorld_ = pPhysWorld;
  92. }
  93. void SetCoordinateSystem(const IntVector3& coordinateSystem)
  94. {
  95. if (vehicle_)
  96. vehicle_->setCoordinateSystem(coordinateSystem.x_, coordinateSystem.y_, coordinateSystem.z_);
  97. }
  98. void SetEnabled(bool enabled)
  99. {
  100. if (!physWorld_ || !vehicle_)
  101. return;
  102. btDynamicsWorld* pbtDynWorld = physWorld_->GetWorld();
  103. if (!pbtDynWorld)
  104. return;
  105. if (enabled && !added_)
  106. {
  107. pbtDynWorld->addAction(vehicle_);
  108. added_ = true;
  109. }
  110. else if (!enabled && added_)
  111. {
  112. pbtDynWorld->removeAction(vehicle_);
  113. added_ = false;
  114. }
  115. }
  116. WeakPtr<PhysicsWorld> physWorld_;
  117. btVehicleRaycaster* vehicleRayCaster_;
  118. btRaycastVehicle* vehicle_;
  119. btRaycastVehicle::btVehicleTuning tuning_;
  120. bool added_;
  121. };
  122. RaycastVehicle::RaycastVehicle(Context* context) :
  123. LogicComponent(context)
  124. {
  125. // fixed update() for inputs and post update() to sync wheels for rendering
  126. SetUpdateEventMask(USE_FIXEDUPDATE | USE_FIXEDPOSTUPDATE | USE_POSTUPDATE);
  127. vehicleData_ = new RaycastVehicleData();
  128. coordinateSystem_ = RIGHT_UP_FORWARD;
  129. wheelNodes_.Clear();
  130. activate_ = false;
  131. inAirRPM_ = 0.0f;
  132. maxSideSlipSpeed_ = 4.0f;
  133. }
  134. RaycastVehicle::~RaycastVehicle()
  135. {
  136. delete vehicleData_;
  137. wheelNodes_.Clear();
  138. }
  139. static const StringVector wheelElementNames =
  140. {
  141. "Number of wheels",
  142. " Wheel node id",
  143. " Wheel direction",
  144. " Wheel axle",
  145. " Wheel rest length",
  146. " Wheel radius",
  147. " Wheel is front wheel",
  148. " Steering",
  149. " Connection point vector",
  150. " Original rotation",
  151. " Cumulative skid info",
  152. " Side skip speed",
  153. " Grounded",
  154. " Contact position",
  155. " Contact normal",
  156. " Suspension stiffness",
  157. " Max suspension force",
  158. " Damping relaxation",
  159. " Damping compression",
  160. " Friction slip",
  161. " Roll influence",
  162. " Engine force",
  163. " Brake"
  164. };
  165. void RaycastVehicle::RegisterObject(Context* context)
  166. {
  167. context->RegisterFactory<RaycastVehicle>();
  168. URHO3D_MIXED_ACCESSOR_ATTRIBUTE("Wheel data", GetWheelDataAttr, SetWheelDataAttr, VariantVector, Variant::emptyVariantVector, AM_DEFAULT)
  169. .SetMetadata(AttributeMetadata::P_VECTOR_STRUCT_ELEMENTS, wheelElementNames);
  170. URHO3D_ATTRIBUTE("Maximum side slip threshold", float, maxSideSlipSpeed_, 4.0f, AM_DEFAULT);
  171. URHO3D_ATTRIBUTE("RPM for wheel motors in air (0=calculate)", float, inAirRPM_, 0.0f, AM_DEFAULT);
  172. URHO3D_ATTRIBUTE("Coordinate system", IntVector3, coordinateSystem_, RIGHT_UP_FORWARD, AM_DEFAULT);
  173. }
  174. void RaycastVehicle::OnSetEnabled()
  175. {
  176. if (vehicleData_)
  177. vehicleData_->SetEnabled(IsEnabledEffective());
  178. }
  179. void RaycastVehicle::ApplyAttributes()
  180. {
  181. int index = 0;
  182. hullBody_ = node_->GetOrCreateComponent<RigidBody>();
  183. Scene* scene = GetScene();
  184. vehicleData_->Init(scene, hullBody_, IsEnabledEffective(), coordinateSystem_);
  185. VariantVector& value = loadedWheelData_;
  186. int numObjects = value[index++].GetInt();
  187. int wheelIndex = 0;
  188. origRotation_.Clear();
  189. skidInfoCumulative_.Clear();
  190. wheelSideSlipSpeed_.Clear();
  191. for (int i = 0; i < numObjects; i++)
  192. {
  193. int node_id = value[index++].GetInt();
  194. Vector3 direction = value[index++].GetVector3();
  195. Vector3 axle = value[index++].GetVector3();
  196. float restLength = value[index++].GetFloat();
  197. float radius = value[index++].GetFloat();
  198. bool isFrontWheel = value[index++].GetBool();
  199. float steering = value[index++].GetFloat();
  200. Vector3 connectionPoint = value[index++].GetVector3();
  201. Quaternion origRotation = value[index++].GetQuaternion();
  202. float skidInfoC = value[index++].GetFloat();
  203. float sideSlipSpeed = value[index++].GetFloat();
  204. bool isContact = value[index++].GetBool();
  205. Vector3 contactPosition = value[index++].GetVector3();
  206. Vector3 contactNormal = value[index++].GetVector3();
  207. float suspensionStiffness = value[index++].GetFloat();
  208. float maxSuspensionForce = value[index++].GetFloat();
  209. float dampingRelaxation = value[index++].GetFloat();
  210. float dampingCompression = value[index++].GetFloat();
  211. float frictionSlip = value[index++].GetFloat();
  212. float rollInfluence = value[index++].GetFloat();
  213. float engineForce = value[index++].GetFloat();
  214. float brake = value[index++].GetFloat();
  215. float skidInfo = value[index++].GetFloat();
  216. Node* wheelNode = GetScene()->GetNode(node_id);
  217. if (!wheelNode)
  218. {
  219. URHO3D_LOGERROR("RaycastVehicle: Incorrect node id = " + String(node_id) + " index: " + String(index));
  220. continue;
  221. }
  222. btRaycastVehicle* vehicle = vehicleData_->Get();
  223. int id = GetNumWheels();
  224. btVector3 connectionPointCS0(connectionPoint.x_, connectionPoint.y_, connectionPoint.z_);
  225. btVector3 wheelDirectionCS0(direction.x_, direction.y_, direction.z_);
  226. btVector3 wheelAxleCS(axle.x_, axle.y_, axle.z_);
  227. btWheelInfo& wheel = vehicle->addWheel(connectionPointCS0,
  228. wheelDirectionCS0,
  229. wheelAxleCS,
  230. restLength,
  231. radius,
  232. vehicleData_->tuning_,
  233. isFrontWheel);
  234. wheelNodes_.Push(wheelNode);
  235. origRotation_.Push(origRotation);
  236. skidInfoCumulative_.Push(skidInfoC);
  237. wheelSideSlipSpeed_.Push(sideSlipSpeed);
  238. SetSteeringValue(wheelIndex, steering);
  239. wheel.m_raycastInfo.m_isInContact = isContact;
  240. wheel.m_raycastInfo.m_contactNormalWS = btVector3(contactNormal.x_, contactNormal.y_, contactNormal.z_);
  241. wheel.m_raycastInfo.m_contactPointWS = btVector3(contactPosition.x_, contactPosition.y_, contactPosition.z_);
  242. wheel.m_suspensionStiffness = suspensionStiffness;
  243. wheel.m_maxSuspensionForce = maxSuspensionForce;
  244. wheel.m_wheelsDampingRelaxation = dampingRelaxation;
  245. wheel.m_wheelsDampingCompression = dampingCompression;
  246. wheel.m_frictionSlip = frictionSlip;
  247. wheel.m_rollInfluence = rollInfluence;
  248. wheel.m_engineForce = engineForce;
  249. wheel.m_brake = brake;
  250. wheel.m_skidInfo = skidInfo;
  251. wheelIndex++;
  252. }
  253. URHO3D_LOGDEBUG("maxSideSlipSpeed_ value: " + String(maxSideSlipSpeed_));
  254. URHO3D_LOGDEBUG("loaded items: " + String(index));
  255. URHO3D_LOGDEBUG("loaded wheels: " + String(GetNumWheels()));
  256. }
  257. void RaycastVehicle::Init()
  258. {
  259. hullBody_ = node_->GetOrCreateComponent<RigidBody>();
  260. Scene* scene = GetScene();
  261. vehicleData_->Init(scene, hullBody_, IsEnabledEffective(), coordinateSystem_);
  262. }
  263. void RaycastVehicle::FixedUpdate(float timeStep)
  264. {
  265. btRaycastVehicle* vehicle = vehicleData_->Get();
  266. for (int i = 0; i < GetNumWheels(); i++)
  267. {
  268. btWheelInfo whInfo = vehicle->getWheelInfo(i);
  269. if (whInfo.m_engineForce != 0.0f || whInfo.m_steering != 0.0f)
  270. {
  271. hullBody_->Activate();
  272. break;
  273. }
  274. }
  275. }
  276. void RaycastVehicle::PostUpdate(float timeStep)
  277. {
  278. btRaycastVehicle* vehicle = vehicleData_->Get();
  279. for (int i = 0; i < GetNumWheels(); i++)
  280. {
  281. vehicle->updateWheelTransform(i, true);
  282. btTransform transform = vehicle->getWheelTransformWS(i);
  283. Vector3 origin = ToVector3(transform.getOrigin());
  284. Quaternion qRot = ToQuaternion(transform.getRotation());
  285. Node* pWheel = wheelNodes_[i];
  286. pWheel->SetWorldPosition(origin);
  287. pWheel->SetWorldRotation(qRot * origRotation_[i]);
  288. }
  289. }
  290. void RaycastVehicle::FixedPostUpdate(float timeStep)
  291. {
  292. btRaycastVehicle* vehicle = vehicleData_->Get();
  293. Vector3 velocity = hullBody_->GetLinearVelocity();
  294. for (int i = 0; i < GetNumWheels(); i++)
  295. {
  296. btWheelInfo& whInfo = vehicle->getWheelInfo(i);
  297. if (!WheelIsGrounded(i) && GetEngineForce(i) != 0.0f)
  298. {
  299. float delta;
  300. if (inAirRPM_ != 0.0f)
  301. {
  302. delta = inAirRPM_ * timeStep / 60.0f;
  303. }
  304. else
  305. {
  306. delta = 8.0f * GetEngineForce(i) * timeStep / (hullBody_->GetMass() * GetWheelRadius(i));
  307. }
  308. if (Abs(whInfo.m_deltaRotation) < Abs(delta))
  309. {
  310. whInfo.m_rotation += delta - whInfo.m_deltaRotation;
  311. whInfo.m_deltaRotation = delta;
  312. }
  313. if (skidInfoCumulative_[i] > 0.05f)
  314. {
  315. skidInfoCumulative_[i] -= 0.002;
  316. }
  317. }
  318. else
  319. {
  320. skidInfoCumulative_[i] = GetWheelSkidInfo(i);
  321. }
  322. wheelSideSlipSpeed_[i] = Abs(ToVector3(whInfo.m_raycastInfo.m_wheelAxleWS).DotProduct(velocity));
  323. if (wheelSideSlipSpeed_[i] > maxSideSlipSpeed_)
  324. {
  325. skidInfoCumulative_[i] = Clamp(skidInfoCumulative_[i], 0.0f, 0.89f);
  326. }
  327. }
  328. }
  329. void RaycastVehicle::SetMaxSideSlipSpeed(float speed)
  330. {
  331. maxSideSlipSpeed_ = speed;
  332. }
  333. float RaycastVehicle::GetMaxSideSlipSpeed() const
  334. {
  335. return maxSideSlipSpeed_;
  336. }
  337. void RaycastVehicle::SetWheelSkidInfoCumulative(int wheel, float skid)
  338. {
  339. skidInfoCumulative_[wheel] = skid;
  340. }
  341. float RaycastVehicle::GetWheelSkidInfoCumulative(int wheel) const
  342. {
  343. return skidInfoCumulative_[wheel];
  344. }
  345. void RaycastVehicle::AddWheel(Node* wheelNode,
  346. Vector3 wheelDirection, Vector3 wheelAxle,
  347. float restLength, float wheelRadius,
  348. bool frontWheel)
  349. {
  350. btRaycastVehicle* vehicle = vehicleData_->Get();
  351. int id = GetNumWheels();
  352. Vector3 connectionPoint = wheelNode->GetWorldPosition() - node_->GetWorldPosition();
  353. btVector3 connectionPointCS0(connectionPoint.x_, connectionPoint.y_, connectionPoint.z_);
  354. btVector3 wheelDirectionCS0(wheelDirection.x_, wheelDirection.y_, wheelDirection.z_);
  355. btVector3 wheelAxleCS(wheelAxle.x_, wheelAxle.y_, wheelAxle.z_);
  356. btWheelInfo& wheel = vehicle->addWheel(connectionPointCS0,
  357. wheelDirectionCS0,
  358. wheelAxleCS,
  359. restLength,
  360. wheelRadius,
  361. vehicleData_->tuning_,
  362. frontWheel);
  363. wheelNodes_.Push(wheelNode);
  364. origRotation_.Push(wheelNode->GetWorldRotation());
  365. skidInfoCumulative_.Push(1.0f);
  366. wheelSideSlipSpeed_.Push(0.0f);
  367. wheel.m_raycastInfo.m_isInContact = false;
  368. }
  369. void RaycastVehicle::ResetSuspension()
  370. {
  371. btRaycastVehicle* vehicle = vehicleData_->Get();
  372. vehicle->resetSuspension();
  373. }
  374. void RaycastVehicle::UpdateWheelTransform(int wheel, bool interpolated)
  375. {
  376. btRaycastVehicle* vehicle = vehicleData_->Get();
  377. vehicle->updateWheelTransform(wheel, interpolated);
  378. }
  379. Vector3 RaycastVehicle::GetWheelPosition(int wheel)
  380. {
  381. btRaycastVehicle* vehicle = vehicleData_->Get();
  382. btTransform transform = vehicle->getWheelTransformWS(wheel);
  383. Vector3 origin = ToVector3(transform.getOrigin());
  384. return origin;
  385. }
  386. Quaternion RaycastVehicle::GetWheelRotation(int wheel)
  387. {
  388. btRaycastVehicle* vehicle = vehicleData_->Get();
  389. const btTransform& transform = vehicle->getWheelTransformWS(wheel);
  390. Quaternion rotation = ToQuaternion(transform.getRotation());
  391. return rotation;
  392. }
  393. Vector3 RaycastVehicle::GetWheelConnectionPoint(int wheel) const
  394. {
  395. btRaycastVehicle* vehicle = vehicleData_->Get();
  396. btWheelInfo whInfo = vehicle->getWheelInfo(wheel);
  397. return ToVector3(whInfo.m_chassisConnectionPointCS);
  398. }
  399. void RaycastVehicle::SetSteeringValue(int wheel, float steeringValue)
  400. {
  401. btRaycastVehicle* vehicle = vehicleData_->Get();
  402. vehicle->setSteeringValue(steeringValue, wheel);
  403. }
  404. float RaycastVehicle::GetSteeringValue(int wheel) const
  405. {
  406. btRaycastVehicle* vehicle = vehicleData_->Get();
  407. btWheelInfo whInfo = vehicle->getWheelInfo(wheel);
  408. return whInfo.m_steering;
  409. }
  410. void RaycastVehicle::SetWheelSuspensionStiffness(int wheel, float stiffness)
  411. {
  412. btRaycastVehicle* vehicle = vehicleData_->Get();
  413. btWheelInfo& whInfo = vehicle->getWheelInfo(wheel);
  414. whInfo.m_suspensionStiffness = stiffness;
  415. }
  416. float RaycastVehicle::GetWheelSuspensionStiffness(int wheel) const
  417. {
  418. btRaycastVehicle* vehicle = vehicleData_->Get();
  419. btWheelInfo whInfo = vehicle->getWheelInfo(wheel);
  420. return whInfo.m_suspensionStiffness;
  421. }
  422. void RaycastVehicle::SetWheelMaxSuspensionForce(int wheel, float force)
  423. {
  424. btRaycastVehicle* vehicle = vehicleData_->Get();
  425. btWheelInfo& whInfo = vehicle->getWheelInfo(wheel);
  426. whInfo.m_maxSuspensionForce = force;
  427. }
  428. float RaycastVehicle::GetWheelMaxSuspensionForce(int wheel) const
  429. {
  430. btRaycastVehicle* vehicle = vehicleData_->Get();
  431. btWheelInfo whInfo = vehicle->getWheelInfo(wheel);
  432. return whInfo.m_maxSuspensionForce;
  433. }
  434. void RaycastVehicle::SetWheelDampingRelaxation(int wheel, float damping)
  435. {
  436. btRaycastVehicle* vehicle = vehicleData_->Get();
  437. btWheelInfo& whInfo = vehicle->getWheelInfo(wheel);
  438. whInfo.m_wheelsDampingRelaxation = damping;
  439. }
  440. float RaycastVehicle::GetWheelDampingRelaxation(int wheel) const
  441. {
  442. btRaycastVehicle* vehicle = vehicleData_->Get();
  443. btWheelInfo whInfo = vehicle->getWheelInfo(wheel);
  444. return whInfo.m_wheelsDampingRelaxation;
  445. }
  446. void RaycastVehicle::SetWheelDampingCompression(int wheel, float compression)
  447. {
  448. btRaycastVehicle* vehicle = vehicleData_->Get();
  449. btWheelInfo& whInfo = vehicle->getWheelInfo(wheel);
  450. whInfo.m_wheelsDampingCompression = compression;
  451. }
  452. float RaycastVehicle::GetWheelDampingCompression(int wheel) const
  453. {
  454. btRaycastVehicle* vehicle = vehicleData_->Get();
  455. btWheelInfo whInfo = vehicle->getWheelInfo(wheel);
  456. return whInfo.m_wheelsDampingCompression;
  457. }
  458. void RaycastVehicle::SetWheelFrictionSlip(int wheel, float slip)
  459. {
  460. btRaycastVehicle* vehicle = vehicleData_->Get();
  461. btWheelInfo& whInfo = vehicle->getWheelInfo(wheel);
  462. whInfo.m_frictionSlip = slip;
  463. }
  464. float RaycastVehicle::GetWheelFrictionSlip(int wheel) const
  465. {
  466. btRaycastVehicle* vehicle = vehicleData_->Get();
  467. btWheelInfo whInfo = vehicle->getWheelInfo(wheel);
  468. return whInfo.m_frictionSlip;
  469. }
  470. void RaycastVehicle::SetWheelRollInfluence(int wheel, float rollInfluence)
  471. {
  472. btRaycastVehicle* vehicle = vehicleData_->Get();
  473. btWheelInfo& whInfo = vehicle->getWheelInfo(wheel);
  474. whInfo.m_rollInfluence = rollInfluence;
  475. }
  476. Vector3 RaycastVehicle::GetContactPosition(int wheel) const
  477. {
  478. btRaycastVehicle* vehicle = vehicleData_->Get();
  479. btWheelInfo& whInfo = vehicle->getWheelInfo(wheel);
  480. return ToVector3(whInfo.m_raycastInfo.m_contactPointWS);
  481. }
  482. Vector3 RaycastVehicle::GetContactNormal(int wheel) const
  483. {
  484. btRaycastVehicle* vehicle = vehicleData_->Get();
  485. btWheelInfo& whInfo = vehicle->getWheelInfo(wheel);
  486. return ToVector3(whInfo.m_raycastInfo.m_contactNormalWS);
  487. }
  488. float RaycastVehicle::GetWheelSideSlipSpeed(int wheel) const
  489. {
  490. return wheelSideSlipSpeed_[wheel];
  491. }
  492. float RaycastVehicle::GetWheelRollInfluence(int wheel) const
  493. {
  494. btRaycastVehicle* vehicle = vehicleData_->Get();
  495. btWheelInfo whInfo = vehicle->getWheelInfo(wheel);
  496. return whInfo.m_rollInfluence;
  497. }
  498. void RaycastVehicle::SetWheelRadius(int wheel, float wheelRadius)
  499. {
  500. btRaycastVehicle* vehicle = vehicleData_->Get();
  501. btWheelInfo& whInfo = vehicle->getWheelInfo(wheel);
  502. whInfo.m_wheelsRadius = wheelRadius;
  503. }
  504. float RaycastVehicle::GetWheelRadius(int wheel) const
  505. {
  506. btRaycastVehicle* vehicle = vehicleData_->Get();
  507. btWheelInfo& whInfo = vehicle->getWheelInfo(wheel);
  508. return whInfo.m_wheelsRadius;
  509. }
  510. void RaycastVehicle::SetEngineForce(int wheel, float force)
  511. {
  512. btRaycastVehicle* vehicle = vehicleData_->Get();
  513. vehicle->applyEngineForce(force, wheel);
  514. }
  515. float RaycastVehicle::GetEngineForce(int wheel) const
  516. {
  517. btRaycastVehicle* vehicle = vehicleData_->Get();
  518. btWheelInfo whInfo = vehicle->getWheelInfo(wheel);
  519. return whInfo.m_engineForce;
  520. }
  521. void RaycastVehicle::SetBrake(int wheel, float force)
  522. {
  523. btRaycastVehicle* vehicle = vehicleData_->Get();
  524. vehicle->setBrake(force, wheel);
  525. }
  526. float RaycastVehicle::GetBrake(int wheel) const
  527. {
  528. btRaycastVehicle* vehicle = vehicleData_->Get();
  529. btWheelInfo whInfo = vehicle->getWheelInfo(wheel);
  530. return whInfo.m_brake;
  531. }
  532. int RaycastVehicle::GetNumWheels() const
  533. {
  534. btRaycastVehicle* vehicle = vehicleData_->Get();
  535. return vehicle->getNumWheels();
  536. }
  537. Node* RaycastVehicle::GetWheelNode(int wheel) const
  538. {
  539. return wheelNodes_[wheel];
  540. }
  541. void RaycastVehicle::SetMaxSuspensionTravel(int wheel, float maxSuspensionTravel)
  542. {
  543. btRaycastVehicle* vehicle = vehicleData_->Get();
  544. btWheelInfo& whInfo = vehicle->getWheelInfo(wheel);
  545. whInfo.m_maxSuspensionTravelCm = maxSuspensionTravel;
  546. }
  547. float RaycastVehicle::GetMaxSuspensionTravel(int wheel)
  548. {
  549. btRaycastVehicle* vehicle = vehicleData_->Get();
  550. btWheelInfo whInfo = vehicle->getWheelInfo(wheel);
  551. return whInfo.m_maxSuspensionTravelCm;
  552. }
  553. void RaycastVehicle::SetWheelDirection(int wheel, Vector3 direction)
  554. {
  555. btVector3 dir(direction.x_, direction.y_, direction.z_);
  556. btRaycastVehicle* vehicle = vehicleData_->Get();
  557. btWheelInfo& whInfo = vehicle->getWheelInfo(wheel);
  558. whInfo.m_wheelDirectionCS = dir;
  559. }
  560. Vector3 RaycastVehicle::GetWheelDirection(int wheel) const
  561. {
  562. btRaycastVehicle* vehicle = vehicleData_->Get();
  563. btWheelInfo& whInfo = vehicle->getWheelInfo(wheel);
  564. return ToVector3(whInfo.m_wheelDirectionCS);
  565. }
  566. void RaycastVehicle::SetWheelAxle(int wheel, Vector3 axle)
  567. {
  568. btVector3 ax(axle.x_, axle.y_, axle.z_);
  569. btRaycastVehicle* vehicle = vehicleData_->Get();
  570. btWheelInfo& whInfo = vehicle->getWheelInfo(wheel);
  571. whInfo.m_wheelAxleCS = ax;
  572. }
  573. Vector3 RaycastVehicle::GetWheelAxle(int wheel) const
  574. {
  575. btRaycastVehicle* vehicle = vehicleData_->Get();
  576. btWheelInfo& whInfo = vehicle->getWheelInfo(wheel);
  577. return ToVector3(whInfo.m_wheelAxleCS);
  578. }
  579. void RaycastVehicle::SetWheelRestLength(int wheel, float length)
  580. {
  581. btRaycastVehicle* vehicle = vehicleData_->Get();
  582. btWheelInfo& whInfo = vehicle->getWheelInfo(wheel);
  583. whInfo.m_suspensionRestLength1 = length;
  584. }
  585. float RaycastVehicle::GetWheelRestLength(int wheel) const
  586. {
  587. btRaycastVehicle* vehicle = vehicleData_->Get();
  588. btWheelInfo& whInfo = vehicle->getWheelInfo(wheel);
  589. return whInfo.m_suspensionRestLength1;
  590. }
  591. void RaycastVehicle::SetWheelSkidInfo(int wheel, float factor)
  592. {
  593. btRaycastVehicle* vehicle = vehicleData_->Get();
  594. btWheelInfo& whInfo = vehicle->getWheelInfo(wheel);
  595. whInfo.m_skidInfo = factor;
  596. }
  597. float RaycastVehicle::GetWheelSkidInfo(int wheel) const
  598. {
  599. btRaycastVehicle* vehicle = vehicleData_->Get();
  600. btWheelInfo& whInfo = vehicle->getWheelInfo(wheel);
  601. return whInfo.m_skidInfo;
  602. }
  603. bool RaycastVehicle::IsFrontWheel(int wheel) const
  604. {
  605. btRaycastVehicle* vehicle = vehicleData_->Get();
  606. btWheelInfo& whInfo = vehicle->getWheelInfo(wheel);
  607. return whInfo.m_bIsFrontWheel;
  608. }
  609. bool RaycastVehicle::WheelIsGrounded(int wheel) const
  610. {
  611. btRaycastVehicle* vehicle = vehicleData_->Get();
  612. btWheelInfo whInfo = vehicle->getWheelInfo(wheel);
  613. return whInfo.m_raycastInfo.m_isInContact;
  614. }
  615. void RaycastVehicle::SetInAirRPM(float rpm)
  616. {
  617. inAirRPM_ = rpm;
  618. }
  619. float RaycastVehicle::GetInAirRPM() const
  620. {
  621. return inAirRPM_;
  622. }
  623. void RaycastVehicle::SetCoordinateSystem(const IntVector3& coordinateSystem)
  624. {
  625. coordinateSystem_ = coordinateSystem;
  626. vehicleData_->SetCoordinateSystem(coordinateSystem_);
  627. }
  628. void RaycastVehicle::ResetWheels()
  629. {
  630. ResetSuspension();
  631. for (int i = 0; i < GetNumWheels(); i++)
  632. {
  633. UpdateWheelTransform(i, true);
  634. Vector3 origin = GetWheelPosition(i);
  635. Node* wheelNode = GetWheelNode(i);
  636. wheelNode->SetWorldPosition(origin);
  637. }
  638. }
  639. VariantVector RaycastVehicle::GetWheelDataAttr() const
  640. {
  641. VariantVector ret;
  642. ret.Reserve(GetNumWheels() * 22 + 1);
  643. ret.Push(GetNumWheels());
  644. for (int i = 0; i < GetNumWheels(); i++)
  645. {
  646. Node* wNode = GetWheelNode(i);
  647. int node_id = wNode->GetID();
  648. URHO3D_LOGDEBUG("RaycastVehicle: Saving node id = " + String(node_id));
  649. ret.Push(node_id);
  650. ret.Push(GetWheelDirection(i));
  651. ret.Push(GetWheelAxle(i));
  652. ret.Push(GetWheelRestLength(i));
  653. ret.Push(GetWheelRadius(i));
  654. ret.Push(IsFrontWheel(i));
  655. ret.Push(GetSteeringValue(i));
  656. ret.Push(GetWheelConnectionPoint(i));
  657. ret.Push(origRotation_[i]);
  658. ret.Push(GetWheelSkidInfoCumulative(i));
  659. ret.Push(GetWheelSideSlipSpeed(i));
  660. ret.Push(WheelIsGrounded(i));
  661. ret.Push(GetContactPosition(i));
  662. ret.Push(GetContactNormal(i)); // 14
  663. ret.Push(GetWheelSuspensionStiffness(i));
  664. ret.Push(GetWheelMaxSuspensionForce(i));
  665. ret.Push(GetWheelDampingRelaxation(i));
  666. ret.Push(GetWheelDampingCompression(i));
  667. ret.Push(GetWheelFrictionSlip(i));
  668. ret.Push(GetWheelRollInfluence(i));
  669. ret.Push(GetEngineForce(i));
  670. ret.Push(GetBrake(i));
  671. ret.Push(GetWheelSkidInfo(i));
  672. }
  673. URHO3D_LOGDEBUG("RaycastVehicle: saved items: " + String(ret.Size()));
  674. URHO3D_LOGDEBUG("maxSideSlipSpeed_ value save: " + String(maxSideSlipSpeed_));
  675. return ret;
  676. }
  677. void RaycastVehicle::SetWheelDataAttr(const VariantVector& value)
  678. {
  679. if (!vehicleData_)
  680. {
  681. URHO3D_LOGERROR("RaycastVehicle: vehicleData doesn't exist");
  682. return;
  683. }
  684. if (value.Size() < 2)
  685. {
  686. URHO3D_LOGERROR("RaycastVehicle: Incorrect vehicleData");
  687. return;
  688. }
  689. loadedWheelData_ = value;
  690. }
  691. } // namespace Urho3D