RaycastVehicle.cpp 23 KB

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