Improve performance of physics

This commit is contained in:
Wenhai Lin 2015-01-07 17:08:04 +08:00
parent 2847a940ed
commit 8524a5fb97
16 changed files with 670 additions and 977 deletions

View File

@ -859,12 +859,6 @@ void RotateTo::update(float time)
} }
else else
{ {
// _startAngle.x != _startAngle.y || _diffAngle.x != _diffAngle.y
if (_target->getPhysicsBody() != nullptr)
{
CCLOG("RotateTo WARNING: PhysicsBody doesn't support skew rotation");
}
_target->setRotationSkewX(_startAngle.x + _diffAngle.x * time); _target->setRotationSkewX(_startAngle.x + _diffAngle.x * time);
_target->setRotationSkewY(_startAngle.y + _diffAngle.y * time); _target->setRotationSkewY(_startAngle.y + _diffAngle.y * time);
} }
@ -1002,12 +996,6 @@ void RotateBy::update(float time)
} }
else else
{ {
// _startAngle.x != _startAngle.y || _deltaAngle.x != _deltaAngle.y
if (_target->getPhysicsBody() != nullptr)
{
CCLOG("RotateBy WARNING: PhysicsBody doesn't support skew rotation");
}
_target->setRotationSkewX(_startAngle.x + _deltaAngle.x * time); _target->setRotationSkewX(_startAngle.x + _deltaAngle.x * time);
_target->setRotationSkewY(_startAngle.y + _deltaAngle.y * time); _target->setRotationSkewY(_startAngle.y + _deltaAngle.y * time);
} }

View File

