issue #2771: change angular damping to moment. (these two have different meaning, change to the correct one)

This commit is contained in:
boyu0 2013-10-14 13:56:08 +08:00
parent 2e01b532f4
commit 5c7603e0ce
5 changed files with 162 additions and 79 deletions

View File

@ -56,8 +56,7 @@ NS_CC_BEGIN
namespace
{
static const float MASS_DEFAULT = 1.0;
static const float DENSITY_DEFAULT = 1.0;
static const float ANGULARDAMPING_DEFAULT = 200;
static const float MOMENT_DEFAULT = 200;
}
PhysicsBody::PhysicsBody()
@ -67,11 +66,11 @@ PhysicsBody::PhysicsBody()
, _dynamic(true)
, _enable(true)
, _massDefault(true)
, _angularDampingDefault(true)
, _momentDefault(true)
, _mass(MASS_DEFAULT)
, _area(0.0)
, _density(DENSITY_DEFAULT)
, _angularDamping(ANGULARDAMPING_DEFAULT)
, _density(0)
, _moment(MOMENT_DEFAULT)
, _tag(0)
{
}
@ -217,7 +216,7 @@ bool PhysicsBody::init()
_info = new PhysicsBodyInfo();
CC_BREAK_IF(_info == nullptr);
_info->body = cpBodyNew(PhysicsHelper::float2cpfloat(_mass), PhysicsHelper::float2cpfloat(_angularDamping));
_info->body = cpBodyNew(PhysicsHelper::float2cpfloat(_mass), PhysicsHelper::float2cpfloat(_moment));
CC_BREAK_IF(_info->body == nullptr);
return true;
@ -233,7 +232,7 @@ void PhysicsBody::setDynamic(bool dynamic)
if (dynamic)
{
cpBodySetMass(_info->body, PhysicsHelper::float2cpfloat(_mass));
cpBodySetMoment(_info->body, PhysicsHelper::float2cpfloat(_angularDamping));
cpBodySetMoment(_info->body, PhysicsHelper::float2cpfloat(_moment));
}else
{
cpBodySetMass(_info->body, PHYSICS_INFINITY);
@ -322,21 +321,7 @@ void PhysicsBody::addShape(PhysicsShape* shape)
}
}
if (shape->getAngularDumping() > 0)
{
if (shape->getAngularDumping() == INFINITY)
{
_angularDamping = INFINITY;
_angularDampingDefault = false;
cpBodySetMoment(_info->body, _angularDamping);
}
else if (_angularDamping != INFINITY)
{
_angularDamping = (_angularDampingDefault ? 0 : _angularDamping) + shape->getAngularDumping();
_angularDampingDefault = false;
cpBodySetMoment(_info->body, _angularDamping);
}
}
addMoment(shape->getMoment());
if (_world != nullptr) _world->addShape(shape);
@ -371,12 +356,112 @@ void PhysicsBody::applyTorque(float torque)
void PhysicsBody::setMass(float mass)
{
if (mass <= 0)
{
return;
}
_mass = mass;
_massDefault = false;
// update density
if (_mass == PHYSICS_INFINITY)
{
_density = PHYSICS_INFINITY;
}
else
{
if (_area > 0)
{
_density = _mass / _area;
}else
{
_density = 0;
}
}
cpBodySetMass(_info->body, PhysicsHelper::float2cpfloat(_mass));
}
void PhysicsBody::addMass(float mass)
{
if (mass == PHYSICS_INFINITY)
{
mass = PHYSICS_INFINITY;
_massDefault = false;
_density = PHYSICS_INFINITY;
}
else if (mass == -PHYSICS_INFINITY)
{
return;
}
else if (_mass != PHYSICS_INFINITY)
{
if (_massDefault)
{
_mass = 0;
_massDefault = false;
}
if (_mass + mass > 0)
{
_mass += mass;
}else
{
_mass = MASS_DEFAULT;
_massDefault = true;
}
if (_area > 0)
{
_density = _mass / _area;
}
else
{
_density = 0;
}
}
}
void PhysicsBody::addMoment(float moment)
{
if (moment == PHYSICS_INFINITY)
{
// if moment is INFINITY, the moment of the body will become INFINITY
_moment = PHYSICS_INFINITY;
_momentDefault = false;
}
else if (moment == -PHYSICS_INFINITY)
{
// if moment is -INFINITY, it won't change
return;
}
else
{
// if moment of the body is INFINITY is has no effect
if (_moment != PHYSICS_INFINITY)
{
if (_momentDefault)
{
_moment = 0;
_momentDefault = false;
}
if (_moment + moment > 0)
{
_moment += moment;
}
else
{
_moment = MOMENT_DEFAULT;
_momentDefault = true;
}
}
}
cpBodySetMoment(_info->body, moment);
}
void PhysicsBody::setVelocity(Point velocity)
{
cpBodySetVel(_info->body, PhysicsHelper::point2cpv(velocity));
@ -387,12 +472,12 @@ Point PhysicsBody::getVelocity()
return PhysicsHelper::cpv2point(cpBodyGetVel(_info->body));
}
void PhysicsBody::setAngularDamping(float angularDamping)
void PhysicsBody::setMoment(float moment)
{
_angularDamping = angularDamping;
_angularDampingDefault = false;
_moment = moment;
_momentDefault = false;
cpBodySetMoment(_info->body, _angularDamping);
cpBodySetMoment(_info->body, _moment);
}
PhysicsShape* PhysicsBody::getShapeByTag(int tag)
@ -434,42 +519,11 @@ void PhysicsBody::removeShape(PhysicsShape* shape)
_shapes.erase(it);
// deduce the mass, area and angularDamping
if (_mass != PHYSICS_INFINITY && shape->getMass() != PHYSICS_INFINITY)
{
if (_mass - shape->getMass() <= 0)
{
_mass = MASS_DEFAULT;
_massDefault = true;
}else
{
_mass = _mass = shape->getMass();
}
_area -= shape->getArea();
if (_mass == PHYSICS_INFINITY)
{
_density = PHYSICS_INFINITY;
}
else if (_area > 0)
{
_density = _mass / _area;
}
else
{
_density = DENSITY_DEFAULT;
}
if (_angularDamping - shape->getAngularDumping() > 0)
{
_angularDamping -= shape->getAngularDumping();
}else
{
_angularDamping = ANGULARDAMPING_DEFAULT;
_angularDampingDefault = true;
}
}
// deduce the area, mass and moment
// area must update before mass, because the density changes depend on it.
_area -= shape->getArea();
addMass(-shape->getMass());
addMoment(-shape->getMoment());
shape->release();
}

