From a3f32cf89433e284a5b7db0a43e05a130cdd367a Mon Sep 17 00:00:00 2001 From: boyu0 Date: Thu, 12 Jun 2014 12:45:21 +0800 Subject: [PATCH] closed #5537: add setAutoStep, isAutoStep and step method for PhysicsWorld. --- cocos/2d/CCScene.cpp | 2 +- cocos/physics/CCPhysicsWorld.cpp | 38 ++++++++++++++++++++++++++------ cocos/physics/CCPhysicsWorld.h | 25 ++++++++++++++++++--- 3 files changed, 54 insertions(+), 11 deletions(-) diff --git a/cocos/2d/CCScene.cpp b/cocos/2d/CCScene.cpp index c59d8439f6..e764028ca3 100644 --- a/cocos/2d/CCScene.cpp +++ b/cocos/2d/CCScene.cpp @@ -113,7 +113,7 @@ void Scene::addChild(Node* child, int zOrder, int tag) void Scene::update(float delta) { Node::update(delta); - if (nullptr != _physicsWorld) + if (nullptr != _physicsWorld && _physicsWorld->isAutoStep()) { _physicsWorld->update(delta); } diff --git a/cocos/physics/CCPhysicsWorld.cpp b/cocos/physics/CCPhysicsWorld.cpp index be97f220c6..27ed867c47 100644 --- a/cocos/physics/CCPhysicsWorld.cpp +++ b/cocos/physics/CCPhysicsWorld.cpp @@ -879,7 +879,19 @@ void PhysicsWorld::setGravity(const Vect& gravity) _info->setGravity(gravity); } -void PhysicsWorld::update(float delta) +void PhysicsWorld::step(float delta) +{ + if (_autoStep) + { + CCLOG("Physics Warning: You need to close auto step( setAutoStep(false) ) first"); + } + else + { + update(delta, true); + } +} + +void PhysicsWorld::update(float delta, bool userCall/* = false*/) { while (_delayDirty) { @@ -889,16 +901,27 @@ void PhysicsWorld::update(float delta) _delayDirty = !(_delayAddBodies.size() == 0 && _delayRemoveBodies.size() == 0 && _delayAddJoints.size() == 0 && _delayRemoveJoints.size() == 0); } - _updateTime += delta; - if (++_updateRateCount >= _updateRate) + if (userCall) { - _info->step(_updateTime * _speed); + _info->step(delta); for (auto& body : _bodies) { - body->update(_updateTime * _speed); + body->update(delta); + } + } + else + { + _updateTime += delta; + if (++_updateRateCount >= _updateRate) + { + _info->step(_updateTime * _speed); + for (auto& body : _bodies) + { + body->update(_updateTime * _speed); + } + _updateRateCount = 0; + _updateTime = 0.0f; } - _updateRateCount = 0; - _updateTime = 0.0f; } if (_debugDrawMask != DEBUGDRAW_NONE) @@ -916,6 +939,7 @@ PhysicsWorld::PhysicsWorld() , _info(nullptr) , _scene(nullptr) , _delayDirty(false) +, _autoStep(true) , _debugDraw(nullptr) , _debugDrawMask(DEBUGDRAW_NONE) { diff --git a/cocos/physics/CCPhysicsWorld.h b/cocos/physics/CCPhysicsWorld.h index e091017426..3c9f5052a7 100644 --- a/cocos/physics/CCPhysicsWorld.h +++ b/cocos/physics/CCPhysicsWorld.h @@ -125,14 +125,18 @@ public: inline Vect getGravity() const { return _gravity; } /** set the gravity value */ void setGravity(const Vect& gravity); - /** Set the speed of physics world, speed is the rate at which the simulation executes. default value is 1.0 */ + /** + * Set the speed of physics world, speed is the rate at which the simulation executes. default value is 1.0 + * Note: if you setAutoStep(false), this won't work. + */ inline void setSpeed(float speed) { if(speed >= 0.0f) { _speed = speed; } } /** get the speed of physics world */ inline float getSpeed() { return _speed; } - /** + /** * set the update rate of physics world, update rate is the value of EngineUpdateTimes/PhysicsWorldUpdateTimes. * set it higher can improve performance, set it lower can improve accuracy of physics world simulation. * default value is 1.0 + * Note: if you setAutoStep(false), this won't work. */ inline void setUpdateRate(int rate) { if(rate > 0) { _updateRate = rate; } } /** get the update rate */ @@ -143,6 +147,20 @@ public: /** get the bebug draw mask */ inline int getDebugDrawMask() { return _debugDrawMask; } + /** + * To control the step of physics, if you want control it by yourself( fixed-timestep for example ), you can set this to false and call step by yourself. + * Defaut value is true. + * Note: if you set auto step to false, setSpeed and setUpdateRate won't work, you need to control the time step by yourself. + */ + void setAutoStep(bool autoStep){ _autoStep = autoStep; } + /** Get the auto step */ + bool isAutoStep() { return _autoStep; } + /** + * The step for physics world, The times passing for simulate the physics. + * Note: you need to setAutoStep(false) first before it can work. + */ + void step(float delta); + protected: static PhysicsWorld* construct(Scene& scene); bool init(Scene& scene); @@ -150,7 +168,7 @@ protected: virtual void addBody(PhysicsBody* body); virtual void addShape(PhysicsShape* shape); virtual void removeShape(PhysicsShape* shape); - virtual void update(float delta); + virtual void update(float delta, bool userCall = false); virtual void debugDraw(); @@ -183,6 +201,7 @@ protected: Scene* _scene; bool _delayDirty; + bool _autoStep; PhysicsDebugDraw* _debugDraw; int _debugDrawMask;