#include "Base.h" #include "PhysicsGhostObject.h" #include "Node.h" #include "Game.h" namespace gameplay { PhysicsGhostObject::PhysicsGhostObject(Node* node, const PhysicsCollisionShape::Definition& shape) : PhysicsCollisionObject(node), _ghostObject(NULL) { Vector3 centerOfMassOffset; PhysicsController* physicsController = Game::getInstance()->getPhysicsController(); GP_ASSERT(physicsController); // Create and set the collision shape for the ghost object. _collisionShape = physicsController->createShape(node, shape, ¢erOfMassOffset); GP_ASSERT(_collisionShape); // Create the ghost object. _ghostObject = bullet_new(); _ghostObject->setCollisionShape(_collisionShape->getShape()); _ghostObject->setCollisionFlags(_ghostObject->getCollisionFlags() | btCollisionObject::CF_NO_CONTACT_RESPONSE); // Initialize a physics motion state object for syncing the transform. _motionState = new PhysicsMotionState(_node, ¢erOfMassOffset); _motionState->getWorldTransform(_ghostObject->getWorldTransform()); // Add the ghost object to the physics world. physicsController->addCollisionObject(this); GP_ASSERT(_node); _node->addListener(this); } PhysicsGhostObject::~PhysicsGhostObject() { GP_ASSERT(_node); _node->removeListener(this); GP_ASSERT(Game::getInstance()->getPhysicsController()); Game::getInstance()->getPhysicsController()->removeCollisionObject(this); SAFE_DELETE(_ghostObject); } PhysicsGhostObject* PhysicsGhostObject::create(Node* node, Properties* properties) { // Check if the properties is valid and has a valid namespace. if (!properties || !(strcmp(properties->getNamespace(), "ghostObject") == 0)) { GP_ERROR("Failed to load ghost object from properties object: must be non-null object and have namespace equal to 'ghost'."); return NULL; } // Load the physics collision shape definition. PhysicsCollisionShape::Definition* shape = PhysicsCollisionShape::Definition::create(node, properties); if (shape == NULL) { GP_ERROR("Failed to create collision shape during ghost object creation."); return NULL; } // Create the ghost object. PhysicsGhostObject* ghost = new PhysicsGhostObject(node, *shape); SAFE_DELETE(shape); return ghost; } PhysicsCollisionObject::Type PhysicsGhostObject::getType() const { return GHOST_OBJECT; } btCollisionObject* PhysicsGhostObject::getCollisionObject() const { return _ghostObject; } void PhysicsGhostObject::transformChanged(Transform* transform, long cookie) { GP_ASSERT(_motionState); GP_ASSERT(_ghostObject); // Update the motion state with the transform from the node. _motionState->updateTransformFromNode(); // Update the transform on the ghost object. _motionState->getWorldTransform(_ghostObject->getWorldTransform()); } }