From dba58f6a9ba09b8a6732d0de411bf8b78e26c33c Mon Sep 17 00:00:00 2001 From: boyu0 Date: Mon, 2 Dec 2013 18:29:04 +0800 Subject: [PATCH] issue #2771: add more joints --- cocos/physics/CCPhysicsJoint.cpp | 491 +++++++++++++++++++++++++++---- cocos/physics/CCPhysicsJoint.h | 164 ++++++++++- 2 files changed, 592 insertions(+), 63 deletions(-) diff --git a/cocos/physics/CCPhysicsJoint.cpp b/cocos/physics/CCPhysicsJoint.cpp index 295560a9e6..91fc2a4dee 100644 --- a/cocos/physics/CCPhysicsJoint.cpp +++ b/cocos/physics/CCPhysicsJoint.cpp @@ -97,46 +97,6 @@ void PhysicsJoint::setEnable(bool enable) } } -PhysicsJointPin::PhysicsJointPin() -{ - -} - -PhysicsJointPin::~PhysicsJointPin() -{ - -} - -PhysicsJointFixed::PhysicsJointFixed() -{ - -} - -PhysicsJointFixed::~PhysicsJointFixed() -{ - -} - -PhysicsJointLimit::PhysicsJointLimit() -{ - -} - -PhysicsJointLimit::~PhysicsJointLimit() -{ - -} - -PhysicsJointDistance::PhysicsJointDistance() -{ - -} - -PhysicsJointDistance::~PhysicsJointDistance() -{ - -} - PhysicsBodyInfo* PhysicsJoint::getBodyInfo(PhysicsBody* body) const { return body->_info; @@ -147,7 +107,6 @@ Node* PhysicsJoint::getBodyNode(PhysicsBody* body) const return body->_node; } - void PhysicsJoint::setCollisionEnable(bool enable) { if (_collisionEnable != enable) @@ -190,6 +149,19 @@ void PhysicsJoint::destroy(PhysicsJoint* joint) } } +void PhysicsJoint::setMaxForce(float force) +{ + for (cpConstraint* joint : _info->getJoints()) + { + joint->maxForce = PhysicsHelper::float2cpfloat(force); + } +} + +float PhysicsJoint::getMaxForce() const +{ + return PhysicsHelper::cpfloat2float(_info->getJoints().front()->maxForce); +} + PhysicsJointFixed* PhysicsJointFixed::construct(PhysicsBody* a, PhysicsBody* b, const Point& anchr) { PhysicsJointFixed* joint = new PhysicsJointFixed(); @@ -262,16 +234,6 @@ bool PhysicsJointPin::init(PhysicsBody *a, PhysicsBody *b, const Point& anchr) return false; } -void PhysicsJointPin::setMaxForce(float force) -{ - _info->getJoints().front()->maxForce = PhysicsHelper::float2cpfloat(force); -} - -float PhysicsJointPin::getMaxForce() const -{ - return PhysicsHelper::cpfloat2float(_info->getJoints().front()->maxForce); -} - PhysicsJointLimit* PhysicsJointLimit::construct(PhysicsBody* a, PhysicsBody* b, const Point& anchr1, const Point& anchr2) { PhysicsJointLimit* joint = new PhysicsJointLimit(); @@ -295,7 +257,7 @@ bool PhysicsJointLimit::init(PhysicsBody* a, PhysicsBody* b, const Point& anchr1 PhysicsHelper::point2cpv(anchr1), PhysicsHelper::point2cpv(anchr2), 0, - PhysicsHelper::float2cpfloat(_bodyA->local2World(anchr1).getDistance(_bodyB->local2World(anchr2)))); + PhysicsHelper::float2cpfloat(_bodyB->local2World(anchr1).getDistance(_bodyA->local2World(anchr2)))); CC_BREAK_IF(joint == nullptr); @@ -327,6 +289,26 @@ void PhysicsJointLimit::setMax(float max) cpSlideJointSetMax(_info->getJoints().front(), PhysicsHelper::float2cpfloat(max)); } +Point PhysicsJointLimit::getAnchr1() const +{ + return PhysicsHelper::cpv2point(cpSlideJointGetAnchr1(_info->getJoints().front())); +} + +void PhysicsJointLimit::setAnchr1(const Point& anchr) +{ + cpSlideJointSetAnchr1(_info->getJoints().front(), PhysicsHelper::point2cpv(anchr)); +} + +Point PhysicsJointLimit::getAnchr2() const +{ + return PhysicsHelper::cpv2point(cpSlideJointGetAnchr2(_info->getJoints().front())); +} + +void PhysicsJointLimit::setAnchr2(const Point& anchr) +{ + cpSlideJointSetAnchr1(_info->getJoints().front(), PhysicsHelper::point2cpv(anchr)); +} + PhysicsJointDistance* PhysicsJointDistance::construct(PhysicsBody* a, PhysicsBody* b, const Point& anchr1, const Point& anchr2) { PhysicsJointDistance* joint = new PhysicsJointDistance(); @@ -361,5 +343,410 @@ bool PhysicsJointDistance::init(PhysicsBody* a, PhysicsBody* b, const Point& anc return false; } +float PhysicsJointDistance::getDistance() const +{ + return PhysicsHelper::cpfloat2float(cpPinJointGetDist(_info->getJoints().front())); +} + +void PhysicsJointDistance::setDistance(float distance) +{ + cpPinJointSetDist(_info->getJoints().front(), PhysicsHelper::float2cpfloat(distance)); +} + +PhysicsJointSpring* PhysicsJointSpring::construct(PhysicsBody* a, PhysicsBody* b, const Point& anchr1, const Point& anchr2, float stiffness, float damping) +{ + PhysicsJointSpring* joint = new PhysicsJointSpring(); + + if (joint && joint->init(a, b, anchr1, anchr2, stiffness, damping)) + { + return joint; + } + + CC_SAFE_DELETE(joint); + return nullptr; +} + +bool PhysicsJointSpring::init(PhysicsBody* a, PhysicsBody* b, const Point& anchr1, const Point& anchr2, float stiffness, float damping) +{ + do { + CC_BREAK_IF(!PhysicsJoint::init(a, b)); + + cpConstraint* joint = cpDampedSpringNew(getBodyInfo(a)->getBody(), + getBodyInfo(b)->getBody(), + PhysicsHelper::point2cpv(anchr1), + PhysicsHelper::point2cpv(anchr2), + PhysicsHelper::float2cpfloat(_bodyB->local2World(anchr1).getDistance(_bodyA->local2World(anchr2))), + PhysicsHelper::float2cpfloat(stiffness), + PhysicsHelper::float2cpfloat(damping)); + + CC_BREAK_IF(joint == nullptr); + + _info->add(joint); + + return true; + } while (false); + + return false; +} + +Point PhysicsJointSpring::getAnchr1() const +{ + return PhysicsHelper::cpv2point(cpDampedSpringGetAnchr1(_info->getJoints().front())); +} + +void PhysicsJointSpring::setAnchr1(const Point& anchr) +{ + cpDampedSpringSetAnchr1(_info->getJoints().front(), PhysicsHelper::point2cpv(anchr)); +} + +Point PhysicsJointSpring::getAnchr2() const +{ + return PhysicsHelper::cpv2point(cpDampedSpringGetAnchr2(_info->getJoints().front())); +} + +void PhysicsJointSpring::setAnchr2(const Point& anchr) +{ + cpDampedSpringSetAnchr1(_info->getJoints().front(), PhysicsHelper::point2cpv(anchr)); +} + +float PhysicsJointSpring::getRestLength() const +{ + return PhysicsHelper::cpfloat2float(cpDampedSpringGetRestLength(_info->getJoints().front())); +} + +void PhysicsJointSpring::setRestLength(float restLength) +{ + cpDampedSpringSetRestLength(_info->getJoints().front(), PhysicsHelper::float2cpfloat(restLength)); +} + +float PhysicsJointSpring::getStiffness() const +{ + return PhysicsHelper::cpfloat2float(cpDampedSpringGetStiffness(_info->getJoints().front())); +} + +void PhysicsJointSpring::setStiffness(float stiffness) +{ + cpDampedSpringSetStiffness(_info->getJoints().front(), PhysicsHelper::float2cpfloat(stiffness)); +} + +float PhysicsJointSpring::getDamping() const +{ + return PhysicsHelper::cpfloat2float(cpDampedSpringGetDamping(_info->getJoints().front())); +} + +void PhysicsJointSpring::setDamping(float damping) +{ + cpDampedSpringSetDamping(_info->getJoints().front(), PhysicsHelper::float2cpfloat(damping)); +} + +Point PhysicsJointGroove::getGrooveA() const +{ + return PhysicsHelper::cpv2point(cpGrooveJointGetGrooveA(_info->getJoints().front())); +} + +void PhysicsJointGroove::setGrooveA(const Point& grooveA) +{ + cpGrooveJointSetGrooveA(_info->getJoints().front(), PhysicsHelper::point2cpv(grooveA)); +} + +Point PhysicsJointGroove::getGrooveB() const +{ + return PhysicsHelper::cpv2point(cpGrooveJointGetGrooveB(_info->getJoints().front())); +} + +void PhysicsJointGroove::setGrooveB(const Point& grooveB) +{ + cpGrooveJointSetGrooveB(_info->getJoints().front(), PhysicsHelper::point2cpv(grooveB)); +} + +Point PhysicsJointGroove::getAnchr2() const +{ + return PhysicsHelper::cpv2point(cpGrooveJointGetAnchr2(_info->getJoints().front())); +} + +void PhysicsJointGroove::setAnchr2(const Point& anchr2) +{ + cpGrooveJointSetAnchr2(_info->getJoints().front(), PhysicsHelper::point2cpv(anchr2)); +} + +PhysicsJointRotarySpring* PhysicsJointRotarySpring::construct(PhysicsBody* a, PhysicsBody* b, float stiffness, float damping) +{ + PhysicsJointRotarySpring* joint = new PhysicsJointRotarySpring(); + + if (joint && joint->init(a, b, stiffness, damping)) + { + return joint; + } + + CC_SAFE_DELETE(joint); + return nullptr; +} + +bool PhysicsJointRotarySpring::init(PhysicsBody* a, PhysicsBody* b, float stiffness, float damping) +{ + do { + CC_BREAK_IF(!PhysicsJoint::init(a, b)); + + cpConstraint* joint = cpDampedRotarySpringNew(getBodyInfo(a)->getBody(), + getBodyInfo(b)->getBody(), + PhysicsHelper::float2cpfloat(_bodyB->getRotation() - _bodyA->getRotation()), + PhysicsHelper::float2cpfloat(stiffness), + PhysicsHelper::float2cpfloat(damping)); + + CC_BREAK_IF(joint == nullptr); + + _info->add(joint); + + return true; + } while (false); + + return false; +} + +float PhysicsJointRotarySpring::getRestAngle() const +{ + return PhysicsHelper::cpfloat2float(cpDampedRotarySpringGetRestAngle(_info->getJoints().front())); +} + +void PhysicsJointRotarySpring::setRestAngle(float restAngle) +{ + cpDampedRotarySpringSetRestAngle(_info->getJoints().front(), PhysicsHelper::float2cpfloat(restAngle)); +} + +float PhysicsJointRotarySpring::getStiffness() const +{ + return PhysicsHelper::cpfloat2float(cpDampedRotarySpringGetStiffness(_info->getJoints().front())); +} + +void PhysicsJointRotarySpring::setStiffness(float stiffness) +{ + cpDampedRotarySpringSetStiffness(_info->getJoints().front(), PhysicsHelper::float2cpfloat(stiffness)); +} + +float PhysicsJointRotarySpring::getDamping() const +{ + return PhysicsHelper::cpfloat2float(cpDampedRotarySpringGetDamping(_info->getJoints().front())); +} + +void PhysicsJointRotarySpring::setDamping(float damping) +{ + cpDampedRotarySpringSetDamping(_info->getJoints().front(), PhysicsHelper::float2cpfloat(damping)); +} + +PhysicsJointRotaryLimit* PhysicsJointRotaryLimit::construct(PhysicsBody* a, PhysicsBody* b) +{ + PhysicsJointRotaryLimit* joint = new PhysicsJointRotaryLimit(); + + if (joint && joint->init(a, b)) + { + return joint; + } + + CC_SAFE_DELETE(joint); + return nullptr; +} + +bool PhysicsJointRotaryLimit::init(PhysicsBody* a, PhysicsBody* b) +{ + do + { + CC_BREAK_IF(!PhysicsJoint::init(a, b)); + + cpConstraint* joint = cpRotaryLimitJointNew(getBodyInfo(a)->getBody(), + getBodyInfo(b)->getBody(), + 0, + PhysicsHelper::float2cpfloat(_bodyB->getRotation() - _bodyA->getRotation())); + + CC_BREAK_IF(joint == nullptr); + + _info->add(joint); + + return true; + } while (false); + + return false; +} + +float PhysicsJointRotaryLimit::getMin() const +{ + return PhysicsHelper::cpfloat2float(cpRotaryLimitJointGetMin(_info->getJoints().front())); +} + +void PhysicsJointRotaryLimit::setMin(float min) +{ + cpRotaryLimitJointSetMin(_info->getJoints().front(), PhysicsHelper::float2cpfloat(min)); +} + +float PhysicsJointRotaryLimit::getMax() const +{ + return PhysicsHelper::cpfloat2float(cpRotaryLimitJointGetMax(_info->getJoints().front())); +} + +void PhysicsJointRotaryLimit::setMax(float max) +{ + cpRotaryLimitJointSetMax(_info->getJoints().front(), PhysicsHelper::float2cpfloat(max)); +} + +PhysicsJointRatchet* PhysicsJointRatchet::construct(PhysicsBody* a, PhysicsBody* b, float phase, float ratchet) +{ + PhysicsJointRatchet* joint = new PhysicsJointRatchet(); + + if (joint && joint->init(a, b, phase, ratchet)) + { + return joint; + } + + CC_SAFE_DELETE(joint); + return nullptr; +} + +bool PhysicsJointRatchet::init(PhysicsBody* a, PhysicsBody* b, float phase, float ratchet) +{ + do + { + CC_BREAK_IF(!PhysicsJoint::init(a, b)); + + cpConstraint* joint = cpRatchetJointNew(getBodyInfo(a)->getBody(), + getBodyInfo(b)->getBody(), + PhysicsHelper::float2cpfloat(phase), + PhysicsHelper::cpfloat2float(ratchet)); + + CC_BREAK_IF(joint == nullptr); + + _info->add(joint); + + return true; + } while (false); + + return false; +} + +float PhysicsJointRatchet::getAngle() const +{ + return PhysicsHelper::cpfloat2float(cpRatchetJointGetAngle(_info->getJoints().front())); +} + +void PhysicsJointRatchet::setAngle(float angle) +{ + cpRatchetJointSetAngle(_info->getJoints().front(), PhysicsHelper::float2cpfloat(angle)); +} + +float PhysicsJointRatchet::getPhase() const +{ + return PhysicsHelper::cpfloat2float(cpRatchetJointGetPhase(_info->getJoints().front())); +} + +void PhysicsJointRatchet::setPhase(float phase) +{ + cpRatchetJointSetPhase(_info->getJoints().front(), PhysicsHelper::float2cpfloat(phase)); +} + +float PhysicsJointRatchet::getRatchet() const +{ + return PhysicsHelper::cpfloat2float(cpRatchetJointGetRatchet(_info->getJoints().front())); +} + +void PhysicsJointRatchet::setRatchet(float ratchet) +{ + cpRatchetJointSetRatchet(_info->getJoints().front(), PhysicsHelper::float2cpfloat(ratchet)); +} + +PhysicsJointGear* PhysicsJointGear::construct(PhysicsBody* a, PhysicsBody* b, float phase, float ratchet) +{ + PhysicsJointGear* joint = new PhysicsJointGear(); + + if (joint && joint->init(a, b, phase, ratchet)) + { + return joint; + } + + CC_SAFE_DELETE(joint); + return nullptr; +} + +bool PhysicsJointGear::init(PhysicsBody* a, PhysicsBody* b, float phase, float ratio) +{ + do + { + CC_BREAK_IF(!PhysicsJoint::init(a, b)); + + cpConstraint* joint = cpGearJointNew(getBodyInfo(a)->getBody(), + getBodyInfo(b)->getBody(), + PhysicsHelper::float2cpfloat(phase), + PhysicsHelper::cpfloat2float(ratio)); + + CC_BREAK_IF(joint == nullptr); + + _info->add(joint); + + return true; + } while (false); + + return false; +} + +float PhysicsJointGear::getPhase() const +{ + return PhysicsHelper::cpfloat2float(cpGearJointGetPhase(_info->getJoints().front())); +} + +void PhysicsJointGear::setPhase(float phase) +{ + cpGearJointSetPhase(_info->getJoints().front(), PhysicsHelper::float2cpfloat(phase)); +} + +float PhysicsJointGear::getRatio() const +{ + return PhysicsHelper::cpfloat2float(cpGearJointGetRatio(_info->getJoints().front())); +} + +void PhysicsJointGear::setRatio(float ratio) +{ + cpGearJointSetRatio(_info->getJoints().front(), PhysicsHelper::float2cpfloat(ratio)); +} + +PhysicsJointMotor* PhysicsJointMotor::construct(PhysicsBody* a, PhysicsBody* b, float rate) +{ + PhysicsJointMotor* joint = new PhysicsJointMotor(); + + if (joint && joint->init(a, b, rate)) + { + return joint; + } + + CC_SAFE_DELETE(joint); + return nullptr; +} + +bool PhysicsJointMotor::init(PhysicsBody* a, PhysicsBody* b, float rate) +{ + do + { + CC_BREAK_IF(!PhysicsJoint::init(a, b)); + + cpConstraint* joint = cpSimpleMotorNew(getBodyInfo(a)->getBody(), + getBodyInfo(b)->getBody(), + PhysicsHelper::float2cpfloat(rate)); + + CC_BREAK_IF(joint == nullptr); + + _info->add(joint); + + return true; + } while (false); + + return false; +} + +float PhysicsJointMotor::getRate() const +{ + return PhysicsHelper::cpfloat2float(cpSimpleMotorGetRate(_info->getJoints().front())); +} + +void PhysicsJointMotor::setRate(float rate) +{ + cpSimpleMotorSetRate(_info->getJoints().front(), PhysicsHelper::float2cpfloat(rate)); +} + NS_CC_END #endif // CC_USE_PHYSICS diff --git a/cocos/physics/CCPhysicsJoint.h b/cocos/physics/CCPhysicsJoint.h index 45e038a774..a5bd923b63 100644 --- a/cocos/physics/CCPhysicsJoint.h +++ b/cocos/physics/CCPhysicsJoint.h @@ -59,6 +59,9 @@ public: void removeFormWorld(); static void destroy(PhysicsJoint* joint); + void setMaxForce(float force); + float getMaxForce() const; + protected: bool init(PhysicsBody* a, PhysicsBody* b); @@ -95,8 +98,8 @@ protected: bool init(PhysicsBody* a, PhysicsBody* b, const Point& anchr); protected: - PhysicsJointFixed(); - virtual ~PhysicsJointFixed(); + PhysicsJointFixed() {} + virtual ~PhysicsJointFixed() {} }; /* @@ -107,6 +110,10 @@ class PhysicsJointLimit : public PhysicsJoint public: static PhysicsJointLimit* construct(PhysicsBody* a, PhysicsBody* b, const Point& anchr1, const Point& anchr2); + Point getAnchr1() const; + void setAnchr1(const Point& anchr1); + Point getAnchr2() const; + void setAnchr2(const Point& anchr2); float getMin() const; void setMin(float min); float getMax() const; @@ -116,8 +123,8 @@ protected: bool init(PhysicsBody* a, PhysicsBody* b, const Point& anchr1, const Point& anchr2); protected: - PhysicsJointLimit(); - virtual ~PhysicsJointLimit(); + PhysicsJointLimit() {} + virtual ~PhysicsJointLimit() {} }; /* @@ -128,15 +135,12 @@ class PhysicsJointPin : public PhysicsJoint public: static PhysicsJointPin* construct(PhysicsBody* a, PhysicsBody* b, const Point& anchr); - void setMaxForce(float force); - float getMaxForce() const; - protected: bool init(PhysicsBody* a, PhysicsBody* b, const Point& anchr); protected: - PhysicsJointPin(); - virtual ~PhysicsJointPin(); + PhysicsJointPin() {} + virtual ~PhysicsJointPin() {} }; class PhysicsJointDistance : public PhysicsJoint @@ -144,12 +148,150 @@ class PhysicsJointDistance : public PhysicsJoint public: static PhysicsJointDistance* construct(PhysicsBody* a, PhysicsBody* b, const Point& anchr1, const Point& anchr2); + float getDistance() const; + void setDistance(float distance); + protected: bool init(PhysicsBody* a, PhysicsBody* b, const Point& anchr1, const Point& anchr2); protected: - PhysicsJointDistance(); - virtual ~PhysicsJointDistance(); + PhysicsJointDistance() {} + virtual ~PhysicsJointDistance() {} +}; + +class PhysicsJointSpring : public PhysicsJoint +{ +public: + static PhysicsJointSpring* construct(PhysicsBody* a, PhysicsBody* b, const Point& anchr1, const Point& anchr2, float stiffness, float damping); + Point getAnchr1() const; + void setAnchr1(const Point& anchr1); + Point getAnchr2() const; + void setAnchr2(const Point& anchr2); + float getRestLength() const; + void setRestLength(float restLength); + float getStiffness() const; + void setStiffness(float stiffness); + float getDamping() const; + void setDamping(float damping); + +protected: + bool init(PhysicsBody* a, PhysicsBody* b, const Point& anchr1, const Point& anchr2, float stiffness, float damping); + +protected: + PhysicsJointSpring() {} + virtual ~PhysicsJointSpring() {} +}; + +class PhysicsJointGroove : public PhysicsJoint +{ +public: + static PhysicsJointGroove* construct(PhysicsBody* a, PhysicsBody* b, const Point& grooveA, const Point& grooveB, const Point& anchr2); + + Point getGrooveA() const; + void setGrooveA(const Point& grooveA); + Point getGrooveB() const; + void setGrooveB(const Point& grooveB); + Point getAnchr2() const; + void setAnchr2(const Point& anchr2); + +protected: + bool init(PhysicsBody* a, PhysicsBody* b, const Point& grooveA, const Point& grooveB, const Point& anchr); + +protected: + PhysicsJointGroove() {} + virtual ~PhysicsJointGroove() {} +}; + +class PhysicsJointRotarySpring : public PhysicsJoint +{ +public: + static PhysicsJointRotarySpring* construct(PhysicsBody* a, PhysicsBody* b, float stiffness, float damping); + + float getRestAngle() const; + void setRestAngle(float restAngle); + float getStiffness() const; + void setStiffness(float stiffness); + float getDamping() const; + void setDamping(float damping); + +protected: + bool init(PhysicsBody* a, PhysicsBody* b, float stiffness, float damping); + +protected: + PhysicsJointRotarySpring() {} + virtual ~PhysicsJointRotarySpring() {} +}; + +class PhysicsJointRotaryLimit : public PhysicsJoint +{ +public: + static PhysicsJointRotaryLimit* construct(PhysicsBody* a, PhysicsBody* b); + + float getMin() const; + void setMin(float min); + float getMax() const; + void setMax(float max); + +protected: + bool init(PhysicsBody* a, PhysicsBody* b); + +protected: + PhysicsJointRotaryLimit() {} + virtual ~PhysicsJointRotaryLimit() {} +}; + +class PhysicsJointRatchet : public PhysicsJoint +{ +public: + static PhysicsJointRatchet* construct(PhysicsBody* a, PhysicsBody* b, float phase, float ratchet); + + float getAngle() const; + void setAngle(float angle); + float getPhase() const; + void setPhase(float phase); + float getRatchet() const; + void setRatchet(float ratchet); + +protected: + bool init(PhysicsBody* a, PhysicsBody* b, float phase, float ratchet); + +protected: + PhysicsJointRatchet() {} + virtual ~PhysicsJointRatchet() {} +}; + +class PhysicsJointGear : public PhysicsJoint +{ +public: + static PhysicsJointGear* construct(PhysicsBody* a, PhysicsBody* b, float phase, float ratio); + + float getPhase() const; + void setPhase(float phase); + float getRatio() const; + void setRatio(float ratchet); + +protected: + bool init(PhysicsBody* a, PhysicsBody* b, float phase, float ratio); + +protected: + PhysicsJointGear() {} + virtual ~PhysicsJointGear() {} +}; + +class PhysicsJointMotor : public PhysicsJoint +{ +public: + static PhysicsJointMotor* construct(PhysicsBody* a, PhysicsBody* b, float rate); + + float getRate() const; + void setRate(float rate); + +protected: + bool init(PhysicsBody* a, PhysicsBody* b, float rate); + +protected: + PhysicsJointMotor() {} + virtual ~PhysicsJointMotor() {} }; NS_CC_END