From 72715ce3fa25d883ad5225193c1d3fd4cbffe855 Mon Sep 17 00:00:00 2001 From: boyu0 Date: Tue, 19 Nov 2013 18:30:12 +0800 Subject: [PATCH 1/4] issue #2771: fix collision bug cause by dynamic/static cast. --- cocos/physics/CCPhysicsBody.cpp | 52 ++++++++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/cocos/physics/CCPhysicsBody.cpp b/cocos/physics/CCPhysicsBody.cpp index 4d69d5c52095..ef528c923f4f 100644 --- a/cocos/physics/CCPhysicsBody.cpp +++ b/cocos/physics/CCPhysicsBody.cpp @@ -293,19 +293,32 @@ void PhysicsBody::setDynamic(bool dynamic) if (dynamic) { cpBodySetMass(_info->getBody(), _mass); + cpBodySetMoment(_info->getBody(), _moment); if (_world != nullptr) { + // reset the gravity enable + if (isGravityEnabled()) + { + _gravityEnable = false; + setGravityEnable(true); + } + cpSpaceAddBody(_world->_info->getSpace(), _info->getBody()); } - }else + } + else { - cpBodySetMass(_info->getBody(), PHYSICS_INFINITY); - if (_world != nullptr) { cpSpaceRemoveBody(_world->_info->getSpace(), _info->getBody()); } + + // avoid incorrect collion simulation. + cpBodySetMass(_info->getBody(), PHYSICS_INFINITY); + cpBodySetMoment(_info->getBody(), PHYSICS_INFINITY); + cpBodySetVel(_info->getBody(), cpvzero); + cpBodySetAngVel(_info->getBody(), 0.0f); } } @@ -432,7 +445,8 @@ void PhysicsBody::applyTorque(float torque) void PhysicsBody::setMass(float mass) { - if (mass <= 0) + // cann't set mass for static body manually + if (mass <= 0 || !_dynamic) { return; } @@ -461,6 +475,12 @@ void PhysicsBody::setMass(float mass) void PhysicsBody::addMass(float mass) { + // cann't set mass for static body manually + if (!_dynamic) + { + return; + } + if (mass == PHYSICS_INFINITY) { _mass = PHYSICS_INFINITY; @@ -503,6 +523,12 @@ void PhysicsBody::addMass(float mass) void PhysicsBody::addMoment(float moment) { + // cann't set moment for static body manually + if (!_dynamic) + { + return; + } + if (moment == PHYSICS_INFINITY) { // if moment is INFINITY, the moment of the body will become INFINITY @@ -545,6 +571,12 @@ void PhysicsBody::addMoment(float moment) void PhysicsBody::setVelocity(const Point& velocity) { + // cann't set velocity for a static body + if (!_dynamic) + { + return; + } + cpBodySetVel(_info->getBody(), PhysicsHelper::point2cpv(velocity)); } @@ -565,6 +597,12 @@ Point PhysicsBody::getVelocityAtWorldPoint(const Point& point) void PhysicsBody::setAngularVelocity(float velocity) { + // cann't set angular velocity for a static body + if (!_dynamic) + { + return; + } + cpBodySetAngVel(_info->getBody(), PhysicsHelper::float2cpfloat(velocity)); } @@ -595,6 +633,12 @@ float PhysicsBody::getAngularVelocityLimit() void PhysicsBody::setMoment(float moment) { + // cann't set moment for static body manually + if (!_dynamic) + { + return; + } + _moment = moment; _momentDefault = false; From 79e4556d8f05d57f26a0b2bf50d60fecfce42de6 Mon Sep 17 00:00:00 2001 From: boyu0 Date: Wed, 20 Nov 2013 10:25:43 +0800 Subject: [PATCH 2/4] issue #2771: add some warning log --- cocos/physics/CCPhysicsBody.cpp | 43 +++++++++++++-------------------- 1 file changed, 17 insertions(+), 26 deletions(-) diff --git a/cocos/physics/CCPhysicsBody.cpp b/cocos/physics/CCPhysicsBody.cpp index ef528c923f4f..69772073ac8e 100644 --- a/cocos/physics/CCPhysicsBody.cpp +++ b/cocos/physics/CCPhysicsBody.cpp @@ -445,8 +445,7 @@ void PhysicsBody::applyTorque(float torque) void PhysicsBody::setMass(float mass) { - // cann't set mass for static body manually - if (mass <= 0 || !_dynamic) + if (mass <= 0) { return; } @@ -470,17 +469,15 @@ void PhysicsBody::setMass(float mass) } } - cpBodySetMass(_info->getBody(), PhysicsHelper::float2cpfloat(_mass)); + // the static body's mass and moment is always infinity + if (_dynamic) + { + cpBodySetMass(_info->getBody(), PhysicsHelper::float2cpfloat(_mass)); + } } void PhysicsBody::addMass(float mass) { - // cann't set mass for static body manually - if (!_dynamic) - { - return; - } - if (mass == PHYSICS_INFINITY) { _mass = PHYSICS_INFINITY; @@ -518,17 +515,15 @@ void PhysicsBody::addMass(float mass) } } - cpBodySetMass(_info->getBody(), PhysicsHelper::float2cpfloat(_mass)); + // the static body's mass and moment is always infinity + if (_dynamic) + { + cpBodySetMass(_info->getBody(), PhysicsHelper::float2cpfloat(_mass)); + } } void PhysicsBody::addMoment(float moment) { - // cann't set moment for static body manually - if (!_dynamic) - { - return; - } - if (moment == PHYSICS_INFINITY) { // if moment is INFINITY, the moment of the body will become INFINITY @@ -563,7 +558,8 @@ void PhysicsBody::addMoment(float moment) } } - if (_rotationEnable) + // the static body's mass and moment is always infinity + if (_rotationEnable && _dynamic) { cpBodySetMoment(_info->getBody(), PhysicsHelper::float2cpfloat(_moment)); } @@ -571,9 +567,9 @@ void PhysicsBody::addMoment(float moment) void PhysicsBody::setVelocity(const Point& velocity) { - // cann't set velocity for a static body if (!_dynamic) { + CCLOG("physics warning: your cann't set velocity for a static body."); return; } @@ -597,9 +593,9 @@ Point PhysicsBody::getVelocityAtWorldPoint(const Point& point) void PhysicsBody::setAngularVelocity(float velocity) { - // cann't set angular velocity for a static body if (!_dynamic) { + CCLOG("physics warning: your cann't set angular velocity for a static body."); return; } @@ -633,16 +629,11 @@ float PhysicsBody::getAngularVelocityLimit() void PhysicsBody::setMoment(float moment) { - // cann't set moment for static body manually - if (!_dynamic) - { - return; - } - _moment = moment; _momentDefault = false; - if (_rotationEnable) + // the static body's mass and moment is always infinity + if (_rotationEnable && _dynamic) { cpBodySetMoment(_info->getBody(), PhysicsHelper::float2cpfloat(_moment)); } From 1e122ce4020c0b4d1c2445ef2e6bc9c6e484722b Mon Sep 17 00:00:00 2001 From: boyu0 Date: Wed, 20 Nov 2013 15:54:09 +0800 Subject: [PATCH 3/4] issue #2771: fix crash bug --- cocos/physics/CCPhysicsWorld.cpp | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/cocos/physics/CCPhysicsWorld.cpp b/cocos/physics/CCPhysicsWorld.cpp index 48023afb0427..ded5105c9396 100644 --- a/cocos/physics/CCPhysicsWorld.cpp +++ b/cocos/physics/CCPhysicsWorld.cpp @@ -481,9 +481,25 @@ void PhysicsWorld::removeBody(PhysicsBody* body) // destory the body's joints for (auto joint : body->_joints) { - removeJoint(joint, true); + // set destroy param to false to keep the iterator available + removeJoint(joint, false); + + PhysicsBody* other = (joint->getBodyA() == body ? body : joint->getBodyB()); + other->removeJoint(joint); + + // test the distraction is delaied or not + if (_delayRemoveJoints.size() > 0 && _delayRemoveJoints.back() == joint) + { + joint->_destoryMark = true; + } + else + { + delete joint; + } } + body->_joints.clear(); + removeBodyOrDelay(body); _bodies->removeObject(body); body->_world = nullptr; From 7f8fb34e334a3d08c0dcf48caa7508a2def89f34 Mon Sep 17 00:00:00 2001 From: boyu0 Date: Wed, 20 Nov 2013 16:08:48 +0800 Subject: [PATCH 4/4] issue #2771: fix a careless mistake --- cocos/physics/CCPhysicsWorld.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cocos/physics/CCPhysicsWorld.cpp b/cocos/physics/CCPhysicsWorld.cpp index ded5105c9396..1e1e06c4c6e1 100644 --- a/cocos/physics/CCPhysicsWorld.cpp +++ b/cocos/physics/CCPhysicsWorld.cpp @@ -484,7 +484,7 @@ void PhysicsWorld::removeBody(PhysicsBody* body) // set destroy param to false to keep the iterator available removeJoint(joint, false); - PhysicsBody* other = (joint->getBodyA() == body ? body : joint->getBodyB()); + PhysicsBody* other = (joint->getBodyA() == body ? joint->getBodyB() : body); other->removeJoint(joint); // test the distraction is delaied or not