@ -60,7 +60,6 @@ THE SOFTWARE.
#define RENDER_IN_SUBPIXEL(__ARGS__) (ceil(__ARGS__)) #define RENDER_IN_SUBPIXEL(__ARGS__) (ceil(__ARGS__))
#endif #endif
extern int g_physicsSceneCount;
NS_CC_BEGIN NS_CC_BEGIN
@ -125,6 +124,8 @@ Node::Node(void)
, _physicsBody(nullptr) , _physicsBody(nullptr)
, _physicsScaleStartX(1.0f) , _physicsScaleStartX(1.0f)
, _physicsScaleStartY(1.0f) , _physicsScaleStartY(1.0f)
, _physicsRotation(0.0f)
, _physicsTransformDirty(true)
#endif #endif
, _displayedOpacity(255) , _displayedOpacity(255)
, _realOpacity(255) , _realOpacity(255)
@ -329,13 +330,6 @@ void Node::setRotation(float rotation)
_rotationZ_X = _rotationZ_Y = rotation; _rotationZ_X = _rotationZ_Y = rotation;
_transformUpdated = _transformDirty = _inverseDirty = true; _transformUpdated = _transformDirty = _inverseDirty = true;
#if CC_USE_PHYSICS
if (!_physicsBody || !_physicsBody->_rotationResetTag)
{
updatePhysicsBodyRotation(getScene());
}
#endif
updateRotationQuat(); updateRotationQuat();
} }
@ -472,16 +466,6 @@ void Node::setScale(float scale)
_scaleX = _scaleY = _scaleZ = scale; _scaleX = _scaleY = _scaleZ = scale;
_transformUpdated = _transformDirty = _inverseDirty = true; _transformUpdated = _transformDirty = _inverseDirty = true;
#if CC_USE_PHYSICS
if(g_physicsSceneCount == 0)
return;
auto scene = getScene();
if (!scene || scene->getPhysicsWorld())
{
updatePhysicsBodyTransform(scene);
}
#endif
} }
/// scaleX getter /// scaleX getter
@ -499,17 +483,6 @@ void Node::setScale(float scaleX,float scaleY)
_scaleX = scaleX; _scaleX = scaleX;
_scaleY = scaleY; _scaleY = scaleY;
_transformUpdated = _transformDirty = _inverseDirty = true; _transformUpdated = _transformDirty = _inverseDirty = true;
#if CC_USE_PHYSICS
if(g_physicsSceneCount == 0)
return;
auto scene = getScene();
if (!scene || scene->getPhysicsWorld())
{
updatePhysicsBodyTransform(scene);
}
#endif
} }
/// scaleX setter /// scaleX setter
@ -520,17 +493,6 @@ void Node::setScaleX(float scaleX)
_scaleX = scaleX; _scaleX = scaleX;
_transformUpdated = _transformDirty = _inverseDirty = true; _transformUpdated = _transformDirty = _inverseDirty = true;
#if CC_USE_PHYSICS
if(g_physicsSceneCount == 0)
return;
auto scene = getScene();
if (!scene || scene->getPhysicsWorld())
{
updatePhysicsBodyTransform(scene);
}
#endif
} }
/// scaleY getter /// scaleY getter
@ -570,17 +532,6 @@ void Node::setScaleY(float scaleY)
_scaleY = scaleY; _scaleY = scaleY;
_transformUpdated = _transformDirty = _inverseDirty = true; _transformUpdated = _transformDirty = _inverseDirty = true;
#if CC_USE_PHYSICS
if (g_physicsSceneCount == 0)
return;
auto scene = getScene();
if (!scene || scene->getPhysicsWorld())
{
updatePhysicsBodyTransform(scene);
}
#endif
} }
@ -612,13 +563,6 @@ void Node::setPosition(float x, float y)
_transformUpdated = _transformDirty = _inverseDirty = true; _transformUpdated = _transformDirty = _inverseDirty = true;
_usingNormalizedPosition = false; _usingNormalizedPosition = false;
#if CC_USE_PHYSICS
if (!_physicsBody || !_physicsBody->_positionResetTag)
{
updatePhysicsBodyPosition(getScene());
}
#endif
} }
void Node::setPosition3D(const Vec3& position) void Node::setPosition3D(const Vec3& position)
@ -1076,7 +1020,6 @@ void Node::addChildHelper(Node* child, int localZOrder, int tag, const std::stri
auto scene = this->getScene(); auto scene = this->getScene();
if (scene && scene->getPhysicsWorld()) if (scene && scene->getPhysicsWorld())
{ {
child->updatePhysicsBodyTransform(scene);
scene->addChildToPhysicsWorld(child); scene->addChildToPhysicsWorld(child);
} }
#endif #endif
@ -1301,6 +1244,12 @@ void Node::visit()
uint32_t Node::processParentFlags(const Mat4& parentTransform, uint32_t parentFlags) uint32_t Node::processParentFlags(const Mat4& parentTransform, uint32_t parentFlags)
{ {
#if CC_USE_PHYSICS
if (_physicsBody && _updateTransformFromPhysics)
{
updateTransformFromPhysics(parentTransform, parentFlags);
}
#endif
if(_usingNormalizedPosition) if(_usingNormalizedPosition)
{ {
CCASSERT(_parent, "setNormalizedPosition() doesn't work with orphan nodes"); CCASSERT(_parent, "setNormalizedPosition() doesn't work with orphan nodes");
@ -2023,87 +1972,6 @@ void Node::removeAllComponents()
// MARK: Physics // MARK: Physics
void Node::updatePhysicsBodyTransform(Scene* scene)
{
updatePhysicsBodyScale(scene);
updatePhysicsBodyPosition(scene);
updatePhysicsBodyRotation(scene);
}
void Node::updatePhysicsBodyPosition(Scene* scene)
{
if (_physicsBody != nullptr)
{
if (scene && scene->getPhysicsWorld())
{
Vec2 pos = _parent == scene ? _position : scene->convertToNodeSpace(_parent->convertToWorldSpace(_position));
_physicsBody->setPosition(pos);
}
else
{
_physicsBody->setPosition(_position);
}
}
for (Node* child : _children)
{
child->updatePhysicsBodyPosition(scene);
}
}
void Node::updatePhysicsBodyRotation(Scene* scene)
{
if (_physicsBody != nullptr)
{
if (scene != nullptr && scene->getPhysicsWorld() != nullptr)
{
float rotation = _rotationZ_X;
for (Node* parent = _parent; parent != scene; parent = parent->_parent)
{
rotation += parent->getRotation();
}
_physicsBody->setRotation(rotation);
}
else
{
_physicsBody->setRotation(_rotationZ_X);
}
}
for (auto child : _children)
{
child->updatePhysicsBodyRotation(scene);
child->updatePhysicsBodyPosition(scene);
}
}
void Node::updatePhysicsBodyScale(Scene* scene)
{
if (_physicsBody != nullptr)
{
if (scene != nullptr && scene->getPhysicsWorld() != nullptr)
{
float scaleX = _scaleX / _physicsScaleStartX;
float scaleY = _scaleY / _physicsScaleStartY;
for (Node* parent = _parent; parent != scene; parent = parent->_parent)
{
scaleX *= parent->_scaleX;
scaleY *= parent->_scaleY;
}
_physicsBody->setScale(scaleX, scaleY);
}
else
{
_physicsBody->setScale(_scaleX / _physicsScaleStartX, _scaleY / _physicsScaleStartY);
}
}
for (const auto& child : _children)
{
child->updatePhysicsBodyScale(scene);
}
}
void Node::setPhysicsBody(PhysicsBody* body) void Node::setPhysicsBody(PhysicsBody* body)
{ {
if (_physicsBody == body) if (_physicsBody == body)
@ -2111,9 +1979,17 @@ void Node::setPhysicsBody(PhysicsBody* body)
return; return;
} }
if (body != nullptr) if (_physicsBody)
{ {
if (body->getNode() != nullptr) _physicsBody->removeFromWorld();
_physicsBody->_node = nullptr;
_physicsBody->release();
_physicsBody = nullptr;
}
if (body)
{
if (body->getNode())
{ {
body->getNode()->setPhysicsBody(nullptr); body->getNode()->setPhysicsBody(nullptr);
} }
@ -2128,52 +2004,65 @@ void Node::setPhysicsBody(PhysicsBody* body)
CCLOG("Node warning: setPhysicsBody sets anchor point to Vec2::ANCHOR_MIDDLE."); CCLOG("Node warning: setPhysicsBody sets anchor point to Vec2::ANCHOR_MIDDLE.");
setAnchorPoint(Vec2::ANCHOR_MIDDLE); setAnchorPoint(Vec2::ANCHOR_MIDDLE);
} }
}
_physicsBody = body;
if (_physicsBody != nullptr) _physicsScaleStartX = _scaleX;
{ _physicsScaleStartY = _scaleY;
PhysicsWorld* world = _physicsBody->getWorld();
_physicsBody->removeFromWorld(); auto scene = getScene();
_physicsBody->_node = nullptr; if (scene && scene->getPhysicsWorld())
_physicsBody->release();
if (world != nullptr && body != nullptr)
{
world->addBody(body);
}
}
_physicsBody = body;
_physicsScaleStartX = _scaleX;
_physicsScaleStartY = _scaleY;
if (body != nullptr)
{
Node* node;
Scene* scene = nullptr;
for (node = this->getParent(); node != nullptr; node = node->getParent())
{
Scene* tmpScene = dynamic_cast<Scene*>(node);
if (tmpScene != nullptr && tmpScene->getPhysicsWorld() != nullptr)
{
scene = tmpScene;
break;
}
}
if (scene != nullptr)
{ {
_physicsTransformDirty = true;
scene->getPhysicsWorld()->addBody(body); scene->getPhysicsWorld()->addBody(body);
} }
updatePhysicsBodyTransform(scene);
} }
} }
PhysicsBody* Node::getPhysicsBody() const void Node::updatePhysicsBodyTransform(Scene* scene, const Mat4& parentTransform, uint32_t parentFlags, float parentScaleX, float parentScaleY)
{ {
return _physicsBody; _updateTransformFromPhysics = false;
auto flags = processParentFlags(parentTransform, parentFlags);
_updateTransformFromPhysics = true;
auto scaleX = parentScaleX * _scaleX;
auto scaleY = parentScaleY * _scaleY;
if (_parent)
{
_physicsRotation = _parent->_physicsRotation + _rotationZ_X;
}
if (_physicsBody && ((flags & FLAGS_DIRTY_MASK) || _physicsTransformDirty))
{
_physicsTransformDirty = false;
Vec3 vec3(_position.x, _position.y, 0);
Vec3 ret;
parentTransform.transformPoint(vec3, &ret);
_physicsBody->setPosition(Vec2(ret.x, ret.y));
_physicsBody->setScale(scaleX / _physicsScaleStartX, scaleY / _physicsScaleStartY);
_physicsBody->setRotation(_physicsRotation);
}
for (auto node : _children)
{
node->updatePhysicsBodyTransform(scene, _modelViewTransform, flags, scaleX, scaleY);
}
} }
void Node::updateTransformFromPhysics(const Mat4& parentTransform, uint32_t parentFlags)
{
auto newPos = _physicsBody->getPosition();
auto& recordPos = _physicsBody->_recordPosition;
if (parentFlags || recordPos.x != newPos.x || recordPos.y != newPos.y)
{
recordPos = newPos;
Vec3 vec3(newPos.x, newPos.y, 0);
Vec3 ret;
parentTransform.getInversed().transformPoint(vec3, &ret);
setPosition(ret.x, ret.y);
}
_physicsRotation = _physicsBody->getRotation();
setRotation(_physicsRotation - _parent->_physicsRotation);
}
#endif //CC_USE_PHYSICS #endif //CC_USE_PHYSICS
// MARK: Opacity and Color // MARK: Opacity and Color

View File

@ -1532,13 +1532,16 @@ public:
/** /**
* get the PhysicsBody the sprite have * get the PhysicsBody the sprite have
*/ */
PhysicsBody* getPhysicsBody() const; PhysicsBody* getPhysicsBody() const { return _physicsBody; }
/** /**
* remove this node from physics world. it will remove all the physics bodies in it's children too. * remove this node from physics world. it will remove all the physics bodies in it's children too.
*/ */
void removeFromPhysicsWorld(); void removeFromPhysicsWorld();
void updateTransformFromPhysics(const Mat4& parentTransform, uint32_t parentFlags);
virtual void updatePhysicsBodyTransform(Scene* scene, const Mat4& parentTransform, uint32_t parentFlags, float parentScaleX, float parentScaleY);
#endif #endif
// overrides // overrides
@ -1612,13 +1615,6 @@ protected:
// update Rotation3D from quaternion // update Rotation3D from quaternion
void updateRotation3D(); void updateRotation3D();
#if CC_USE_PHYSICS
void updatePhysicsBodyTransform(Scene* layer);
virtual void updatePhysicsBodyPosition(Scene* layer);
virtual void updatePhysicsBodyRotation(Scene* layer);
virtual void updatePhysicsBodyScale(Scene* scene);
#endif // CC_USE_PHYSICS
private: private:
void addChildHelper(Node* child, int localZOrder, int tag, const std::string &name, bool setTag); void addChildHelper(Node* child, int localZOrder, int tag, const std::string &name, bool setTag);
@ -1709,6 +1705,9 @@ protected:
PhysicsBody* _physicsBody; ///< the physicsBody the node have PhysicsBody* _physicsBody; ///< the physicsBody the node have
float _physicsScaleStartX; ///< the scale x value when setPhysicsBody float _physicsScaleStartX; ///< the scale x value when setPhysicsBody
float _physicsScaleStartY; ///< the scale y value when setPhysicsBody float _physicsScaleStartY; ///< the scale y value when setPhysicsBody
float _physicsRotation;
bool _physicsTransformDirty;
bool _updateTransformFromPhysics;
#endif #endif
// opacity controls // opacity controls

View File

@ -37,8 +37,6 @@ THE SOFTWARE.
#include "physics/CCPhysicsWorld.h" #include "physics/CCPhysicsWorld.h"
#endif #endif
int g_physicsSceneCount = 0;
NS_CC_BEGIN NS_CC_BEGIN
Scene::Scene() Scene::Scene()
@ -60,10 +58,6 @@ Scene::Scene()
Scene::~Scene() Scene::~Scene()
{ {
#if CC_USE_PHYSICS #if CC_USE_PHYSICS
if (_physicsWorld)
{
g_physicsSceneCount--;
}
CC_SAFE_DELETE(_physicsWorld); CC_SAFE_DELETE(_physicsWorld);
#endif #endif
Director::getInstance()->getEventDispatcher()->removeEventListener(_event); Director::getInstance()->getEventDispatcher()->removeEventListener(_event);
@ -177,15 +171,6 @@ void Scene::addChild(Node* child, int zOrder, const std::string &name)
addChildToPhysicsWorld(child); addChildToPhysicsWorld(child);
} }
void Scene::update(float delta)
{
Node::update(delta);
if (nullptr != _physicsWorld && _physicsWorld->isAutoStep())
{
_physicsWorld->update(delta);
}
}
Scene* Scene::createWithPhysics() Scene* Scene::createWithPhysics()
{ {
Scene *ret = new (std::nothrow) Scene(); Scene *ret = new (std::nothrow) Scene();
@ -212,9 +197,7 @@ bool Scene::initWithPhysics()
this->setContentSize(director->getWinSize()); this->setContentSize(director->getWinSize());
CC_BREAK_IF(! (_physicsWorld = PhysicsWorld::construct(*this))); CC_BREAK_IF(! (_physicsWorld = PhysicsWorld::construct(*this)));
this->scheduleUpdate();
// success // success
g_physicsSceneCount += 1;
ret = true; ret = true;
} while (0); } while (0);
return ret; return ret;

View File

@ -108,7 +108,6 @@ private:
public: public:
virtual void addChild(Node* child, int zOrder, int tag) override; virtual void addChild(Node* child, int zOrder, int tag) override;
virtual void addChild(Node* child, int zOrder, const std::string &name) override; virtual void addChild(Node* child, int zOrder, const std::string &name) override;
virtual void update(float delta) override;
inline PhysicsWorld* getPhysicsWorld() { return _physicsWorld; } inline PhysicsWorld* getPhysicsWorld() { return _physicsWorld; }
static Scene *createWithPhysics(); static Scene *createWithPhysics();

View File

@ -366,8 +366,17 @@ void SpriteBatchNode::draw(Renderer *renderer, const Mat4 &transform, uint32_t f
return; return;
} }
for(const auto &child: _children) for (const auto &child : _children)
{
#if CC_USE_PHYSICS
auto physicsBody = child->getPhysicsBody();
if (physicsBody)
{
child->updateTransformFromPhysics(transform, flags);
}
#endif
child->updateTransform(); child->updateTransform();
}
_batchCommand.init( _batchCommand.init(
_globalZOrder, _globalZOrder,

View File

@ -65,6 +65,10 @@ THE SOFTWARE.
#include "CCScriptSupport.h" #include "CCScriptSupport.h"
#endif #endif
#if CC_USE_PHYSICS
#include "physics/CCPhysicsWorld.h"
#endif
/** /**
Position of the FPS Position of the FPS
@ -265,12 +269,6 @@ void Director::drawScene()
// calculate "global" dt // calculate "global" dt
calculateDeltaTime(); calculateDeltaTime();
// skip one flame when _deltaTime equal to zero.
if(_deltaTime < FLT_EPSILON)
{
return;
}
if (_openGLView) if (_openGLView)
{ {
_openGLView->pollEvents(); _openGLView->pollEvents();
@ -297,6 +295,13 @@ void Director::drawScene()
if (_runningScene) if (_runningScene)
{ {
#if CC_USE_PHYSICS
auto physicsWorld = _runningScene->getPhysicsWorld();
if (physicsWorld && physicsWorld->isAutoStep())
{
physicsWorld->update(_deltaTime, false);
}
#endif
//clear draw stats //clear draw stats
_renderer->clearDrawStats(); _renderer->clearDrawStats();

View File

@ -68,9 +68,8 @@ PhysicsBody::PhysicsBody()
, _linearDamping(0.0f) , _linearDamping(0.0f)
, _angularDamping(0.0f) , _angularDamping(0.0f)
, _tag(0) , _tag(0)
, _positionResetTag(false)
, _rotationResetTag(false)
, _rotationOffset(0) , _rotationOffset(0)
, _recordPosition(Vec2::ZERO)
{ {
} }
@ -333,6 +332,7 @@ void PhysicsBody::setGravityEnable(bool enable)
void PhysicsBody::setPosition(const Vec2& position) void PhysicsBody::setPosition(const Vec2& position)
{ {
_recordPosition = position;
cpBodySetPos(_cpBody, PhysicsHelper::point2cpv(position + _positionOffset)); cpBodySetPos(_cpBody, PhysicsHelper::point2cpv(position + _positionOffset));
} }
@ -341,14 +341,6 @@ void PhysicsBody::setRotation(float rotation)
cpBodySetAngle(_cpBody, -PhysicsHelper::float2cpfloat((rotation + _rotationOffset) * (M_PI / 180.0f))); cpBodySetAngle(_cpBody, -PhysicsHelper::float2cpfloat((rotation + _rotationOffset) * (M_PI / 180.0f)));
} }
void PhysicsBody::setScale(float scale)
{
for (auto shape : _shapes)
{
shape->setScale(scale);
}
}
void PhysicsBody::setScale(float scaleX, float scaleY) void PhysicsBody::setScale(float scaleX, float scaleY)
{ {
for (auto shape : _shapes) for (auto shape : _shapes)
@ -357,22 +349,6 @@ void PhysicsBody::setScale(float scaleX, float scaleY)
} }
} }
void PhysicsBody::setScaleX(float scaleX)
{
for (auto shape : _shapes)
{
shape->setScaleX(scaleX);
}
}
void PhysicsBody::setScaleY(float scaleY)
{
for (auto shape : _shapes)
{
shape->setScaleY(scaleY);
}
}
Vec2 PhysicsBody::getPosition() const Vec2 PhysicsBody::getPosition() const
{ {
cpVect vec = cpBodyGetPos(_cpBody); cpVect vec = cpBodyGetPos(_cpBody);
@ -402,7 +378,7 @@ PhysicsShape* PhysicsBody::addShape(PhysicsShape* shape, bool addMassAndMoment/*
addMoment(shape->getMoment()); addMoment(shape->getMoment());
} }
if (_world != nullptr) if (_world && _cpBody->CP_PRIVATE(space))
{ {
_world->addShape(shape); _world->addShape(shape);
} }
@ -764,30 +740,8 @@ void PhysicsBody::setResting(bool rest) const
void PhysicsBody::update(float delta) void PhysicsBody::update(float delta)
{ {
if (_node != nullptr) if (_node)
{ {
for (auto shape : _shapes)
{
shape->update(delta);
}
Node* parent = _node->getParent();
Node* scene = &_world->getScene();
Vec2 position = parent != scene ? parent->convertToNodeSpace(scene->convertToWorldSpace(getPosition())) : getPosition();
float rotation = getRotation();
for (; parent != scene; parent = parent->getParent())
{
rotation -= parent->getRotation();
}
_positionResetTag = true;
_rotationResetTag = true;
_node->setPosition(position);
_node->setRotation(rotation);
_positionResetTag = false;
_rotationResetTag = false;
// damping compute // damping compute
if (_isDamping && _dynamic && !isResting()) if (_isDamping && _dynamic && !isResting())
{ {

View File

@ -306,10 +306,7 @@ protected:
virtual void setPosition(const Vec2& position); virtual void setPosition(const Vec2& position);
virtual void setRotation(float rotation); virtual void setRotation(float rotation);
virtual void setScale(float scale);
virtual void setScale(float scaleX, float scaleY); virtual void setScale(float scaleX, float scaleY);
virtual void setScaleX(float scaleX);
virtual void setScaleY(float scaleY);
void update(float delta); void update(float delta);
@ -341,8 +338,7 @@ protected:
float _angularDamping; float _angularDamping;
int _tag; int _tag;
bool _positionResetTag; /// To avoid reset the body position when body invoke Node::setPosition(). Vec2 _recordPosition;
bool _rotationResetTag; /// To avoid reset the body rotation when body invoke Node::setRotation().
Vec2 _positionOffset; Vec2 _positionOffset;
float _rotationOffset; float _rotationOffset;

View File

@ -40,20 +40,23 @@ PhysicsJoint::PhysicsJoint()
, _enable(false) , _enable(false)
, _collisionEnable(true) , _collisionEnable(true)
, _destoryMark(false) , _destoryMark(false)
, _initDirty(true)
, _tag(0) , _tag(0)
, _maxForce(PHYSICS_INFINITY)
{ {
} }
PhysicsJoint::~PhysicsJoint() PhysicsJoint::~PhysicsJoint()
{ {
// reset the shapes collision group // reset the shapes collision group
setCollisionEnable(true); setCollisionEnable(true);
for (auto constraint : _cpConstraints) for (cpConstraint* joint : _cpConstraints)
{ {
cpConstraintFree(constraint); cpConstraintFree(joint);
} }
_cpConstraints.clear();
} }
bool PhysicsJoint::init(cocos2d::PhysicsBody *a, cocos2d::PhysicsBody *b) bool PhysicsJoint::init(cocos2d::PhysicsBody *a, cocos2d::PhysicsBody *b)
@ -62,42 +65,59 @@ bool PhysicsJoint::init(cocos2d::PhysicsBody *a, cocos2d::PhysicsBody *b)
{ {
CCASSERT(a != nullptr && b != nullptr, "the body passed in is nil"); CCASSERT(a != nullptr && b != nullptr, "the body passed in is nil");
CCASSERT(a != b, "the two bodies are equal"); CCASSERT(a != b, "the two bodies are equal");
_bodyA = a; _bodyA = a;
_bodyA->_joints.push_back(this);
_bodyB = b; _bodyB = b;
_bodyA->_joints.push_back(this);
_bodyB->_joints.push_back(this); _bodyB->_joints.push_back(this);
return true; return true;
} while (false); } while (false);
return false; return false;
} }
bool PhysicsJoint::initJoint()
{
bool ret = !_initDirty;
while (_initDirty)
{
ret = createConstraints();
CC_BREAK_IF(!ret);
for (auto subjoint : _cpConstraints)
{
subjoint->maxForce = _maxForce;
subjoint->errorBias = cpfpow(1.0f - 0.15f, 60.0f);
cpSpaceAddConstraint(_world->_cpSpace, subjoint);
}
_initDirty = false;
ret = true;
}
return ret;
}
void PhysicsJoint::setEnable(bool enable) void PhysicsJoint::setEnable(bool enable)
{ {
if (_enable != enable) if (_enable != enable)
{ {
_enable = enable; _enable = enable;
if (_world != nullptr) if (_world)
{ {
if (enable) if (enable)
{ {
_world->addJointOrDelay(this); _world->addJoint(this);
}else }
else
{ {
_world->removeJointOrDelay(this); _world->removeJoint(this, false);
} }
} }
} }
} }
Node* PhysicsJoint::getBodyNode(PhysicsBody* body) const
{
return body->_node;
}
void PhysicsJoint::setCollisionEnable(bool enable) void PhysicsJoint::setCollisionEnable(bool enable)
{ {
if (_collisionEnable != enable) if (_collisionEnable != enable)
@ -114,126 +134,126 @@ void PhysicsJoint::removeFormWorld()
} }
} }
void PhysicsJoint::destroy(PhysicsJoint* joint)
{
if (joint!= nullptr)
{
// remove the joint and delete it.
if (joint->_world != nullptr)
{
joint->_world->removeJoint(joint, true);
}
else
{
if (joint->_bodyA != nullptr)
{
joint->_bodyA->removeJoint(joint);
}
if (joint->_bodyB != nullptr)
{
joint->_bodyB->removeJoint(joint);
}
delete joint;
}
}
}
void PhysicsJoint::setMaxForce(float force) void PhysicsJoint::setMaxForce(float force)
{ {
_maxForce = force;
for (auto joint : _cpConstraints) for (auto joint : _cpConstraints)
{ {
joint->maxForce = PhysicsHelper::float2cpfloat(force); joint->maxForce = PhysicsHelper::float2cpfloat(force);
} }
} }
float PhysicsJoint::getMaxForce() const
{
return PhysicsHelper::cpfloat2float(_cpConstraints.front()->maxForce);
}
PhysicsJointFixed* PhysicsJointFixed::construct(PhysicsBody* a, PhysicsBody* b, const Vec2& anchr) PhysicsJointFixed* PhysicsJointFixed::construct(PhysicsBody* a, PhysicsBody* b, const Vec2& anchr)
{ {
PhysicsJointFixed* joint = new (std::nothrow) PhysicsJointFixed(); auto joint = new (std::nothrow) PhysicsJointFixed();
if (joint && joint->init(a, b, anchr)) if (joint && joint->init(a, b))
{ {
joint->_anchr = anchr;
return joint; return joint;
} }
CC_SAFE_DELETE(joint); CC_SAFE_DELETE(joint);
return nullptr; return nullptr;
} }
bool PhysicsJointFixed::init(PhysicsBody* a, PhysicsBody* b, const Vec2& anchr) bool PhysicsJointFixed::createConstraints()
{ {
do do
{ {
CC_BREAK_IF(!PhysicsJoint::init(a, b)); _bodyA->getNode()->setPosition(_anchr);
_bodyB->getNode()->setPosition(_anchr);
getBodyNode(a)->setPosition(anchr);
getBodyNode(b)->setPosition(anchr);
// add a pivot joint to fixed two body together // add a pivot joint to fixed two body together
auto constraint = cpPivotJointNew(a->getCPBody(), b->getCPBody(), auto joint = cpPivotJointNew(_bodyA->getCPBody(), _bodyB->getCPBody(),
PhysicsHelper::point2cpv(anchr)); PhysicsHelper::point2cpv(_anchr));
CC_BREAK_IF(constraint == nullptr); CC_BREAK_IF(joint == nullptr);
_cpConstraints.push_back(constraint); _cpConstraints.push_back(joint);
// add a gear joint to make two body have the same rotation. // add a gear joint to make two body have the same rotation.
constraint = cpGearJointNew(a->getCPBody(), b->getCPBody(), 0, 1); joint = cpGearJointNew(_bodyA->getCPBody(), _bodyB->getCPBody(), 0, 1);
CC_BREAK_IF(constraint == nullptr); CC_BREAK_IF(joint == nullptr);
_cpConstraints.push_back(constraint); _cpConstraints.push_back(joint);
setCollisionEnable(false); _collisionEnable = false;
return true; return true;
} while (false); } while (false);
return false; return false;
} }
PhysicsJointPin* PhysicsJointPin::construct(PhysicsBody* a, PhysicsBody* b, const Vec2& anchr) PhysicsJointPin* PhysicsJointPin::construct(PhysicsBody* a, PhysicsBody* b, const Vec2& pivot)
{ {
PhysicsJointPin* joint = new (std::nothrow) PhysicsJointPin(); auto joint = new (std::nothrow) PhysicsJointPin();
if (joint && joint->init(a, b, anchr)) if (joint && joint->init(a, b))
{ {
joint->_anchr1 = pivot;
joint->_useSpecificAnchr = false;
return joint; return joint;
} }
CC_SAFE_DELETE(joint); CC_SAFE_DELETE(joint);
return nullptr; return nullptr;
} }
bool PhysicsJointPin::init(PhysicsBody *a, PhysicsBody *b, const Vec2& anchr) PhysicsJointPin* PhysicsJointPin::construct(PhysicsBody* a, PhysicsBody* b, const Vec2& anchr1, const Vec2& anchr2)
{
auto joint = new (std::nothrow) PhysicsJointPin();
if (joint && joint->init(a, b))
{
joint->_anchr1 = anchr1;
joint->_anchr2 = anchr2;
joint->_useSpecificAnchr = true;
return joint;
}
CC_SAFE_DELETE(joint);
return nullptr;
}
bool PhysicsJointPin::createConstraints()
{ {
do do
{ {
CC_BREAK_IF(!PhysicsJoint::init(a, b)); cpConstraint* joint = nullptr;
auto constraint = cpPivotJointNew(a->getCPBody(), b->getCPBody(), if (_useSpecificAnchr)
PhysicsHelper::point2cpv(anchr)); {
joint = cpPivotJointNew2(_bodyA->getCPBody(), _bodyB->getCPBody(),
CC_BREAK_IF(constraint == nullptr); PhysicsHelper::point2cpv(_anchr1), PhysicsHelper::point2cpv(_anchr2));
}
_cpConstraints.push_back(constraint); else
{
joint = cpPivotJointNew(_bodyA->getCPBody(), _bodyB->getCPBody(),
PhysicsHelper::point2cpv(_anchr1));
}
CC_BREAK_IF(joint == nullptr);
_cpConstraints.push_back(joint);
return true; return true;
} while (false); } while (false);
return false; return false;
} }
PhysicsJointLimit* PhysicsJointLimit::construct(PhysicsBody* a, PhysicsBody* b, const Vec2& anchr1, const Vec2& anchr2, float min, float max) PhysicsJointLimit* PhysicsJointLimit::construct(PhysicsBody* a, PhysicsBody* b, const Vec2& anchr1, const Vec2& anchr2, float min, float max)
{ {
PhysicsJointLimit* joint = new (std::nothrow) PhysicsJointLimit(); auto joint = new (std::nothrow) PhysicsJointLimit();
if (joint && joint->init(a, b, anchr1, anchr2, min, max)) if (joint && joint->init(a, b))
{ {
joint->_anchr1 = anchr1;
joint->_anchr2 = anchr2;
joint->_min = min;
joint->_max = max;
return joint; return joint;
} }
CC_SAFE_DELETE(joint); CC_SAFE_DELETE(joint);
return nullptr; return nullptr;
} }
@ -243,25 +263,22 @@ PhysicsJointLimit* PhysicsJointLimit::construct(PhysicsBody* a, PhysicsBody* b,
return construct(a, b, anchr1, anchr2, 0, b->local2World(anchr1).getDistance(a->local2World(anchr2))); return construct(a, b, anchr1, anchr2, 0, b->local2World(anchr1).getDistance(a->local2World(anchr2)));
} }
bool PhysicsJointLimit::init(PhysicsBody* a, PhysicsBody* b, const Vec2& anchr1, const Vec2& anchr2, float min, float max) bool PhysicsJointLimit::createConstraints()
{ {
do do
{ {
CC_BREAK_IF(!PhysicsJoint::init(a, b)); auto joint = cpSlideJointNew(_bodyA->getCPBody(), _bodyB->getCPBody(),
PhysicsHelper::point2cpv(_anchr1),
auto constraint = cpSlideJointNew(a->getCPBody(), b->getCPBody(), PhysicsHelper::point2cpv(_anchr2),
PhysicsHelper::point2cpv(anchr1), PhysicsHelper::float2cpfloat(_min),
PhysicsHelper::point2cpv(anchr2), PhysicsHelper::float2cpfloat(_max));
PhysicsHelper::float2cpfloat(min),
PhysicsHelper::float2cpfloat(max)); CC_BREAK_IF(joint == nullptr);
_cpConstraints.push_back(joint);
CC_BREAK_IF(constraint == nullptr);
_cpConstraints.push_back(constraint);
return true; return true;
} while (false); } while (false);
return false; return false;
} }
@ -307,35 +324,34 @@ void PhysicsJointLimit::setAnchr2(const Vec2& anchr)
PhysicsJointDistance* PhysicsJointDistance::construct(PhysicsBody* a, PhysicsBody* b, const Vec2& anchr1, const Vec2& anchr2) PhysicsJointDistance* PhysicsJointDistance::construct(PhysicsBody* a, PhysicsBody* b, const Vec2& anchr1, const Vec2& anchr2)
{ {
PhysicsJointDistance* joint = new (std::nothrow) PhysicsJointDistance(); auto joint = new (std::nothrow) PhysicsJointDistance();
if (joint && joint->init(a, b, anchr1, anchr2)) if (joint && joint->init(a, b))
{ {
joint->_anchr1 = anchr1;
joint->_anchr2 = anchr2;
return joint; return joint;
} }
CC_SAFE_DELETE(joint); CC_SAFE_DELETE(joint);
return nullptr; return nullptr;
} }
bool PhysicsJointDistance::init(PhysicsBody* a, PhysicsBody* b, const Vec2& anchr1, const Vec2& anchr2) bool PhysicsJointDistance::createConstraints()
{ {
do do
{ {
CC_BREAK_IF(!PhysicsJoint::init(a, b)); auto joint = cpPinJointNew(_bodyA->getCPBody(),
_bodyB->getCPBody(),
auto constraint = cpPinJointNew(a->getCPBody(), PhysicsHelper::point2cpv(_anchr1),
b->getCPBody(), PhysicsHelper::point2cpv(_anchr2));
PhysicsHelper::point2cpv(anchr1), CC_BREAK_IF(joint == nullptr);
PhysicsHelper::point2cpv(anchr2)); _cpConstraints.push_back(joint);
CC_BREAK_IF(constraint == nullptr);
_cpConstraints.push_back(constraint);
return true; return true;
} while (false); } while (false);
return false; return false;
} }
@ -351,37 +367,39 @@ void PhysicsJointDistance::setDistance(float distance)
PhysicsJointSpring* PhysicsJointSpring::construct(PhysicsBody* a, PhysicsBody* b, const Vec2& anchr1, const Vec2& anchr2, float stiffness, float damping) PhysicsJointSpring* PhysicsJointSpring::construct(PhysicsBody* a, PhysicsBody* b, const Vec2& anchr1, const Vec2& anchr2, float stiffness, float damping)
{ {
PhysicsJointSpring* joint = new (std::nothrow) PhysicsJointSpring(); auto joint = new (std::nothrow) PhysicsJointSpring();
if (joint && joint->init(a, b, anchr1, anchr2, stiffness, damping)) if (joint && joint->init(a, b))
{ {
joint->_anchr1 = anchr1;
joint->_anchr2 = anchr2;
joint->_stiffness = stiffness;
joint->_damping = damping;
return joint; return joint;
} }
CC_SAFE_DELETE(joint); CC_SAFE_DELETE(joint);
return nullptr; return nullptr;
} }
bool PhysicsJointSpring::init(PhysicsBody* a, PhysicsBody* b, const Vec2& anchr1, const Vec2& anchr2, float stiffness, float damping) bool PhysicsJointSpring::createConstraints()
{ {
do { do {
CC_BREAK_IF(!PhysicsJoint::init(a, b)); auto joint = cpDampedSpringNew(_bodyA->getCPBody(),
_bodyB->getCPBody(),
auto constraint = cpDampedSpringNew(a->getCPBody(), PhysicsHelper::point2cpv(_anchr1),
b->getCPBody(), PhysicsHelper::point2cpv(_anchr2),
PhysicsHelper::point2cpv(anchr1), PhysicsHelper::float2cpfloat(_bodyB->local2World(_anchr1).getDistance(_bodyA->local2World(_anchr2))),
PhysicsHelper::point2cpv(anchr2), PhysicsHelper::float2cpfloat(_stiffness),
PhysicsHelper::float2cpfloat(_bodyB->local2World(anchr1).getDistance(_bodyA->local2World(anchr2))), PhysicsHelper::float2cpfloat(_damping));
PhysicsHelper::float2cpfloat(stiffness),
PhysicsHelper::float2cpfloat(damping)); CC_BREAK_IF(joint == nullptr);
_cpConstraints.push_back(joint);
CC_BREAK_IF(constraint == nullptr);
_cpConstraints.push_back(constraint);
return true; return true;
} while (false); } while (false);
return false; return false;
} }
@ -437,35 +455,36 @@ void PhysicsJointSpring::setDamping(float damping)
PhysicsJointGroove* PhysicsJointGroove::construct(PhysicsBody* a, PhysicsBody* b, const Vec2& grooveA, const Vec2& grooveB, const Vec2& anchr2) PhysicsJointGroove* PhysicsJointGroove::construct(PhysicsBody* a, PhysicsBody* b, const Vec2& grooveA, const Vec2& grooveB, const Vec2& anchr2)
{ {
PhysicsJointGroove* joint = new (std::nothrow) PhysicsJointGroove(); auto joint = new (std::nothrow) PhysicsJointGroove();
if (joint && joint->init(a, b, grooveA, grooveB, anchr2)) if (joint && joint->init(a, b))
{ {
joint->_grooveA = grooveA;
joint->_grooveB = grooveB;
joint->_anchr2 = anchr2;
return joint; return joint;
} }
CC_SAFE_DELETE(joint); CC_SAFE_DELETE(joint);
return nullptr; return nullptr;
} }
bool PhysicsJointGroove::init(PhysicsBody* a, PhysicsBody* b, const Vec2& grooveA, const Vec2& grooveB, const Vec2& anchr2) bool PhysicsJointGroove::createConstraints()
{ {
do { do {
CC_BREAK_IF(!PhysicsJoint::init(a, b)); auto joint = cpGrooveJointNew(_bodyA->getCPBody(),
_bodyB->getCPBody(),
auto constraint = cpGrooveJointNew(a->getCPBody(), PhysicsHelper::point2cpv(_grooveA),
b->getCPBody(), PhysicsHelper::point2cpv(_grooveB),
PhysicsHelper::point2cpv(grooveA), PhysicsHelper::point2cpv(_anchr2));
PhysicsHelper::point2cpv(grooveB),
PhysicsHelper::point2cpv(anchr2)); CC_BREAK_IF(joint == nullptr);
_cpConstraints.push_back(joint);
CC_BREAK_IF(constraint == nullptr);
_cpConstraints.push_back(constraint);
return true; return true;
} while (false); } while (false);
return false; return false;
} }
@ -501,35 +520,35 @@ void PhysicsJointGroove::setAnchr2(const Vec2& anchr2)
PhysicsJointRotarySpring* PhysicsJointRotarySpring::construct(PhysicsBody* a, PhysicsBody* b, float stiffness, float damping) PhysicsJointRotarySpring* PhysicsJointRotarySpring::construct(PhysicsBody* a, PhysicsBody* b, float stiffness, float damping)
{ {
PhysicsJointRotarySpring* joint = new (std::nothrow) PhysicsJointRotarySpring(); auto joint = new (std::nothrow) PhysicsJointRotarySpring();
if (joint && joint->init(a, b, stiffness, damping)) if (joint && joint->init(a, b))
{ {
joint->_stiffness = stiffness;
joint->_damping = damping;
return joint; return joint;
} }
CC_SAFE_DELETE(joint); CC_SAFE_DELETE(joint);
return nullptr; return nullptr;
} }
bool PhysicsJointRotarySpring::init(PhysicsBody* a, PhysicsBody* b, float stiffness, float damping) bool PhysicsJointRotarySpring::createConstraints()
{ {
do { do {
CC_BREAK_IF(!PhysicsJoint::init(a, b)); auto joint = cpDampedRotarySpringNew(_bodyA->getCPBody(),
_bodyB->getCPBody(),
auto constraint = cpDampedRotarySpringNew(a->getCPBody(), PhysicsHelper::float2cpfloat(_bodyB->getRotation() - _bodyA->getRotation()),
b->getCPBody(), PhysicsHelper::float2cpfloat(_stiffness),
PhysicsHelper::float2cpfloat(_bodyB->getRotation() - _bodyA->getRotation()), PhysicsHelper::float2cpfloat(_damping));
PhysicsHelper::float2cpfloat(stiffness),
PhysicsHelper::float2cpfloat(damping)); CC_BREAK_IF(joint == nullptr);
_cpConstraints.push_back(joint);
CC_BREAK_IF(constraint == nullptr);
_cpConstraints.push_back(constraint);
return true; return true;
} while (false); } while (false);
return false; return false;
} }
@ -565,13 +584,16 @@ void PhysicsJointRotarySpring::setDamping(float damping)
PhysicsJointRotaryLimit* PhysicsJointRotaryLimit::construct(PhysicsBody* a, PhysicsBody* b, float min, float max) PhysicsJointRotaryLimit* PhysicsJointRotaryLimit::construct(PhysicsBody* a, PhysicsBody* b, float min, float max)
{ {
PhysicsJointRotaryLimit* joint = new (std::nothrow) PhysicsJointRotaryLimit(); auto joint = new (std::nothrow) PhysicsJointRotaryLimit();
if (joint && joint->init(a, b, min, max)) if (joint && joint->init(a, b))
{ {
joint->_min = min;
joint->_max = max;
return joint; return joint;
} }
CC_SAFE_DELETE(joint); CC_SAFE_DELETE(joint);
return nullptr; return nullptr;
} }
@ -581,24 +603,21 @@ PhysicsJointRotaryLimit* PhysicsJointRotaryLimit::construct(PhysicsBody* a, Phys
return construct(a, b, 0.0f, 0.0f); return construct(a, b, 0.0f, 0.0f);
} }
bool PhysicsJointRotaryLimit::init(PhysicsBody* a, PhysicsBody* b, float min, float max) bool PhysicsJointRotaryLimit::createConstraints()
{ {
do do
{ {
CC_BREAK_IF(!PhysicsJoint::init(a, b)); auto joint = cpRotaryLimitJointNew(_bodyA->getCPBody(),
_bodyB->getCPBody(),
auto constraint = cpRotaryLimitJointNew(a->getCPBody(), PhysicsHelper::float2cpfloat(_min),
b->getCPBody(), PhysicsHelper::float2cpfloat(_max));
PhysicsHelper::float2cpfloat(min),
PhysicsHelper::float2cpfloat(max)); CC_BREAK_IF(joint == nullptr);
_cpConstraints.push_back(joint);
CC_BREAK_IF(constraint == nullptr);
_cpConstraints.push_back(constraint);
return true; return true;
} while (false); } while (false);
return false; return false;
} }
@ -624,35 +643,35 @@ void PhysicsJointRotaryLimit::setMax(float max)
PhysicsJointRatchet* PhysicsJointRatchet::construct(PhysicsBody* a, PhysicsBody* b, float phase, float ratchet) PhysicsJointRatchet* PhysicsJointRatchet::construct(PhysicsBody* a, PhysicsBody* b, float phase, float ratchet)
{ {
PhysicsJointRatchet* joint = new (std::nothrow) PhysicsJointRatchet(); auto joint = new (std::nothrow) PhysicsJointRatchet();
if (joint && joint->init(a, b, phase, ratchet)) if (joint && joint->init(a, b))
{ {
joint->_phase = phase;
joint->_ratchet = ratchet;
return joint; return joint;
} }
CC_SAFE_DELETE(joint); CC_SAFE_DELETE(joint);
return nullptr; return nullptr;
} }
bool PhysicsJointRatchet::init(PhysicsBody* a, PhysicsBody* b, float phase, float ratchet) bool PhysicsJointRatchet::createConstraints()
{ {
do do
{ {
CC_BREAK_IF(!PhysicsJoint::init(a, b)); auto joint = cpRatchetJointNew(_bodyA->getCPBody(),
_bodyB->getCPBody(),
auto constraint = cpRatchetJointNew(a->getCPBody(), PhysicsHelper::float2cpfloat(_phase),
b->getCPBody(), PhysicsHelper::cpfloat2float(_ratchet));
PhysicsHelper::float2cpfloat(phase),
PhysicsHelper::cpfloat2float(ratchet)); CC_BREAK_IF(joint == nullptr);
_cpConstraints.push_back(joint);
CC_BREAK_IF(constraint == nullptr);
_cpConstraints.push_back(constraint);
return true; return true;
} while (false); } while (false);
return false; return false;
} }
@ -686,37 +705,37 @@ void PhysicsJointRatchet::setRatchet(float ratchet)
cpRatchetJointSetRatchet(_cpConstraints.front(), PhysicsHelper::float2cpfloat(ratchet)); cpRatchetJointSetRatchet(_cpConstraints.front(), PhysicsHelper::float2cpfloat(ratchet));
} }
PhysicsJointGear* PhysicsJointGear::construct(PhysicsBody* a, PhysicsBody* b, float phase, float ratchet) PhysicsJointGear* PhysicsJointGear::construct(PhysicsBody* a, PhysicsBody* b, float phase, float ratio)
{ {
PhysicsJointGear* joint = new (std::nothrow) PhysicsJointGear(); auto joint = new (std::nothrow) PhysicsJointGear();
if (joint && joint->init(a, b, phase, ratchet)) if (joint && joint->init(a, b))
{ {
joint->_phase = phase;
joint->_ratio = ratio;
return joint; return joint;
} }
CC_SAFE_DELETE(joint); CC_SAFE_DELETE(joint);
return nullptr; return nullptr;
} }
bool PhysicsJointGear::init(PhysicsBody* a, PhysicsBody* b, float phase, float ratio) bool PhysicsJointGear::createConstraints()
{ {
do do
{ {
CC_BREAK_IF(!PhysicsJoint::init(a, b)); auto joint = cpGearJointNew(_bodyA->getCPBody(),
_bodyB->getCPBody(),
auto constraint = cpGearJointNew(a->getCPBody(), PhysicsHelper::float2cpfloat(_phase),
b->getCPBody(), PhysicsHelper::float2cpfloat(_ratio));
PhysicsHelper::float2cpfloat(phase),
PhysicsHelper::float2cpfloat(ratio)); CC_BREAK_IF(joint == nullptr);
_cpConstraints.push_back(joint);
CC_BREAK_IF(constraint == nullptr);
_cpConstraints.push_back(constraint);
return true; return true;
} while (false); } while (false);
return false; return false;
} }
@ -742,34 +761,33 @@ void PhysicsJointGear::setRatio(float ratio)
PhysicsJointMotor* PhysicsJointMotor::construct(PhysicsBody* a, PhysicsBody* b, float rate) PhysicsJointMotor* PhysicsJointMotor::construct(PhysicsBody* a, PhysicsBody* b, float rate)
{ {
PhysicsJointMotor* joint = new (std::nothrow) PhysicsJointMotor(); auto joint = new (std::nothrow) PhysicsJointMotor();
if (joint && joint->init(a, b, rate)) if (joint && joint->init(a, b))
{ {
joint->_rate = rate;
return joint; return joint;
} }
CC_SAFE_DELETE(joint); CC_SAFE_DELETE(joint);
return nullptr; return nullptr;
} }
bool PhysicsJointMotor::init(PhysicsBody* a, PhysicsBody* b, float rate) bool PhysicsJointMotor::createConstraints()
{ {
do do
{ {
CC_BREAK_IF(!PhysicsJoint::init(a, b)); auto joint = cpSimpleMotorNew(_bodyA->getCPBody(),
_bodyB->getCPBody(),
auto constraint = cpSimpleMotorNew(a->getCPBody(), PhysicsHelper::float2cpfloat(_rate));
b->getCPBody(),
PhysicsHelper::float2cpfloat(rate)); CC_BREAK_IF(joint == nullptr);
_cpConstraints.push_back(joint);
CC_BREAK_IF(constraint == nullptr);
_cpConstraints.push_back(constraint);
return true; return true;
} while (false); } while (false);
return false; return false;
} }

View File

@ -62,58 +62,62 @@ public:
void setCollisionEnable(bool enable); void setCollisionEnable(bool enable);
/** Remove the joint from the world */ /** Remove the joint from the world */
void removeFormWorld(); void removeFormWorld();
/** Distory the joint*/
static void destroy(PhysicsJoint* joint);
/** Set the max force between two bodies */ /** Set the max force between two bodies */
void setMaxForce(float force); void setMaxForce(float force);
/** Get the max force setting */ /** Get the max force setting */
float getMaxForce() const; float getMaxForce() const { return _maxForce; }
protected: protected:
bool init(PhysicsBody* a, PhysicsBody* b); bool init(PhysicsBody* a, PhysicsBody* b);
Node* getBodyNode(PhysicsBody* body) const;
bool initJoint();
protected: virtual bool createConstraints() { return false; }
std::vector<cpConstraint*> _cpConstraints;
PhysicsBody* _bodyA; PhysicsBody* _bodyA;
PhysicsBody* _bodyB; PhysicsBody* _bodyB;
PhysicsWorld* _world; PhysicsWorld* _world;
std::vector<cpConstraint*> _cpConstraints;
bool _enable; bool _enable;
bool _collisionEnable; bool _collisionEnable;
bool _destoryMark; bool _destoryMark;
int _tag; int _tag;
float _maxForce;
bool _initDirty;
friend class PhysicsBody; friend class PhysicsBody;
friend class PhysicsWorld; friend class PhysicsWorld;
friend class PhysicsDebugDraw; friend class PhysicsDebugDraw;
}; };
/* /*
* @brief A fixed joint fuses the two bodies together at a reference point. Fixed joints are useful for creating complex shapes that can be broken apart later. * @brief A fixed joint fuses the two bodies together at a reference point. Fixed joints are useful for creating complex shapes that can be broken apart later.
*/ */
class CC_DLL PhysicsJointFixed : public PhysicsJoint class CC_DLL PhysicsJointFixed : public PhysicsJoint
{ {
public: public:
static PhysicsJointFixed* construct(PhysicsBody* a, PhysicsBody* b, const Vec2& anchr); static PhysicsJointFixed* construct(PhysicsBody* a, PhysicsBody* b, const Vec2& anchr);
protected: virtual bool createConstraints() override;
bool init(PhysicsBody* a, PhysicsBody* b, const Vec2& anchr);
protected: protected:
PhysicsJointFixed() {} PhysicsJointFixed() {}
virtual ~PhysicsJointFixed() {} virtual ~PhysicsJointFixed() {}
Vec2 _anchr;
}; };
/* /*
* @brief A limit joint imposes a maximum distance between the two bodies, as if they were connected by a rope. * @brief A limit joint imposes a maximum distance between the two bodies, as if they were connected by a rope.
*/ */
class CC_DLL PhysicsJointLimit : public PhysicsJoint class CC_DLL PhysicsJointLimit : public PhysicsJoint
{ {
public: public:
static PhysicsJointLimit* construct(PhysicsBody* a, PhysicsBody* b, const Vec2& anchr1, const Vec2& anchr2); static PhysicsJointLimit* construct(PhysicsBody* a, PhysicsBody* b, const Vec2& anchr1, const Vec2& anchr2);
static PhysicsJointLimit* construct(PhysicsBody* a, PhysicsBody* b, const Vec2& anchr1, const Vec2& anchr2, float min, float max); static PhysicsJointLimit* construct(PhysicsBody* a, PhysicsBody* b, const Vec2& anchr1, const Vec2& anchr2, float min, float max);
Vec2 getAnchr1() const; Vec2 getAnchr1() const;
void setAnchr1(const Vec2& anchr1); void setAnchr1(const Vec2& anchr1);
Vec2 getAnchr2() const; Vec2 getAnchr2() const;
@ -122,29 +126,37 @@ public:
void setMin(float min); void setMin(float min);
float getMax() const; float getMax() const;
void setMax(float max); void setMax(float max);
protected: virtual bool createConstraints() override;
bool init(PhysicsBody* a, PhysicsBody* b, const Vec2& anchr1, const Vec2& anchr2, float min, float max);
protected: protected:
PhysicsJointLimit() {} PhysicsJointLimit() {}
virtual ~PhysicsJointLimit() {} virtual ~PhysicsJointLimit() {}
Vec2 _anchr1;
Vec2 _anchr2;
float _min;
float _max;
}; };
/* /*
* @brief A pin joint allows the two bodies to independently rotate around the anchor point as if pinned together. * @brief A pin joint allows the two bodies to independently rotate around the anchor point as if pinned together.
*/ */
class CC_DLL PhysicsJointPin : public PhysicsJoint class CC_DLL PhysicsJointPin : public PhysicsJoint
{ {
public: public:
static PhysicsJointPin* construct(PhysicsBody* a, PhysicsBody* b, const Vec2& anchr); static PhysicsJointPin* construct(PhysicsBody* a, PhysicsBody* b, const Vec2& pivot);
static PhysicsJointPin* construct(PhysicsBody* a, PhysicsBody* b, const Vec2& anchr1, const Vec2& anchr2);
protected:
bool init(PhysicsBody* a, PhysicsBody* b, const Vec2& anchr); virtual bool createConstraints() override;
protected: protected:
PhysicsJointPin() {} PhysicsJointPin() {}
virtual ~PhysicsJointPin() {} virtual ~PhysicsJointPin() {}
bool _useSpecificAnchr;
Vec2 _anchr1;
Vec2 _anchr2;
}; };
/** Set the fixed distance with two bodies */ /** Set the fixed distance with two bodies */
@ -152,16 +164,17 @@ class CC_DLL PhysicsJointDistance : public PhysicsJoint
{ {
public: public:
static PhysicsJointDistance* construct(PhysicsBody* a, PhysicsBody* b, const Vec2& anchr1, const Vec2& anchr2); static PhysicsJointDistance* construct(PhysicsBody* a, PhysicsBody* b, const Vec2& anchr1, const Vec2& anchr2);
float getDistance() const; float getDistance() const;
void setDistance(float distance); void setDistance(float distance);
virtual bool createConstraints() override;
protected:
bool init(PhysicsBody* a, PhysicsBody* b, const Vec2& anchr1, const Vec2& anchr2);
protected: protected:
PhysicsJointDistance() {} PhysicsJointDistance() {}
virtual ~PhysicsJointDistance() {} virtual ~PhysicsJointDistance() {}
Vec2 _anchr1;
Vec2 _anchr2;
}; };
/** Connecting two physics bodies together with a spring. */ /** Connecting two physics bodies together with a spring. */
@ -179,13 +192,16 @@ public:
void setStiffness(float stiffness); void setStiffness(float stiffness);
float getDamping() const; float getDamping() const;
void setDamping(float damping); void setDamping(float damping);
virtual bool createConstraints() override;
protected:
bool init(PhysicsBody* a, PhysicsBody* b, const Vec2& anchr1, const Vec2& anchr2, float stiffness, float damping);
protected: protected:
PhysicsJointSpring() {} PhysicsJointSpring() {}
virtual ~PhysicsJointSpring() {} virtual ~PhysicsJointSpring() {}
Vec2 _anchr1;
Vec2 _anchr2;
float _stiffness;
float _damping;
}; };
/** Attach body a to a line, and attach body b to a dot */ /** Attach body a to a line, and attach body b to a dot */
@ -193,20 +209,22 @@ class CC_DLL PhysicsJointGroove : public PhysicsJoint
{ {
public: public:
static PhysicsJointGroove* construct(PhysicsBody* a, PhysicsBody* b, const Vec2& grooveA, const Vec2& grooveB, const Vec2& anchr2); static PhysicsJointGroove* construct(PhysicsBody* a, PhysicsBody* b, const Vec2& grooveA, const Vec2& grooveB, const Vec2& anchr2);
Vec2 getGrooveA() const; Vec2 getGrooveA() const;
void setGrooveA(const Vec2& grooveA); void setGrooveA(const Vec2& grooveA);
Vec2 getGrooveB() const; Vec2 getGrooveB() const;
void setGrooveB(const Vec2& grooveB); void setGrooveB(const Vec2& grooveB);
Vec2 getAnchr2() const; Vec2 getAnchr2() const;
void setAnchr2(const Vec2& anchr2); void setAnchr2(const Vec2& anchr2);
virtual bool createConstraints() override;
protected:
bool init(PhysicsBody* a, PhysicsBody* b, const Vec2& grooveA, const Vec2& grooveB, const Vec2& anchr);
protected: protected:
PhysicsJointGroove() {} PhysicsJointGroove() {}
virtual ~PhysicsJointGroove() {} virtual ~PhysicsJointGroove() {}
Vec2 _grooveA;
Vec2 _grooveB;
Vec2 _anchr2;
}; };
/** Likes a spring joint, but works with rotary */ /** Likes a spring joint, but works with rotary */
@ -214,20 +232,21 @@ class CC_DLL PhysicsJointRotarySpring : public PhysicsJoint
{ {
public: public:
static PhysicsJointRotarySpring* construct(PhysicsBody* a, PhysicsBody* b, float stiffness, float damping); static PhysicsJointRotarySpring* construct(PhysicsBody* a, PhysicsBody* b, float stiffness, float damping);
float getRestAngle() const; float getRestAngle() const;
void setRestAngle(float restAngle); void setRestAngle(float restAngle);
float getStiffness() const; float getStiffness() const;
void setStiffness(float stiffness); void setStiffness(float stiffness);
float getDamping() const; float getDamping() const;
void setDamping(float damping); void setDamping(float damping);
virtual bool createConstraints() override;
protected:
bool init(PhysicsBody* a, PhysicsBody* b, float stiffness, float damping);
protected: protected:
PhysicsJointRotarySpring() {} PhysicsJointRotarySpring() {}
virtual ~PhysicsJointRotarySpring() {} virtual ~PhysicsJointRotarySpring() {}
float _stiffness;
float _damping;
}; };
/** Likes a limit joint, but works with rotary */ /** Likes a limit joint, but works with rotary */
@ -236,18 +255,19 @@ class CC_DLL PhysicsJointRotaryLimit : public PhysicsJoint
public: public:
static PhysicsJointRotaryLimit* construct(PhysicsBody* a, PhysicsBody* b, float min, float max); static PhysicsJointRotaryLimit* construct(PhysicsBody* a, PhysicsBody* b, float min, float max);
static PhysicsJointRotaryLimit* construct(PhysicsBody* a, PhysicsBody* b); static PhysicsJointRotaryLimit* construct(PhysicsBody* a, PhysicsBody* b);
float getMin() const; float getMin() const;
void setMin(float min); void setMin(float min);
float getMax() const; float getMax() const;
void setMax(float max); void setMax(float max);
virtual bool createConstraints() override;
protected:
bool init(PhysicsBody* a, PhysicsBody* b, float min, float max);
protected: protected:
PhysicsJointRotaryLimit() {} PhysicsJointRotaryLimit() {}
virtual ~PhysicsJointRotaryLimit() {} virtual ~PhysicsJointRotaryLimit() {}
float _min;
float _max;
}; };
/** Works like a socket wrench. */ /** Works like a socket wrench. */
@ -255,20 +275,21 @@ class CC_DLL PhysicsJointRatchet : public PhysicsJoint
{ {
public: public:
static PhysicsJointRatchet* construct(PhysicsBody* a, PhysicsBody* b, float phase, float ratchet); static PhysicsJointRatchet* construct(PhysicsBody* a, PhysicsBody* b, float phase, float ratchet);
float getAngle() const; float getAngle() const;
void setAngle(float angle); void setAngle(float angle);
float getPhase() const; float getPhase() const;
void setPhase(float phase); void setPhase(float phase);
float getRatchet() const; float getRatchet() const;
void setRatchet(float ratchet); void setRatchet(float ratchet);
virtual bool createConstraints() override;
protected:
bool init(PhysicsBody* a, PhysicsBody* b, float phase, float ratchet);
protected: protected:
PhysicsJointRatchet() {} PhysicsJointRatchet() {}
virtual ~PhysicsJointRatchet() {} virtual ~PhysicsJointRatchet() {}
float _phase;
float _ratchet;
}; };
/** Keeps the angular velocity ratio of a pair of bodies constant. */ /** Keeps the angular velocity ratio of a pair of bodies constant. */
@ -276,18 +297,20 @@ class CC_DLL PhysicsJointGear : public PhysicsJoint
{ {
public: public:
static PhysicsJointGear* construct(PhysicsBody* a, PhysicsBody* b, float phase, float ratio); static PhysicsJointGear* construct(PhysicsBody* a, PhysicsBody* b, float phase, float ratio);
float getPhase() const; float getPhase() const;
void setPhase(float phase); void setPhase(float phase);
float getRatio() const; float getRatio() const;
void setRatio(float ratchet); void setRatio(float ratchet);
protected: virtual bool createConstraints() override;
bool init(PhysicsBody* a, PhysicsBody* b, float phase, float ratio);
protected: protected:
PhysicsJointGear() {} PhysicsJointGear() {}
virtual ~PhysicsJointGear() {} virtual ~PhysicsJointGear() {}
float _phase;
float _ratio;
}; };
/** Keeps the relative angular velocity of a pair of bodies constant */ /** Keeps the relative angular velocity of a pair of bodies constant */
@ -295,16 +318,16 @@ class CC_DLL PhysicsJointMotor : public PhysicsJoint
{ {
public: public:
static PhysicsJointMotor* construct(PhysicsBody* a, PhysicsBody* b, float rate); static PhysicsJointMotor* construct(PhysicsBody* a, PhysicsBody* b, float rate);
float getRate() const; float getRate() const;
void setRate(float rate); void setRate(float rate);
virtual bool createConstraints() override;
protected:
bool init(PhysicsBody* a, PhysicsBody* b, float rate);
protected: protected:
PhysicsJointMotor() {} PhysicsJointMotor() {}
virtual ~PhysicsJointMotor() {} virtual ~PhysicsJointMotor() {}
float _rate;
}; };
NS_CC_END NS_CC_END

