RaycastVehicle.cpp 24 KB

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