View File

@ -172,21 +172,49 @@ public:
/*
* @brief set the body mass.
* @note if you need add/subtract mass to body, don't use setMass(getMass() +/- mass), because the mass of body may be equal to PHYSICS_INFINITY, it will cause some unexpected result, please use addMass() instead.
*/
void setMass(float mass);
/*
* @brief get the body mass.
*/
inline float getMass() { return _mass; }
/*
* @brief add mass to body.
* if _mass(mass of the body) == PHYSICS_INFINITY, it remains.
* if mass == PHYSICS_INFINITY, _mass will be PHYSICS_INFINITY.
* if mass == -PHYSICS_INFINITY, _mass will not change.
* if mass + _mass <= 0, _mass will equal to MASS_DEFAULT(1.0)
* other wise, mass = mass + _mass;
*/
void addMass(float mass);
/*
* @brief set the body moment of inertia.
* @note if you need add/subtract moment to body, don't use setMoment(getMoment() +/- moment), because the moment of body may be equal to PHYSICS_INFINITY, it will cause some unexpected result, please use addMoment() instead.
*/
void setMoment(float moment);
/*
* @brief get the body moment of inertia.
*/
inline float getMoment(float moment) { return _moment; }
/*
* @brief add moment of inertia to body.
* if _moment(moment of the body) == PHYSICS_INFINITY, it remains.
* if moment == PHYSICS_INFINITY, _moment will be PHYSICS_INFINITY.
* if moment == -PHYSICS_INFINITY, _moment will not change.
* if moment + _moment <= 0, _moment will equal to MASS_DEFAULT(1.0)
* other wise, moment = moment + _moment;
*/
void addMoment(float moment);
/*
* @brief set angular damping.
*/
void setAngularDamping(float angularDamping);
//void setAngularDamping(float angularDamping);
/*
* @brief get angular damping.
*/
inline float getAngularDamping() { return _angularDamping; }
//inline float getAngularDamping() { return _angularDamping; }
//virtual Clonable* clone() const override;
@ -196,6 +224,7 @@ public:
inline int getTag() { return _tag; }
inline void setTag(int tag) { _tag = tag; }
protected:
bool init();
@ -216,11 +245,12 @@ protected:
bool _dynamic;
bool _enable;
bool _massDefault;
bool _angularDampingDefault;
bool _momentDefault;
float _mass;
float _area;
float _density;
float _angularDamping;
float _moment;
//float _angularDamping;
int _tag;
int _categoryBitmask;

View File

