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
|
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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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())
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue