issue #2771: add more joint tests, add some joint api, fix bugs

This commit is contained in:
boyu0 2013-12-03 12:47:03 +08:00
parent dba58f6a9b
commit 63a4e09c90
5 changed files with 184 additions and 19 deletions

View File

@ -26,6 +26,7 @@
#include <climits>
#include <algorithm>
#include <cmath>
#include "chipmunk.h"
@ -348,7 +349,7 @@ void PhysicsBody::setPosition(Point position)
void PhysicsBody::setRotation(float rotation)
{
cpBodySetAngle(_info->getBody(), PhysicsHelper::float2cpfloat(rotation));
cpBodySetAngle(_info->getBody(), PhysicsHelper::float2cpfloat(rotation * M_PI / 180.0f));
}
Point PhysicsBody::getPosition() const
@ -359,7 +360,7 @@ Point PhysicsBody::getPosition() const
float PhysicsBody::getRotation() const
{
return -PhysicsHelper::cpfloat2float(cpBodyGetAngle(_info->getBody()) / 3.14f * 180.0f);
return -PhysicsHelper::cpfloat2float(cpBodyGetAngle(_info->getBody()) / M_PI * 180.0f);
}
PhysicsShape* PhysicsBody::addShape(PhysicsShape* shape, bool addMassAndMoment/* = true*/)

View File

@ -234,11 +234,11 @@ bool PhysicsJointPin::init(PhysicsBody *a, PhysicsBody *b, const Point& anchr)
return false;
}
PhysicsJointLimit* PhysicsJointLimit::construct(PhysicsBody* a, PhysicsBody* b, const Point& anchr1, const Point& anchr2)
PhysicsJointLimit* PhysicsJointLimit::construct(PhysicsBody* a, PhysicsBody* b, const Point& anchr1, const Point& anchr2, float min, float max)
{
PhysicsJointLimit* joint = new PhysicsJointLimit();
if (joint && joint->init(a, b, anchr1, anchr2))
if (joint && joint->init(a, b, anchr1, anchr2, min, max))
{
return joint;
}
@ -247,7 +247,12 @@ PhysicsJointLimit* PhysicsJointLimit::construct(PhysicsBody* a, PhysicsBody* b,
return nullptr;
}
bool PhysicsJointLimit::init(PhysicsBody* a, PhysicsBody* b, const Point& anchr1, const Point& anchr2)
PhysicsJointLimit* PhysicsJointLimit::construct(PhysicsBody* a, PhysicsBody* b, const Point& anchr1, const Point& anchr2)
{
return construct(a, b, anchr1, anchr2, 0, b->local2World(anchr1).getDistance(a->local2World(anchr2)));
}
bool PhysicsJointLimit::init(PhysicsBody* a, PhysicsBody* b, const Point& anchr1, const Point& anchr2, float min, float max)
{
do
{
@ -256,8 +261,8 @@ bool PhysicsJointLimit::init(PhysicsBody* a, PhysicsBody* b, const Point& anchr1
cpConstraint* joint = cpSlideJointNew(getBodyInfo(a)->getBody(), getBodyInfo(b)->getBody(),
PhysicsHelper::point2cpv(anchr1),
PhysicsHelper::point2cpv(anchr2),
0,
PhysicsHelper::float2cpfloat(_bodyB->local2World(anchr1).getDistance(_bodyA->local2World(anchr2))));
PhysicsHelper::float2cpfloat(min),
PhysicsHelper::float2cpfloat(max));
CC_BREAK_IF(joint == nullptr);
@ -439,6 +444,40 @@ void PhysicsJointSpring::setDamping(float damping)
cpDampedSpringSetDamping(_info->getJoints().front(), PhysicsHelper::float2cpfloat(damping));
}
PhysicsJointGroove* PhysicsJointGroove::construct(PhysicsBody* a, PhysicsBody* b, const Point& grooveA, const Point& grooveB, const Point& anchr2)
{
PhysicsJointGroove* joint = new PhysicsJointGroove();
if (joint && joint->init(a, b, grooveA, grooveB, anchr2))
{
return joint;
}
CC_SAFE_DELETE(joint);
return nullptr;
}
bool PhysicsJointGroove::init(PhysicsBody* a, PhysicsBody* b, const Point& grooveA, const Point& grooveB, const Point& anchr2)
{
do {
CC_BREAK_IF(!PhysicsJoint::init(a, b));
cpConstraint* joint = cpGrooveJointNew(getBodyInfo(a)->getBody(),
getBodyInfo(b)->getBody(),
PhysicsHelper::point2cpv(grooveA),
PhysicsHelper::point2cpv(grooveB),
PhysicsHelper::point2cpv(anchr2));
CC_BREAK_IF(joint == nullptr);
_info->add(joint);
return true;
} while (false);
return false;
}
Point PhysicsJointGroove::getGrooveA() const
{
return PhysicsHelper::cpv2point(cpGrooveJointGetGrooveA(_info->getJoints().front()));
@ -533,11 +572,11 @@ void PhysicsJointRotarySpring::setDamping(float damping)
cpDampedRotarySpringSetDamping(_info->getJoints().front(), PhysicsHelper::float2cpfloat(damping));
}
PhysicsJointRotaryLimit* PhysicsJointRotaryLimit::construct(PhysicsBody* a, PhysicsBody* b)
PhysicsJointRotaryLimit* PhysicsJointRotaryLimit::construct(PhysicsBody* a, PhysicsBody* b, float min, float max)
{
PhysicsJointRotaryLimit* joint = new PhysicsJointRotaryLimit();
if (joint && joint->init(a, b))
if (joint && joint->init(a, b, min, max))
{
return joint;
}
@ -546,7 +585,12 @@ PhysicsJointRotaryLimit* PhysicsJointRotaryLimit::construct(PhysicsBody* a, Phys
return nullptr;
}
bool PhysicsJointRotaryLimit::init(PhysicsBody* a, PhysicsBody* b)
PhysicsJointRotaryLimit* PhysicsJointRotaryLimit::construct(PhysicsBody* a, PhysicsBody* b)
{
return construct(a, b, 0.0f, 0.0f);
}
bool PhysicsJointRotaryLimit::init(PhysicsBody* a, PhysicsBody* b, float min, float max)
{
do
{
@ -554,8 +598,8 @@ bool PhysicsJointRotaryLimit::init(PhysicsBody* a, PhysicsBody* b)
cpConstraint* joint = cpRotaryLimitJointNew(getBodyInfo(a)->getBody(),
getBodyInfo(b)->getBody(),
0,
PhysicsHelper::float2cpfloat(_bodyB->getRotation() - _bodyA->getRotation()));
PhysicsHelper::float2cpfloat(min),
PhysicsHelper::float2cpfloat(max));
CC_BREAK_IF(joint == nullptr);
@ -673,7 +717,7 @@ bool PhysicsJointGear::init(PhysicsBody* a, PhysicsBody* b, float phase, float r
cpConstraint* joint = cpGearJointNew(getBodyInfo(a)->getBody(),
getBodyInfo(b)->getBody(),
PhysicsHelper::float2cpfloat(phase),
PhysicsHelper::cpfloat2float(ratio));
PhysicsHelper::float2cpfloat(ratio));
CC_BREAK_IF(joint == nullptr);

View File

@ -109,6 +109,7 @@ class PhysicsJointLimit : public PhysicsJoint
{
public:
static PhysicsJointLimit* construct(PhysicsBody* a, PhysicsBody* b, const Point& anchr1, const Point& anchr2);
static PhysicsJointLimit* construct(PhysicsBody* a, PhysicsBody* b, const Point& anchr1, const Point& anchr2, float min, float max);
Point getAnchr1() const;
void setAnchr1(const Point& anchr1);
@ -120,7 +121,7 @@ public:
void setMax(float max);
protected:
bool init(PhysicsBody* a, PhysicsBody* b, const Point& anchr1, const Point& anchr2);
bool init(PhysicsBody* a, PhysicsBody* b, const Point& anchr1, const Point& anchr2, float min, float max);
protected:
PhysicsJointLimit() {}
@ -225,6 +226,7 @@ protected:
class PhysicsJointRotaryLimit : public PhysicsJoint
{
public:
static PhysicsJointRotaryLimit* construct(PhysicsBody* a, PhysicsBody* b, float min, float max);
static PhysicsJointRotaryLimit* construct(PhysicsBody* a, PhysicsBody* b);
float getMin() const;
@ -233,7 +235,7 @@ public:
void setMax(float max);
protected:
bool init(PhysicsBody* a, PhysicsBody* b);
bool init(PhysicsBody* a, PhysicsBody* b, float min, float max);
protected:
PhysicsJointRotaryLimit() {}

View File

@ -519,6 +519,19 @@ void PhysicsDebugDraw::drawJoint(PhysicsJoint& joint)
_drawNode->drawSegment(PhysicsHelper::cpv2point(a), PhysicsHelper::cpv2point(b), 1, Color4F(0.0f, 0.0f, 1.0f, 1.0f));
_drawNode->drawDot(PhysicsHelper::cpv2point(c), 2, Color4F(0.0f, 1.0f, 0.0f, 1.0f));
}
else if(klass == cpDampedSpringGetClass())
{
cpDampedSpring *subJoint = (cpDampedSpring *)constraint;
cpVect a = cpvadd(body_a->p, cpvrotate(subJoint->anchr1, body_a->rot));
cpVect b = cpvadd(body_b->p, cpvrotate(subJoint->anchr2, body_b->rot));
_drawNode->drawSegment(PhysicsHelper::cpv2point(a), PhysicsHelper::cpv2point(b), 1, Color4F(0.0f, 0.0f, 1.0f, 1.0f));
_drawNode->drawDot(PhysicsHelper::cpv2point(a), 2, Color4F(0.0f, 1.0f, 0.0f, 1.0f));
_drawNode->drawDot(PhysicsHelper::cpv2point(b), 2, Color4F(0.0f, 1.0f, 0.0f, 1.0f));
}
}
}

View File

@ -686,7 +686,6 @@ void PhysicsDemoJoints::onEnter()
node->setPhysicsBody(box);
box->setDynamic(false);
node->setPosition(Point::ZERO);
this->addChild(node);
for (int i = 0; i < 4; ++i)
@ -749,9 +748,115 @@ void PhysicsDemoJoints::onEnter()
auto sp2 = makeBox(offset + Point(30, 0), Size(30, 10));
sp2->getPhysicsBody()->setTag(DRAG_BODYS_TAG);
PhysicsJointLimit* joint = PhysicsJointLimit::construct(sp1->getPhysicsBody(), sp2->getPhysicsBody(), Point::ZERO, Point::ZERO);
joint->setMin(30.0f);
joint->setMax(60.0f);
PhysicsJointLimit* joint = PhysicsJointLimit::construct(sp1->getPhysicsBody(), sp2->getPhysicsBody(), Point::ZERO, Point::ZERO, 30.0f, 60.0f);
_scene->getPhysicsWorld()->addJoint(joint);
this->addChild(sp1);
this->addChild(sp2);
break;
}
case 4:
{
auto sp1 = makeBall(offset - Point(30, 0), 10);
sp1->getPhysicsBody()->setTag(DRAG_BODYS_TAG);
auto sp2 = makeBox(offset + Point(30, 0), Size(30, 10));
sp2->getPhysicsBody()->setTag(DRAG_BODYS_TAG);
PhysicsJointSpring* joint = PhysicsJointSpring::construct(sp1->getPhysicsBody(), sp2->getPhysicsBody(), Point::ZERO, Point::ZERO, 500.0f, 0.3f);
_scene->getPhysicsWorld()->addJoint(joint);
this->addChild(sp1);
this->addChild(sp2);
break;
}
case 5:
{
auto sp1 = makeBall(offset - Point(30, 0), 10);
sp1->getPhysicsBody()->setTag(DRAG_BODYS_TAG);
auto sp2 = makeBox(offset + Point(30, 0), Size(30, 10));
sp2->getPhysicsBody()->setTag(DRAG_BODYS_TAG);
PhysicsJointGroove* joint = PhysicsJointGroove::construct(sp1->getPhysicsBody(), sp2->getPhysicsBody(), Point(30, 15), Point(30, -15), Point(-30, 0));
_scene->getPhysicsWorld()->addJoint(joint);
this->addChild(sp1);
this->addChild(sp2);
break;
}
case 6:
{
auto sp1 = makeBox(offset - Point(30, 0), Size(30, 10));
sp1->getPhysicsBody()->setTag(DRAG_BODYS_TAG);
auto sp2 = makeBox(offset + Point(30, 0), Size(30, 10));
sp2->getPhysicsBody()->setTag(DRAG_BODYS_TAG);
_scene->getPhysicsWorld()->addJoint(PhysicsJointPin::construct(sp1->getPhysicsBody(), box, sp1->getPosition()));
_scene->getPhysicsWorld()->addJoint(PhysicsJointPin::construct(sp2->getPhysicsBody(), box, sp2->getPosition()));
PhysicsJointRotarySpring* joint = PhysicsJointRotarySpring::construct(sp1->getPhysicsBody(), sp2->getPhysicsBody(), 3000.0f, 60.0f);
_scene->getPhysicsWorld()->addJoint(joint);
this->addChild(sp1);
this->addChild(sp2);
break;
}
case 7:
{
auto sp1 = makeBox(offset - Point(30, 0), Size(30, 10));
sp1->getPhysicsBody()->setTag(DRAG_BODYS_TAG);
auto sp2 = makeBox(offset + Point(30, 0), Size(30, 10));
sp2->getPhysicsBody()->setTag(DRAG_BODYS_TAG);
_scene->getPhysicsWorld()->addJoint(PhysicsJointPin::construct(sp1->getPhysicsBody(), box, sp1->getPosition()));
_scene->getPhysicsWorld()->addJoint(PhysicsJointPin::construct(sp2->getPhysicsBody(), box, sp2->getPosition()));
PhysicsJointRotaryLimit* joint = PhysicsJointRotaryLimit::construct(sp1->getPhysicsBody(), sp2->getPhysicsBody(), 0.0f, M_PI_2);
_scene->getPhysicsWorld()->addJoint(joint);
this->addChild(sp1);
this->addChild(sp2);
break;
}
case 8:
{
auto sp1 = makeBox(offset - Point(30, 0), Size(30, 10));
sp1->getPhysicsBody()->setTag(DRAG_BODYS_TAG);
auto sp2 = makeBox(offset + Point(30, 0), Size(30, 10));
sp2->getPhysicsBody()->setTag(DRAG_BODYS_TAG);
_scene->getPhysicsWorld()->addJoint(PhysicsJointPin::construct(sp1->getPhysicsBody(), box, sp1->getPosition()));
_scene->getPhysicsWorld()->addJoint(PhysicsJointPin::construct(sp2->getPhysicsBody(), box, sp2->getPosition()));
PhysicsJointRatchet* joint = PhysicsJointRatchet::construct(sp1->getPhysicsBody(), sp2->getPhysicsBody(), 0.0f, M_PI_2);
_scene->getPhysicsWorld()->addJoint(joint);
this->addChild(sp1);
this->addChild(sp2);
break;
}
case 9:
{
auto sp1 = makeBox(offset - Point(30, 0), Size(30, 10));
sp1->getPhysicsBody()->setTag(DRAG_BODYS_TAG);
auto sp2 = makeBox(offset + Point(30, 0), Size(30, 10));
sp2->getPhysicsBody()->setTag(DRAG_BODYS_TAG);
_scene->getPhysicsWorld()->addJoint(PhysicsJointPin::construct(sp1->getPhysicsBody(), box, sp1->getPosition()));
_scene->getPhysicsWorld()->addJoint(PhysicsJointPin::construct(sp2->getPhysicsBody(), box, sp2->getPosition()));
PhysicsJointGear* joint = PhysicsJointGear::construct(sp1->getPhysicsBody(), sp2->getPhysicsBody(), 0.0f, 2.0f);
_scene->getPhysicsWorld()->addJoint(joint);
this->addChild(sp1);
this->addChild(sp2);
break;
}
case 10:
{
auto sp1 = makeBox(offset - Point(30, 0), Size(30, 10));
sp1->getPhysicsBody()->setTag(DRAG_BODYS_TAG);
auto sp2 = makeBox(offset + Point(30, 0), Size(30, 10));
sp2->getPhysicsBody()->setTag(DRAG_BODYS_TAG);
_scene->getPhysicsWorld()->addJoint(PhysicsJointPin::construct(sp1->getPhysicsBody(), box, sp1->getPosition()));
_scene->getPhysicsWorld()->addJoint(PhysicsJointPin::construct(sp2->getPhysicsBody(), box, sp2->getPosition()));
PhysicsJointMotor* joint = PhysicsJointMotor::construct(sp1->getPhysicsBody(), sp2->getPhysicsBody(), M_PI_2);
_scene->getPhysicsWorld()->addJoint(joint);
this->addChild(sp1);