View File

@ -50,7 +50,6 @@ PhysicsShape::PhysicsShape()
, _scaleY(1.0f) , _scaleY(1.0f)
, _newScaleX(1.0f) , _newScaleX(1.0f)
, _newScaleY(1.0f) , _newScaleY(1.0f)
, _dirty(false)
, _tag(0) , _tag(0)
, _categoryBitmask(UINT_MAX) , _categoryBitmask(UINT_MAX)
, _collisionBitmask(UINT_MAX) , _collisionBitmask(UINT_MAX)
@ -112,50 +111,25 @@ void PhysicsShape::setMaterial(const PhysicsMaterial& material)
setFriction(material.friction); setFriction(material.friction);
} }
void PhysicsShape::setScale(float scale)
{
setScaleX(scale);
setScaleY(scale);
}
void PhysicsShape::setScale(float scaleX, float scaleY) void PhysicsShape::setScale(float scaleX, float scaleY)
{ {
setScaleX(scaleX); if (_scaleX != scaleX || _scaleY != scaleY)
setScaleY(scaleY); {
if (_type == Type::CIRCLE && scaleX != scaleY)
{
CCLOG("PhysicsShapeCircle WARNING: CANNOT support setScale with different x and y");
return;
}
_newScaleX = scaleX;
_newScaleY = scaleY;
updateScale();
}
} }
void PhysicsShape::setScaleX(float scaleX) void PhysicsShape::updateScale()
{ {
if (_scaleX == scaleX) _scaleX = _newScaleX;
{ _scaleY = _newScaleY;
return;
}
_newScaleX = scaleX;
_dirty = true;
}
void PhysicsShape::setScaleY(float scaleY)
{
if (_scaleY == scaleY)
{
return;
}
_newScaleY = scaleY;
_dirty = true;
}
void PhysicsShape::update(float delta)
{
CC_UNUSED_PARAM(delta);
if (_dirty)
{
_scaleX = _newScaleX;
_scaleY = _newScaleY;
_dirty = false;
}
} }
void PhysicsShape::addShape(cpShape* shape) void PhysicsShape::addShape(cpShape* shape)
@ -399,63 +373,18 @@ Vec2 PhysicsShapeCircle::getOffset()
return PhysicsHelper::cpv2point(cpCircleShapeGetOffset(_cpShapes.front())); return PhysicsHelper::cpv2point(cpCircleShapeGetOffset(_cpShapes.front()));
} }
void PhysicsShapeCircle::setScale(float scale) void PhysicsShapeCircle::updateScale()
{ {
if (_scaleX == scale) cpFloat factor = std::abs(PhysicsHelper::float2cpfloat(_newScaleX / _scaleX));
{
return;
}
_newScaleX = _newScaleY = scale;
_dirty = true;
}
void PhysicsShapeCircle::setScale(float scaleX, float scaleY) cpShape* shape = _cpShapes.front();
{ cpVect v = cpCircleShapeGetOffset(shape);
if (scaleX != scaleY) v = cpvmult(v, PhysicsHelper::float2cpfloat(factor));
{ ((cpCircleShape*)shape)->c = v;
CCLOG("PhysicsShapeCircle WARNING: CANNOT support setScale with different x and y");
}
if (_scaleX == scaleX)
{
return;
}
_newScaleX = _newScaleY = scaleX;
_dirty = true;
}
void PhysicsShapeCircle::setScaleX(float scale) cpCircleShapeSetRadius(shape, cpCircleShapeGetRadius(shape) * factor);
{
CCLOG("PhysicsShapeCircle WARNING: CANNOT support setScaleX");
setScale(scale);
}
void PhysicsShapeCircle::setScaleY(float scale) PhysicsShape::updateScale();
{
CCLOG("PhysicsShapeCircle WARNING: CANNOT support setScaleY");
setScale(scale);
}
void PhysicsShapeCircle::update(float delta)
{
if (_dirty)
{
cpFloat factor = std::abs(PhysicsHelper::float2cpfloat( _newScaleX / _scaleX ));
auto shape = _cpShapes.front();
auto v = cpCircleShapeGetOffset(shape);
v = cpvmult(v, PhysicsHelper::float2cpfloat(factor));
((cpCircleShape*)shape)->c = v;
cpCircleShapeSetRadius(shape, cpCircleShapeGetRadius(shape) * factor);
}
PhysicsShape::update(delta);
} }
// PhysicsShapeEdgeSegment // PhysicsShapeEdgeSegment
@ -515,24 +444,21 @@ Vec2 PhysicsShapeEdgeSegment::getCenter()
return ( a + b ) / 2; return ( a + b ) / 2;
} }
void PhysicsShapeEdgeSegment::update(float delta) void PhysicsShapeEdgeSegment::updateScale()
{ {
if (_dirty) cpFloat factorX = PhysicsHelper::float2cpfloat(_newScaleX / _scaleX);
{ cpFloat factorY = PhysicsHelper::float2cpfloat(_newScaleY / _scaleY);
auto factorX = PhysicsHelper::float2cpfloat(_newScaleX / _scaleX);
auto factorY = PhysicsHelper::float2cpfloat(_newScaleY / _scaleY); cpShape* shape = _cpShapes.front();
cpVect a = cpSegmentShapeGetA(shape);
auto shape = _cpShapes.front(); a.x *= factorX;
auto a = cpSegmentShapeGetA(shape); a.y *= factorY;
a.x *= factorX; cpVect b = cpSegmentShapeGetB(shape);
a.y *= factorY; b.x *= factorX;
auto b = cpSegmentShapeGetB(shape); b.y *= factorY;
b.x *= factorX; cpSegmentShapeSetEndpoints(shape, a, b);
b.y *= factorY;
cpSegmentShapeSetEndpoints(shape, a, b); PhysicsShape::updateScale();
}
PhysicsShape::update(delta);
} }
// PhysicsShapeBox // PhysicsShapeBox
@ -682,45 +608,42 @@ Vec2 PhysicsShapePolygon::getCenter()
return PhysicsHelper::cpv2point(cpCentroidForPoly(((cpPolyShape*)_cpShapes.front())->numVerts, ((cpPolyShape*)_cpShapes.front())->verts)); return PhysicsHelper::cpv2point(cpCentroidForPoly(((cpPolyShape*)_cpShapes.front())->numVerts, ((cpPolyShape*)_cpShapes.front())->verts));
} }
void PhysicsShapePolygon::update(float delta) void PhysicsShapePolygon::updateScale()
{ {
if (_dirty) cpFloat factorX = PhysicsHelper::float2cpfloat(_newScaleX / _scaleX);
{ cpFloat factorY = PhysicsHelper::float2cpfloat(_newScaleY / _scaleY);
cpFloat factorX = PhysicsHelper::float2cpfloat( _newScaleX / _scaleX );
cpFloat factorY = PhysicsHelper::float2cpfloat( _newScaleY / _scaleY );
auto shape = _cpShapes.front();
int count = cpPolyShapeGetNumVerts(shape);
cpVect* vects = ((cpPolyShape*)shape)->verts;
cpSplittingPlane* planes = ((cpPolyShape*)shape)->planes;
for (int i = 0; i < count ; ++i) auto shape = _cpShapes.front();
int count = cpPolyShapeGetNumVerts(shape);
cpVect* vects = ((cpPolyShape*)shape)->verts;
cpSplittingPlane* planes = ((cpPolyShape*)shape)->planes;
for (int i = 0; i < count; ++i)
{
vects[i].x *= factorX;
vects[i].y *= factorY;
}
// convert hole to clockwise
if (factorX * factorY < 0)
{
for (int i = 0; i < count / 2; ++i)
{ {
vects[i].x *= factorX; cpVect v = vects[i];
vects[i].y *= factorY; vects[i] = vects[count - i - 1];
} vects[count - i - 1] = v;
// convert hole to clockwise
if ( factorX * factorY < 0 )
{
for (int i = 0; i < count / 2; ++i)
{
cpVect v = vects[i];
vects[i] = vects[count - i - 1];
vects[count - i - 1] = v;
}
}
for (int i = 0; i < count; ++i)
{
cpVect n = cpvnormalize(cpvperp(cpvsub(vects[i], vects[(i + 1) % count])));
planes[i].n = n;
planes[i].d = cpvdot(n, vects[i]);
} }
} }
for (int i = 0; i < count; ++i)
{
cpVect n = cpvnormalize(cpvperp(cpvsub(vects[i], vects[(i + 1) % count])));
planes[i].n = n;
planes[i].d = cpvdot(n, vects[i]);
}
PhysicsShape::update(delta); PhysicsShape::updateScale();
} }
// PhysicsShapeEdgeBox // PhysicsShapeEdgeBox
@ -865,26 +788,23 @@ PhysicsShapeEdgeChain* PhysicsShapeEdgeChain::create(const Vec2* points, int cou
return nullptr; return nullptr;
} }
void PhysicsShapeEdgePolygon::update(float delta) void PhysicsShapeEdgePolygon::updateScale()
{ {
if (_dirty) cpFloat factorX = PhysicsHelper::float2cpfloat(_newScaleX / _scaleX);
cpFloat factorY = PhysicsHelper::float2cpfloat(_newScaleY / _scaleY);
for (auto shape : _cpShapes)
{ {
cpFloat factorX = PhysicsHelper::float2cpfloat(_newScaleX / _scaleX); cpVect a = cpSegmentShapeGetA(shape);
cpFloat factorY = PhysicsHelper::float2cpfloat(_newScaleY / _scaleY); a.x *= factorX;
a.y *= factorY;
for(auto shape : _cpShapes) cpVect b = cpSegmentShapeGetB(shape);
{ b.x *= factorX;
cpVect a = cpSegmentShapeGetA(shape); b.y *= factorY;
a.x *= factorX; cpSegmentShapeSetEndpoints(shape, a, b);
a.y *= factorY;
cpVect b = cpSegmentShapeGetB(shape);
b.x *= factorX;
b.y *= factorY;
cpSegmentShapeSetEndpoints(shape, a, b);
}
} }
PhysicsShape::update(delta); PhysicsShape::updateScale();
} }
bool PhysicsShapeEdgeChain::init(const Vec2* points, int count, const PhysicsMaterial& material/* = MaterialDefault*/, float border/* = 1*/) bool PhysicsShapeEdgeChain::init(const Vec2* points, int count, const PhysicsMaterial& material/* = MaterialDefault*/, float border/* = 1*/)
@ -957,26 +877,23 @@ int PhysicsShapeEdgeChain::getPointsCount() const
return static_cast<int>(_cpShapes.size() + 1); return static_cast<int>(_cpShapes.size() + 1);
} }
void PhysicsShapeEdgeChain::update(float delta) void PhysicsShapeEdgeChain::updateScale()
{ {
if (_dirty) cpFloat factorX = PhysicsHelper::float2cpfloat(_newScaleX / _scaleX);
cpFloat factorY = PhysicsHelper::float2cpfloat(_newScaleY / _scaleY);
for (auto shape : _cpShapes)
{ {
cpFloat factorX = PhysicsHelper::float2cpfloat(_newScaleX / _scaleX); cpVect a = cpSegmentShapeGetA(shape);
cpFloat factorY = PhysicsHelper::float2cpfloat(_newScaleY / _scaleY); a.x *= factorX;
a.y *= factorY;
for(auto shape : _cpShapes) cpVect b = cpSegmentShapeGetB(shape);
{ b.x *= factorX;
cpVect a = cpSegmentShapeGetA(shape); b.y *= factorY;
a.x *= factorX; cpSegmentShapeSetEndpoints(shape, a, b);
a.y *= factorY;
cpVect b = cpSegmentShapeGetB(shape);
b.x *= factorX;
b.y *= factorY;
cpSegmentShapeSetEndpoints(shape, a, b);
}
} }
PhysicsShape::update(delta); PhysicsShape::updateScale();
} }
void PhysicsShape::setGroup(int group) void PhysicsShape::setGroup(int group)

