actor.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517
  1. /*
  2. * Copyright (c) 2012-2014 Daniele Bartolini and individual contributors.
  3. * License: https://github.com/taylor001/crown/blob/master/LICENSE
  4. */
  5. #include "actor.h"
  6. #include "device.h"
  7. #include "log.h"
  8. #include "matrix4x4.h"
  9. #include "mesh_resource.h"
  10. #include "physics_resource.h"
  11. #include "quaternion.h"
  12. #include "resource_manager.h"
  13. #include "scene_graph.h"
  14. #include "unit.h"
  15. #include "vector3.h"
  16. #include "world.h"
  17. #include "physics_world.h"
  18. #include "quaternion.h"
  19. #include "string_utils.h"
  20. #include "PxPhysicsAPI.h"
  21. #include "PxCooking.h"
  22. #include "PxDefaultStreams.h"
  23. using physx::PxActorFlag;
  24. using physx::PxActorType;
  25. using physx::PxBoxGeometry;
  26. using physx::PxCapsuleGeometry;
  27. using physx::PxConvexFlag;
  28. using physx::PxConvexMesh;
  29. using physx::PxConvexMeshDesc;
  30. using physx::PxConvexMeshGeometry;
  31. using physx::PxD6Axis;
  32. using physx::PxD6Joint;
  33. using physx::PxD6JointCreate;
  34. using physx::PxD6Motion;
  35. using physx::PxDefaultMemoryInputData;
  36. using physx::PxDefaultMemoryOutputStream;
  37. using physx::PxFilterData;
  38. using physx::PxForceMode;
  39. using physx::PxMat44;
  40. using physx::PxPlaneGeometry;
  41. using physx::PxQuat;
  42. using physx::PxReal;
  43. using physx::PxRigidActor;
  44. using physx::PxRigidBody;
  45. using physx::PxRigidBodyExt;
  46. using physx::PxRigidBodyFlag;
  47. using physx::PxRigidDynamic;
  48. using physx::PxRigidDynamicFlag;
  49. using physx::PxRigidStatic;
  50. using physx::PxShape;
  51. using physx::PxShapeFlag;
  52. using physx::PxSphereGeometry;
  53. using physx::PxTransform;
  54. using physx::PxU16;
  55. using physx::PxU32;
  56. using physx::PxVec3;
  57. using physx::PxTransformFromPlaneEquation;
  58. using physx::PxPlane;
  59. namespace crown
  60. {
  61. Actor::Actor(PhysicsWorld& pw, const PhysicsResource* res, uint32_t actor_idx, SceneGraph& sg, int32_t node, UnitId unit_id)
  62. : m_world(pw)
  63. , m_resource(res)
  64. , m_index(actor_idx)
  65. , m_scene_graph(sg)
  66. , m_node(node)
  67. , m_unit(unit_id)
  68. {
  69. create_objects();
  70. }
  71. Actor::~Actor()
  72. {
  73. destroy_objects();
  74. }
  75. void Actor::create_objects()
  76. {
  77. const PhysicsActor* actor = physics_resource::actor(m_resource, m_index);
  78. PxScene* scene = m_world.physx_scene();
  79. PxPhysics* physics = m_world.physx_physics();
  80. const PhysicsConfigResource* config = m_world.resource();
  81. const PhysicsActor2* actor_class = physics_config_resource::actor(config, actor->actor_class);
  82. // Create rigid body
  83. const PxMat44 pose((PxReal*) matrix4x4::to_float_ptr(m_scene_graph.world_pose(m_node)));
  84. if (actor_class->flags & PhysicsActor2::DYNAMIC)
  85. {
  86. m_actor = physics->createRigidDynamic(PxTransform(pose));
  87. if (actor_class->flags & PhysicsActor2::KINEMATIC)
  88. {
  89. static_cast<PxRigidDynamic*>(m_actor)->setRigidDynamicFlag(PxRigidDynamicFlag::eKINEMATIC, true);
  90. }
  91. // PxD6Joint* joint = PxD6JointCreate(*physics, m_actor, PxTransform(pose), NULL, PxTransform(pose));
  92. // joint->setMotion(PxD6Axis::eX, PxD6Motion::eFREE);
  93. // joint->setMotion(PxD6Axis::eY, PxD6Motion::eFREE);
  94. // joint->setMotion(PxD6Axis::eSWING2, PxD6Motion::eFREE);
  95. }
  96. else
  97. {
  98. m_actor = physics->createRigidStatic(PxTransform(pose));
  99. }
  100. // Create shapes
  101. uint32_t shape_index = physics_resource::shape_index(m_resource, m_index);
  102. for (uint32_t i = 0; i < actor->num_shapes; i++)
  103. {
  104. const PhysicsShape* shape = physics_resource::shape(m_resource, shape_index);
  105. const PhysicsShape2* shape_class = physics_config_resource::shape(config, shape->shape_class);
  106. const PhysicsMaterial* material = physics_config_resource::material(config, shape->material);
  107. PxMaterial* mat = physics->createMaterial(material->static_friction, material->dynamic_friction, material->restitution);
  108. PxShape* px_shape = NULL;
  109. switch(shape->type)
  110. {
  111. case PhysicsShapeType::SPHERE:
  112. {
  113. px_shape = m_actor->createShape(PxSphereGeometry(shape->data_0), *mat);
  114. break;
  115. }
  116. case PhysicsShapeType::CAPSULE:
  117. {
  118. px_shape = m_actor->createShape(PxCapsuleGeometry(shape->data_0, shape->data_1), *mat);
  119. break;
  120. }
  121. case PhysicsShapeType::BOX:
  122. {
  123. px_shape = m_actor->createShape(PxBoxGeometry(shape->data_0, shape->data_1, shape->data_2), *mat);
  124. break;
  125. }
  126. case PhysicsShapeType::PLANE:
  127. {
  128. px_shape = m_actor->createShape(PxPlaneGeometry(), *mat);
  129. break;
  130. }
  131. case PhysicsShapeType::CONVEX_MESH:
  132. {
  133. // MeshResource* resource = (MeshResource*) device()->resource_manager()->get(MESH_TYPE, shape->resource.name);
  134. // PxConvexMeshDesc convex_mesh_desc;
  135. // convex_mesh_desc.points.count = resource->num_vertices();
  136. // convex_mesh_desc.points.stride = sizeof(PxVec3);
  137. // convex_mesh_desc.points.data = (PxVec3*) resource->vertices();
  138. // convex_mesh_desc.triangles.count = resource->num_indices();
  139. // convex_mesh_desc.triangles.stride = 3 * sizeof(PxU16);
  140. // convex_mesh_desc.triangles.data = (PxU16*) resource->indices();
  141. // convex_mesh_desc.flags = PxConvexFlag::eCOMPUTE_CONVEX;
  142. // convex_mesh_desc.vertexLimit = MAX_PHYSX_VERTICES;
  143. // PxDefaultMemoryOutputStream buf;
  144. // if(!m_world.physx_cooking()->cookConvexMesh(convex_mesh_desc, buf))
  145. // CE_FATAL("");
  146. // PxDefaultMemoryInputData input(buf.getData(), buf.getSize());
  147. // PxConvexMesh* convex_mesh = physics->createConvexMesh(input);
  148. // px_shape = m_actor->createShape(PxConvexMeshGeometry(convex_mesh), *mat);
  149. break;
  150. }
  151. default:
  152. {
  153. CE_FATAL("Oops, unknown shape type");
  154. }
  155. }
  156. // Setup shape pose
  157. if (shape->type == PhysicsShapeType::PLANE)
  158. {
  159. px_shape->setLocalPose(PxTransformFromPlaneEquation(
  160. PxPlane(shape->data_0, shape->data_1, shape->data_2, shape->data_3)));
  161. }
  162. else
  163. {
  164. px_shape->setLocalPose(PxTransform(
  165. PxVec3(shape->position.x, shape->position.y, shape->position.z),
  166. PxQuat(shape->rotation.x, shape->rotation.y, shape->rotation.z, shape->rotation.w).getNormalized()));
  167. }
  168. // Setup collision filters
  169. PxFilterData filter_data;
  170. filter_data.word0 = physics_config_resource::filter(config, shape_class->collision_filter)->me;
  171. filter_data.word1 = physics_config_resource::filter(config, shape_class->collision_filter)->mask;
  172. px_shape->setSimulationFilterData(filter_data);
  173. if (shape_class->trigger)
  174. {
  175. px_shape->setFlag(PxShapeFlag::eSIMULATION_SHAPE, false);
  176. px_shape->setFlag(PxShapeFlag::eTRIGGER_SHAPE, true);
  177. }
  178. shape_index++;
  179. }
  180. if (is_dynamic())
  181. {
  182. PxRigidBodyExt::updateMassAndInertia(*static_cast<PxRigidBody*>(m_actor), actor->mass);
  183. }
  184. m_actor->userData = this;
  185. scene->addActor(*m_actor);
  186. }
  187. void Actor::destroy_objects()
  188. {
  189. if (m_actor)
  190. {
  191. m_world.physx_scene()->removeActor(*m_actor);
  192. m_actor->release();
  193. }
  194. }
  195. Vector3 Actor::world_position() const
  196. {
  197. const PxTransform tr = m_actor->getGlobalPose();
  198. return Vector3(tr.p.x, tr.p.y, tr.p.z);
  199. }
  200. Quaternion Actor::world_rotation() const
  201. {
  202. const PxTransform tr = m_actor->getGlobalPose();
  203. return Quaternion(tr.q.x, tr.q.y, tr.q.z, tr.q.w);
  204. }
  205. Matrix4x4 Actor::world_pose() const
  206. {
  207. const PxTransform tr = m_actor->getGlobalPose();
  208. return Matrix4x4(Quaternion(tr.q.x, tr.q.y, tr.q.z, tr.q.w), Vector3(tr.p.x, tr.p.y, tr.p.z));
  209. }
  210. void Actor::teleport_world_position(const Vector3& p)
  211. {
  212. PxTransform tr = m_actor->getGlobalPose();
  213. tr.p.x = p.x;
  214. tr.p.y = p.y;
  215. tr.p.z = p.z;
  216. m_actor->setGlobalPose(tr);
  217. }
  218. void Actor::teleport_world_rotation(const Quaternion& r)
  219. {
  220. PxTransform tr = m_actor->getGlobalPose();
  221. tr.q.x = r.x;
  222. tr.q.y = r.y;
  223. tr.q.z = r.z;
  224. tr.q.w = r.w;
  225. m_actor->setGlobalPose(tr);
  226. }
  227. void Actor::teleport_world_pose(const Matrix4x4& m)
  228. {
  229. using namespace matrix4x4;
  230. const PxVec3 x(m.x.x, m.x.y, m.x.z);
  231. const PxVec3 y(m.y.x, m.y.y, m.y.z);
  232. const PxVec3 z(m.z.x, m.z.y, m.z.z);
  233. const PxVec3 t(translation(m).x, translation(m).y, translation(m).z);
  234. m_actor->setGlobalPose(PxTransform(PxMat44(x, y, z, t)));
  235. }
  236. Vector3 Actor::center_of_mass() const
  237. {
  238. if (is_static())
  239. return Vector3(0, 0, 0);
  240. const PxTransform tr = static_cast<PxRigidBody*>(m_actor)->getCMassLocalPose();
  241. return Vector3(tr.p.x, tr.p.y, tr.p.z);
  242. }
  243. void Actor::enable_gravity()
  244. {
  245. m_actor->setActorFlag(PxActorFlag::eDISABLE_GRAVITY, false);
  246. }
  247. void Actor::disable_gravity()
  248. {
  249. m_actor->setActorFlag(PxActorFlag::eDISABLE_GRAVITY, true);
  250. }
  251. void Actor::enable_collision()
  252. {
  253. // const PxU32 num_shapes = m_actor->getNbShapes();
  254. // PxU32 idx = 0;
  255. // while (idx != num_shapes)
  256. // {
  257. // PxShape* shapes[8];
  258. // const PxU32 written = m_actor->getShapes(shapes, 8, idx);
  259. // for (PxU32 i = 0; i < written; i++)
  260. // {
  261. // PxFilterData fdata;
  262. // fdata.word0 = 0;
  263. // fdata.word1 = 0;
  264. // shapes[i]->setSimulationFilterData(fdata);
  265. // }
  266. // idx += written;
  267. // }
  268. }
  269. void Actor::disable_collision()
  270. {
  271. }
  272. void Actor::set_collision_filter(const char* name)
  273. {
  274. set_collision_filter(murmur32(name, strlen(name)));
  275. }
  276. void Actor::set_collision_filter(StringId32 filter)
  277. {
  278. const PhysicsCollisionFilter* pcf = physics_config_resource::filter(m_world.resource(), filter);
  279. const PxU32 num_shapes = m_actor->getNbShapes();
  280. PxU32 idx = 0;
  281. while (idx != num_shapes)
  282. {
  283. PxShape* shapes[8];
  284. const PxU32 written = m_actor->getShapes(shapes, 8, idx);
  285. for (PxU32 i = 0; i < written; i++)
  286. {
  287. PxFilterData fdata;
  288. fdata.word0 = pcf->me;
  289. fdata.word1 = pcf->mask;
  290. shapes[i]->setSimulationFilterData(fdata);
  291. }
  292. idx += written;
  293. }
  294. }
  295. void Actor::set_kinematic(bool kinematic)
  296. {
  297. if (is_static())
  298. return;
  299. static_cast<PxRigidBody*>(m_actor)->setRigidBodyFlag(PxRigidBodyFlag::eKINEMATIC, kinematic);
  300. }
  301. void Actor::move(const Vector3& pos)
  302. {
  303. if (!is_kinematic())
  304. return;
  305. const PxVec3 position(pos.x, pos.y, pos.z);
  306. static_cast<PxRigidDynamic*>(m_actor)->setKinematicTarget(PxTransform(position));
  307. }
  308. bool Actor::is_static() const
  309. {
  310. return m_actor->getType() & PxActorType::eRIGID_STATIC;
  311. }
  312. bool Actor::is_dynamic() const
  313. {
  314. return m_actor->getType() & PxActorType::eRIGID_DYNAMIC;
  315. }
  316. bool Actor::is_kinematic() const
  317. {
  318. if (!is_dynamic())
  319. return false;
  320. return static_cast<PxRigidDynamic*>(m_actor)->getRigidDynamicFlags() & PxRigidDynamicFlag::eKINEMATIC;
  321. }
  322. bool Actor::is_nonkinematic() const
  323. {
  324. return is_dynamic() && !is_kinematic();
  325. }
  326. float Actor::linear_damping() const
  327. {
  328. if (is_static())
  329. return 0;
  330. return static_cast<PxRigidDynamic*>(m_actor)->getLinearDamping();
  331. }
  332. void Actor::set_linear_damping(float rate)
  333. {
  334. if (is_static())
  335. return;
  336. static_cast<PxRigidDynamic*>(m_actor)->setLinearDamping(rate);
  337. }
  338. float Actor::angular_damping() const
  339. {
  340. if (is_static())
  341. return 0;
  342. return static_cast<PxRigidDynamic*>(m_actor)->getAngularDamping();
  343. }
  344. void Actor::set_angular_damping(float rate)
  345. {
  346. if (is_static())
  347. return;
  348. static_cast<PxRigidDynamic*>(m_actor)->setAngularDamping(rate);
  349. }
  350. Vector3 Actor::linear_velocity() const
  351. {
  352. if (is_static())
  353. return Vector3(0, 0, 0);
  354. const PxVec3 vel = static_cast<PxRigidBody*>(m_actor)->getLinearVelocity();
  355. return Vector3(vel.x, vel.y, vel.z);
  356. }
  357. void Actor::set_linear_velocity(const Vector3& vel)
  358. {
  359. if (!is_nonkinematic())
  360. return;
  361. const PxVec3 velocity(vel.x, vel.y, vel.z);
  362. static_cast<PxRigidBody*>(m_actor)->setLinearVelocity(velocity);
  363. }
  364. Vector3 Actor::angular_velocity() const
  365. {
  366. if (is_static())
  367. return Vector3(0, 0, 0);
  368. const PxVec3 vel = static_cast<PxRigidBody*>(m_actor)->getAngularVelocity();
  369. return Vector3(vel.x, vel.y, vel.z);
  370. }
  371. void Actor::set_angular_velocity(const Vector3& vel)
  372. {
  373. if (!is_nonkinematic())
  374. return;
  375. const PxVec3 velocity(vel.x, vel.y, vel.z);
  376. static_cast<PxRigidBody*>(m_actor)->setAngularVelocity(velocity);
  377. }
  378. void Actor::add_impulse(const Vector3& impulse)
  379. {
  380. if (!is_nonkinematic())
  381. return;
  382. static_cast<PxRigidDynamic*>(m_actor)->addForce(PxVec3(impulse.x, impulse.y, impulse.z), PxForceMode::eIMPULSE);
  383. }
  384. void Actor::add_impulse_at(const Vector3& impulse, const Vector3& pos)
  385. {
  386. if (!is_nonkinematic())
  387. return;
  388. PxRigidBodyExt::addForceAtPos(*static_cast<PxRigidDynamic*>(m_actor),
  389. PxVec3(impulse.x, impulse.y, impulse.z),
  390. PxVec3(pos.x, pos.y, pos.z),
  391. PxForceMode::eIMPULSE);
  392. }
  393. void Actor::add_torque_impulse(const Vector3& i)
  394. {
  395. if (!is_nonkinematic())
  396. return;
  397. static_cast<PxRigidBody*>(m_actor)->addTorque(PxVec3(i.x, i.y, i.z), PxForceMode::eIMPULSE);
  398. }
  399. void Actor::push(const Vector3& vel, float mass)
  400. {
  401. add_impulse(vel * mass);
  402. }
  403. void Actor::push_at(const Vector3& vel, float mass, const Vector3& pos)
  404. {
  405. add_impulse_at(vel * mass, pos);
  406. }
  407. bool Actor::is_sleeping()
  408. {
  409. if (is_static())
  410. return true;
  411. return static_cast<PxRigidDynamic*>(m_actor)->isSleeping();
  412. }
  413. void Actor::wake_up()
  414. {
  415. if (is_static())
  416. return;
  417. static_cast<PxRigidDynamic*>(m_actor)->wakeUp();
  418. }
  419. UnitId Actor::unit_id() const
  420. {
  421. return m_unit;
  422. }
  423. Unit* Actor::unit()
  424. {
  425. return (m_unit.id == INVALID_ID) ? NULL : m_world.world().get_unit(m_unit);
  426. }
  427. void Actor::update(const Matrix4x4& pose)
  428. {
  429. m_scene_graph.set_world_pose(m_node, pose);
  430. }
  431. } // namespace crown