mirror of https://github.com/axmolengine/axmol.git
Improve performance of physics
This commit is contained in:
parent
2847a940ed
commit
8524a5fb97
|
@ -859,12 +859,6 @@ void RotateTo::update(float time)
|
|||
}
|
||||
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->setRotationSkewY(_startAngle.y + _diffAngle.y * time);
|
||||
}
|
||||
|
@ -1002,12 +996,6 @@ void RotateBy::update(float time)
|
|||
}
|
||||
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->setRotationSkewY(_startAngle.y + _deltaAngle.y * time);
|
||||
}
|
||||
|
|
|
@ -60,7 +60,6 @@ THE SOFTWARE.
|
|||
#define RENDER_IN_SUBPIXEL(__ARGS__) (ceil(__ARGS__))
|
||||
#endif
|
||||
|
||||
extern int g_physicsSceneCount;
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
||||
|
@ -125,6 +124,8 @@ Node::Node(void)
|
|||
, _physicsBody(nullptr)
|
||||
, _physicsScaleStartX(1.0f)
|
||||
, _physicsScaleStartY(1.0f)
|
||||
, _physicsRotation(0.0f)
|
||||
, _physicsTransformDirty(true)
|
||||
#endif
|
||||
, _displayedOpacity(255)
|
||||
, _realOpacity(255)
|
||||
|
@ -330,13 +331,6 @@ void Node::setRotation(float rotation)
|
|||
_rotationZ_X = _rotationZ_Y = rotation;
|
||||
_transformUpdated = _transformDirty = _inverseDirty = true;
|
||||
|
||||
#if CC_USE_PHYSICS
|
||||
if (!_physicsBody || !_physicsBody->_rotationResetTag)
|
||||
{
|
||||
updatePhysicsBodyRotation(getScene());
|
||||
}
|
||||
#endif
|
||||
|
||||
updateRotationQuat();
|
||||
}
|
||||
|
||||
|
@ -472,16 +466,6 @@ void Node::setScale(float scale)
|
|||
|
||||
_scaleX = _scaleY = _scaleZ = scale;
|
||||
_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
|
||||
|
@ -499,17 +483,6 @@ void Node::setScale(float scaleX,float scaleY)
|
|||
_scaleX = scaleX;
|
||||
_scaleY = scaleY;
|
||||
_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
|
||||
|
@ -520,17 +493,6 @@ void Node::setScaleX(float scaleX)
|
|||
|
||||
_scaleX = scaleX;
|
||||
_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
|
||||
|
@ -570,17 +532,6 @@ void Node::setScaleY(float scaleY)
|
|||
|
||||
_scaleY = scaleY;
|
||||
_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;
|
||||
_usingNormalizedPosition = false;
|
||||
|
||||
#if CC_USE_PHYSICS
|
||||
if (!_physicsBody || !_physicsBody->_positionResetTag)
|
||||
{
|
||||
updatePhysicsBodyPosition(getScene());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
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();
|
||||
if (scene && scene->getPhysicsWorld())
|
||||
{
|
||||
child->updatePhysicsBodyTransform(scene);
|
||||
scene->addChildToPhysicsWorld(child);
|
||||
}
|
||||
#endif
|
||||
|
@ -1301,6 +1244,12 @@ void Node::visit()
|
|||
|
||||
uint32_t Node::processParentFlags(const Mat4& parentTransform, uint32_t parentFlags)
|
||||
{
|
||||
#if CC_USE_PHYSICS
|
||||
if (_physicsBody && _updateTransformFromPhysics)
|
||||
{
|
||||
updateTransformFromPhysics(parentTransform, parentFlags);
|
||||
}
|
||||
#endif
|
||||
if(_usingNormalizedPosition)
|
||||
{
|
||||
CCASSERT(_parent, "setNormalizedPosition() doesn't work with orphan nodes");
|
||||
|
@ -2023,87 +1972,6 @@ void Node::removeAllComponents()
|
|||
|
||||
// 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)
|
||||
{
|
||||
if (_physicsBody == body)
|
||||
|
@ -2111,9 +1979,17 @@ void Node::setPhysicsBody(PhysicsBody* body)
|
|||
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);
|
||||
}
|
||||
|
@ -2128,52 +2004,65 @@ void Node::setPhysicsBody(PhysicsBody* body)
|
|||
CCLOG("Node warning: setPhysicsBody sets anchor point to Vec2::ANCHOR_MIDDLE.");
|
||||
setAnchorPoint(Vec2::ANCHOR_MIDDLE);
|
||||
}
|
||||
}
|
||||
|
||||
if (_physicsBody != nullptr)
|
||||
{
|
||||
PhysicsWorld* world = _physicsBody->getWorld();
|
||||
_physicsBody->removeFromWorld();
|
||||
_physicsBody->_node = nullptr;
|
||||
_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)
|
||||
auto scene = getScene();
|
||||
if (scene && scene->getPhysicsWorld())
|
||||
{
|
||||
_physicsTransformDirty = true;
|
||||
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
|
||||
|
||||
// MARK: Opacity and Color
|
||||
|
|
|
@ -1532,13 +1532,16 @@ public:
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
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
|
||||
|
||||
// overrides
|
||||
|
@ -1612,13 +1615,6 @@ protected:
|
|||
// update Rotation3D from quaternion
|
||||
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:
|
||||
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
|
||||
float _physicsScaleStartX; ///< the scale x value when setPhysicsBody
|
||||
float _physicsScaleStartY; ///< the scale y value when setPhysicsBody
|
||||
float _physicsRotation;
|
||||
bool _physicsTransformDirty;
|
||||
bool _updateTransformFromPhysics;
|
||||
#endif
|
||||
|
||||
// opacity controls
|
||||
|
|
|
@ -37,8 +37,6 @@ THE SOFTWARE.
|
|||
#include "physics/CCPhysicsWorld.h"
|
||||
#endif
|
||||
|
||||
int g_physicsSceneCount = 0;
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
||||
Scene::Scene()
|
||||
|
@ -60,10 +58,6 @@ Scene::Scene()
|
|||
Scene::~Scene()
|
||||
{
|
||||
#if CC_USE_PHYSICS
|
||||
if (_physicsWorld)
|
||||
{
|
||||
g_physicsSceneCount--;
|
||||
}
|
||||
CC_SAFE_DELETE(_physicsWorld);
|
||||
#endif
|
||||
Director::getInstance()->getEventDispatcher()->removeEventListener(_event);
|
||||
|
@ -177,15 +171,6 @@ void Scene::addChild(Node* child, int zOrder, const std::string &name)
|
|||
addChildToPhysicsWorld(child);
|
||||
}
|
||||
|
||||
void Scene::update(float delta)
|
||||
{
|
||||
Node::update(delta);
|
||||
if (nullptr != _physicsWorld && _physicsWorld->isAutoStep())
|
||||
{
|
||||
_physicsWorld->update(delta);
|
||||
}
|
||||
}
|
||||
|
||||
Scene* Scene::createWithPhysics()
|
||||
{
|
||||
Scene *ret = new (std::nothrow) Scene();
|
||||
|
@ -212,9 +197,7 @@ bool Scene::initWithPhysics()
|
|||
this->setContentSize(director->getWinSize());
|
||||
CC_BREAK_IF(! (_physicsWorld = PhysicsWorld::construct(*this)));
|
||||
|
||||
this->scheduleUpdate();
|
||||
// success
|
||||
g_physicsSceneCount += 1;
|
||||
ret = true;
|
||||
} while (0);
|
||||
return ret;
|
||||
|
|
|
@ -108,7 +108,6 @@ private:
|
|||
public:
|
||||
virtual void addChild(Node* child, int zOrder, int tag) override;
|
||||
virtual void addChild(Node* child, int zOrder, const std::string &name) override;
|
||||
virtual void update(float delta) override;
|
||||
inline PhysicsWorld* getPhysicsWorld() { return _physicsWorld; }
|
||||
static Scene *createWithPhysics();
|
||||
|
||||
|
|
|
@ -366,8 +366,17 @@ void SpriteBatchNode::draw(Renderer *renderer, const Mat4 &transform, uint32_t f
|
|||
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();
|
||||
}
|
||||
|
||||
_batchCommand.init(
|
||||
_globalZOrder,
|
||||
|
|
|
@ -65,6 +65,10 @@ THE SOFTWARE.
|
|||
#include "CCScriptSupport.h"
|
||||
#endif
|
||||
|
||||
#if CC_USE_PHYSICS
|
||||
#include "physics/CCPhysicsWorld.h"
|
||||
#endif
|
||||
|
||||
/**
|
||||
Position of the FPS
|
||||
|
||||
|
@ -265,12 +269,6 @@ void Director::drawScene()
|
|||
// calculate "global" dt
|
||||
calculateDeltaTime();
|
||||
|
||||
// skip one flame when _deltaTime equal to zero.
|
||||
if(_deltaTime < FLT_EPSILON)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_openGLView)
|
||||
{
|
||||
_openGLView->pollEvents();
|
||||
|
@ -297,6 +295,13 @@ void Director::drawScene()
|
|||
|
||||
if (_runningScene)
|
||||
{
|
||||
#if CC_USE_PHYSICS
|
||||
auto physicsWorld = _runningScene->getPhysicsWorld();
|
||||
if (physicsWorld && physicsWorld->isAutoStep())
|
||||
{
|
||||
physicsWorld->update(_deltaTime, false);
|
||||
}
|
||||
#endif
|
||||
//clear draw stats
|
||||
_renderer->clearDrawStats();
|
||||
|
||||
|
|
|
@ -68,9 +68,8 @@ PhysicsBody::PhysicsBody()
|
|||
, _linearDamping(0.0f)
|
||||
, _angularDamping(0.0f)
|
||||
, _tag(0)
|
||||
, _positionResetTag(false)
|
||||
, _rotationResetTag(false)
|
||||
, _rotationOffset(0)
|
||||
, _recordPosition(Vec2::ZERO)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -333,6 +332,7 @@ void PhysicsBody::setGravityEnable(bool enable)
|
|||
|
||||
void PhysicsBody::setPosition(const Vec2& position)
|
||||
{
|
||||
_recordPosition = position;
|
||||
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)));
|
||||
}
|
||||
|
||||
void PhysicsBody::setScale(float scale)
|
||||
{
|
||||
for (auto shape : _shapes)
|
||||
{
|
||||
shape->setScale(scale);
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicsBody::setScale(float scaleX, float scaleY)
|
||||
{
|
||||
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
|
||||
{
|
||||
cpVect vec = cpBodyGetPos(_cpBody);
|
||||
|
@ -402,7 +378,7 @@ PhysicsShape* PhysicsBody::addShape(PhysicsShape* shape, bool addMassAndMoment/*
|
|||
addMoment(shape->getMoment());
|
||||
}
|
||||
|
||||
if (_world != nullptr)
|
||||
if (_world && _cpBody->CP_PRIVATE(space))
|
||||
{
|
||||
_world->addShape(shape);
|
||||
}
|
||||
|
@ -764,30 +740,8 @@ void PhysicsBody::setResting(bool rest) const
|
|||
|
||||
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
|
||||
if (_isDamping && _dynamic && !isResting())
|
||||
{
|
||||
|
|
|
@ -306,10 +306,7 @@ protected:
|
|||
|
||||
virtual void setPosition(const Vec2& position);
|
||||
virtual void setRotation(float rotation);
|
||||
virtual void setScale(float scale);
|
||||
virtual void setScale(float scaleX, float scaleY);
|
||||
virtual void setScaleX(float scaleX);
|
||||
virtual void setScaleY(float scaleY);
|
||||
|
||||
void update(float delta);
|
||||
|
||||
|
@ -341,8 +338,7 @@ protected:
|
|||
float _angularDamping;
|
||||
int _tag;
|
||||
|
||||
bool _positionResetTag; /// To avoid reset the body position when body invoke Node::setPosition().
|
||||
bool _rotationResetTag; /// To avoid reset the body rotation when body invoke Node::setRotation().
|
||||
Vec2 _recordPosition;
|
||||
Vec2 _positionOffset;
|
||||
float _rotationOffset;
|
||||
|
||||
|
|
|
@ -40,7 +40,9 @@ PhysicsJoint::PhysicsJoint()
|
|||
, _enable(false)
|
||||
, _collisionEnable(true)
|
||||
, _destoryMark(false)
|
||||
, _initDirty(true)
|
||||
, _tag(0)
|
||||
, _maxForce(PHYSICS_INFINITY)
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -50,10 +52,11 @@ PhysicsJoint::~PhysicsJoint()
|
|||
// reset the shapes collision group
|
||||
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)
|
||||
|
@ -64,8 +67,8 @@ bool PhysicsJoint::init(cocos2d::PhysicsBody *a, cocos2d::PhysicsBody *b)
|
|||
CCASSERT(a != b, "the two bodies are equal");
|
||||
|
||||
_bodyA = a;
|
||||
_bodyA->_joints.push_back(this);
|
||||
_bodyB = b;
|
||||
_bodyA->_joints.push_back(this);
|
||||
_bodyB->_joints.push_back(this);
|
||||
|
||||
return true;
|
||||
|
@ -74,30 +77,47 @@ bool PhysicsJoint::init(cocos2d::PhysicsBody *a, cocos2d::PhysicsBody *b)
|
|||
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)
|
||||
{
|
||||
if (_enable != enable)
|
||||
{
|
||||
_enable = enable;
|
||||
|
||||
if (_world != nullptr)
|
||||
if (_world)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
_world->addJointOrDelay(this);
|
||||
}else
|
||||
_world->addJoint(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
_world->removeJointOrDelay(this);
|
||||
_world->removeJoint(this, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Node* PhysicsJoint::getBodyNode(PhysicsBody* body) const
|
||||
{
|
||||
return body->_node;
|
||||
}
|
||||
|
||||
void PhysicsJoint::setCollisionEnable(bool enable)
|
||||
{
|
||||
if (_collisionEnable != enable)
|
||||
|
@ -114,51 +134,22 @@ 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)
|
||||
{
|
||||
_maxForce = force;
|
||||
for (auto joint : _cpConstraints)
|
||||
{
|
||||
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* 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;
|
||||
}
|
||||
|
||||
|
@ -166,27 +157,25 @@ PhysicsJointFixed* PhysicsJointFixed::construct(PhysicsBody* a, PhysicsBody* b,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
bool PhysicsJointFixed::init(PhysicsBody* a, PhysicsBody* b, const Vec2& anchr)
|
||||
bool PhysicsJointFixed::createConstraints()
|
||||
{
|
||||
do
|
||||
{
|
||||
CC_BREAK_IF(!PhysicsJoint::init(a, b));
|
||||
|
||||
getBodyNode(a)->setPosition(anchr);
|
||||
getBodyNode(b)->setPosition(anchr);
|
||||
_bodyA->getNode()->setPosition(_anchr);
|
||||
_bodyB->getNode()->setPosition(_anchr);
|
||||
|
||||
// add a pivot joint to fixed two body together
|
||||
auto constraint = cpPivotJointNew(a->getCPBody(), b->getCPBody(),
|
||||
PhysicsHelper::point2cpv(anchr));
|
||||
CC_BREAK_IF(constraint == nullptr);
|
||||
_cpConstraints.push_back(constraint);
|
||||
auto joint = cpPivotJointNew(_bodyA->getCPBody(), _bodyB->getCPBody(),
|
||||
PhysicsHelper::point2cpv(_anchr));
|
||||
CC_BREAK_IF(joint == nullptr);
|
||||
_cpConstraints.push_back(joint);
|
||||
|
||||
// add a gear joint to make two body have the same rotation.
|
||||
constraint = cpGearJointNew(a->getCPBody(), b->getCPBody(), 0, 1);
|
||||
CC_BREAK_IF(constraint == nullptr);
|
||||
_cpConstraints.push_back(constraint);
|
||||
joint = cpGearJointNew(_bodyA->getCPBody(), _bodyB->getCPBody(), 0, 1);
|
||||
CC_BREAK_IF(joint == nullptr);
|
||||
_cpConstraints.push_back(joint);
|
||||
|
||||
setCollisionEnable(false);
|
||||
_collisionEnable = false;
|
||||
|
||||
return true;
|
||||
} while (false);
|
||||
|
@ -194,12 +183,14 @@ bool PhysicsJointFixed::init(PhysicsBody* a, PhysicsBody* b, const Vec2& anchr)
|
|||
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;
|
||||
}
|
||||
|
||||
|
@ -207,17 +198,41 @@ PhysicsJointPin* PhysicsJointPin::construct(PhysicsBody* a, PhysicsBody* b, cons
|
|||
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
|
||||
{
|
||||
CC_BREAK_IF(!PhysicsJoint::init(a, b));
|
||||
auto constraint = cpPivotJointNew(a->getCPBody(), b->getCPBody(),
|
||||
PhysicsHelper::point2cpv(anchr));
|
||||
cpConstraint* joint = nullptr;
|
||||
if (_useSpecificAnchr)
|
||||
{
|
||||
joint = cpPivotJointNew2(_bodyA->getCPBody(), _bodyB->getCPBody(),
|
||||
PhysicsHelper::point2cpv(_anchr1), PhysicsHelper::point2cpv(_anchr2));
|
||||
}
|
||||
else
|
||||
{
|
||||
joint = cpPivotJointNew(_bodyA->getCPBody(), _bodyB->getCPBody(),
|
||||
PhysicsHelper::point2cpv(_anchr1));
|
||||
}
|
||||
|
||||
CC_BREAK_IF(constraint == nullptr);
|
||||
|
||||
_cpConstraints.push_back(constraint);
|
||||
CC_BREAK_IF(joint == nullptr);
|
||||
_cpConstraints.push_back(joint);
|
||||
|
||||
return true;
|
||||
} while (false);
|
||||
|
@ -227,10 +242,15 @@ bool PhysicsJointPin::init(PhysicsBody *a, PhysicsBody *b, const Vec2& anchr)
|
|||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -243,21 +263,18 @@ PhysicsJointLimit* PhysicsJointLimit::construct(PhysicsBody* a, PhysicsBody* b,
|
|||
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
|
||||
{
|
||||
CC_BREAK_IF(!PhysicsJoint::init(a, b));
|
||||
auto joint = cpSlideJointNew(_bodyA->getCPBody(), _bodyB->getCPBody(),
|
||||
PhysicsHelper::point2cpv(_anchr1),
|
||||
PhysicsHelper::point2cpv(_anchr2),
|
||||
PhysicsHelper::float2cpfloat(_min),
|
||||
PhysicsHelper::float2cpfloat(_max));
|
||||
|
||||
auto constraint = cpSlideJointNew(a->getCPBody(), b->getCPBody(),
|
||||
PhysicsHelper::point2cpv(anchr1),
|
||||
PhysicsHelper::point2cpv(anchr2),
|
||||
PhysicsHelper::float2cpfloat(min),
|
||||
PhysicsHelper::float2cpfloat(max));
|
||||
|
||||
CC_BREAK_IF(constraint == nullptr);
|
||||
|
||||
_cpConstraints.push_back(constraint);
|
||||
CC_BREAK_IF(joint == nullptr);
|
||||
_cpConstraints.push_back(joint);
|
||||
|
||||
return true;
|
||||
} while (false);
|
||||
|
@ -307,10 +324,13 @@ void PhysicsJointLimit::setAnchr2(const Vec2& anchr)
|
|||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -318,20 +338,16 @@ PhysicsJointDistance* PhysicsJointDistance::construct(PhysicsBody* a, PhysicsBod
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
bool PhysicsJointDistance::init(PhysicsBody* a, PhysicsBody* b, const Vec2& anchr1, const Vec2& anchr2)
|
||||
bool PhysicsJointDistance::createConstraints()
|
||||
{
|
||||
do
|
||||
{
|
||||
CC_BREAK_IF(!PhysicsJoint::init(a, b));
|
||||
|
||||
auto constraint = cpPinJointNew(a->getCPBody(),
|
||||
b->getCPBody(),
|
||||
PhysicsHelper::point2cpv(anchr1),
|
||||
PhysicsHelper::point2cpv(anchr2));
|
||||
|
||||
CC_BREAK_IF(constraint == nullptr);
|
||||
|
||||
_cpConstraints.push_back(constraint);
|
||||
auto joint = cpPinJointNew(_bodyA->getCPBody(),
|
||||
_bodyB->getCPBody(),
|
||||
PhysicsHelper::point2cpv(_anchr1),
|
||||
PhysicsHelper::point2cpv(_anchr2));
|
||||
CC_BREAK_IF(joint == nullptr);
|
||||
_cpConstraints.push_back(joint);
|
||||
|
||||
return true;
|
||||
} while (false);
|
||||
|
@ -351,10 +367,15 @@ void PhysicsJointDistance::setDistance(float distance)
|
|||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -362,22 +383,19 @@ PhysicsJointSpring* PhysicsJointSpring::construct(PhysicsBody* a, PhysicsBody* b
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
bool PhysicsJointSpring::init(PhysicsBody* a, PhysicsBody* b, const Vec2& anchr1, const Vec2& anchr2, float stiffness, float damping)
|
||||
bool PhysicsJointSpring::createConstraints()
|
||||
{
|
||||
do {
|
||||
CC_BREAK_IF(!PhysicsJoint::init(a, b));
|
||||
auto joint = cpDampedSpringNew(_bodyA->getCPBody(),
|
||||
_bodyB->getCPBody(),
|
||||
PhysicsHelper::point2cpv(_anchr1),
|
||||
PhysicsHelper::point2cpv(_anchr2),
|
||||
PhysicsHelper::float2cpfloat(_bodyB->local2World(_anchr1).getDistance(_bodyA->local2World(_anchr2))),
|
||||
PhysicsHelper::float2cpfloat(_stiffness),
|
||||
PhysicsHelper::float2cpfloat(_damping));
|
||||
|
||||
auto constraint = cpDampedSpringNew(a->getCPBody(),
|
||||
b->getCPBody(),
|
||||
PhysicsHelper::point2cpv(anchr1),
|
||||
PhysicsHelper::point2cpv(anchr2),
|
||||
PhysicsHelper::float2cpfloat(_bodyB->local2World(anchr1).getDistance(_bodyA->local2World(anchr2))),
|
||||
PhysicsHelper::float2cpfloat(stiffness),
|
||||
PhysicsHelper::float2cpfloat(damping));
|
||||
|
||||
CC_BREAK_IF(constraint == nullptr);
|
||||
|
||||
_cpConstraints.push_back(constraint);
|
||||
CC_BREAK_IF(joint == nullptr);
|
||||
_cpConstraints.push_back(joint);
|
||||
|
||||
return true;
|
||||
} while (false);
|
||||
|
@ -437,10 +455,14 @@ void PhysicsJointSpring::setDamping(float damping)
|
|||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -448,20 +470,17 @@ PhysicsJointGroove* PhysicsJointGroove::construct(PhysicsBody* a, PhysicsBody* b
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
bool PhysicsJointGroove::init(PhysicsBody* a, PhysicsBody* b, const Vec2& grooveA, const Vec2& grooveB, const Vec2& anchr2)
|
||||
bool PhysicsJointGroove::createConstraints()
|
||||
{
|
||||
do {
|
||||
CC_BREAK_IF(!PhysicsJoint::init(a, b));
|
||||
auto joint = cpGrooveJointNew(_bodyA->getCPBody(),
|
||||
_bodyB->getCPBody(),
|
||||
PhysicsHelper::point2cpv(_grooveA),
|
||||
PhysicsHelper::point2cpv(_grooveB),
|
||||
PhysicsHelper::point2cpv(_anchr2));
|
||||
|
||||
auto constraint = cpGrooveJointNew(a->getCPBody(),
|
||||
b->getCPBody(),
|
||||
PhysicsHelper::point2cpv(grooveA),
|
||||
PhysicsHelper::point2cpv(grooveB),
|
||||
PhysicsHelper::point2cpv(anchr2));
|
||||
|
||||
CC_BREAK_IF(constraint == nullptr);
|
||||
|
||||
_cpConstraints.push_back(constraint);
|
||||
CC_BREAK_IF(joint == nullptr);
|
||||
_cpConstraints.push_back(joint);
|
||||
|
||||
return true;
|
||||
} while (false);
|
||||
|
@ -501,10 +520,13 @@ void PhysicsJointGroove::setAnchr2(const Vec2& anchr2)
|
|||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -512,20 +534,17 @@ PhysicsJointRotarySpring* PhysicsJointRotarySpring::construct(PhysicsBody* a, Ph
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
bool PhysicsJointRotarySpring::init(PhysicsBody* a, PhysicsBody* b, float stiffness, float damping)
|
||||
bool PhysicsJointRotarySpring::createConstraints()
|
||||
{
|
||||
do {
|
||||
CC_BREAK_IF(!PhysicsJoint::init(a, b));
|
||||
|
||||
auto constraint = cpDampedRotarySpringNew(a->getCPBody(),
|
||||
b->getCPBody(),
|
||||
auto joint = cpDampedRotarySpringNew(_bodyA->getCPBody(),
|
||||
_bodyB->getCPBody(),
|
||||
PhysicsHelper::float2cpfloat(_bodyB->getRotation() - _bodyA->getRotation()),
|
||||
PhysicsHelper::float2cpfloat(stiffness),
|
||||
PhysicsHelper::float2cpfloat(damping));
|
||||
PhysicsHelper::float2cpfloat(_stiffness),
|
||||
PhysicsHelper::float2cpfloat(_damping));
|
||||
|
||||
CC_BREAK_IF(constraint == nullptr);
|
||||
|
||||
_cpConstraints.push_back(constraint);
|
||||
CC_BREAK_IF(joint == nullptr);
|
||||
_cpConstraints.push_back(joint);
|
||||
|
||||
return true;
|
||||
} while (false);
|
||||
|
@ -565,10 +584,13 @@ void PhysicsJointRotarySpring::setDamping(float damping)
|
|||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -581,20 +603,17 @@ PhysicsJointRotaryLimit* PhysicsJointRotaryLimit::construct(PhysicsBody* a, Phys
|
|||
return construct(a, b, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
bool PhysicsJointRotaryLimit::init(PhysicsBody* a, PhysicsBody* b, float min, float max)
|
||||
bool PhysicsJointRotaryLimit::createConstraints()
|
||||
{
|
||||
do
|
||||
{
|
||||
CC_BREAK_IF(!PhysicsJoint::init(a, b));
|
||||
auto joint = cpRotaryLimitJointNew(_bodyA->getCPBody(),
|
||||
_bodyB->getCPBody(),
|
||||
PhysicsHelper::float2cpfloat(_min),
|
||||
PhysicsHelper::float2cpfloat(_max));
|
||||
|
||||
auto constraint = cpRotaryLimitJointNew(a->getCPBody(),
|
||||
b->getCPBody(),
|
||||
PhysicsHelper::float2cpfloat(min),
|
||||
PhysicsHelper::float2cpfloat(max));
|
||||
|
||||
CC_BREAK_IF(constraint == nullptr);
|
||||
|
||||
_cpConstraints.push_back(constraint);
|
||||
CC_BREAK_IF(joint == nullptr);
|
||||
_cpConstraints.push_back(joint);
|
||||
|
||||
return true;
|
||||
} while (false);
|
||||
|
@ -624,10 +643,13 @@ void PhysicsJointRotaryLimit::setMax(float max)
|
|||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -635,20 +657,17 @@ PhysicsJointRatchet* PhysicsJointRatchet::construct(PhysicsBody* a, PhysicsBody*
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
bool PhysicsJointRatchet::init(PhysicsBody* a, PhysicsBody* b, float phase, float ratchet)
|
||||
bool PhysicsJointRatchet::createConstraints()
|
||||
{
|
||||
do
|
||||
{
|
||||
CC_BREAK_IF(!PhysicsJoint::init(a, b));
|
||||
auto joint = cpRatchetJointNew(_bodyA->getCPBody(),
|
||||
_bodyB->getCPBody(),
|
||||
PhysicsHelper::float2cpfloat(_phase),
|
||||
PhysicsHelper::cpfloat2float(_ratchet));
|
||||
|
||||
auto constraint = cpRatchetJointNew(a->getCPBody(),
|
||||
b->getCPBody(),
|
||||
PhysicsHelper::float2cpfloat(phase),
|
||||
PhysicsHelper::cpfloat2float(ratchet));
|
||||
|
||||
CC_BREAK_IF(constraint == nullptr);
|
||||
|
||||
_cpConstraints.push_back(constraint);
|
||||
CC_BREAK_IF(joint == nullptr);
|
||||
_cpConstraints.push_back(joint);
|
||||
|
||||
return true;
|
||||
} while (false);
|
||||
|
@ -686,12 +705,15 @@ void PhysicsJointRatchet::setRatchet(float 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;
|
||||
}
|
||||
|
||||
|
@ -699,20 +721,17 @@ PhysicsJointGear* PhysicsJointGear::construct(PhysicsBody* a, PhysicsBody* b, fl
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
bool PhysicsJointGear::init(PhysicsBody* a, PhysicsBody* b, float phase, float ratio)
|
||||
bool PhysicsJointGear::createConstraints()
|
||||
{
|
||||
do
|
||||
{
|
||||
CC_BREAK_IF(!PhysicsJoint::init(a, b));
|
||||
auto joint = cpGearJointNew(_bodyA->getCPBody(),
|
||||
_bodyB->getCPBody(),
|
||||
PhysicsHelper::float2cpfloat(_phase),
|
||||
PhysicsHelper::float2cpfloat(_ratio));
|
||||
|
||||
auto constraint = cpGearJointNew(a->getCPBody(),
|
||||
b->getCPBody(),
|
||||
PhysicsHelper::float2cpfloat(phase),
|
||||
PhysicsHelper::float2cpfloat(ratio));
|
||||
|
||||
CC_BREAK_IF(constraint == nullptr);
|
||||
|
||||
_cpConstraints.push_back(constraint);
|
||||
CC_BREAK_IF(joint == nullptr);
|
||||
_cpConstraints.push_back(joint);
|
||||
|
||||
return true;
|
||||
} while (false);
|
||||
|
@ -742,10 +761,12 @@ void PhysicsJointGear::setRatio(float ratio)
|
|||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -753,19 +774,16 @@ PhysicsJointMotor* PhysicsJointMotor::construct(PhysicsBody* a, PhysicsBody* b,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
bool PhysicsJointMotor::init(PhysicsBody* a, PhysicsBody* b, float rate)
|
||||
bool PhysicsJointMotor::createConstraints()
|
||||
{
|
||||
do
|
||||
{
|
||||
CC_BREAK_IF(!PhysicsJoint::init(a, b));
|
||||
auto joint = cpSimpleMotorNew(_bodyA->getCPBody(),
|
||||
_bodyB->getCPBody(),
|
||||
PhysicsHelper::float2cpfloat(_rate));
|
||||
|
||||
auto constraint = cpSimpleMotorNew(a->getCPBody(),
|
||||
b->getCPBody(),
|
||||
PhysicsHelper::float2cpfloat(rate));
|
||||
|
||||
CC_BREAK_IF(constraint == nullptr);
|
||||
|
||||
_cpConstraints.push_back(constraint);
|
||||
CC_BREAK_IF(joint == nullptr);
|
||||
_cpConstraints.push_back(joint);
|
||||
|
||||
return true;
|
||||
} while (false);
|
||||
|
|
|
@ -62,27 +62,30 @@ public:
|
|||
void setCollisionEnable(bool enable);
|
||||
/** Remove the joint from the world */
|
||||
void removeFormWorld();
|
||||
/** Distory the joint*/
|
||||
static void destroy(PhysicsJoint* joint);
|
||||
|
||||
/** Set the max force between two bodies */
|
||||
void setMaxForce(float force);
|
||||
/** Get the max force setting */
|
||||
float getMaxForce() const;
|
||||
float getMaxForce() const { return _maxForce; }
|
||||
|
||||
protected:
|
||||
bool init(PhysicsBody* a, PhysicsBody* b);
|
||||
Node* getBodyNode(PhysicsBody* body) const;
|
||||
|
||||
protected:
|
||||
bool initJoint();
|
||||
virtual bool createConstraints() { return false; }
|
||||
|
||||
std::vector<cpConstraint*> _cpConstraints;
|
||||
PhysicsBody* _bodyA;
|
||||
PhysicsBody* _bodyB;
|
||||
PhysicsWorld* _world;
|
||||
std::vector<cpConstraint*> _cpConstraints;
|
||||
|
||||
bool _enable;
|
||||
bool _collisionEnable;
|
||||
bool _destoryMark;
|
||||
int _tag;
|
||||
float _maxForce;
|
||||
|
||||
bool _initDirty;
|
||||
|
||||
friend class PhysicsBody;
|
||||
friend class PhysicsWorld;
|
||||
|
@ -90,24 +93,25 @@ protected:
|
|||
};
|
||||
|
||||
/*
|
||||
* @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
|
||||
{
|
||||
public:
|
||||
static PhysicsJointFixed* construct(PhysicsBody* a, PhysicsBody* b, const Vec2& anchr);
|
||||
|
||||
protected:
|
||||
bool init(PhysicsBody* a, PhysicsBody* b, const Vec2& anchr);
|
||||
virtual bool createConstraints() override;
|
||||
|
||||
protected:
|
||||
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
|
||||
{
|
||||
public:
|
||||
|
@ -123,28 +127,36 @@ public:
|
|||
float getMax() const;
|
||||
void setMax(float max);
|
||||
|
||||
protected:
|
||||
bool init(PhysicsBody* a, PhysicsBody* b, const Vec2& anchr1, const Vec2& anchr2, float min, float max);
|
||||
virtual bool createConstraints() override;
|
||||
|
||||
protected:
|
||||
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
|
||||
{
|
||||
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:
|
||||
PhysicsJointPin() {}
|
||||
virtual ~PhysicsJointPin() {}
|
||||
|
||||
bool _useSpecificAnchr;
|
||||
Vec2 _anchr1;
|
||||
Vec2 _anchr2;
|
||||
};
|
||||
|
||||
/** Set the fixed distance with two bodies */
|
||||
|
@ -155,13 +167,14 @@ public:
|
|||
|
||||
float getDistance() const;
|
||||
void setDistance(float distance);
|
||||
|
||||
protected:
|
||||
bool init(PhysicsBody* a, PhysicsBody* b, const Vec2& anchr1, const Vec2& anchr2);
|
||||
virtual bool createConstraints() override;
|
||||
|
||||
protected:
|
||||
PhysicsJointDistance() {}
|
||||
virtual ~PhysicsJointDistance() {}
|
||||
|
||||
Vec2 _anchr1;
|
||||
Vec2 _anchr2;
|
||||
};
|
||||
|
||||
/** Connecting two physics bodies together with a spring. */
|
||||
|
@ -179,13 +192,16 @@ public:
|
|||
void setStiffness(float stiffness);
|
||||
float getDamping() const;
|
||||
void setDamping(float damping);
|
||||
|
||||
protected:
|
||||
bool init(PhysicsBody* a, PhysicsBody* b, const Vec2& anchr1, const Vec2& anchr2, float stiffness, float damping);
|
||||
virtual bool createConstraints() override;
|
||||
|
||||
protected:
|
||||
PhysicsJointSpring() {}
|
||||
virtual ~PhysicsJointSpring() {}
|
||||
|
||||
Vec2 _anchr1;
|
||||
Vec2 _anchr2;
|
||||
float _stiffness;
|
||||
float _damping;
|
||||
};
|
||||
|
||||
/** Attach body a to a line, and attach body b to a dot */
|
||||
|
@ -200,13 +216,15 @@ public:
|
|||
void setGrooveB(const Vec2& grooveB);
|
||||
Vec2 getAnchr2() const;
|
||||
void setAnchr2(const Vec2& anchr2);
|
||||
|
||||
protected:
|
||||
bool init(PhysicsBody* a, PhysicsBody* b, const Vec2& grooveA, const Vec2& grooveB, const Vec2& anchr);
|
||||
virtual bool createConstraints() override;
|
||||
|
||||
protected:
|
||||
PhysicsJointGroove() {}
|
||||
virtual ~PhysicsJointGroove() {}
|
||||
|
||||
Vec2 _grooveA;
|
||||
Vec2 _grooveB;
|
||||
Vec2 _anchr2;
|
||||
};
|
||||
|
||||
/** Likes a spring joint, but works with rotary */
|
||||
|
@ -221,13 +239,14 @@ public:
|
|||
void setStiffness(float stiffness);
|
||||
float getDamping() const;
|
||||
void setDamping(float damping);
|
||||
|
||||
protected:
|
||||
bool init(PhysicsBody* a, PhysicsBody* b, float stiffness, float damping);
|
||||
virtual bool createConstraints() override;
|
||||
|
||||
protected:
|
||||
PhysicsJointRotarySpring() {}
|
||||
virtual ~PhysicsJointRotarySpring() {}
|
||||
|
||||
float _stiffness;
|
||||
float _damping;
|
||||
};
|
||||
|
||||
/** Likes a limit joint, but works with rotary */
|
||||
|
@ -241,13 +260,14 @@ public:
|
|||
void setMin(float min);
|
||||
float getMax() const;
|
||||
void setMax(float max);
|
||||
|
||||
protected:
|
||||
bool init(PhysicsBody* a, PhysicsBody* b, float min, float max);
|
||||
virtual bool createConstraints() override;
|
||||
|
||||
protected:
|
||||
PhysicsJointRotaryLimit() {}
|
||||
virtual ~PhysicsJointRotaryLimit() {}
|
||||
|
||||
float _min;
|
||||
float _max;
|
||||
};
|
||||
|
||||
/** Works like a socket wrench. */
|
||||
|
@ -262,13 +282,14 @@ public:
|
|||
void setPhase(float phase);
|
||||
float getRatchet() const;
|
||||
void setRatchet(float ratchet);
|
||||
|
||||
protected:
|
||||
bool init(PhysicsBody* a, PhysicsBody* b, float phase, float ratchet);
|
||||
virtual bool createConstraints() override;
|
||||
|
||||
protected:
|
||||
PhysicsJointRatchet() {}
|
||||
virtual ~PhysicsJointRatchet() {}
|
||||
|
||||
float _phase;
|
||||
float _ratchet;
|
||||
};
|
||||
|
||||
/** Keeps the angular velocity ratio of a pair of bodies constant. */
|
||||
|
@ -282,12 +303,14 @@ public:
|
|||
float getRatio() const;
|
||||
void setRatio(float ratchet);
|
||||
|
||||
protected:
|
||||
bool init(PhysicsBody* a, PhysicsBody* b, float phase, float ratio);
|
||||
virtual bool createConstraints() override;
|
||||
|
||||
protected:
|
||||
PhysicsJointGear() {}
|
||||
virtual ~PhysicsJointGear() {}
|
||||
|
||||
float _phase;
|
||||
float _ratio;
|
||||
};
|
||||
|
||||
/** Keeps the relative angular velocity of a pair of bodies constant */
|
||||
|
@ -298,13 +321,13 @@ public:
|
|||
|
||||
float getRate() const;
|
||||
void setRate(float rate);
|
||||
|
||||
protected:
|
||||
bool init(PhysicsBody* a, PhysicsBody* b, float rate);
|
||||
virtual bool createConstraints() override;
|
||||
|
||||
protected:
|
||||
PhysicsJointMotor() {}
|
||||
virtual ~PhysicsJointMotor() {}
|
||||
|
||||
float _rate;
|
||||
};
|
||||
|
||||
NS_CC_END
|
||||
|
|
|
@ -50,7 +50,6 @@ PhysicsShape::PhysicsShape()
|
|||
, _scaleY(1.0f)
|
||||
, _newScaleX(1.0f)
|
||||
, _newScaleY(1.0f)
|
||||
, _dirty(false)
|
||||
, _tag(0)
|
||||
, _categoryBitmask(UINT_MAX)
|
||||
, _collisionBitmask(UINT_MAX)
|
||||
|
@ -112,50 +111,25 @@ void PhysicsShape::setMaterial(const PhysicsMaterial& material)
|
|||
setFriction(material.friction);
|
||||
}
|
||||
|
||||
void PhysicsShape::setScale(float scale)
|
||||
{
|
||||
setScaleX(scale);
|
||||
setScaleY(scale);
|
||||
}
|
||||
|
||||
void PhysicsShape::setScale(float scaleX, float scaleY)
|
||||
{
|
||||
setScaleX(scaleX);
|
||||
setScaleY(scaleY);
|
||||
}
|
||||
|
||||
void PhysicsShape::setScaleX(float scaleX)
|
||||
{
|
||||
if (_scaleX == scaleX)
|
||||
if (_scaleX != scaleX || _scaleY != scaleY)
|
||||
{
|
||||
if (_type == Type::CIRCLE && scaleX != scaleY)
|
||||
{
|
||||
CCLOG("PhysicsShapeCircle WARNING: CANNOT support setScale with different x and y");
|
||||
return;
|
||||
}
|
||||
|
||||
_newScaleX = scaleX;
|
||||
_dirty = true;
|
||||
}
|
||||
|
||||
void PhysicsShape::setScaleY(float scaleY)
|
||||
{
|
||||
if (_scaleY == scaleY)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_newScaleY = scaleY;
|
||||
_dirty = true;
|
||||
updateScale();
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicsShape::update(float delta)
|
||||
void PhysicsShape::updateScale()
|
||||
{
|
||||
CC_UNUSED_PARAM(delta);
|
||||
|
||||
if (_dirty)
|
||||
{
|
||||
_scaleX = _newScaleX;
|
||||
_scaleY = _newScaleY;
|
||||
_dirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicsShape::addShape(cpShape* shape)
|
||||
|
@ -399,63 +373,18 @@ Vec2 PhysicsShapeCircle::getOffset()
|
|||
return PhysicsHelper::cpv2point(cpCircleShapeGetOffset(_cpShapes.front()));
|
||||
}
|
||||
|
||||
void PhysicsShapeCircle::setScale(float scale)
|
||||
void PhysicsShapeCircle::updateScale()
|
||||
{
|
||||
if (_scaleX == scale)
|
||||
{
|
||||
return;
|
||||
}
|
||||
cpFloat factor = std::abs(PhysicsHelper::float2cpfloat(_newScaleX / _scaleX));
|
||||
|
||||
_newScaleX = _newScaleY = scale;
|
||||
_dirty = true;
|
||||
}
|
||||
|
||||
void PhysicsShapeCircle::setScale(float scaleX, float scaleY)
|
||||
{
|
||||
if (scaleX != scaleY)
|
||||
{
|
||||
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)
|
||||
{
|
||||
CCLOG("PhysicsShapeCircle WARNING: CANNOT support setScaleX");
|
||||
|
||||
setScale(scale);
|
||||
}
|
||||
|
||||
void PhysicsShapeCircle::setScaleY(float scale)
|
||||
{
|
||||
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);
|
||||
cpShape* shape = _cpShapes.front();
|
||||
cpVect v = cpCircleShapeGetOffset(shape);
|
||||
v = cpvmult(v, PhysicsHelper::float2cpfloat(factor));
|
||||
((cpCircleShape*)shape)->c = v;
|
||||
|
||||
cpCircleShapeSetRadius(shape, cpCircleShapeGetRadius(shape) * factor);
|
||||
}
|
||||
|
||||
PhysicsShape::update(delta);
|
||||
|
||||
PhysicsShape::updateScale();
|
||||
}
|
||||
|
||||
// PhysicsShapeEdgeSegment
|
||||
|
@ -515,24 +444,21 @@ Vec2 PhysicsShapeEdgeSegment::getCenter()
|
|||
return ( a + b ) / 2;
|
||||
}
|
||||
|
||||
void PhysicsShapeEdgeSegment::update(float delta)
|
||||
void PhysicsShapeEdgeSegment::updateScale()
|
||||
{
|
||||
if (_dirty)
|
||||
{
|
||||
auto factorX = PhysicsHelper::float2cpfloat(_newScaleX / _scaleX);
|
||||
auto factorY = PhysicsHelper::float2cpfloat(_newScaleY / _scaleY);
|
||||
cpFloat factorX = PhysicsHelper::float2cpfloat(_newScaleX / _scaleX);
|
||||
cpFloat factorY = PhysicsHelper::float2cpfloat(_newScaleY / _scaleY);
|
||||
|
||||
auto shape = _cpShapes.front();
|
||||
auto a = cpSegmentShapeGetA(shape);
|
||||
cpShape* shape = _cpShapes.front();
|
||||
cpVect a = cpSegmentShapeGetA(shape);
|
||||
a.x *= factorX;
|
||||
a.y *= factorY;
|
||||
auto b = cpSegmentShapeGetB(shape);
|
||||
cpVect b = cpSegmentShapeGetB(shape);
|
||||
b.x *= factorX;
|
||||
b.y *= factorY;
|
||||
cpSegmentShapeSetEndpoints(shape, a, b);
|
||||
}
|
||||
|
||||
PhysicsShape::update(delta);
|
||||
PhysicsShape::updateScale();
|
||||
}
|
||||
|
||||
// PhysicsShapeBox
|
||||
|
@ -682,26 +608,24 @@ Vec2 PhysicsShapePolygon::getCenter()
|
|||
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)
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
vects[i].x *= factorX;
|
||||
vects[i].y *= factorY;
|
||||
}
|
||||
|
||||
// convert hole to clockwise
|
||||
if ( factorX * factorY < 0 )
|
||||
if (factorX * factorY < 0)
|
||||
{
|
||||
for (int i = 0; i < count / 2; ++i)
|
||||
{
|
||||
|
@ -718,9 +642,8 @@ void PhysicsShapePolygon::update(float delta)
|
|||
planes[i].n = n;
|
||||
planes[i].d = cpvdot(n, vects[i]);
|
||||
}
|
||||
}
|
||||
|
||||
PhysicsShape::update(delta);
|
||||
PhysicsShape::updateScale();
|
||||
}
|
||||
|
||||
// PhysicsShapeEdgeBox
|
||||
|
@ -865,14 +788,12 @@ PhysicsShapeEdgeChain* PhysicsShapeEdgeChain::create(const Vec2* points, int cou
|
|||
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)
|
||||
for (auto shape : _cpShapes)
|
||||
{
|
||||
cpVect a = cpSegmentShapeGetA(shape);
|
||||
a.x *= factorX;
|
||||
|
@ -882,9 +803,8 @@ void PhysicsShapeEdgePolygon::update(float delta)
|
|||
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*/)
|
||||
|
@ -957,14 +877,12 @@ int PhysicsShapeEdgeChain::getPointsCount() const
|
|||
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)
|
||||
for (auto shape : _cpShapes)
|
||||
{
|
||||
cpVect a = cpSegmentShapeGetA(shape);
|
||||
a.x *= factorX;
|
||||
|
@ -974,9 +892,8 @@ void PhysicsShapeEdgeChain::update(float delta)
|
|||
b.y *= factorY;
|
||||
cpSegmentShapeSetEndpoints(shape, a, b);
|
||||
}
|
||||
}
|
||||
|
||||
PhysicsShape::update(delta);
|
||||
PhysicsShape::updateScale();
|
||||
}
|
||||
|
||||
void PhysicsShape::setGroup(int group)
|
||||
|
|
|
@ -56,7 +56,7 @@ typedef struct CC_DLL 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.
|
||||
|
@ -153,11 +153,8 @@ protected:
|
|||
/** calculate the area of this shape */
|
||||
virtual float calculateArea() { return 0.0f; }
|
||||
|
||||
virtual void setScale(float scale);
|
||||
virtual void setScale(float scaleX, float scaleY);
|
||||
virtual void setScaleX(float scaleX);
|
||||
virtual void setScaleY(float scaleY);
|
||||
virtual void update(float delta);
|
||||
virtual void updateScale();
|
||||
void addShape(cpShape* shape);
|
||||
|
||||
protected:
|
||||
|
@ -176,7 +173,6 @@ protected:
|
|||
float _scaleY;
|
||||
float _newScaleX;
|
||||
float _newScaleY;
|
||||
bool _dirty;
|
||||
PhysicsMaterial _material;
|
||||
int _tag;
|
||||
int _categoryBitmask;
|
||||
|
@ -206,11 +202,7 @@ public:
|
|||
protected:
|
||||
bool init(float radius, const PhysicsMaterial& material = PHYSICSSHAPE_MATERIAL_DEFAULT, const Vec2& offset = Vec2::ZERO);
|
||||
virtual float calculateArea() override;
|
||||
virtual void setScale(float scale) 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;
|
||||
virtual void updateScale() override;
|
||||
|
||||
protected:
|
||||
PhysicsShapeCircle();
|
||||
|
@ -234,7 +226,7 @@ public:
|
|||
protected:
|
||||
bool init(const Vec2* points, int count, const PhysicsMaterial& material = PHYSICSSHAPE_MATERIAL_DEFAULT, const Vec2& offset = Vec2::ZERO);
|
||||
float calculateArea() override;
|
||||
virtual void update(float delta) override;
|
||||
virtual void updateScale() override;
|
||||
|
||||
protected:
|
||||
PhysicsShapePolygon();
|
||||
|
@ -270,7 +262,7 @@ public:
|
|||
|
||||
protected:
|
||||
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:
|
||||
PhysicsShapeEdgeSegment();
|
||||
|
@ -290,7 +282,7 @@ public:
|
|||
|
||||
protected:
|
||||
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:
|
||||
PhysicsShapeEdgePolygon();
|
||||
|
@ -327,7 +319,7 @@ public:
|
|||
|
||||
protected:
|
||||
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:
|
||||
PhysicsShapeEdgeChain();
|
||||
|
|
|
@ -481,7 +481,6 @@ void PhysicsWorld::doAddBody(PhysicsBody* body)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void PhysicsWorld::addBodyOrDelay(PhysicsBody* body)
|
||||
{
|
||||
auto removeBodyIter = _delayRemoveBodies.find(body);
|
||||
|
@ -491,18 +490,11 @@ void PhysicsWorld::addBodyOrDelay(PhysicsBody* body)
|
|||
return;
|
||||
}
|
||||
|
||||
if (cpSpaceIsLocked(_cpSpace))
|
||||
{
|
||||
if (_delayAddBodies.find(body) == _delayAddBodies.end())
|
||||
{
|
||||
_delayAddBodies.pushBack(body);
|
||||
_delayDirty = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
doAddBody(body);
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicsWorld::updateBodies()
|
||||
|
@ -542,7 +534,6 @@ void PhysicsWorld::removeBody(int tag)
|
|||
|
||||
void PhysicsWorld::removeBody(PhysicsBody* body)
|
||||
{
|
||||
|
||||
if (body->getWorld() != this)
|
||||
{
|
||||
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
|
||||
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, 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;
|
||||
removeJoint(joint, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
delete joint;
|
||||
}
|
||||
}
|
||||
|
||||
body->_joints.clear();
|
||||
|
||||
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)
|
||||
{
|
||||
for (auto constraint : joint->_cpConstraints)
|
||||
{
|
||||
cpSpaceAddConstraint(_cpSpace, constraint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicsWorld::removeJoint(PhysicsJoint* joint, bool destroy)
|
||||
{
|
||||
if (joint->getWorld() != this)
|
||||
{
|
||||
if (destroy)
|
||||
if (joint->getWorld() != this && destroy)
|
||||
{
|
||||
CCLOG("physics warnning: the joint is not in this world, it won't be destoried utill the body it conntect is destoried");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
removeJointOrDelay(joint);
|
||||
|
||||
_joints.remove(joint);
|
||||
joint->_world = nullptr;
|
||||
|
||||
// clean the connection to this joint
|
||||
if (destroy)
|
||||
joint->_destoryMark = destroy;
|
||||
if (cpSpaceIsLocked(_cpSpace))
|
||||
{
|
||||
if (joint->getBodyA() != nullptr)
|
||||
auto it = std::find(_delayAddJoints.begin(), _delayAddJoints.end(), joint);
|
||||
if (it != _delayAddJoints.end())
|
||||
{
|
||||
joint->getBodyA()->removeJoint(joint);
|
||||
_delayAddJoints.erase(it);
|
||||
return;
|
||||
}
|
||||
|
||||
if (joint->getBodyB() != nullptr)
|
||||
if (std::find(_delayRemoveJoints.rbegin(), _delayRemoveJoints.rend(), joint) == _delayRemoveJoints.rend())
|
||||
{
|
||||
joint->getBodyB()->removeJoint(joint);
|
||||
_delayRemoveJoints.push_back(joint);
|
||||
_delayDirty = true;
|
||||
}
|
||||
|
||||
// test the distraction is delaied or not
|
||||
if (std::find(_delayRemoveJoints.rbegin(), _delayRemoveJoints.rend(), joint) != _delayRemoveJoints.rend())
|
||||
{
|
||||
joint->_destoryMark = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
delete joint;
|
||||
doRemoveJoint(joint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -657,24 +615,25 @@ void PhysicsWorld::updateJoints()
|
|||
return;
|
||||
}
|
||||
|
||||
auto addCopy = _delayAddJoints;
|
||||
_delayAddJoints.clear();
|
||||
for (auto joint : addCopy)
|
||||
for (auto joint : _delayAddJoints)
|
||||
{
|
||||
doAddJoint(joint);
|
||||
joint->_world = this;
|
||||
if (joint->initJoint())
|
||||
{
|
||||
_joints.push_back(joint);
|
||||
}
|
||||
|
||||
auto removeCopy = _delayRemoveJoints;
|
||||
_delayRemoveJoints.clear();
|
||||
for (auto joint : removeCopy)
|
||||
{
|
||||
doRemoveJoint(joint);
|
||||
|
||||
if (joint->_destoryMark)
|
||||
else
|
||||
{
|
||||
delete joint;
|
||||
}
|
||||
}
|
||||
_delayAddJoints.clear();
|
||||
|
||||
for (auto joint : _delayRemoveJoints)
|
||||
{
|
||||
doRemoveJoint(joint);
|
||||
}
|
||||
_delayRemoveJoints.clear();
|
||||
}
|
||||
|
||||
void PhysicsWorld::removeShape(PhysicsShape* shape)
|
||||
|
@ -691,8 +650,15 @@ void PhysicsWorld::removeShape(PhysicsShape* shape)
|
|||
}
|
||||
}
|
||||
|
||||
void PhysicsWorld::addJointOrDelay(PhysicsJoint* joint)
|
||||
void PhysicsWorld::addJoint(PhysicsJoint* joint)
|
||||
{
|
||||
if (joint)
|
||||
{
|
||||
if (joint->getWorld() && joint->getWorld() != this)
|
||||
{
|
||||
joint->removeFormWorld();
|
||||
}
|
||||
|
||||
auto it = std::find(_delayRemoveJoints.begin(), _delayRemoveJoints.end(), joint);
|
||||
if (it != _delayRemoveJoints.end())
|
||||
{
|
||||
|
@ -700,86 +666,21 @@ void PhysicsWorld::addJointOrDelay(PhysicsJoint* joint)
|
|||
return;
|
||||
}
|
||||
|
||||
if (cpSpaceIsLocked(_cpSpace))
|
||||
{
|
||||
if (std::find(_delayAddJoints.begin(), _delayAddJoints.end(), joint) == _delayAddJoints.end())
|
||||
{
|
||||
_delayAddJoints.push_back(joint);
|
||||
_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)
|
||||
{
|
||||
for (auto joint : _joints)
|
||||
auto removeCopy = _joints;
|
||||
for (auto joint : removeCopy)
|
||||
{
|
||||
removeJointOrDelay(joint);
|
||||
joint->_world = nullptr;
|
||||
|
||||
// clean the connection to this joint
|
||||
if (destroy)
|
||||
{
|
||||
if (joint->getBodyA() != nullptr)
|
||||
{
|
||||
joint->getBodyA()->removeJoint(joint);
|
||||
removeJoint(joint, destroy);
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -816,6 +717,23 @@ void PhysicsWorld::doRemoveJoint(PhysicsJoint* joint)
|
|||
{
|
||||
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()
|
||||
|
@ -889,11 +807,18 @@ void PhysicsWorld::step(float delta)
|
|||
|
||||
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)
|
||||
{
|
||||
// the updateJoints must run before the updateBodies.
|
||||
updateJoints();
|
||||
updateBodies();
|
||||
updateJoints();
|
||||
|
||||
_delayDirty = !(_delayAddBodies.size() == 0 && _delayRemoveBodies.size() == 0 && _delayAddJoints.size() == 0 && _delayRemoveJoints.size() == 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@ class PhysicsContact;
|
|||
|
||||
typedef Vec2 Vect;
|
||||
|
||||
class Director;
|
||||
class Node;
|
||||
class Sprite;
|
||||
class Scene;
|
||||
|
@ -188,12 +189,9 @@ protected:
|
|||
|
||||
virtual void doAddBody(PhysicsBody* body);
|
||||
virtual void doRemoveBody(PhysicsBody* body);
|
||||
virtual void doAddJoint(PhysicsJoint* joint);
|
||||
virtual void doRemoveJoint(PhysicsJoint* joint);
|
||||
virtual void addBodyOrDelay(PhysicsBody* body);
|
||||
virtual void removeBodyOrDelay(PhysicsBody* body);
|
||||
virtual void addJointOrDelay(PhysicsJoint* joint);
|
||||
virtual void removeJointOrDelay(PhysicsJoint* joint);
|
||||
virtual void updateBodies();
|
||||
virtual void updateJoints();
|
||||
|
||||
|
@ -228,6 +226,7 @@ protected:
|
|||
friend class Node;
|
||||
friend class Sprite;
|
||||
friend class Scene;
|
||||
friend class Director;
|
||||
friend class PhysicsBody;
|
||||
friend class PhysicsShape;
|
||||
friend class PhysicsJoint;
|
||||
|
|
|
@ -434,7 +434,6 @@ void PhysicsDemo::onTouchEnded(Touch* touch, Event* event)
|
|||
this->removeChild(it->second);
|
||||
_mouses.erase(it);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void PhysicsDemoLogoSmash::onEnter()
|
||||
|
@ -716,8 +715,6 @@ void PhysicsDemoJoints::onEnter()
|
|||
listener->onTouchEnded = CC_CALLBACK_2(PhysicsDemoJoints::onTouchEnded, this);
|
||||
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
|
||||
|
||||
//_scene->getPhysicsWorld()->setGravity(Point::ZERO);
|
||||
|
||||
float width = (VisibleRect::getVisibleRect().size.width - 10) / 4;
|
||||
float height = (VisibleRect::getVisibleRect().size.height - 50) / 4;
|
||||
|
||||
|
@ -768,7 +765,6 @@ void PhysicsDemoJoints::onEnter()
|
|||
}
|
||||
case 2:
|
||||
{
|
||||
|
||||
auto sp1 = makeBall(offset - Vec2(30, 0), 10);
|
||||
sp1->getPhysicsBody()->setTag(DRAG_BODYS_TAG);
|
||||
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->setCategoryBitmask(0x01);
|
||||
node->setPhysicsBody(body);
|
||||
node->setPosition(Vec2::ZERO);
|
||||
this->addChild(node);
|
||||
|
||||
// balls
|
||||
for (int i = 0; i < 6; ++i)
|
||||
|
@ -997,8 +996,7 @@ void PhysicsDemoPump::onEnter()
|
|||
addChild(ball);
|
||||
}
|
||||
|
||||
node->setPhysicsBody(body);
|
||||
this->addChild(node);
|
||||
auto _world = _scene->getPhysicsWorld();
|
||||
|
||||
Vec2 vec[4] =
|
||||
{
|
||||
|
@ -1008,30 +1006,6 @@ void PhysicsDemoPump::onEnter()
|
|||
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
|
||||
auto pump = Node::create();
|
||||
auto center = PhysicsShape::getPolyonCenter(vec, 4);
|
||||
|
@ -1041,8 +1015,31 @@ void PhysicsDemoPump::onEnter()
|
|||
this->addChild(pump);
|
||||
pumpB->setCategoryBitmask(0x02);
|
||||
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)));
|
||||
|
||||
// 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
|
||||
Vec2 seg[] = {VisibleRect::leftTop() + Vec2(75, -120), VisibleRect::leftBottom() + Vec2(75, -100)};
|
||||
Vec2 segCenter = (seg[1] + seg[0])/2;
|
||||
|
@ -1059,7 +1056,7 @@ void PhysicsDemoPump::onEnter()
|
|||
pluggerB->setCategoryBitmask(0x02);
|
||||
sgearB->setCollisionBitmask(0x04 | 0x01);
|
||||
_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)
|
||||
|
|
Loading…
Reference in New Issue