PhysicsGhostObject.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. #include "Base.h"
  2. #include "PhysicsGhostObject.h"
  3. #include "Node.h"
  4. #include "Game.h"
  5. namespace gameplay
  6. {
  7. PhysicsGhostObject::PhysicsGhostObject(Node* node, const PhysicsCollisionShape::Definition& shape, int group, int mask)
  8. : PhysicsCollisionObject(node, group, mask), _ghostObject(NULL)
  9. {
  10. Vector3 centerOfMassOffset;
  11. PhysicsController* physicsController = Game::getInstance()->getPhysicsController();
  12. GP_ASSERT(physicsController);
  13. // Create and set the collision shape for the ghost object.
  14. _collisionShape = physicsController->createShape(node, shape, &centerOfMassOffset);
  15. GP_ASSERT(_collisionShape);
  16. // Create the ghost object.
  17. _ghostObject = bullet_new<btPairCachingGhostObject>();
  18. _ghostObject->setCollisionShape(_collisionShape->getShape());
  19. _ghostObject->setCollisionFlags(_ghostObject->getCollisionFlags() | btCollisionObject::CF_NO_CONTACT_RESPONSE);
  20. // Initialize a physics motion state object for syncing the transform.
  21. _motionState = new PhysicsMotionState(_node, this, &centerOfMassOffset);
  22. _motionState->getWorldTransform(_ghostObject->getWorldTransform());
  23. // Add the ghost object to the physics world.
  24. physicsController->addCollisionObject(this);
  25. GP_ASSERT(_node);
  26. _node->addListener(this);
  27. }
  28. PhysicsGhostObject::~PhysicsGhostObject()
  29. {
  30. GP_ASSERT(_node);
  31. _node->removeListener(this);
  32. GP_ASSERT(Game::getInstance()->getPhysicsController());
  33. Game::getInstance()->getPhysicsController()->removeCollisionObject(this, true);
  34. SAFE_DELETE(_ghostObject);
  35. }
  36. PhysicsGhostObject* PhysicsGhostObject::create(Node* node, Properties* properties)
  37. {
  38. // Check if the properties is valid and has a valid namespace.
  39. if (!properties || !(strcmp(properties->getNamespace(), "collisionObject") == 0))
  40. {
  41. GP_ERROR("Failed to load ghost object from properties object: must be non-null object and have namespace equal to 'collisionObject'.");
  42. return NULL;
  43. }
  44. // Check that the type is specified and correct.
  45. const char* type = properties->getString("type");
  46. if (!type)
  47. {
  48. GP_ERROR("Failed to load ghost object from properties object; required attribute 'type' is missing.");
  49. return NULL;
  50. }
  51. if (strcmp(type, "GHOST_OBJECT") != 0)
  52. {
  53. GP_ERROR("Failed to load ghost object from properties object; attribute 'type' must be equal to 'GHOST_OBJECT'.");
  54. return NULL;
  55. }
  56. // Load the physics collision shape definition.
  57. PhysicsCollisionShape::Definition shape = PhysicsCollisionShape::Definition::create(node, properties);
  58. if (shape.isEmpty())
  59. {
  60. GP_ERROR("Failed to create collision shape during ghost object creation.");
  61. return NULL;
  62. }
  63. // Create the ghost object.
  64. PhysicsGhostObject* ghost = new PhysicsGhostObject(node, shape);
  65. return ghost;
  66. }
  67. PhysicsCollisionObject::Type PhysicsGhostObject::getType() const
  68. {
  69. return GHOST_OBJECT;
  70. }
  71. btCollisionObject* PhysicsGhostObject::getCollisionObject() const
  72. {
  73. return _ghostObject;
  74. }
  75. void PhysicsGhostObject::transformChanged(Transform* transform, long cookie)
  76. {
  77. GP_ASSERT(_motionState);
  78. GP_ASSERT(_ghostObject);
  79. // Update the motion state with the transform from the node.
  80. _motionState->updateTransformFromNode();
  81. // Update the transform on the ghost object.
  82. _motionState->getWorldTransform(_ghostObject->getWorldTransform());
  83. }
  84. }