View File

@ -56,7 +56,7 @@ typedef struct CC_DLL PhysicsMaterial
{} {}
}PhysicsMaterial; }PhysicsMaterial;
const PhysicsMaterial PHYSICSSHAPE_MATERIAL_DEFAULT(0.0f, 0.5f, 0.5f); const PhysicsMaterial PHYSICSSHAPE_MATERIAL_DEFAULT;
/** /**
* @brief A shape for body. You do not create PhysicsWorld objects directly, instead, you can view PhysicsBody to see how to create it. * @brief A shape for body. You do not create PhysicsWorld objects directly, instead, you can view PhysicsBody to see how to create it.
@ -153,11 +153,8 @@ protected:
/** calculate the area of this shape */ /** calculate the area of this shape */
virtual float calculateArea() { return 0.0f; } virtual float calculateArea() { return 0.0f; }
virtual void setScale(float scale);
virtual void setScale(float scaleX, float scaleY); virtual void setScale(float scaleX, float scaleY);
virtual void setScaleX(float scaleX); virtual void updateScale();
virtual void setScaleY(float scaleY);
virtual void update(float delta);
void addShape(cpShape* shape); void addShape(cpShape* shape);
protected: protected:
@ -176,7 +173,6 @@ protected:
float _scaleY; float _scaleY;
float _newScaleX; float _newScaleX;
float _newScaleY; float _newScaleY;
bool _dirty;
PhysicsMaterial _material; PhysicsMaterial _material;
int _tag; int _tag;
int _categoryBitmask; int _categoryBitmask;
@ -206,11 +202,7 @@ public:
protected: protected:
bool init(float radius, const PhysicsMaterial& material = PHYSICSSHAPE_MATERIAL_DEFAULT, const Vec2& offset = Vec2::ZERO); bool init(float radius, const PhysicsMaterial& material = PHYSICSSHAPE_MATERIAL_DEFAULT, const Vec2& offset = Vec2::ZERO);
virtual float calculateArea() override; virtual float calculateArea() override;
virtual void setScale(float scale) override; virtual void updateScale() override;
virtual void setScale(float scaleX, float scaleY) override;
virtual void setScaleX(float scale) override;
virtual void setScaleY(float scale) override;
virtual void update(float delta) override;
protected: protected:
PhysicsShapeCircle(); PhysicsShapeCircle();
@ -234,7 +226,7 @@ public:
protected: protected:
bool init(const Vec2* points, int count, const PhysicsMaterial& material = PHYSICSSHAPE_MATERIAL_DEFAULT, const Vec2& offset = Vec2::ZERO); bool init(const Vec2* points, int count, const PhysicsMaterial& material = PHYSICSSHAPE_MATERIAL_DEFAULT, const Vec2& offset = Vec2::ZERO);
float calculateArea() override; float calculateArea() override;
virtual void update(float delta) override; virtual void updateScale() override;
protected: protected:
PhysicsShapePolygon(); PhysicsShapePolygon();
@ -270,7 +262,7 @@ public:
protected: protected:
bool init(const Vec2& a, const Vec2& b, const PhysicsMaterial& material = PHYSICSSHAPE_MATERIAL_DEFAULT, float border = 1); bool init(const Vec2& a, const Vec2& b, const PhysicsMaterial& material = PHYSICSSHAPE_MATERIAL_DEFAULT, float border = 1);
virtual void update(float delta) override; virtual void updateScale() override;
protected: protected:
PhysicsShapeEdgeSegment(); PhysicsShapeEdgeSegment();
@ -290,7 +282,7 @@ public:
protected: protected:
bool init(const Vec2* points, int count, const PhysicsMaterial& material = PHYSICSSHAPE_MATERIAL_DEFAULT, float border = 1); bool init(const Vec2* points, int count, const PhysicsMaterial& material = PHYSICSSHAPE_MATERIAL_DEFAULT, float border = 1);
virtual void update(float delta) override; virtual void updateScale() override;
protected: protected:
PhysicsShapeEdgePolygon(); PhysicsShapeEdgePolygon();
@ -327,7 +319,7 @@ public:
protected: protected:
bool init(const Vec2* points, int count, const PhysicsMaterial& material = PHYSICSSHAPE_MATERIAL_DEFAULT, float border = 1); bool init(const Vec2* points, int count, const PhysicsMaterial& material = PHYSICSSHAPE_MATERIAL_DEFAULT, float border = 1);
virtual void update(float delta) override; virtual void updateScale() override;
protected: protected:
PhysicsShapeEdgeChain(); PhysicsShapeEdgeChain();

