From cae9a3e54f0ceef46de85e5cafd516b3b8ef09b1 Mon Sep 17 00:00:00 2001 From: boyu0 Date: Tue, 29 Oct 2013 17:31:35 +0800 Subject: [PATCH] issue #2771: add physics pump demo and fix bugs --- cocos/physics/CCPhysicsBody.cpp | 66 ++++- cocos/physics/CCPhysicsBody.h | 20 +- cocos/physics/CCPhysicsJoint.cpp | 43 ++++ cocos/physics/CCPhysicsJoint.h | 14 ++ cocos/physics/CCPhysicsShape.cpp | 15 ++ cocos/physics/CCPhysicsShape.h | 14 ++ cocos/physics/CCPhysicsWorld.cpp | 139 +++++++--- cocos/physics/CCPhysicsWorld.h | 12 +- cocos/physics/chipmunk/CCPhysicsBodyInfo.cpp | 1 - cocos/physics/chipmunk/CCPhysicsBodyInfo.h | 7 +- cocos/physics/chipmunk/CCPhysicsContactInfo.h | 6 +- cocos/physics/chipmunk/CCPhysicsHelper.h | 6 +- cocos/physics/chipmunk/CCPhysicsJointInfo.h | 6 +- cocos/physics/chipmunk/CCPhysicsShapeInfo.h | 6 +- cocos/physics/chipmunk/CCPhysicsWorldInfo.h | 6 +- .../Classes/PhysicsTest/PhysicsTest.cpp | 237 ++++++++++++++++-- .../TestCpp/Classes/PhysicsTest/PhysicsTest.h | 29 ++- 17 files changed, 529 insertions(+), 98 deletions(-) diff --git a/cocos/physics/CCPhysicsBody.cpp b/cocos/physics/CCPhysicsBody.cpp index e3335c7c16..a4393c4435 100644 --- a/cocos/physics/CCPhysicsBody.cpp +++ b/cocos/physics/CCPhysicsBody.cpp @@ -57,7 +57,6 @@ namespace { static const float MASS_DEFAULT = 1.0; static const float MOMENT_DEFAULT = 200; - static float GROUP_INDEX = 0; } PhysicsBody::PhysicsBody() @@ -81,6 +80,7 @@ PhysicsBody::PhysicsBody() , _categoryBitmask(UINT_MAX) , _collisionBitmask(UINT_MAX) , _contactTestBitmask(0) +, _group(0) { } @@ -273,7 +273,6 @@ bool PhysicsBody::init() _shapes->retain(); _info->body = cpBodyNew(PhysicsHelper::float2cpfloat(_mass), PhysicsHelper::float2cpfloat(_moment)); - _info->group = ++GROUP_INDEX; CC_BREAK_IF(_info->body == nullptr); @@ -321,10 +320,10 @@ void PhysicsBody::setGravityEnable(bool enable) { if (enable) { - applyForce(_world->getGravity()); + applyForce(_world->getGravity() * _mass); }else { - applyForce(-_world->getGravity()); + applyForce(-_world->getGravity() * _mass); } } } @@ -351,9 +350,9 @@ float PhysicsBody::getRotation() const return -PhysicsHelper::cpfloat2float(cpBodyGetAngle(_info->body) / 3.14f * 180.0f); } -void PhysicsBody::addShape(PhysicsShape* shape) +PhysicsShape* PhysicsBody::addShape(PhysicsShape* shape) { - if (shape == nullptr) return; + if (shape == nullptr) return nullptr; // add shape to body if (_shapes->getIndexOfObject(shape) == UINT_MAX) @@ -372,7 +371,14 @@ void PhysicsBody::addShape(PhysicsShape* shape) } _shapes->addObject(shape); + + if (_group != CP_NO_GROUP && shape->getGroup() == CP_NO_GROUP) + { + shape->setGroup(_group); + } } + + return shape; } void PhysicsBody::applyForce(Point force) @@ -676,6 +682,54 @@ void PhysicsBody::update(float delta) } } +void PhysicsBody::setCategoryBitmask(int bitmask) +{ + _categoryBitmask = bitmask; + + for (auto shape : *_shapes) + { + ((PhysicsShape*)shape)->setCategoryBitmask(bitmask); + } +} + +void PhysicsBody::setContactTestBitmask(int bitmask) +{ + _contactTestBitmask = bitmask; + + for (auto shape : *_shapes) + { + ((PhysicsShape*)shape)->setContactTestBitmask(bitmask); + } +} + +void PhysicsBody::setCollisionBitmask(int bitmask) +{ + _collisionBitmask = bitmask; + + for (auto shape : *_shapes) + { + ((PhysicsShape*)shape)->setCollisionBitmask(bitmask); + } +} + +void PhysicsBody::setGroup(int group) +{ + for (auto shape : *_shapes) + { + ((PhysicsShape*)shape)->setGroup(group); + } +} + +Point PhysicsBody::world2Local(const Point& point) +{ + return PhysicsHelper::cpv2point(cpBodyWorld2Local(_info->body, PhysicsHelper::point2cpv(point))); +} + +Point PhysicsBody::local2World(const Point& point) +{ + return PhysicsHelper::cpv2point(cpBodyLocal2World(_info->body, PhysicsHelper::point2cpv(point))); +} + //Clonable* PhysicsBody::clone() const //{ // PhysicsBody* body = new PhysicsBody(); diff --git a/cocos/physics/CCPhysicsBody.h b/cocos/physics/CCPhysicsBody.h index 7d569075f8..a82b7dc1d4 100644 --- a/cocos/physics/CCPhysicsBody.h +++ b/cocos/physics/CCPhysicsBody.h @@ -87,7 +87,7 @@ public: */ static PhysicsBody* createEdgeChain(Point* points, int count, PhysicsMaterial material = PHYSICSBODY_MATERIAL_DEFAULT, float border = 1); - virtual void addShape(PhysicsShape* shape); + virtual PhysicsShape* addShape(PhysicsShape* shape); /** * @brief Applies a immediate force to body. @@ -154,13 +154,16 @@ public: */ inline Node* getOwner() const { return _owner; } - inline void setCategoryBitmask(int bitmask) { _categoryBitmask = bitmask; } + void setCategoryBitmask(int bitmask); + void setContactTestBitmask(int bitmask); + void setCollisionBitmask(int bitmask); inline int getCategoryBitmask() const { return _categoryBitmask; } - inline void setContactTestBitmask(int bitmask) { _contactTestBitmask = bitmask; } inline int getContactTestBitmask() const { return _contactTestBitmask; } - inline void setCollisionBitmask(int bitmask) { _collisionBitmask = bitmask; } inline int getCollisionBitmask() const { return _collisionBitmask; } + void setGroup(int group); + inline int getGroup() { return _group; } + /* * @brief get the body position. */ @@ -246,6 +249,8 @@ public: inline int getTag() { return _tag; } inline void setTag(int tag) { _tag = tag; } + Point world2Local(const Point& point); + Point local2World(const Point& point); protected: @@ -280,9 +285,10 @@ protected: float _angularDamping; int _tag; - int _categoryBitmask; - int _collisionBitmask; - int _contactTestBitmask; + int _categoryBitmask; + int _collisionBitmask; + int _contactTestBitmask; + int _group; friend class PhysicsWorld; friend class PhysicsShape; diff --git a/cocos/physics/CCPhysicsJoint.cpp b/cocos/physics/CCPhysicsJoint.cpp index 0abca9e9a4..1268ac2460 100644 --- a/cocos/physics/CCPhysicsJoint.cpp +++ b/cocos/physics/CCPhysicsJoint.cpp @@ -144,6 +144,16 @@ PhysicsJointLimit::~PhysicsJointLimit() } +PhysicsJointDistance::PhysicsJointDistance() +{ + +} + +PhysicsJointDistance::~PhysicsJointDistance() +{ + +} + #if (CC_PHYSICS_ENGINE == CC_PHYSICS_CHIPMUNK) PhysicsBodyInfo* PhysicsJoint::bodyInfo(PhysicsBody* body) const { @@ -343,6 +353,39 @@ void PhysicsJointLimit::setMax(float max) cpSlideJointSetMax(_info->joints.front(), PhysicsHelper::float2cpfloat(max)); } +PhysicsJointDistance* PhysicsJointDistance::create(PhysicsBody* a, PhysicsBody* b, const Point& anchr1, const Point& anchr2) +{ + PhysicsJointDistance* joint = new PhysicsJointDistance(); + + if (joint && joint->init(a, b, anchr1, anchr2)) + { + return joint; + } + + CC_SAFE_DELETE(joint); + return nullptr; +} + +bool PhysicsJointDistance::init(PhysicsBody* a, PhysicsBody* b, const Point& anchr1, const Point& anchr2) +{ + do + { + CC_BREAK_IF(!PhysicsJoint::init(a, b)); + + cpConstraint* joint = cpPinJointNew(bodyInfo(a)->body, + bodyInfo(b)->body, + PhysicsHelper::point2cpv(anchr1), PhysicsHelper::point2cpv(anchr2)); + + CC_BREAK_IF(joint == nullptr); + + _info->add(joint); + + return true; + } while (false); + + return false; +} + #elif (CC_PHYSICS_ENGINE == CC_PHYSICS_BOX2D) #endif diff --git a/cocos/physics/CCPhysicsJoint.h b/cocos/physics/CCPhysicsJoint.h index d6c0d5df15..298992c5f3 100644 --- a/cocos/physics/CCPhysicsJoint.h +++ b/cocos/physics/CCPhysicsJoint.h @@ -165,6 +165,20 @@ protected: virtual ~PhysicsJointPin(); }; +class PhysicsJointDistance : public PhysicsJoint +{ + +public: + static PhysicsJointDistance* create(PhysicsBody* a, PhysicsBody* b, const Point& anchr1, const Point& anchr2); + +protected: + bool init(PhysicsBody* a, PhysicsBody* b, const Point& anchr1, const Point& anchr2); + +protected: + PhysicsJointDistance(); + virtual ~PhysicsJointDistance(); +}; + NS_CC_END #endif // __CCPHYSICS_JOINT_H__ diff --git a/cocos/physics/CCPhysicsShape.cpp b/cocos/physics/CCPhysicsShape.cpp index 77634e9113..6b166da351 100644 --- a/cocos/physics/CCPhysicsShape.cpp +++ b/cocos/physics/CCPhysicsShape.cpp @@ -50,6 +50,10 @@ PhysicsShape::PhysicsShape() , _mass(0) , _moment(0) , _tag(0) +, _categoryBitmask(UINT_MAX) +, _collisionBitmask(UINT_MAX) +, _contactTestBitmask(0) +, _group(0) { } @@ -777,6 +781,17 @@ int PhysicsShapeEdgeChain::getPointsCount() return _info->shapes.size() + 1; } +void PhysicsShape::setGroup(int group) +{ + if (group < 0) + { + for (auto shape : _info->shapes) + { + cpShapeSetGroup(shape, (cpGroup)group); + } + } +} + #elif (CC_PHYSICS_ENGINE == CC_PHYSICS_BOX2D) #endif diff --git a/cocos/physics/CCPhysicsShape.h b/cocos/physics/CCPhysicsShape.h index 02e6f604c0..8bc9224bf1 100644 --- a/cocos/physics/CCPhysicsShape.h +++ b/cocos/physics/CCPhysicsShape.h @@ -102,6 +102,16 @@ public: static Point* recenterPoints(Point* points, int count, Point center = Point::ZERO); static Point getPolyonCenter(Point* points, int count); + inline void setCategoryBitmask(int bitmask) { _categoryBitmask = bitmask; } + inline int getCategoryBitmask() const { return _categoryBitmask; } + inline void setContactTestBitmask(int bitmask) { _contactTestBitmask = bitmask; } + inline int getContactTestBitmask() const { return _contactTestBitmask; } + inline void setCollisionBitmask(int bitmask) { _collisionBitmask = bitmask; } + inline int getCollisionBitmask() const { return _collisionBitmask; } + + void setGroup(int group); + inline int getGroup() { return _group; } + protected: bool init(Type type); @@ -125,6 +135,10 @@ protected: float _moment; PhysicsMaterial _material; int _tag; + int _categoryBitmask; + int _collisionBitmask; + int _contactTestBitmask; + int _group; friend class PhysicsWorld; friend class PhysicsBody; diff --git a/cocos/physics/CCPhysicsWorld.cpp b/cocos/physics/CCPhysicsWorld.cpp index c01f9ac640..459261f896 100644 --- a/cocos/physics/CCPhysicsWorld.cpp +++ b/cocos/physics/CCPhysicsWorld.cpp @@ -181,9 +181,9 @@ bool PhysicsWorld::init() { _info = new PhysicsWorldInfo(); CC_BREAK_IF(_info == nullptr); - _bodys = Array::create(); - CC_BREAK_IF(_bodys == nullptr); - _bodys->retain(); + _bodies = Array::create(); + CC_BREAK_IF(_bodies == nullptr); + _bodies->retain(); cpSpaceSetGravity(_info->space, PhysicsHelper::point2cpv(_gravity)); @@ -253,7 +253,7 @@ void PhysicsWorld::removeAllJoints() _joints.clear(); } -void PhysicsWorld::addShape(PhysicsShape* shape) +PhysicsShape* PhysicsWorld::addShape(PhysicsShape* shape) { for (auto cps : shape->_info->shapes) { @@ -270,9 +270,11 @@ void PhysicsWorld::addShape(PhysicsShape* shape) cpSpaceAddShape(_info->space, cps); } } + + return shape; } -void PhysicsWorld::addBody(PhysicsBody* body) +PhysicsBody* PhysicsWorld::addBody(PhysicsBody* body) { CCASSERT(body != nullptr, "the body can not be nullptr"); @@ -304,7 +306,9 @@ void PhysicsWorld::addBody(PhysicsBody* body) } } - _bodys->addObject(body); + _bodies->addObject(body); + + return body; } void PhysicsWorld::removeBody(PhysicsBody* body) @@ -341,12 +345,12 @@ void PhysicsWorld::removeBody(PhysicsBody* body) } body->_world = nullptr; - _bodys->removeObject(body); + _bodies->removeObject(body); } void PhysicsWorld::removeBodyByTag(int tag) { - for (Object* obj : *_bodys) + for (Object* obj : *_bodies) { PhysicsBody* body = dynamic_cast(obj); if (body->getTag() == tag) @@ -357,9 +361,9 @@ void PhysicsWorld::removeBodyByTag(int tag) } } -void PhysicsWorld::removeAllBodys() +void PhysicsWorld::removeAllBodies() { - for (Object* obj : *_bodys) + for (Object* obj : *_bodies) { PhysicsBody* body = dynamic_cast(obj); @@ -390,8 +394,8 @@ void PhysicsWorld::removeAllBodys() body->_world = nullptr; } - _bodys->removeAllObjects(); - CC_SAFE_RELEASE(_bodys); + _bodies->removeAllObjects(); + CC_SAFE_RELEASE(_bodies); } void PhysicsWorld::removeShape(PhysicsShape* shape) @@ -407,7 +411,7 @@ void PhysicsWorld::removeShape(PhysicsShape* shape) void PhysicsWorld::update(float delta) { - for (auto body : *_bodys) + for (auto body : *_bodies) { body->update(delta); } @@ -428,11 +432,11 @@ void PhysicsWorld::update(float delta) void PhysicsWorld::debugDraw() { - if (_debugDraw && _bodys != nullptr) + if (_debugDraw && _bodies != nullptr) { _drawNode= DrawNode::create(); - for (Object* obj : *_bodys) + for (Object* obj : *_bodies) { PhysicsBody* body = dynamic_cast(obj); @@ -442,6 +446,11 @@ void PhysicsWorld::debugDraw() } } + for (auto joint : _joints) + { + drawWithJoint(_drawNode, joint); + } + if (_scene) { _scene->addChild(_drawNode); @@ -454,6 +463,58 @@ void PhysicsWorld::setScene(Scene *scene) _scene = scene; } +void PhysicsWorld::drawWithJoint(DrawNode* node, PhysicsJoint* joint) +{ + for (auto it = joint->_info->joints.begin(); it != joint->_info->joints.end(); ++it) + { + cpConstraint *constraint = *it; + + + cpBody *body_a = constraint->a; + cpBody *body_b = constraint->b; + + const cpConstraintClass *klass = constraint->klass_private; + if(klass == cpPinJointGetClass()){ + cpPinJoint *joint = (cpPinJoint *)constraint; + + cpVect a = cpvadd(body_a->p, cpvrotate(joint->anchr1, body_a->rot)); + cpVect b = cpvadd(body_b->p, cpvrotate(joint->anchr2, body_b->rot)); + + node->drawSegment(PhysicsHelper::cpv2point(a), PhysicsHelper::cpv2point(b), 1, Color4F(0.0f, 0.0f, 1.0f, 1.0f)); + node->drawDot(PhysicsHelper::cpv2point(a), 2, Color4F(0.0f, 1.0f, 0.0f, 1.0f)); + node->drawDot(PhysicsHelper::cpv2point(b), 2, Color4F(0.0f, 1.0f, 0.0f, 1.0f)); + } else if(klass == cpSlideJointGetClass()){ + cpSlideJoint *joint = (cpSlideJoint *)constraint; + + cpVect a = cpvadd(body_a->p, cpvrotate(joint->anchr1, body_a->rot)); + cpVect b = cpvadd(body_b->p, cpvrotate(joint->anchr2, body_b->rot)); + + node->drawSegment(PhysicsHelper::cpv2point(a), PhysicsHelper::cpv2point(b), 1, Color4F(0.0f, 0.0f, 1.0f, 1.0f)); + node->drawDot(PhysicsHelper::cpv2point(a), 2, Color4F(0.0f, 1.0f, 0.0f, 1.0f)); + node->drawDot(PhysicsHelper::cpv2point(b), 2, Color4F(0.0f, 1.0f, 0.0f, 1.0f)); + } else if(klass == cpPivotJointGetClass()){ + cpPivotJoint *joint = (cpPivotJoint *)constraint; + + cpVect a = cpvadd(body_a->p, cpvrotate(joint->anchr1, body_a->rot)); + cpVect b = cpvadd(body_b->p, cpvrotate(joint->anchr2, body_b->rot)); + + node->drawDot(PhysicsHelper::cpv2point(a), 2, Color4F(0.0f, 1.0f, 0.0f, 1.0f)); + node->drawDot(PhysicsHelper::cpv2point(b), 2, Color4F(0.0f, 1.0f, 0.0f, 1.0f)); + } else if(klass == cpGrooveJointGetClass()){ + cpGrooveJoint *joint = (cpGrooveJoint *)constraint; + + cpVect a = cpvadd(body_a->p, cpvrotate(joint->grv_a, body_a->rot)); + cpVect b = cpvadd(body_a->p, cpvrotate(joint->grv_b, body_a->rot)); + cpVect c = cpvadd(body_b->p, cpvrotate(joint->anchr2, body_b->rot)); + + node->drawSegment(PhysicsHelper::cpv2point(a), PhysicsHelper::cpv2point(b), 1, Color4F(0.0f, 0.0f, 1.0f, 1.0f)); + node->drawDot(PhysicsHelper::cpv2point(c), 2, Color4F(0.0f, 1.0f, 0.0f, 1.0f)); + } else if(klass == cpDampedSpringGetClass()){ + + } + } +} + void PhysicsWorld::drawWithShape(DrawNode* node, PhysicsShape* shape) { for (auto it = shape->_info->shapes.begin(); it != shape->_info->shapes.end(); ++it) @@ -510,8 +571,10 @@ void PhysicsWorld::drawWithShape(DrawNode* node, PhysicsShape* shape) int PhysicsWorld::collisionBeginCallback(PhysicsContact& contact) { bool ret = true; - PhysicsBody* bodyA = contact.getShapeA()->getBody(); - PhysicsBody* bodyB = contact.getShapeB()->getBody(); + PhysicsShape* shapeA = contact.getShapeA(); + PhysicsShape* shapeB = contact.getShapeB(); + PhysicsBody* bodyA = shapeA->getBody(); + PhysicsBody* bodyB = shapeB->getBody(); std::vector jointsA = bodyA->getJoints(); // check the joint is collision enable or not @@ -534,17 +597,24 @@ int PhysicsWorld::collisionBeginCallback(PhysicsContact& contact) } } + // bitmask check - if ((bodyA->getCategoryBitmask() & bodyB->getContactTestBitmask()) == 0 - || (bodyB->getContactTestBitmask() & bodyA->getCategoryBitmask()) == 0) + if ((shapeA->getCategoryBitmask() & shapeB->getContactTestBitmask()) == 0 + || (shapeB->getContactTestBitmask() & shapeA->getCategoryBitmask()) == 0) { contact.setNotify(false); } - if ((bodyA->getCategoryBitmask() & bodyB->getCollisionBitmask()) == 0 - || (bodyB->getCategoryBitmask() & bodyA->getCollisionBitmask()) == 0) + if (shapeA->getGroup() != 0 && shapeA->getGroup() == shapeB->getGroup()) { - ret = false; + ret = shapeA->getGroup() > 0; + }else + { + if ((shapeA->getCategoryBitmask() & shapeB->getCollisionBitmask()) == 0 + || (shapeB->getCategoryBitmask() & shapeA->getCollisionBitmask()) == 0) + { + ret = false; + } } if (contact.getNotify() && _listener && _listener->onContactBegin) @@ -614,9 +684,9 @@ void PhysicsWorld::collisionSeparateCallback(PhysicsContact& contact) void PhysicsWorld::setGravity(Point gravity) { - if (_bodys != nullptr) + if (_bodies != nullptr) { - for (auto child : *_bodys) + for (auto child : *_bodies) { PhysicsBody* body = dynamic_cast(child); @@ -694,9 +764,22 @@ PhysicsShape* PhysicsWorld::getShapeAtPoint(Point point) return shape == nullptr ? nullptr : PhysicsShapeInfo::map.find(shape)->second->shape; } -Array* PhysicsWorld::getAllBody() const +Array* PhysicsWorld::getAllBodies() const { - return _bodys; + return _bodies; +} + +PhysicsBody* PhysicsWorld::getBodyByTag(int tag) +{ + for (auto body : *_bodies) + { + if (((PhysicsBody*)body)->getTag() == tag) + { + return (PhysicsBody*)body; + } + } + + return nullptr; } #elif (CC_PHYSICS_ENGINE == CC_PHYSICS_BOX2D) @@ -720,7 +803,7 @@ PhysicsWorld::PhysicsWorld() , _speed(1.0f) , _info(nullptr) , _listener(nullptr) -, _bodys(nullptr) +, _bodies(nullptr) , _scene(nullptr) , _debugDraw(false) , _drawNode(nullptr) @@ -730,7 +813,7 @@ PhysicsWorld::PhysicsWorld() PhysicsWorld::~PhysicsWorld() { - removeAllBodys(); + removeAllBodies(); removeAllJoints(); CC_SAFE_DELETE(_info); } diff --git a/cocos/physics/CCPhysicsWorld.h b/cocos/physics/CCPhysicsWorld.h index 9fa8b28240..aff9119485 100644 --- a/cocos/physics/CCPhysicsWorld.h +++ b/cocos/physics/CCPhysicsWorld.h @@ -97,7 +97,8 @@ public: void rectQuery(PhysicsRectQueryCallback& callback, Rect rect, void* data); Array* getShapesAtPoint(Point point); PhysicsShape* getShapeAtPoint(Point point); - Array* getAllBody() const; + Array* getAllBodies() const; + PhysicsBody* getBodyByTag(int tag); /** Register a listener to receive contact callbacks*/ inline void registerContactListener(PhysicsContactListener* delegate) { _listener = delegate; } @@ -116,7 +117,7 @@ public: virtual void removeBody(PhysicsBody* body); virtual void removeBodyByTag(int tag); - virtual void removeAllBodys(); + virtual void removeAllBodies(); protected: static PhysicsWorld* create(); @@ -124,13 +125,14 @@ protected: void setScene(Scene* scene); - virtual void addBody(PhysicsBody* body); - virtual void addShape(PhysicsShape* shape); + virtual PhysicsBody* addBody(PhysicsBody* body); + virtual PhysicsShape* addShape(PhysicsShape* shape); virtual void removeShape(PhysicsShape* shape); virtual void update(float delta); virtual void debugDraw(); virtual void drawWithShape(DrawNode* node, PhysicsShape* shape); + virtual void drawWithJoint(DrawNode* node, PhysicsJoint* joint); virtual int collisionBeginCallback(PhysicsContact& contact); @@ -145,7 +147,7 @@ protected: PhysicsContactListener* _listener; - Array* _bodys; + Array* _bodies; std::list _joints; Scene* _scene; diff --git a/cocos/physics/chipmunk/CCPhysicsBodyInfo.cpp b/cocos/physics/chipmunk/CCPhysicsBodyInfo.cpp index 852dad1eeb..5fd8ceb171 100644 --- a/cocos/physics/chipmunk/CCPhysicsBodyInfo.cpp +++ b/cocos/physics/chipmunk/CCPhysicsBodyInfo.cpp @@ -28,7 +28,6 @@ NS_CC_BEGIN PhysicsBodyInfo::PhysicsBodyInfo() : body(nullptr) -, group(CP_NO_GROUP) { } diff --git a/cocos/physics/chipmunk/CCPhysicsBodyInfo.h b/cocos/physics/chipmunk/CCPhysicsBodyInfo.h index ec84526b59..54e4313b38 100644 --- a/cocos/physics/chipmunk/CCPhysicsBodyInfo.h +++ b/cocos/physics/chipmunk/CCPhysicsBodyInfo.h @@ -22,11 +22,11 @@ THE SOFTWARE. ****************************************************************************/ -#include "../CCPhysicsSetting.h" -#if (CC_PHYSICS_ENGINE == CC_PHYSICS_CHIPMUNK) - #ifndef __CCPHYSICS_BODY_INFO_H__ #define __CCPHYSICS_BODY_INFO_H__ + +#include "../CCPhysicsSetting.h" +#if (CC_PHYSICS_ENGINE == CC_PHYSICS_CHIPMUNK) #include "chipmunk.h" #include "CCPlatformMacros.h" #include "CCObject.h" @@ -37,7 +37,6 @@ class PhysicsBodyInfo : public Clonable { public: cpBody* body; - cpGroup group; private: PhysicsBodyInfo(); diff --git a/cocos/physics/chipmunk/CCPhysicsContactInfo.h b/cocos/physics/chipmunk/CCPhysicsContactInfo.h index 6c302947b7..fb455cdfc5 100644 --- a/cocos/physics/chipmunk/CCPhysicsContactInfo.h +++ b/cocos/physics/chipmunk/CCPhysicsContactInfo.h @@ -22,11 +22,11 @@ THE SOFTWARE. ****************************************************************************/ -#include "../CCPhysicsSetting.h" -#if (CC_PHYSICS_ENGINE == CC_PHYSICS_CHIPMUNK) - #ifndef __CCPHYSICS_CONTACT_INFO_H__ #define __CCPHYSICS_CONTACT_INFO_H__ + +#include "../CCPhysicsSetting.h" +#if (CC_PHYSICS_ENGINE == CC_PHYSICS_CHIPMUNK) #include "chipmunk.h" #include "CCPlatformMacros.h" NS_CC_BEGIN diff --git a/cocos/physics/chipmunk/CCPhysicsHelper.h b/cocos/physics/chipmunk/CCPhysicsHelper.h index bf6f6d14db..8ad6fa29bd 100644 --- a/cocos/physics/chipmunk/CCPhysicsHelper.h +++ b/cocos/physics/chipmunk/CCPhysicsHelper.h @@ -22,12 +22,12 @@ THE SOFTWARE. ****************************************************************************/ -#include "../CCPhysicsSetting.h" -#if (CC_PHYSICS_ENGINE == CC_PHYSICS_CHIPMUNK) - #ifndef __CCPHYSICS_HELPER_H__ #define __CCPHYSICS_HELPER_H__ +#include "../CCPhysicsSetting.h" +#if (CC_PHYSICS_ENGINE == CC_PHYSICS_CHIPMUNK) + #include "chipmunk.h" #include "CCPlatformMacros.h" #include "CCGeometry.h" diff --git a/cocos/physics/chipmunk/CCPhysicsJointInfo.h b/cocos/physics/chipmunk/CCPhysicsJointInfo.h index 04a2c716bf..5033e4aaba 100644 --- a/cocos/physics/chipmunk/CCPhysicsJointInfo.h +++ b/cocos/physics/chipmunk/CCPhysicsJointInfo.h @@ -22,11 +22,11 @@ THE SOFTWARE. ****************************************************************************/ -#include "../CCPhysicsSetting.h" -#if (CC_PHYSICS_ENGINE == CC_PHYSICS_CHIPMUNK) - #ifndef __CCPHYSICS_JOINT_INFO_H__ #define __CCPHYSICS_JOINT_INFO_H__ + +#include "../CCPhysicsSetting.h" +#if (CC_PHYSICS_ENGINE == CC_PHYSICS_CHIPMUNK) #include "chipmunk.h" #include "CCPlatformMacros.h" #include diff --git a/cocos/physics/chipmunk/CCPhysicsShapeInfo.h b/cocos/physics/chipmunk/CCPhysicsShapeInfo.h index 83be655b02..9229ba6d7f 100644 --- a/cocos/physics/chipmunk/CCPhysicsShapeInfo.h +++ b/cocos/physics/chipmunk/CCPhysicsShapeInfo.h @@ -22,12 +22,12 @@ THE SOFTWARE. ****************************************************************************/ -#include "../CCPhysicsSetting.h" -#if (CC_PHYSICS_ENGINE == CC_PHYSICS_CHIPMUNK) - #ifndef __CCPHYSICS_SHAPE_INFO_H__ #define __CCPHYSICS_SHAPE_INFO_H__ +#include "../CCPhysicsSetting.h" +#if (CC_PHYSICS_ENGINE == CC_PHYSICS_CHIPMUNK) + #include #include #include "chipmunk.h" diff --git a/cocos/physics/chipmunk/CCPhysicsWorldInfo.h b/cocos/physics/chipmunk/CCPhysicsWorldInfo.h index 71d56f0a5b..8c60cde415 100644 --- a/cocos/physics/chipmunk/CCPhysicsWorldInfo.h +++ b/cocos/physics/chipmunk/CCPhysicsWorldInfo.h @@ -22,11 +22,11 @@ THE SOFTWARE. ****************************************************************************/ -#include "../CCPhysicsSetting.h" -#if (CC_PHYSICS_ENGINE == CC_PHYSICS_CHIPMUNK) - #ifndef __CCPHYSICS_WORLD_INFO_H__ #define __CCPHYSICS_WORLD_INFO_H__ + +#include "../CCPhysicsSetting.h" +#if (CC_PHYSICS_ENGINE == CC_PHYSICS_CHIPMUNK) #include "chipmunk.h" #include "CCPlatformMacros.h" NS_CC_BEGIN diff --git a/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.cpp b/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.cpp index 51d5d3252c..ae7f7d07a4 100644 --- a/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.cpp +++ b/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.cpp @@ -11,6 +11,8 @@ namespace CL(PhysicsDemoClickAdd), CL(PhysicsDemoRayCast), CL(PhysicsDemoJoints), + CL(PhysicsDemoActions), + CL(PhysicsDemoPump), }; static int sceneIdx=-1; @@ -52,7 +54,7 @@ namespace } static const Color4F STATIC_COLOR(1.0f, 0.0f, 0.0f, 1.0f); - static const int DRAG_BODYS_TAG = 100; + static const int DRAG_BODYS_TAG = 0x80; } @@ -314,7 +316,7 @@ namespace } } -Sprite* PhysicsDemo::makeBall(float x, float y, float radius, PhysicsMaterial material) +Sprite* PhysicsDemo::makeBall(Point point, float radius, PhysicsMaterial material) { Sprite* ball = nullptr; if (_ball != nullptr) @@ -329,12 +331,12 @@ Sprite* PhysicsDemo::makeBall(float x, float y, float radius, PhysicsMaterial ma auto body = PhysicsBody::createCircle(radius, material); ball->setPhysicsBody(body); - ball->setPosition(Point(x, y)); + ball->setPosition(Point(point.x, point.y)); return ball; } -Sprite* PhysicsDemo::makeBox(float x, float y, Size size, PhysicsMaterial material) +Sprite* PhysicsDemo::makeBox(Point point, Size size, PhysicsMaterial material) { auto box = CCRANDOM_0_1() > 0.5f ? Sprite::create("Images/YellowSquare.png") : Sprite::create("Images/CyanSquare.png"); @@ -343,12 +345,12 @@ Sprite* PhysicsDemo::makeBox(float x, float y, Size size, PhysicsMaterial materi auto body = PhysicsBody::createBox(size); box->setPhysicsBody(body); - box->setPosition(Point(x, y)); + box->setPosition(Point(point.x, point.y)); return box; } -Sprite* PhysicsDemo::makeTriangle(float x, float y, Size size, PhysicsMaterial material) +Sprite* PhysicsDemo::makeTriangle(Point point, Size size, PhysicsMaterial material) { auto triangle = CCRANDOM_0_1() > 0.5f ? Sprite::create("Images/YellowTriangle.png") : Sprite::create("Images/CyanTriangle.png"); @@ -365,7 +367,7 @@ Sprite* PhysicsDemo::makeTriangle(float x, float y, Size size, PhysicsMaterial m auto body = PhysicsBody::createPolygon(vers, 3); triangle->setPhysicsBody(body); - triangle->setPosition(Point(x, y)); + triangle->setPosition(Point(point.x, point.y)); return triangle; } @@ -380,7 +382,7 @@ bool PhysicsDemo::onTouchBegan(Touch* touch, Event* event) { shape = dynamic_cast(obj); - if (shape->getTag() == DRAG_BODYS_TAG) + if ((shape->getTag() & DRAG_BODYS_TAG) != 0) { break; } @@ -395,7 +397,7 @@ bool PhysicsDemo::onTouchBegan(Touch* touch, Event* event) mouse->setPosition(location); this->addChild(mouse); PhysicsJointPin* joint = PhysicsJointPin::create(mouse->getPhysicsBody(), shape->getBody(), location); - joint->setMaxForce(5000.0f); + joint->setMaxForce(5000.0f * shape->getBody()->getMass()); _scene->getPhysicsWorld()->addJoint(joint); _mouses.insert(std::make_pair(touch->getID(), mouse)); @@ -445,9 +447,9 @@ void PhysicsDemoLogoSmash::onEnter() float x_jitter = 0.05*frand(); float y_jitter = 0.05*frand(); - Node* ball = makeBall(2*(x - logo_width/2 + x_jitter) + VisibleRect::getVisibleRect().size.width/2, - 2*(logo_height-y + y_jitter) + VisibleRect::getVisibleRect().size.height/2 - logo_height/2, - 0.95f, PhysicsMaterial(1.0f, 0.0f, 0.0f)); + Node* ball = makeBall(Point(2*(x - logo_width/2 + x_jitter) + VisibleRect::getVisibleRect().size.width/2, + 2*(logo_height-y + y_jitter) + VisibleRect::getVisibleRect().size.height/2 - logo_height/2), + 0.95f, PhysicsMaterial(0.01f, 0.0f, 0.0f)); ball->getPhysicsBody()->setMass(1.0); ball->getPhysicsBody()->setMoment(PHYSICS_INFINITY); @@ -459,7 +461,7 @@ void PhysicsDemoLogoSmash::onEnter() } - auto bullet = makeBall(400, 0, 10, PhysicsMaterial(PHYSICS_INFINITY, 0, 0)); + auto bullet = makeBall(Point(400, 0), 10, PhysicsMaterial(PHYSICS_INFINITY, 0, 0)); bullet->getPhysicsBody()->setVelocity(Point(400, 0)); bullet->setPosition(Point(-1000, VisibleRect::getVisibleRect().size.height/2)); @@ -727,13 +729,13 @@ void PhysicsDemoRayCast::onTouchesEnded(const std::vector& touches, Even if (r < 1.0f/3.0f) { - addChild(makeBall(location.x, location.y, 5 + CCRANDOM_0_1()*10)); + addChild(makeBall(location, 5 + CCRANDOM_0_1()*10)); }else if(r < 2.0f/3.0f) { - addChild(makeBox(location.x, location.y, Size(10 + CCRANDOM_0_1()*15, 10 + CCRANDOM_0_1()*15))); + addChild(makeBox(location, Size(10 + CCRANDOM_0_1()*15, 10 + CCRANDOM_0_1()*15))); }else { - addChild(makeTriangle(location.x, location.y, Size(10 + CCRANDOM_0_1()*20, 10 + CCRANDOM_0_1()*20))); + addChild(makeTriangle(location, Size(10 + CCRANDOM_0_1()*20, 10 + CCRANDOM_0_1()*20))); } } } @@ -743,12 +745,6 @@ std::string PhysicsDemoRayCast::title() return "Ray Cast"; } - -PhysicsDemoJoints::PhysicsDemoJoints() -{ - -} - void PhysicsDemoJoints::onEnter() { PhysicsDemo::onEnter(); @@ -780,9 +776,9 @@ void PhysicsDemoJoints::onEnter() { case 0: { - auto sp1 = makeBall(offset.x - 30, offset.y, 10); + auto sp1 = makeBall(offset - Point(30, 0), 10); sp1->getPhysicsBody()->setTag(DRAG_BODYS_TAG); - auto sp2 = makeBall(offset.x + 30, offset.y, 10); + auto sp2 = makeBall(offset + Point(30, 0), 10); sp2->getPhysicsBody()->setTag(DRAG_BODYS_TAG); PhysicsJointPin* joint = PhysicsJointPin::create(sp1->getPhysicsBody(), sp2->getPhysicsBody(), offset); @@ -795,9 +791,9 @@ void PhysicsDemoJoints::onEnter() case 1: { - auto sp1 = makeBall(offset.x - 30, offset.y, 10); + auto sp1 = makeBall(offset - Point(30, 0), 10); sp1->getPhysicsBody()->setTag(DRAG_BODYS_TAG); - auto sp2 = makeBox(offset.x + 30, offset.y, Size(30, 10)); + auto sp2 = makeBox(offset + Point(30, 0), Size(30, 10)); sp2->getPhysicsBody()->setTag(DRAG_BODYS_TAG); PhysicsJointFixed* joint = PhysicsJointFixed::create(sp1->getPhysicsBody(), sp2->getPhysicsBody(), offset); @@ -817,4 +813,193 @@ void PhysicsDemoJoints::onEnter() std::string PhysicsDemoJoints::title() { return "Joints"; +} + +void PhysicsDemoActions::onEnter() +{ + PhysicsDemo::onEnter(); + + setTouchEnabled(true); + setTouchMode(Touch::DispatchMode::ONE_BY_ONE); + + auto node = Node::create(); + node->setPhysicsBody(PhysicsBody::createEdgeBox(VisibleRect::getVisibleRect().size)); + node->setPosition(VisibleRect::center()); + this->addChild(node); + + Sprite* sp1 = addGrossiniAtPosition(VisibleRect::center()); + Sprite* sp2 = addGrossiniAtPosition(VisibleRect::left() + Point(50, 0)); + Sprite* sp3 = addGrossiniAtPosition(VisibleRect::right() - Point(20, 0)); + Sprite* sp4 = addGrossiniAtPosition(VisibleRect::leftTop() + Point(50, -50)); + sp4->getPhysicsBody()->setGravityEnable(false); + + + auto actionTo = JumpTo::create(2, Point(100,100), 50, 4); + auto actionBy = JumpBy::create(2, Point(300,0), 50, 4); + auto actionUp = JumpBy::create(2, Point(0,50), 80, 4); + auto actionByBack = actionBy->reverse(); + + sp1->runAction(RepeatForever::create(actionUp)); + sp2->runAction(RepeatForever::create(Sequence::create(actionBy, actionByBack, NULL))); + sp3->runAction(actionTo); + sp4->runAction(RepeatForever::create(Sequence::create(actionBy->clone(), actionByBack->clone(), NULL))); +} + +std::string PhysicsDemoActions::title() +{ + return "Actions"; +} + +void PhysicsDemoPump::onEnter() +{ + PhysicsDemo::onEnter(); + + _distance = 0.0f; + _rotationV = 0.0f; + setTouchEnabled(true); + setTouchMode(Touch::DispatchMode::ONE_BY_ONE); + scheduleUpdate(); + + auto node = Node::create(); + auto body = PhysicsBody::create(); + body->setDynamic(false); + + PhysicsMaterial staticMaterial(PHYSICS_INFINITY, 0, 0.5f); + body->addShape(PhysicsShapeEdgeSegment::create(VisibleRect::leftTop() + Point(50, 0), VisibleRect::leftTop() + Point(50, -130), staticMaterial, 2.0f)); + body->addShape(PhysicsShapeEdgeSegment::create(VisibleRect::leftTop() + Point(190, 0), VisibleRect::leftTop() + Point(100, -50), staticMaterial, 2.0f)); + body->addShape(PhysicsShapeEdgeSegment::create(VisibleRect::leftTop() + Point(100, -50), VisibleRect::leftTop() + Point(100, -90), staticMaterial, 2.0f)); + body->addShape(PhysicsShapeEdgeSegment::create(VisibleRect::leftTop() + Point(50, -130), VisibleRect::leftTop() + Point(100, -145), staticMaterial, 2.0f)); + body->addShape(PhysicsShapeEdgeSegment::create(VisibleRect::leftTop() + Point(100, -145), VisibleRect::leftBottom() + Point(100, 80), staticMaterial, 2.0f)); + body->addShape(PhysicsShapeEdgeSegment::create(VisibleRect::leftTop() + Point(150, -80), VisibleRect::leftBottom() + Point(150, 80), staticMaterial, 2.0f)); + body->addShape(PhysicsShapeEdgeSegment::create(VisibleRect::leftTop() + Point(150, -80), VisibleRect::rightTop() + Point(-100, -150), staticMaterial, 2.0f)); + + body->setCategoryBitmask(0x01); + + // balls + for (int i = 0; i < 6; ++i) + { + auto ball = makeBall(VisibleRect::leftTop() + Point(75 + CCRANDOM_0_1() * 90, 0), 22, PhysicsMaterial(0.5f, 0.0f, 0.1f)); + ball->getPhysicsBody()->setTag(DRAG_BODYS_TAG); + addChild(ball); + } + + node->setPhysicsBody(body); + this->addChild(node); + + Point vec[4] = + { + VisibleRect::leftTop() + Point(102, -146), + VisibleRect::leftTop() + Point(148, -159), + VisibleRect::leftBottom() + Point(148, 20), + VisibleRect::leftBottom() + Point(102, 20) + }; + + auto _world = _scene->getPhysicsWorld(); + + // small gear + auto sgear = Node::create(); + auto sgearB = PhysicsBody::createCircle(50); + sgear->setPhysicsBody(sgearB); + sgear->setPosition(VisibleRect::leftBottom() + Point(125, 0)); + this->addChild(sgear); + sgearB->setCategoryBitmask(0x04); + sgearB->setCollisionBitmask(0x04); + sgearB->setTag(1); + _world->addJoint(PhysicsJointPin::create(body, sgearB, sgearB->getPosition())); + + + // big gear + auto bgear = Node::create(); + auto bgearB = PhysicsBody::createCircle(100); + bgear->setPhysicsBody(bgearB); + bgear->setPosition(VisibleRect::leftBottom() + Point(275, 0)); + this->addChild(bgear); + bgearB->setCategoryBitmask(0x04); + _world->addJoint(PhysicsJointPin::create(body, bgearB, bgearB->getPosition())); + + + // pump + auto pump = Node::create(); + pump->setPosition(PhysicsShape::getPolyonCenter(vec, 4)); + auto pumpB = PhysicsBody::createPolygon(PhysicsShape::recenterPoints(vec, 4), 4); + pump->setPhysicsBody(pumpB); + this->addChild(pump); + pumpB->setCategoryBitmask(0x02); + pumpB->setGravityEnable(false); + _world->addJoint(PhysicsJointDistance::create(pumpB, sgearB, Point(0, 0), Point(0, -50))); + + // plugger + Point seg[] = {VisibleRect::leftTop() + Point(75, -120), VisibleRect::leftBottom() + Point(75, -100)}; + Point segCenter = (seg[1] + seg[0])/2; + seg[1] -= segCenter; + seg[0] -= segCenter; + auto plugger = Node::create(); + auto pluggerB = PhysicsBody::createEdgeSegment(seg[0], seg[1], PhysicsMaterial(0.01f, 0.0f, 0.5f), 20); + pluggerB->setDynamic(true); + pluggerB->setMass(30); + pluggerB->setMoment(100000); + plugger->setPhysicsBody(pluggerB); + plugger->setPosition(segCenter); + this->addChild(plugger); + pluggerB->setCategoryBitmask(0x02); + sgearB->setCollisionBitmask(0x04 | 0x01); + _world->addJoint(PhysicsJointPin::create(body, pluggerB, VisibleRect::leftBottom() + Point(75, -90))); + _world->addJoint(PhysicsJointDistance::create(pluggerB, sgearB, pluggerB->world2Local(VisibleRect::leftBottom() + Point(75, 0)), Point(50, 0))); +} + +void PhysicsDemoPump::update(float delta) +{ + for (auto obj : *_scene->getPhysicsWorld()->getAllBodies()) + { + PhysicsBody* body = dynamic_cast(obj); + if (body->getTag() == DRAG_BODYS_TAG && body->getPosition().y < 0.0f) + { + body->getOwner()->setPosition(VisibleRect::leftTop() + Point(75 + CCRANDOM_0_1() * 90, 0)); + body->setVelocity(Point(0, 0)); + } + } + + PhysicsBody* gear = _scene->getPhysicsWorld()->getBodyByTag(1); + + if (gear != nullptr) + { + if (_distance != 0.0f) + { + _rotationV += _distance/2500.0f; + + if (_rotationV > 30) _rotationV = 30.0f; + if (_rotationV < -30) _rotationV = -30.0f; + } + + gear->setAngularVelocity(_rotationV); + _rotationV *= 0.995; + } +} + +bool PhysicsDemoPump::onTouchBegan(Touch* touch, Event* event) +{ + PhysicsDemo::onTouchBegan(touch, event); + + _distance = touch->getLocation().x - VisibleRect::center().x; + + return true; +} + +void PhysicsDemoPump::onTouchMoved(Touch* touch, Event* event) +{ + PhysicsDemo::onTouchMoved(touch, event); + + _distance = touch->getLocation().x - VisibleRect::center().x; +} + +void PhysicsDemoPump::onTouchEnded(Touch* touch, Event* event) +{ + PhysicsDemo::onTouchEnded(touch, event); + + _distance = 0; +} + +std::string PhysicsDemoPump::title() +{ + return "Pump"; } \ No newline at end of file diff --git a/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.h b/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.h index fe58196372..79932c60a7 100644 --- a/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.h +++ b/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.h @@ -39,9 +39,9 @@ public: void toggleDebugCallback(Object* sender); Sprite* addGrossiniAtPosition(Point p, float scale = 1.0); - Sprite* makeBall(float x, float y, float radius, PhysicsMaterial material = PHYSICSBODY_MATERIAL_DEFAULT); - Sprite* makeBox(float x, float y, Size size, PhysicsMaterial material = PHYSICSBODY_MATERIAL_DEFAULT); - Sprite* makeTriangle(float x, float y, Size size, PhysicsMaterial material = PHYSICSBODY_MATERIAL_DEFAULT); + Sprite* makeBall(Point point, float radius, PhysicsMaterial material = PHYSICSBODY_MATERIAL_DEFAULT); + Sprite* makeBox(Point point, Size size, PhysicsMaterial material = PHYSICSBODY_MATERIAL_DEFAULT); + Sprite* makeTriangle(Point point, Size size, PhysicsMaterial material = PHYSICSBODY_MATERIAL_DEFAULT); bool onTouchBegan(Touch* touch, Event* event) override; void onTouchMoved(Touch* touch, Event* event) override; @@ -107,14 +107,31 @@ private: class PhysicsDemoJoints : public PhysicsDemo { public: - PhysicsDemoJoints(); - + void onEnter() override; + std::string title() override; +}; + +class PhysicsDemoActions : public PhysicsDemo +{ public: void onEnter() override; std::string title() override; +}; + +class PhysicsDemoPump : public PhysicsDemo +{ +public: + void onEnter() override; + std::string title() override; + void update(float delta) override; + + bool onTouchBegan(Touch* touch, Event* event) override; + void onTouchMoved(Touch* touch, Event* event) override; + void onTouchEnded(Touch* touch, Event* event) override; private: - PhysicsShape* _touchesShape; + float _distance; + float _rotationV; }; #endif