@ -48,7 +48,7 @@ PhysicsShape::PhysicsShape()
, _type(Type::UNKNOWN)
, _area(0)
, _mass(0)
, _angularDamping(0)
, _moment(0)
, _tag(0)
, _enable(true)
{
@ -234,7 +234,7 @@ bool PhysicsShapeCircle::init(float radius, PhysicsMaterial material/* = Materia
_area = PhysicsHelper::cpfloat2float(cpAreaForCircle(0, radius));
_mass = _material.density == PHYSICS_INFINITY ? PHYSICS_INFINITY : _material.density * _area;
_angularDamping = _mass == PHYSICS_INFINITY ? PHYSICS_INFINITY : cpMomentForCircle(_mass, 0, radius, PhysicsHelper::point2cpv(offset));
_moment = _mass == PHYSICS_INFINITY ? PHYSICS_INFINITY : cpMomentForCircle(_mass, 0, radius, PhysicsHelper::point2cpv(offset));
_info->add(shape);
@ -273,7 +273,7 @@ bool PhysicsShapeEdgeSegment::init(Point a, Point b, PhysicsMaterial material/*
CC_BREAK_IF(shape == nullptr);
_mass = PHYSICS_INFINITY;
_angularDamping = PHYSICS_INFINITY;
_moment = PHYSICS_INFINITY;
_info->add(shape);
@ -311,7 +311,7 @@ bool PhysicsShapeBox::init(Size size, PhysicsMaterial material/* = MaterialDefau
_area = PhysicsHelper::cpfloat2float(cpAreaForPoly(4, ((cpPolyShape*)shape)->verts));
_mass = _material.density == PHYSICS_INFINITY ? PHYSICS_INFINITY : _material.density * _area;
_angularDamping = _mass == PHYSICS_INFINITY ? PHYSICS_INFINITY : cpMomentForBox(_mass, PhysicsHelper::float2cpfloat(size.width), PhysicsHelper::float2cpfloat(size.height));
_moment = _mass == PHYSICS_INFINITY ? PHYSICS_INFINITY : cpMomentForBox(_mass, PhysicsHelper::float2cpfloat(size.width), PhysicsHelper::float2cpfloat(size.height));
_info->add(shape);
@ -352,7 +352,7 @@ bool PhysicsShapePolygon::init(Point* points, int count, PhysicsMaterial materia
_area = PhysicsHelper::cpfloat2float(cpAreaForPoly(((cpPolyShape*)shape)->numVerts, ((cpPolyShape*)shape)->verts));
_mass = _material.density == PHYSICS_INFINITY ? PHYSICS_INFINITY : _material.density * _area;
_angularDamping = _mass == PHYSICS_INFINITY ? PHYSICS_INFINITY : cpMomentForPoly(_mass, ((cpPolyShape*)shape)->numVerts, ((cpPolyShape*)shape)->verts, PhysicsHelper::point2cpv(offset));
_moment = _mass == PHYSICS_INFINITY ? PHYSICS_INFINITY : cpMomentForPoly(_mass, ((cpPolyShape*)shape)->numVerts, ((cpPolyShape*)shape)->verts, PhysicsHelper::point2cpv(offset));
_info->add(shape);
@ -401,7 +401,7 @@ bool PhysicsShapeEdgeBox::init(Size size, PhysicsMaterial material/* = MaterialD
CC_BREAK_IF(i < 4);
_mass = PHYSICS_INFINITY;
_angularDamping = PHYSICS_INFINITY;
_moment = PHYSICS_INFINITY;
initEnd();
@ -450,7 +450,7 @@ bool PhysicsShapeEdgePolygon::init(Point* points, int count, PhysicsMaterial mat
CC_BREAK_IF(i < count);
_mass = PHYSICS_INFINITY;
_angularDamping = PHYSICS_INFINITY;
_moment = PHYSICS_INFINITY;
initEnd();
@ -500,7 +500,7 @@ bool PhysicsShapeEdgeChain::init(Point* points, int count, PhysicsMaterial mater
CC_BREAK_IF(i < count);
_mass = PHYSICS_INFINITY;
_angularDamping = PHYSICS_INFINITY;
_moment = PHYSICS_INFINITY;
initEnd();

View File

@ -79,8 +79,8 @@ public:
inline PhysicsBody* getBody(){ return _body; }
inline Type getType() { return _type; }
inline float getArea() { return _area; }
inline float getAngularDumping() { return _angularDamping; }
void setAngularDumping(float angularDumping);
inline float getMoment() { return _moment; }
void setMoment(float moment);
inline void setTag(int tag) { _tag = tag; }
inline int getTag() { return _tag; }
void setEnable(bool enable);
@ -115,7 +115,7 @@ protected:
Type _type;
float _area;
float _mass;
float _angularDamping;
float _moment;
PhysicsMaterial _material;
int _tag;
bool _enable;

View File

@ -311,9 +311,8 @@ Node* PhysicsDemoLogoSmash::makeBall(float x, float y)
auto body = PhysicsBody::createCircle(0.95, PhysicsMaterial(1, 0, 0));
body->setMass(1.0);
body->setAngularDamping(PHYSICS_INFINITY);
body->setMoment(PHYSICS_INFINITY);
//body->setDynamic(false);
ball->setPhysicsBody(body);
ball->setPosition(Point(x, y));