View File

@ -481,7 +481,6 @@ void PhysicsWorld::doAddBody(PhysicsBody* body)
} }
} }
void PhysicsWorld::addBodyOrDelay(PhysicsBody* body) void PhysicsWorld::addBodyOrDelay(PhysicsBody* body)
{ {
auto removeBodyIter = _delayRemoveBodies.find(body); auto removeBodyIter = _delayRemoveBodies.find(body);
@ -491,17 +490,10 @@ void PhysicsWorld::addBodyOrDelay(PhysicsBody* body)
return; return;
} }
if (cpSpaceIsLocked(_cpSpace)) if (_delayAddBodies.find(body) == _delayAddBodies.end())
{ {
if (_delayAddBodies.find(body) == _delayAddBodies.end()) _delayAddBodies.pushBack(body);
{ _delayDirty = true;
_delayAddBodies.pushBack(body);
_delayDirty = true;
}
}
else
{
doAddBody(body);
} }
} }
@ -542,7 +534,6 @@ void PhysicsWorld::removeBody(int tag)
void PhysicsWorld::removeBody(PhysicsBody* body) void PhysicsWorld::removeBody(PhysicsBody* body)
{ {
if (body->getWorld() != this) if (body->getWorld() != this)
{ {
CCLOG("Physics Warnning: this body doesn't belong to this world"); CCLOG("Physics Warnning: this body doesn't belong to this world");
@ -550,25 +541,11 @@ void PhysicsWorld::removeBody(PhysicsBody* body)
} }
// destory the body's joints // destory the body's joints
for (auto joint : body->_joints) auto removeCopy = body->_joints;
for (auto joint : removeCopy)
{ {
// set destroy param to false to keep the iterator available removeJoint(joint, true);
removeJoint(joint, false);
PhysicsBody* other = (joint->getBodyA() == body ? joint->getBodyB() : joint->getBodyA());
other->removeJoint(joint);
// test the distraction is delaied or not
if (std::find(_delayRemoveJoints.rbegin(), _delayRemoveJoints.rend(), joint) != _delayRemoveJoints.rend())
{
joint->_destoryMark = true;
}
else
{
delete joint;
}
} }
body->_joints.clear(); body->_joints.clear();
removeBodyOrDelay(body); removeBodyOrDelay(body);
@ -598,54 +575,35 @@ void PhysicsWorld::removeBodyOrDelay(PhysicsBody* body)
} }
} }
void PhysicsWorld::doAddJoint(PhysicsJoint *joint) void PhysicsWorld::removeJoint(PhysicsJoint* joint, bool destroy)
{ {
if (joint) if (joint)
{ {
for (auto constraint : joint->_cpConstraints) if (joint->getWorld() != this && destroy)
{
cpSpaceAddConstraint(_cpSpace, constraint);
}
}
}
void PhysicsWorld::removeJoint(PhysicsJoint* joint, bool destroy)
{
if (joint->getWorld() != this)
{
if (destroy)
{ {
CCLOG("physics warnning: the joint is not in this world, it won't be destoried utill the body it conntect is destoried"); CCLOG("physics warnning: the joint is not in this world, it won't be destoried utill the body it conntect is destoried");
return;
} }
return;
} joint->_destoryMark = destroy;
if (cpSpaceIsLocked(_cpSpace))
removeJointOrDelay(joint);
_joints.remove(joint);
joint->_world = nullptr;
// clean the connection to this joint
if (destroy)
{
if (joint->getBodyA() != nullptr)
{ {
joint->getBodyA()->removeJoint(joint); auto it = std::find(_delayAddJoints.begin(), _delayAddJoints.end(), joint);
} if (it != _delayAddJoints.end())
{
if (joint->getBodyB() != nullptr) _delayAddJoints.erase(it);
{ return;
joint->getBodyB()->removeJoint(joint); }
}
if (std::find(_delayRemoveJoints.rbegin(), _delayRemoveJoints.rend(), joint) == _delayRemoveJoints.rend())
// test the distraction is delaied or not {
if (std::find(_delayRemoveJoints.rbegin(), _delayRemoveJoints.rend(), joint) != _delayRemoveJoints.rend()) _delayRemoveJoints.push_back(joint);
{ _delayDirty = true;
joint->_destoryMark = true; }
} }
else else
{ {
delete joint; doRemoveJoint(joint);
} }
} }
} }
@ -657,24 +615,25 @@ void PhysicsWorld::updateJoints()
return; return;
} }
auto addCopy = _delayAddJoints; for (auto joint : _delayAddJoints)
_delayAddJoints.clear();
for (auto joint : addCopy)
{ {
doAddJoint(joint); joint->_world = this;
} if (joint->initJoint())
{
auto removeCopy = _delayRemoveJoints; _joints.push_back(joint);
_delayRemoveJoints.clear(); }
for (auto joint : removeCopy) else
{
doRemoveJoint(joint);
if (joint->_destoryMark)
{ {
delete joint; delete joint;
} }
} }
_delayAddJoints.clear();
for (auto joint : _delayRemoveJoints)
{
doRemoveJoint(joint);
}
_delayRemoveJoints.clear();
} }
void PhysicsWorld::removeShape(PhysicsShape* shape) void PhysicsWorld::removeShape(PhysicsShape* shape)
@ -691,95 +650,37 @@ void PhysicsWorld::removeShape(PhysicsShape* shape)
} }
} }
void PhysicsWorld::addJointOrDelay(PhysicsJoint* joint) void PhysicsWorld::addJoint(PhysicsJoint* joint)
{ {
auto it = std::find(_delayRemoveJoints.begin(), _delayRemoveJoints.end(), joint); if (joint)
if (it != _delayRemoveJoints.end())
{
_delayRemoveJoints.erase(it);
return;
}
if (cpSpaceIsLocked(_cpSpace))
{ {
if (joint->getWorld() && joint->getWorld() != this)
{
joint->removeFormWorld();
}
auto it = std::find(_delayRemoveJoints.begin(), _delayRemoveJoints.end(), joint);
if (it != _delayRemoveJoints.end())
{
_delayRemoveJoints.erase(it);
return;
}
if (std::find(_delayAddJoints.begin(), _delayAddJoints.end(), joint) == _delayAddJoints.end()) if (std::find(_delayAddJoints.begin(), _delayAddJoints.end(), joint) == _delayAddJoints.end())
{ {
_delayAddJoints.push_back(joint); _delayAddJoints.push_back(joint);
_delayDirty = true; _delayDirty = true;
} }
}else
{
doAddJoint(joint);
} }
} }
void PhysicsWorld::removeJointOrDelay(PhysicsJoint* joint)
{
auto it = std::find(_delayAddJoints.begin(), _delayAddJoints.end(), joint);
if (it != _delayAddJoints.end())
{
_delayAddJoints.erase(it);
return;
}
if (cpSpaceIsLocked(_cpSpace))
{
if (std::find(_delayRemoveJoints.rbegin(), _delayRemoveJoints.rend(), joint) == _delayRemoveJoints.rend())
{
_delayRemoveJoints.push_back(joint);
_delayDirty = true;
}
}else
{
doRemoveJoint(joint);
}
}
void PhysicsWorld::addJoint(PhysicsJoint* joint)
{
if (joint->getWorld() != nullptr && joint->getWorld() != this)
{
joint->removeFormWorld();
}
addJointOrDelay(joint);
_joints.push_back(joint);
joint->_world = this;
}
void PhysicsWorld::removeAllJoints(bool destroy) void PhysicsWorld::removeAllJoints(bool destroy)
{ {
for (auto joint : _joints) auto removeCopy = _joints;
for (auto joint : removeCopy)
{ {
removeJointOrDelay(joint); removeJoint(joint, destroy);
joint->_world = nullptr;
// clean the connection to this joint
if (destroy)
{
if (joint->getBodyA() != nullptr)
{
joint->getBodyA()->removeJoint(joint);
}
if (joint->getBodyB() != nullptr)
{
joint->getBodyB()->removeJoint(joint);
}
// test the distraction is delaied or not
if (std::find(_delayRemoveJoints.rbegin(), _delayRemoveJoints.rend(), joint) != _delayRemoveJoints.rend())
{
joint->_destoryMark = true;
}
else
{
delete joint;
}
}
} }
_joints.clear();
} }
void PhysicsWorld::addShape(PhysicsShape* physicsShape) void PhysicsWorld::addShape(PhysicsShape* physicsShape)
@ -816,6 +717,23 @@ void PhysicsWorld::doRemoveJoint(PhysicsJoint* joint)
{ {
cpSpaceRemoveConstraint(_cpSpace, constraint); cpSpaceRemoveConstraint(_cpSpace, constraint);
} }
_joints.remove(joint);
joint->_world = nullptr;
if (joint->getBodyA())
{
joint->getBodyA()->removeJoint(joint);
}
if (joint->getBodyB())
{
joint->getBodyB()->removeJoint(joint);
}
if (joint->_destoryMark)
{
delete joint;
}
} }
void PhysicsWorld::removeAllBodies() void PhysicsWorld::removeAllBodies()
@ -889,11 +807,18 @@ void PhysicsWorld::step(float delta)
void PhysicsWorld::update(float delta, bool userCall/* = false*/) void PhysicsWorld::update(float delta, bool userCall/* = false*/)
{ {
if (delta < FLT_EPSILON)
{
return;
}
_scene->updatePhysicsBodyTransform(_scene, _scene->getNodeToParentTransform(), 0, 1.0f, 1.0f);
while (_delayDirty) while (_delayDirty)
{ {
// the updateJoints must run before the updateBodies.
updateJoints();
updateBodies(); updateBodies();
updateJoints();
_delayDirty = !(_delayAddBodies.size() == 0 && _delayRemoveBodies.size() == 0 && _delayAddJoints.size() == 0 && _delayRemoveJoints.size() == 0); _delayDirty = !(_delayAddBodies.size() == 0 && _delayRemoveBodies.size() == 0 && _delayAddJoints.size() == 0 && _delayRemoveJoints.size() == 0);
} }

View File

@ -45,6 +45,7 @@ class PhysicsContact;
typedef Vec2 Vect; typedef Vec2 Vect;
class Director;
class Node; class Node;
class Sprite; class Sprite;
class Scene; class Scene;
@ -188,12 +189,9 @@ protected:
virtual void doAddBody(PhysicsBody* body); virtual void doAddBody(PhysicsBody* body);
virtual void doRemoveBody(PhysicsBody* body); virtual void doRemoveBody(PhysicsBody* body);
virtual void doAddJoint(PhysicsJoint* joint);
virtual void doRemoveJoint(PhysicsJoint* joint); virtual void doRemoveJoint(PhysicsJoint* joint);
virtual void addBodyOrDelay(PhysicsBody* body); virtual void addBodyOrDelay(PhysicsBody* body);
virtual void removeBodyOrDelay(PhysicsBody* body); virtual void removeBodyOrDelay(PhysicsBody* body);
virtual void addJointOrDelay(PhysicsJoint* joint);
virtual void removeJointOrDelay(PhysicsJoint* joint);
virtual void updateBodies(); virtual void updateBodies();
virtual void updateJoints(); virtual void updateJoints();
@ -228,6 +226,7 @@ protected:
friend class Node; friend class Node;
friend class Sprite; friend class Sprite;
friend class Scene; friend class Scene;
friend class Director;
friend class PhysicsBody; friend class PhysicsBody;
friend class PhysicsShape; friend class PhysicsShape;
friend class PhysicsJoint; friend class PhysicsJoint;

View File

@ -434,7 +434,6 @@ void PhysicsDemo::onTouchEnded(Touch* touch, Event* event)
this->removeChild(it->second); this->removeChild(it->second);
_mouses.erase(it); _mouses.erase(it);
} }
} }
void PhysicsDemoLogoSmash::onEnter() void PhysicsDemoLogoSmash::onEnter()
@ -716,8 +715,6 @@ void PhysicsDemoJoints::onEnter()
listener->onTouchEnded = CC_CALLBACK_2(PhysicsDemoJoints::onTouchEnded, this); listener->onTouchEnded = CC_CALLBACK_2(PhysicsDemoJoints::onTouchEnded, this);
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
//_scene->getPhysicsWorld()->setGravity(Point::ZERO);
float width = (VisibleRect::getVisibleRect().size.width - 10) / 4; float width = (VisibleRect::getVisibleRect().size.width - 10) / 4;
float height = (VisibleRect::getVisibleRect().size.height - 50) / 4; float height = (VisibleRect::getVisibleRect().size.height - 50) / 4;
@ -734,7 +731,7 @@ void PhysicsDemoJoints::onEnter()
{ {
Vec2 offset(VisibleRect::leftBottom().x + 5 + j * width + width/2, VisibleRect::leftBottom().y + 50 + i * height + height/2); Vec2 offset(VisibleRect::leftBottom().x + 5 + j * width + width/2, VisibleRect::leftBottom().y + 50 + i * height + height/2);
box->addShape(PhysicsShapeEdgeBox::create(Size(width, height), PHYSICSSHAPE_MATERIAL_DEFAULT, 1, offset)); box->addShape(PhysicsShapeEdgeBox::create(Size(width, height), PHYSICSSHAPE_MATERIAL_DEFAULT, 1, offset));
switch (i*4 + j) switch (i*4 + j)
{ {
case 0: case 0:
@ -768,7 +765,6 @@ void PhysicsDemoJoints::onEnter()
} }
case 2: case 2:
{ {
auto sp1 = makeBall(offset - Vec2(30, 0), 10); auto sp1 = makeBall(offset - Vec2(30, 0), 10);
sp1->getPhysicsBody()->setTag(DRAG_BODYS_TAG); sp1->getPhysicsBody()->setTag(DRAG_BODYS_TAG);
auto sp2 = makeBox(offset + Vec2(30, 0), Size(30, 10)); auto sp2 = makeBox(offset + Vec2(30, 0), Size(30, 10));
@ -988,6 +984,9 @@ void PhysicsDemoPump::onEnter()
body->addShape(PhysicsShapeEdgeSegment::create(VisibleRect::leftTop() + Vec2(150, -80), VisibleRect::rightTop() + Vec2(-100, -150), staticMaterial, 2.0f)); body->addShape(PhysicsShapeEdgeSegment::create(VisibleRect::leftTop() + Vec2(150, -80), VisibleRect::rightTop() + Vec2(-100, -150), staticMaterial, 2.0f));
body->setCategoryBitmask(0x01); body->setCategoryBitmask(0x01);
node->setPhysicsBody(body);
node->setPosition(Vec2::ZERO);
this->addChild(node);
// balls // balls
for (int i = 0; i < 6; ++i) for (int i = 0; i < 6; ++i)
@ -997,9 +996,8 @@ void PhysicsDemoPump::onEnter()
addChild(ball); addChild(ball);
} }
node->setPhysicsBody(body); auto _world = _scene->getPhysicsWorld();
this->addChild(node);
Vec2 vec[4] = Vec2 vec[4] =
{ {
VisibleRect::leftTop() + Vec2(102, -148), VisibleRect::leftTop() + Vec2(102, -148),
@ -1008,30 +1006,6 @@ void PhysicsDemoPump::onEnter()
VisibleRect::leftBottom() + Vec2(102, 20) VisibleRect::leftBottom() + Vec2(102, 20)
}; };
auto _world = _scene->getPhysicsWorld();
// small gear
auto sgear = Node::create();
auto sgearB = PhysicsBody::createCircle(44);
sgear->setPhysicsBody(sgearB);
sgear->setPosition(VisibleRect::leftBottom() + Vec2(125, 0));
this->addChild(sgear);
sgearB->setCategoryBitmask(0x04);
sgearB->setCollisionBitmask(0x04);
sgearB->setTag(1);
_world->addJoint(PhysicsJointPin::construct(body, sgearB, sgearB->getPosition()));
// big gear
auto bgear = Node::create();
auto bgearB = PhysicsBody::createCircle(100);
bgear->setPhysicsBody(bgearB);
bgear->setPosition(VisibleRect::leftBottom() + Vec2(275, 0));
this->addChild(bgear);
bgearB->setCategoryBitmask(0x04);
_world->addJoint(PhysicsJointPin::construct(body, bgearB, bgearB->getPosition()));
// pump // pump
auto pump = Node::create(); auto pump = Node::create();
auto center = PhysicsShape::getPolyonCenter(vec, 4); auto center = PhysicsShape::getPolyonCenter(vec, 4);
@ -1041,8 +1015,31 @@ void PhysicsDemoPump::onEnter()
this->addChild(pump); this->addChild(pump);
pumpB->setCategoryBitmask(0x02); pumpB->setCategoryBitmask(0x02);
pumpB->setGravityEnable(false); pumpB->setGravityEnable(false);
// small gear
auto sgear = Node::create();
auto sgearB = PhysicsBody::createCircle(44);
sgear->setPhysicsBody(sgearB);
sgear->setPosition(VisibleRect::leftBottom() + Vec2(125, 0));
this->addChild(sgear);
sgearB->setCategoryBitmask(0x04);
sgearB->setCollisionBitmask(0x04);
sgearB->setTag(1);
_world->addJoint(PhysicsJointPin::construct(body, sgearB, sgear->getPosition()));
_world->addJoint(PhysicsJointDistance::construct(pumpB, sgearB, Vec2(0, 0), Vec2(0, -44))); _world->addJoint(PhysicsJointDistance::construct(pumpB, sgearB, Vec2(0, 0), Vec2(0, -44)));
// big gear
auto bgear = Node::create();
auto bgearB = PhysicsBody::createCircle(100);
bgear->setPhysicsBody(bgearB);
bgear->setPosition(VisibleRect::leftBottom() + Vec2(275, 0));
this->addChild(bgear);
bgearB->setCategoryBitmask(0x04);
_world->addJoint(PhysicsJointPin::construct(bgearB, body, bgear->getPosition()));
_world->addJoint(PhysicsJointGear::construct(sgearB, bgearB, -M_PI_2, -2.0f));
// plugger // plugger
Vec2 seg[] = {VisibleRect::leftTop() + Vec2(75, -120), VisibleRect::leftBottom() + Vec2(75, -100)}; Vec2 seg[] = {VisibleRect::leftTop() + Vec2(75, -120), VisibleRect::leftBottom() + Vec2(75, -100)};
Vec2 segCenter = (seg[1] + seg[0])/2; Vec2 segCenter = (seg[1] + seg[0])/2;
@ -1059,7 +1056,7 @@ void PhysicsDemoPump::onEnter()
pluggerB->setCategoryBitmask(0x02); pluggerB->setCategoryBitmask(0x02);
sgearB->setCollisionBitmask(0x04 | 0x01); sgearB->setCollisionBitmask(0x04 | 0x01);
_world->addJoint(PhysicsJointPin::construct(body, pluggerB, VisibleRect::leftBottom() + Vec2(75, -90))); _world->addJoint(PhysicsJointPin::construct(body, pluggerB, VisibleRect::leftBottom() + Vec2(75, -90)));
_world->addJoint(PhysicsJointDistance::construct(pluggerB, sgearB, pluggerB->world2Local(VisibleRect::leftBottom() + Vec2(75, 0)), Vec2(44, 0))); _world->addJoint(PhysicsJointDistance::construct(pluggerB, sgearB, Vec2::ZERO, Vec2(44, 0)));
} }
void PhysicsDemoPump::update(float delta) void PhysicsDemoPump::update(float delta)