Преглед изворни кода

Merge pull request #536 from blackberry-gaming/next-kcunney

Fixes for physics
Sean Paul Taylor пре 13 година
родитељ
комит
673a13cc6b

+ 9 - 4
gameplay/src/Game.cpp

@@ -27,6 +27,7 @@ Game::Game()
 {
     GP_ASSERT(__gameInstance == NULL);
     __gameInstance = this;
+    _gamepads = new std::vector<Gamepad*>;
     _timeEvents = new std::priority_queue<TimeEvent, std::vector<TimeEvent>, std::less<TimeEvent> >();
 }
 
@@ -177,11 +178,15 @@ void Game::shutdown()
         finalize();
 
         
-        for (std::vector<Gamepad*>::iterator itr = _gamepads.begin(); itr != _gamepads.end(); itr++)
+        std::vector<Gamepad*>::iterator itr = _gamepads->begin();
+        std::vector<Gamepad*>::iterator end = _gamepads->end();
+        while (itr != end)
         {
-            SAFE_DELETE((*itr));
+            SAFE_DELETE(*itr);
+            itr++;
         }
-        _gamepads.clear();
+        _gamepads->clear();
+        SAFE_DELETE(_gamepads);
         
         _scriptController->finalizeGame();
 
@@ -504,7 +509,7 @@ Gamepad* Game::createGamepad(const char* gamepadId, const char* gamepadFormPath)
     GP_ASSERT(gamepadFormPath);
     Gamepad* gamepad = new Gamepad(gamepadId, gamepadFormPath);
     GP_ASSERT(gamepad);
-    _gamepads.push_back(gamepad);
+    _gamepads->push_back(gamepad);
 
     return gamepad;
 }

+ 3 - 3
gameplay/src/Game.h

@@ -531,9 +531,9 @@ private:
     AudioController* _audioController;          // Controls audio sources that are playing in the game.
     PhysicsController* _physicsController;      // Controls the simulation of a physics scene and entities.
     AudioListener* _audioListener;              // The audio listener in 3D space.
-    ScriptController* _scriptController;        // Controls the scripting engine.
-    std::vector<Gamepad*> _gamepads;            // The connected gamepads.
-    std::priority_queue<TimeEvent, std::vector<TimeEvent>, std::less<TimeEvent> >* _timeEvents; // Contains the scheduled time events.
+    std::vector<Gamepad*>* _gamepads;           // The connected gamepads.
+    std::priority_queue<TimeEvent, std::vector<TimeEvent>, std::less<TimeEvent> >* _timeEvents;     // Contains the scheduled time events.
+    ScriptController* _scriptController;            // Controls the scripting engine.
     std::vector<ScriptListener*>* _scriptListeners; // Lua script listeners.
 
     // Note: Do not add STL object member variables on the stack; this will cause false memory leaks to be reported.

+ 4 - 4
gameplay/src/Game.inl

@@ -110,15 +110,15 @@ inline void Game::displayKeyboard(bool display)
 
 inline unsigned int Game::getGamepadCount() const
 {
-    return _gamepads.size();
+    return _gamepads->size();
 }
 
 inline Gamepad* Game::getGamepad(unsigned int index) const
 {
-    GP_ASSERT(index < _gamepads.size());
+    GP_ASSERT(index < _gamepads->size());
 
-    if (!_gamepads.empty())
-        return _gamepads[index];
+    if (!_gamepads->empty())
+        return _gamepads->at(index);
     else
         return NULL;
 }

+ 3 - 2
gameplay/src/Gamepad.cpp

@@ -56,14 +56,15 @@ Gamepad::~Gamepad()
     {
         SAFE_RELEASE((*itr));
     }
+    _joysticks.clear();
 
     for (std::vector<Button*>::iterator itr = _buttons.begin(); itr!= _buttons.end(); itr++)
     {
         SAFE_RELEASE((*itr));
     }
+    _buttons.clear();
 
-    if (_gamepadForm)
-        SAFE_RELEASE(_gamepadForm);
+    SAFE_RELEASE(_gamepadForm);
 }
 
 const char* Gamepad::getId() const

+ 2 - 1
gameplay/src/PhysicsCollisionObject.cpp

@@ -98,6 +98,7 @@ void PhysicsCollisionObject::setEnabled(bool enable)
         if (!_enabled)
         {
             Game::getInstance()->getPhysicsController()->addCollisionObject(this);
+            _motionState->updateTransformFromNode();
             _enabled = true;
         }
     }
@@ -105,7 +106,7 @@ void PhysicsCollisionObject::setEnabled(bool enable)
     {
         if (_enabled)
         {
-            Game::getInstance()->getPhysicsController()->removeCollisionObject(this);
+            Game::getInstance()->getPhysicsController()->removeCollisionObject(this, false);
             _enabled = false;
         }
     }

+ 4 - 1
gameplay/src/PhysicsCollisionObject.h

@@ -111,6 +111,9 @@ public:
         /**
          * Called when a collision occurs between two objects in the physics world.
          * 
+         * NOTE: You are not permitted to disable physics objects from within this callback. Disabling physics on a collision object
+         *  removes the object from the physics world. This is not permitted during the PhysicsController::update.
+         *
          * @param type The type of collision event.
          * @param collisionPair The two collision objects involved in the collision.
          * @param contactPointA The contact point with the first object (in world space).
@@ -177,7 +180,7 @@ public:
     bool isEnabled() const;
 
     /**
-     * Sets the collision object be enabled or disabled.
+     * Sets the collision object to be enabled or disabled.
      *
      * @param enable true enables the collision object, false disables it.
      */

+ 13 - 6
gameplay/src/PhysicsController.cpp

@@ -21,7 +21,7 @@ const int PhysicsController::REGISTERED    = 0x04;
 const int PhysicsController::REMOVE        = 0x08;
 
 PhysicsController::PhysicsController()
