RaycastVehicle.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742
  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 <Bullet/BulletDynamics/Vehicle/btRaycastVehicle.h>
  30. #include <Bullet/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h>
  31. namespace Urho3D
  32. {
  33. struct RaycastVehicleData
  34. {
  35. RaycastVehicleData()
  36. {
  37. vehicleRayCaster_ = nullptr;
  38. vehicle_ = nullptr;
  39. added_ = false;
  40. }
  41. ~RaycastVehicleData()
  42. {
  43. if (vehicleRayCaster_)
  44. {
  45. delete vehicleRayCaster_;
  46. }
  47. vehicleRayCaster_ = nullptr;
  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_ = nullptr;
  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. static const StringVector 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. };
  159. void RaycastVehicle::RegisterObject(Context* context)
  160. {
  161. context->RegisterFactory<RaycastVehicle>();
  162. URHO3D_MIXED_ACCESSOR_ATTRIBUTE("Wheel data", GetWheelDataAttr, SetWheelDataAttr, VariantVector, Variant::emptyVariantVector, AM_DEFAULT)
  163. .SetMetadata(AttributeMetadata::P_VECTOR_STRUCT_ELEMENTS, wheelElementNames);
  164. URHO3D_ATTRIBUTE("Maximum side slip threshold", float, maxSideSlipSpeed_, 4.0f, AM_DEFAULT);
  165. URHO3D_ATTRIBUTE("RPM for wheel motors in air (0=calculate)", float, inAirRPM_, 0.0f, AM_DEFAULT);
  166. }
  167. void RaycastVehicle::OnSetEnabled()
  168. {
  169. if (vehicleData_)
  170. vehicleData_->SetEnabled(IsEnabledEffective());
  171. }
  172. void RaycastVehicle::ApplyAttributes()
  173. {
  174. int index = 0;
  175. hullBody_ = node_->GetOrCreateComponent<RigidBody>();
  176. Scene* scene = GetScene();
  177. vehicleData_->Init(scene, hullBody_, IsEnabledEffective());
  178. VariantVector& value = loadedWheelData_;
  179. int numObjects = value[index++].GetInt();
  180. int wheelIndex = 0;
  181. origRotation_.Clear();
  182. skidInfoCumulative_.Clear();
  183. wheelSideSlipSpeed_.Clear();
  184. for (int i = 0; i < numObjects; i++)
  185. {
  186. int node_id = value[index++].GetInt();
  187. Vector3 direction = value[index++].GetVector3();
  188. Vector3 axle = value[index++].GetVector3();
  189. float restLength = value[index++].GetFloat();
  190. float radius = value[index++].GetFloat();
  191. bool isFrontWheel = value[index++].GetBool();
  192. float steering = value[index++].GetFloat();
  193. Vector3 connectionPoint = value[index++].GetVector3();
  194. Quaternion origRotation = value[index++].GetQuaternion();
  195. float skidInfoC = value[index++].GetFloat();
  196. float sideSlipSpeed = value[index++].GetFloat();
  197. bool isContact = value[index++].GetBool();
  198. Vector3 contactPosition = value[index++].GetVector3();
  199. Vector3 contactNormal = value[index++].GetVector3();
  200. float suspensionStiffness = value[index++].GetFloat();
  201. float dampingRelaxation = value[index++].GetFloat();
  202. float dampingCompression = value[index++].GetFloat();
  203. float frictionSlip = value[index++].GetFloat();
  204. float rollInfluence = value[index++].GetFloat();
  205. float engineForce = value[index++].GetFloat();
  206. float brake = value[index++].GetFloat();
  207. float skidInfo = value[index++].GetFloat();
  208. Node* wheelNode = GetScene()->GetNode(node_id);
  209. if (!wheelNode)
  210. {
  211. URHO3D_LOGERROR("RaycastVehicle: Incorrect node id = " + String(node_id) + " index: " + String(index));
  212. continue;
  213. }
  214. btRaycastVehicle* vehicle = vehicleData_->Get();
  215. int id = GetNumWheels();
  216. btVector3 connectionPointCS0(connectionPoint.x_, connectionPoint.y_, connectionPoint.z_);
  217. btVector3 wheelDirectionCS0(direction.x_, direction.y_, direction.z_);
  218. btVector3 wheelAxleCS(axle.x_, axle.y_, axle.z_);
  219. btWheelInfo& wheel = vehicle->addWheel(connectionPointCS0,
  220. wheelDirectionCS0,
  221. wheelAxleCS,
  222. restLength,
  223. radius,
  224. vehicleData_->tuning_,
  225. isFrontWheel);
  226. wheelNodes_.Push(wheelNode);
  227. origRotation_.Push(origRotation);
  228. skidInfoCumulative_.Push(skidInfoC);
  229. wheelSideSlipSpeed_.Push(sideSlipSpeed);
  230. SetSteeringValue(wheelIndex, steering);
  231. wheel.m_raycastInfo.m_isInContact = isContact;
  232. wheel.m_raycastInfo.m_contactNormalWS = btVector3(contactNormal.x_, contactNormal.y_, contactNormal.z_);
  233. wheel.m_raycastInfo.m_contactPointWS = btVector3(contactPosition.x_, contactPosition.y_, contactPosition.z_);
  234. wheel.m_suspensionStiffness = suspensionStiffness;
  235. wheel.m_wheelsDampingRelaxation = dampingRelaxation;
  236. wheel.m_wheelsDampingCompression = dampingCompression;
  237. wheel.m_frictionSlip = frictionSlip;
  238. wheel.m_rollInfluence = rollInfluence;
  239. wheel.m_engineForce = engineForce;
  240. wheel.m_brake = brake;
  241. wheel.m_skidInfo = skidInfo;
  242. wheelIndex++;
  243. }
  244. URHO3D_LOGDEBUG("maxSideSlipSpeed_ value: " + String(maxSideSlipSpeed_));
  245. URHO3D_LOGDEBUG("loaded items: " + String(index));
  246. URHO3D_LOGDEBUG("loaded wheels: " + String(GetNumWheels()));
  247. }
  248. void RaycastVehicle::Init()
  249. {
  250. hullBody_ = node_->GetOrCreateComponent<RigidBody>();
  251. Scene* scene = GetScene();
  252. vehicleData_->Init(scene, hullBody_, IsEnabledEffective());
  253. }
  254. void RaycastVehicle::FixedUpdate(float timeStep)
  255. {
  256. btRaycastVehicle* vehicle = vehicleData_->Get();
  257. for (int i = 0; i < GetNumWheels(); i++)
  258. {
  259. btWheelInfo whInfo = vehicle->getWheelInfo(i);
  260. if (whInfo.m_engineForce != 0.0f || whInfo.m_steering != 0.0f)
  261. {
  262. hullBody_->Activate();
  263. break;
  264. }
  265. }
  266. }
  267. void RaycastVehicle::PostUpdate(float timeStep)
  268. {
  269. btRaycastVehicle* vehicle = vehicleData_->Get();
  270. for (int i = 0; i < GetNumWheels(); i++)
  271. {
  272. vehicle->updateWheelTransform(i, true);
  273. btTransform transform = vehicle->getWheelTransformWS(i);
  274. Vector3 origin = ToVector3(transform.getOrigin());
  275. Quaternion qRot = ToQuaternion(transform.getRotation());
  276. Node* pWheel = wheelNodes_[i];
  277. pWheel->SetWorldPosition(origin);
  278. pWheel->SetWorldRotation(qRot * origRotation_[i]);
  279. }
  280. }
  281. void RaycastVehicle::FixedPostUpdate(float timeStep)
  282. {
  283. btRaycastVehicle* vehicle = vehicleData_->Get();
  284. Vector3 velocity = hullBody_->GetLinearVelocity();
  285. for (int i = 0; i < GetNumWheels(); i++)
  286. {
  287. btWheelInfo& whInfo = vehicle->getWheelInfo(i);
  288. if (!WheelIsGrounded(i) && GetEngineForce(i) != 0.0f)
  289. {
  290. float delta;
  291. if (inAirRPM_ != 0.0f)
  292. {
  293. delta = inAirRPM_ * timeStep / 60.0f;
  294. }
  295. else
  296. {
  297. delta = 8.0f * GetEngineForce(i) * timeStep / (hullBody_->GetMass() * GetWheelRadius(i));
  298. }
  299. if (Abs(whInfo.m_deltaRotation) < Abs(delta))
  300. {
  301. whInfo.m_rotation += delta - whInfo.m_deltaRotation;
  302. whInfo.m_deltaRotation = delta;
  303. }
  304. if (skidInfoCumulative_[i] > 0.05f)
  305. {
  306. skidInfoCumulative_[i] -= 0.002;
  307. }
  308. }
  309. else
  310. {
  311. skidInfoCumulative_[i] = GetWheelSkidInfo(i);
  312. }
  313. wheelSideSlipSpeed_[i] = Abs(ToVector3(whInfo.m_raycastInfo.m_wheelAxleWS).DotProduct(velocity));
  314. if (wheelSideSlipSpeed_[i] > maxSideSlipSpeed_)
  315. {
  316. skidInfoCumulative_[i] = Clamp(skidInfoCumulative_[i], 0.0f, 0.89f);
  317. }
  318. }
  319. }
  320. void RaycastVehicle::SetMaxSideSlipSpeed(float speed)
  321. {
  322. maxSideSlipSpeed_ = speed;
  323. }
  324. float RaycastVehicle::GetMaxSideSlipSpeed() const
  325. {
  326. return maxSideSlipSpeed_;
  327. }
  328. void RaycastVehicle::SetWheelSkidInfoCumulative(int wheel, float skid)
  329. {
  330. skidInfoCumulative_[wheel] = skid;
  331. }
  332. float RaycastVehicle::GetWheelSkidInfoCumulative(int wheel) const
  333. {
  334. return skidInfoCumulative_[wheel];
  335. }
  336. void RaycastVehicle::AddWheel(Node* wheelNode,
  337. Vector3 wheelDirection, Vector3 wheelAxle,
  338. float restLength, float wheelRadius,
  339. bool frontWheel)
  340. {
  341. btRaycastVehicle* vehicle = vehicleData_->Get();
  342. int id = GetNumWheels();
  343. Vector3 connectionPoint = wheelNode->GetWorldPosition() - node_->GetWorldPosition();
  344. btVector3 connectionPointCS0(connectionPoint.x_, connectionPoint.y_, connectionPoint.z_);
  345. btVector3 wheelDirectionCS0(wheelDirection.x_, wheelDirection.y_, wheelDirection.z_);
  346. btVector3 wheelAxleCS(wheelAxle.x_, wheelAxle.y_, wheelAxle.z_);
  347. btWheelInfo& wheel = vehicle->addWheel(connectionPointCS0,
  348. wheelDirectionCS0,
  349. wheelAxleCS,
  350. restLength,
  351. wheelRadius,
  352. vehicleData_->tuning_,
  353. frontWheel);
  354. wheelNodes_.Push(wheelNode);
  355. origRotation_.Push(wheelNode->GetWorldRotation());
  356. skidInfoCumulative_.Push(1.0f);
  357. wheelSideSlipSpeed_.Push(0.0f);
  358. wheel.m_raycastInfo.m_isInContact = false;
  359. }
  360. void RaycastVehicle::ResetSuspension()
  361. {
  362. btRaycastVehicle* vehicle = vehicleData_->Get();
  363. vehicle->resetSuspension();
  364. }
  365. void RaycastVehicle::UpdateWheelTransform(int wheel, bool interpolated)
  366. {
  367. btRaycastVehicle* vehicle = vehicleData_->Get();
  368. vehicle->updateWheelTransform(wheel, interpolated);
  369. }
  370. Vector3 RaycastVehicle::GetWheelPosition(int wheel)
  371. {
  372. btRaycastVehicle* vehicle = vehicleData_->Get();
  373. btTransform transform = vehicle->getWheelTransformWS(wheel);
  374. Vector3 origin = ToVector3(transform.getOrigin());
  375. return origin;
  376. }
  377. Quaternion RaycastVehicle::GetWheelRotation(int wheel)
  378. {
  379. btRaycastVehicle* vehicle = vehicleData_->Get();
  380. btTransform transform = vehicle->getWheelTransformWS(wheel);
  381. Quaternion rotation = ToQuaternion(transform.getRotation());
  382. return rotation;
  383. }
  384. Vector3 RaycastVehicle::GetWheelConnectionPoint(int wheel) const
  385. {
  386. btRaycastVehicle* vehicle = vehicleData_->Get();
  387. btWheelInfo whInfo = vehicle->getWheelInfo(wheel);
  388. return ToVector3(whInfo.m_chassisConnectionPointCS);
  389. }
  390. void RaycastVehicle::SetSteeringValue(int wheel, float steeringValue)
  391. {
  392. btRaycastVehicle* vehicle = vehicleData_->Get();
  393. vehicle->setSteeringValue(steeringValue, wheel);
  394. }
  395. float RaycastVehicle::GetSteeringValue(int wheel) const
  396. {
  397. btRaycastVehicle* vehicle = vehicleData_->Get();
  398. btWheelInfo whInfo = vehicle->getWheelInfo(wheel);
  399. return whInfo.m_steering;
  400. }
  401. void RaycastVehicle::SetWheelSuspensionStiffness(int wheel, float stiffness)
  402. {
  403. btRaycastVehicle* vehicle = vehicleData_->Get();
  404. btWheelInfo& whInfo = vehicle->getWheelInfo(wheel);
  405. whInfo.m_suspensionStiffness = stiffness;
  406. }
  407. float RaycastVehicle::GetWheelSuspensionStiffness(int wheel) const
  408. {
  409. btRaycastVehicle* vehicle = vehicleData_->Get();
  410. btWheelInfo whInfo = vehicle->getWheelInfo(wheel);
  411. return whInfo.m_suspensionStiffness;
  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::ResetWheels()
  603. {
  604. ResetSuspension();
  605. for (int i = 0; i < GetNumWheels(); i++)
  606. {
  607. UpdateWheelTransform(i, true);
  608. Vector3 origin = GetWheelPosition(i);
  609. Node* wheelNode = GetWheelNode(i);
  610. wheelNode->SetWorldPosition(origin);
  611. }
  612. }
  613. VariantVector RaycastVehicle::GetWheelDataAttr() const
  614. {
  615. VariantVector ret;
  616. ret.Reserve(GetNumWheels() * 22 + 1);
  617. ret.Push(GetNumWheels());
  618. for (int i = 0; i < GetNumWheels(); i++)
  619. {
  620. Node* wNode = GetWheelNode(i);
  621. int node_id = wNode->GetID();
  622. URHO3D_LOGDEBUG("RaycastVehicle: Saving node id = " + String(node_id));
  623. ret.Push(node_id);
  624. ret.Push(GetWheelDirection(i));
  625. ret.Push(GetWheelAxle(i));
  626. ret.Push(GetWheelRestLength(i));
  627. ret.Push(GetWheelRadius(i));
  628. ret.Push(IsFrontWheel(i));
  629. ret.Push(GetSteeringValue(i));
  630. ret.Push(GetWheelConnectionPoint(i));
  631. ret.Push(origRotation_[i]);
  632. ret.Push(GetWheelSkidInfoCumulative(i));
  633. ret.Push(GetWheelSideSlipSpeed(i));
  634. ret.Push(WheelIsGrounded(i));
  635. ret.Push(GetContactPosition(i));
  636. ret.Push(GetContactNormal(i)); // 14
  637. ret.Push(GetWheelSuspensionStiffness(i));
  638. ret.Push(GetWheelDampingRelaxation(i));
  639. ret.Push(GetWheelDampingCompression(i));
  640. ret.Push(GetWheelFrictionSlip(i));
  641. ret.Push(GetWheelRollInfluence(i));
  642. ret.Push(GetEngineForce(i));
  643. ret.Push(GetBrake(i));
  644. ret.Push(GetWheelSkidInfo(i));
  645. }
  646. URHO3D_LOGDEBUG("RaycastVehicle: saved items: " + String(ret.Size()));
  647. URHO3D_LOGDEBUG("maxSideSlipSpeed_ value save: " + String(maxSideSlipSpeed_));
  648. return ret;
  649. }
  650. void RaycastVehicle::SetWheelDataAttr(const VariantVector& value)
  651. {
  652. if (!vehicleData_)
  653. {
  654. URHO3D_LOGERROR("RaycastVehicle: vehicleData doesn't exist");
  655. return;
  656. }
  657. if (value.Size() < 2)
  658. {
  659. URHO3D_LOGERROR("RaycastVehicle: Incorrect vehicleData");
  660. return;
  661. }
  662. loadedWheelData_ = value;
  663. }
  664. } // namespace Urho3D