-  : _collisionConfiguration(NULL), _dispatcher(NULL),
+  : _isUpdating(false), _collisionConfiguration(NULL), _dispatcher(NULL),
     _overlappingPairCache(NULL), _solver(NULL), _world(NULL), _ghostPairCallback(NULL),
     _debugDrawer(NULL), _status(PhysicsController::Listener::DEACTIVATED), _listeners(NULL),
     _gravity(btScalar(0.0), btScalar(-9.8), btScalar(0.0)), _collisionCallback(NULL), _scriptListeners(NULL)
@@ -502,6 +502,7 @@ void PhysicsController::resume()
 void PhysicsController::update(float elapsedTime)
 {
     GP_ASSERT(_world);
+    _isUpdating = true;
 
     // Update the physics simulation, with a maximum
     // of 10 simulation steps being performed in a given frame.
@@ -613,6 +614,8 @@ void PhysicsController::update(float elapsedTime)
             iter->second._status &= ~COLLISION;
         }
     }
+
+    _isUpdating = false;
 }
 
 void PhysicsController::addCollisionListener(PhysicsCollisionObject::CollisionListener* listener, PhysicsCollisionObject* objectA, PhysicsCollisionObject* objectB)
@@ -672,10 +675,11 @@ void PhysicsController::addCollisionObject(PhysicsCollisionObject* object)
     }
 }
 
-void PhysicsController::removeCollisionObject(PhysicsCollisionObject* object)
+void PhysicsController::removeCollisionObject(PhysicsCollisionObject* object, bool removeListeners)
 {
     GP_ASSERT(object);
     GP_ASSERT(_world);
+    GP_ASSERT(!_isUpdating);
 
     // Remove the collision object from the world.
     if (object->getCollisionObject())
@@ -698,11 +702,14 @@ void PhysicsController::removeCollisionObject(PhysicsCollisionObject* object)
     }
 
     // Find all references to the object in the collision status cache and mark them for removal.
-    std::map<PhysicsCollisionObject::CollisionPair, CollisionInfo>::iterator iter = _collisionStatus.begin();
-    for (; iter != _collisionStatus.end(); iter++)
+    if (removeListeners)
     {
-        if (iter->first.objectA == object || iter->first.objectB == object)
-            iter->second._status |= REMOVE;
+        std::map<PhysicsCollisionObject::CollisionPair, CollisionInfo>::iterator iter = _collisionStatus.begin();
+        for (; iter != _collisionStatus.end(); iter++)
+        {
+            if (iter->first.objectA == object || iter->first.objectB == object)
+                iter->second._status |= REMOVE;
+        }
     }
 }
 

+ 2 - 1
gameplay/src/PhysicsController.h

@@ -425,7 +425,7 @@ private:
     void addCollisionObject(PhysicsCollisionObject* object);
     
     // Removes the given collision object from the simulated physics world.
-    void removeCollisionObject(PhysicsCollisionObject* object);
+    void removeCollisionObject(PhysicsCollisionObject* object, bool removeListeners);
     
     // Gets the corresponding GamePlay object for the given Bullet object.
     PhysicsCollisionObject* getCollisionObject(const btCollisionObject* collisionObject) const;
@@ -545,6 +545,7 @@ private:
         MeshBatch* _meshBatch;
     };
 
+    bool _isUpdating;
     btDefaultCollisionConfiguration* _collisionConfiguration;
     btCollisionDispatcher* _dispatcher;
     btBroadphaseInterface* _overlappingPairCache;

+ 1 - 1
gameplay/src/PhysicsGhostObject.cpp

@@ -39,7 +39,7 @@ PhysicsGhostObject::~PhysicsGhostObject()
     _node->removeListener(this);
 
     GP_ASSERT(Game::getInstance()->getPhysicsController());
-    Game::getInstance()->getPhysicsController()->removeCollisionObject(this);
+    Game::getInstance()->getPhysicsController()->removeCollisionObject(this, true);
 
     SAFE_DELETE(_ghostObject);
 }

+ 8 - 1
gameplay/src/PhysicsRigidBody.cpp

@@ -73,7 +73,7 @@ PhysicsRigidBody::~PhysicsRigidBody()
     }
 
     // Remove collision object from physics controller.
-    Game::getInstance()->getPhysicsController()->removeCollisionObject(this);
+    Game::getInstance()->getPhysicsController()->removeCollisionObject(this, true);
 
     // Clean up the rigid body and its related objects.
     SAFE_DELETE(_body);
@@ -258,6 +258,13 @@ void PhysicsRigidBody::setKinematic(bool kinematic)
     }
 }
 
+void PhysicsRigidBody::setEnabled(bool enable)
+{
+    PhysicsCollisionObject::setEnabled(enable);
+    if (enable)
+        _body->setMotionState(_motionState);
+}
+
 float PhysicsRigidBody::getHeight(float x, float y, Vector3* normal) const
 {
     GP_ASSERT(_collisionShape);

+ 11 - 0
gameplay/src/PhysicsRigidBody.h

@@ -219,7 +219,18 @@ public:
     void setKinematic(bool kinematic);
 
     /**
+<<<<<<< HEAD
+     * Sets whether the rigid body is enabled or disabled in the physics world.
+     *
+     * @param enable true enables the collision object, false disables it.
+     */
+    void setEnabled(bool enable);
+
+    /**
+     * Gets the height at the given point (only for rigid bodies of type HEIGHTFIELD).
+=======
      * Gets the height and normal at the given point (only for rigid bodies of type HEIGHTFIELD).
+>>>>>>> 0d45c907dd0ead0b5318d9a32bc78b367c01e532
      * 
      * @param x The x position.
      * @param y The y position.