Update kiwano::physics
This commit is contained in:
parent
2c4258c087
commit
ae5d985238
|
|
@ -41,20 +41,6 @@ namespace kiwano
|
||||||
SetActor(actor);
|
SetActor(actor);
|
||||||
}
|
}
|
||||||
|
|
||||||
Body::Body(World* world, Actor* actor)
|
|
||||||
: Body()
|
|
||||||
{
|
|
||||||
world_ = world;
|
|
||||||
if (world_)
|
|
||||||
{
|
|
||||||
b2BodyDef def;
|
|
||||||
b2Body* body = world_->GetB2World()->CreateBody(&def);
|
|
||||||
SetB2Body(body);
|
|
||||||
}
|
|
||||||
SetActor(actor);
|
|
||||||
UpdateFromActor();
|
|
||||||
}
|
|
||||||
|
|
||||||
Body::~Body()
|
Body::~Body()
|
||||||
{
|
{
|
||||||
if (world_)
|
if (world_)
|
||||||
|
|
@ -63,40 +49,58 @@ namespace kiwano
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Fixture Body::AddShape(Shape* shape, Fixture::Property const& prop)
|
BodyPtr Body::Create(World* world, Actor* actor)
|
||||||
|
{
|
||||||
|
BodyPtr body = new Body;
|
||||||
|
if (body)
|
||||||
|
{
|
||||||
|
body->world_ = world;
|
||||||
|
if (world)
|
||||||
|
{
|
||||||
|
b2BodyDef def;
|
||||||
|
b2Body* b2body = world->GetB2World()->CreateBody(&def);
|
||||||
|
body->SetB2Body(b2body);
|
||||||
|
}
|
||||||
|
body->SetActor(actor);
|
||||||
|
body->UpdateFromActor();
|
||||||
|
}
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
|
||||||
|
Fixture Body::AddShape(Shape* shape, float density, float friction, float restitution)
|
||||||
{
|
{
|
||||||
KGE_ASSERT(body_ && world_);
|
KGE_ASSERT(body_ && world_);
|
||||||
|
|
||||||
if (shape)
|
if (shape)
|
||||||
{
|
{
|
||||||
return Fixture(this, shape, prop);
|
return Fixture::Create(this, shape, density, friction, restitution);
|
||||||
}
|
}
|
||||||
return Fixture();
|
return Fixture();
|
||||||
}
|
}
|
||||||
|
|
||||||
Fixture Body::AddCircleShape(float radius, Fixture::Property const& prop)
|
Fixture Body::AddCircleShape(float radius, float density)
|
||||||
{
|
{
|
||||||
return AddShape(&CircleShape(radius), prop);
|
return AddShape(&CircleShape(radius), density);
|
||||||
}
|
}
|
||||||
|
|
||||||
Fixture Body::AddBoxShape(Vec2 const& size, Fixture::Property const& prop)
|
Fixture Body::AddBoxShape(Vec2 const& size, float density)
|
||||||
{
|
{
|
||||||
return AddShape(&BoxShape(size), prop);
|
return AddShape(&BoxShape(size), density);
|
||||||
}
|
}
|
||||||
|
|
||||||
Fixture Body::AddPolygonShape(Vector<Point> const& vertexs, Fixture::Property const& prop)
|
Fixture Body::AddPolygonShape(Vector<Point> const& vertexs, float density)
|
||||||
{
|
{
|
||||||
return AddShape(&PolygonShape(vertexs), prop);
|
return AddShape(&PolygonShape(vertexs), density);
|
||||||
}
|
}
|
||||||
|
|
||||||
Fixture Body::AddEdgeShape(Point const& p1, Point const& p2, Fixture::Property const& prop)
|
Fixture Body::AddEdgeShape(Point const& p1, Point const& p2, float density)
|
||||||
{
|
{
|
||||||
return AddShape(&EdgeShape(p1, p2), prop);
|
return AddShape(&EdgeShape(p1, p2), density);
|
||||||
}
|
}
|
||||||
|
|
||||||
Fixture Body::AddChainShape(Vector<Point> const& vertexs, bool loop, Fixture::Property const& prop)
|
Fixture Body::AddChainShape(Vector<Point> const& vertexs, bool loop, float density)
|
||||||
{
|
{
|
||||||
return AddShape(&ChainShape(vertexs, loop), prop);
|
return AddShape(&ChainShape(vertexs, loop), density);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Body::RemoveFixture(Fixture const& fixture)
|
void Body::RemoveFixture(Fixture const& fixture)
|
||||||
|
|
@ -120,6 +124,24 @@ namespace kiwano
|
||||||
return world_->World2Stage(body_->GetWorldPoint(world_->Stage2World(local)));
|
return world_->World2Stage(body_->GetWorldPoint(world_->Stage2World(local)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Body::ApplyForce(Vec2 const& force, Point const& point, bool wake)
|
||||||
|
{
|
||||||
|
KGE_ASSERT(body_ && world_);
|
||||||
|
body_->ApplyForce(b2Vec2(force.x, force.y), world_->Stage2World(point), wake);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Body::ApplyForceToCenter(Vec2 const& force, bool wake)
|
||||||
|
{
|
||||||
|
KGE_ASSERT(body_ && world_);
|
||||||
|
body_->ApplyForceToCenter(b2Vec2(force.x, force.y), wake);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Body::ApplyTorque(float torque, bool wake)
|
||||||
|
{
|
||||||
|
KGE_ASSERT(body_ && world_);
|
||||||
|
body_->ApplyTorque(torque, wake);
|
||||||
|
}
|
||||||
|
|
||||||
void Body::SetB2Body(b2Body* body)
|
void Body::SetB2Body(b2Body* body)
|
||||||
{
|
{
|
||||||
body_ = body;
|
body_ = body;
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ namespace kiwano
|
||||||
class World;
|
class World;
|
||||||
|
|
||||||
// 먼竟
|
// 먼竟
|
||||||
|
KGE_DECLARE_SMART_PTR(Body);
|
||||||
class KGE_API Body
|
class KGE_API Body
|
||||||
: public ObjectBase
|
: public ObjectBase
|
||||||
{
|
{
|
||||||
|
|
@ -43,16 +44,17 @@ namespace kiwano
|
||||||
|
|
||||||
Body();
|
Body();
|
||||||
Body(b2Body* body, Actor* actor);
|
Body(b2Body* body, Actor* actor);
|
||||||
Body(World* world, Actor* actor);
|
|
||||||
virtual ~Body();
|
virtual ~Body();
|
||||||
|
|
||||||
|
static BodyPtr Create(World* world, Actor* actor);
|
||||||
|
|
||||||
// 警속近榴
|
// 警속近榴
|
||||||
Fixture AddShape(Shape* shape, Fixture::Property const& prop = Fixture::Property());
|
Fixture AddShape(Shape* shape, float density = 0.f, float friction = 0.2f, float restitution = 0.f);
|
||||||
Fixture AddCircleShape(float radius, Fixture::Property const& prop = Fixture::Property());
|
Fixture AddCircleShape(float radius, float density = 0.f);
|
||||||
Fixture AddBoxShape(Vec2 const& size, Fixture::Property const& prop = Fixture::Property());
|
Fixture AddBoxShape(Vec2 const& size, float density = 0.f);
|
||||||
Fixture AddPolygonShape(Vector<Point> const& vertexs, Fixture::Property const& prop = Fixture::Property());
|
Fixture AddPolygonShape(Vector<Point> const& vertexs, float density = 0.f);
|
||||||
Fixture AddEdgeShape(Point const& p1, Point const& p2, Fixture::Property const& prop = Fixture::Property());
|
Fixture AddEdgeShape(Point const& p1, Point const& p2, float density = 0.f);
|
||||||
Fixture AddChainShape(Vector<Point> const& vertexs, bool loop = false, Fixture::Property const& prop = Fixture::Property());
|
Fixture AddChainShape(Vector<Point> const& vertexs, bool loop, float density = 0.f);
|
||||||
|
|
||||||
// 삿혤셸야죗깊
|
// 삿혤셸야죗깊
|
||||||
Fixture GetFixture() const { KGE_ASSERT(body_); Fixture(body_->GetFixtureList()); }
|
Fixture GetFixture() const { KGE_ASSERT(body_); Fixture(body_->GetFixtureList()); }
|
||||||
|
|
@ -69,6 +71,11 @@ namespace kiwano
|
||||||
Type GetType() const { KGE_ASSERT(body_); return Type(body_->GetType()); }
|
Type GetType() const { KGE_ASSERT(body_); return Type(body_->GetType()); }
|
||||||
void SetType(Type type) { KGE_ASSERT(body_); body_->SetType(static_cast<b2BodyType>(type)); }
|
void SetType(Type type) { KGE_ASSERT(body_); body_->SetType(static_cast<b2BodyType>(type)); }
|
||||||
|
|
||||||
|
void ApplyForce(Vec2 const& force, Point const& point, bool wake = true);
|
||||||
|
void ApplyForceToCenter(Vec2 const& force, bool wake = true);
|
||||||
|
|
||||||
|
void ApplyTorque(float torque, bool wake = true);
|
||||||
|
|
||||||
bool IsIgnoreRotation() const { return ignore_rotation_; }
|
bool IsIgnoreRotation() const { return ignore_rotation_; }
|
||||||
void SetIgnoreRotation(bool ignore_rotation) { ignore_rotation_ = ignore_rotation; }
|
void SetIgnoreRotation(bool ignore_rotation) { ignore_rotation_ = ignore_rotation; }
|
||||||
|
|
||||||
|
|
@ -91,7 +98,5 @@ namespace kiwano
|
||||||
World* world_;
|
World* world_;
|
||||||
b2Body* body_;
|
b2Body* body_;
|
||||||
};
|
};
|
||||||
|
|
||||||
KGE_DECLARE_SMART_PTR(Body);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,8 +38,7 @@ namespace kiwano
|
||||||
SetB2Fixture(fixture);
|
SetB2Fixture(fixture);
|
||||||
}
|
}
|
||||||
|
|
||||||
Fixture::Fixture(Body* body, Shape* shape, Property const& prop)
|
Fixture Fixture::Create(Body* body, Shape* shape, float density, float friction, float restitution)
|
||||||
: Fixture()
|
|
||||||
{
|
{
|
||||||
KGE_ASSERT(body);
|
KGE_ASSERT(body);
|
||||||
|
|
||||||
|
|
@ -49,12 +48,14 @@ namespace kiwano
|
||||||
|
|
||||||
b2Body* b2body = body->GetB2Body();
|
b2Body* b2body = body->GetB2Body();
|
||||||
b2FixtureDef fd;
|
b2FixtureDef fd;
|
||||||
fd.density = prop.density;
|
fd.density = density;
|
||||||
fd.friction = prop.friction;
|
fd.friction = friction;
|
||||||
fd.restitution = prop.restitution;
|
fd.restitution = restitution;
|
||||||
fd.shape = shape->GetB2Shape();
|
fd.shape = shape->GetB2Shape();
|
||||||
fixture_ = b2body->CreateFixture(&fd);
|
auto fixture = b2body->CreateFixture(&fd);
|
||||||
|
return Fixture(fixture);
|
||||||
}
|
}
|
||||||
|
return Fixture();
|
||||||
}
|
}
|
||||||
|
|
||||||
Shape Fixture::GetShape() const
|
Shape Fixture::GetShape() const
|
||||||
|
|
|
||||||
|
|
@ -32,34 +32,16 @@ namespace kiwano
|
||||||
class Fixture
|
class Fixture
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
struct Property
|
|
||||||
{
|
|
||||||
float density; // 密度 kg/m^2
|
|
||||||
float friction; // 摩擦系数 [0,1]
|
|
||||||
float restitution; // 弹性 [0,1]
|
|
||||||
|
|
||||||
Property()
|
|
||||||
: density(0.f)
|
|
||||||
, friction(0.2f)
|
|
||||||
, restitution(0.f)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Property(float density, float friction, float restitution)
|
|
||||||
: density(density)
|
|
||||||
, friction(friction)
|
|
||||||
, restitution(restitution)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Fixture();
|
Fixture();
|
||||||
Fixture(b2Fixture* fixture);
|
Fixture(b2Fixture* fixture);
|
||||||
Fixture(Body* body, Shape* shape, Property const& prop);
|
|
||||||
|
static Fixture Create(Body* body, Shape* shape, float density = 0.f, float friction = 0.2f, float restitution = 0.f);
|
||||||
|
|
||||||
Shape GetShape() const;
|
Shape GetShape() const;
|
||||||
Fixture GetNext() const;
|
Fixture GetNext() const;
|
||||||
|
|
||||||
|
bool IsValid() const { return !!fixture_; }
|
||||||
|
|
||||||
b2Fixture* GetB2Fixture() { return fixture_; }
|
b2Fixture* GetB2Fixture() { return fixture_; }
|
||||||
const b2Fixture* GetB2Fixture() const { return fixture_; }
|
const b2Fixture* GetB2Fixture() const { return fixture_; }
|
||||||
void SetB2Fixture(b2Fixture* fixture) { fixture_ = fixture; }
|
void SetB2Fixture(b2Fixture* fixture) { fixture_ = fixture; }
|
||||||
|
|
|
||||||
|
|
@ -86,5 +86,33 @@ namespace kiwano
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
//
|
||||||
|
// DistanceJoint
|
||||||
|
//
|
||||||
|
|
||||||
|
DistanceJoint::DistanceJoint()
|
||||||
|
: Joint()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
DistanceJoint::DistanceJoint(World* world, b2DistanceJointDef* def)
|
||||||
|
: Joint(world, def)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
DistanceJointPtr DistanceJoint::Create(World* world, Param const& param)
|
||||||
|
{
|
||||||
|
KGE_ASSERT(param.body_a && param.body_b);
|
||||||
|
|
||||||
|
b2DistanceJointDef def;
|
||||||
|
def.bodyA = param.body_a->GetB2Body();
|
||||||
|
def.bodyB = param.body_b->GetB2Body();
|
||||||
|
def.localAnchorA = world->Stage2World(param.local_anchor_a);
|
||||||
|
def.localAnchorB = world->Stage2World(param.local_anchor_b);
|
||||||
|
def.length = world->Stage2World((param.body_a->GetWorldPoint(param.local_anchor_a) - param.body_b->GetWorldPoint(param.local_anchor_b)).Length());
|
||||||
|
|
||||||
|
DistanceJointPtr joint = new DistanceJoint(world, &def);
|
||||||
|
return joint;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,15 @@ namespace kiwano
|
||||||
Motor
|
Motor
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ParamBase
|
||||||
|
{
|
||||||
|
Body* body_a;
|
||||||
|
Body* body_b;
|
||||||
|
|
||||||
|
ParamBase(Body* body_a, Body* body_b) : body_a(body_a), body_b(body_b) {}
|
||||||
|
ParamBase(BodyPtr body_a, BodyPtr body_b) : body_a(body_a.get()), body_b(body_b.get()) {}
|
||||||
|
};
|
||||||
|
|
||||||
Joint();
|
Joint();
|
||||||
Joint(b2Joint* joint);
|
Joint(b2Joint* joint);
|
||||||
Joint(World* world, b2JointDef* joint_def);
|
Joint(World* world, b2JointDef* joint_def);
|
||||||
|
|
@ -67,5 +76,32 @@ namespace kiwano
|
||||||
World* world_;
|
World* world_;
|
||||||
Type type_;
|
Type type_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
KGE_DECLARE_SMART_PTR(DistanceJoint);
|
||||||
|
class KGE_API DistanceJoint
|
||||||
|
: public Joint
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
struct Param : public Joint::ParamBase
|
||||||
|
{
|
||||||
|
Point local_anchor_a;
|
||||||
|
Point local_anchor_b;
|
||||||
|
|
||||||
|
Param(Body* body_a, Body* body_b, Point const& local_anchor_a, Point const& local_anchor_b)
|
||||||
|
: ParamBase(body_a, body_b)
|
||||||
|
, local_anchor_a(local_anchor_a)
|
||||||
|
, local_anchor_b(local_anchor_b)
|
||||||
|
{}
|
||||||
|
|
||||||
|
Param(BodyPtr body_a, BodyPtr body_b, Point const& local_anchor_a, Point const& local_anchor_b)
|
||||||
|
: Param(body_a.get(), body_b.get(), local_anchor_a, local_anchor_b)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
DistanceJoint();
|
||||||
|
DistanceJoint(World* world, b2DistanceJointDef* def);
|
||||||
|
|
||||||
|
static DistanceJointPtr Create(World* world, Param const& param);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ namespace kiwano
|
||||||
|
|
||||||
BodyPtr World::CreateBody(Actor* actor)
|
BodyPtr World::CreateBody(Actor* actor)
|
||||||
{
|
{
|
||||||
BodyPtr body = new Body(this, actor);
|
BodyPtr body = Body::Create(this, actor);
|
||||||
bodies_.push_back(body.get());
|
bodies_.push_back(body.get());
|
||||||
return body;
|
return body;
|
||||||
}
|
}
|
||||||
|
|
@ -156,13 +156,25 @@ namespace kiwano
|
||||||
{
|
{
|
||||||
Stage::Update(dt);
|
Stage::Update(dt);
|
||||||
|
|
||||||
world_.Step(dt.Seconds(), vel_iter_, pos_iter_);
|
|
||||||
|
|
||||||
b2Body* b2body = world_.GetBodyList();
|
b2Body* b2body = world_.GetBodyList();
|
||||||
while (b2body)
|
while (b2body)
|
||||||
{
|
{
|
||||||
Body* body = static_cast<Body*>(b2body->GetUserData());
|
Body* body = static_cast<Body*>(b2body->GetUserData());
|
||||||
if (body)
|
if (body && body->GetType() != Body::Type::Static)
|
||||||
|
{
|
||||||
|
body->UpdateFromActor();
|
||||||
|
}
|
||||||
|
|
||||||
|
b2body = b2body->GetNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
world_.Step(dt.Seconds(), vel_iter_, pos_iter_);
|
||||||
|
|
||||||
|
b2body = world_.GetBodyList();
|
||||||
|
while (b2body)
|
||||||
|
{
|
||||||
|
Body* body = static_cast<Body*>(b2body->GetUserData());
|
||||||
|
if (body && body->GetType() != Body::Type::Static)
|
||||||
{
|
{
|
||||||
body->UpdateActor();
|
body->UpdateActor();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -108,7 +108,7 @@ namespace kiwano
|
||||||
{
|
{
|
||||||
PrepareRender(rt);
|
PrepareRender(rt);
|
||||||
|
|
||||||
rt->DrawTexture(frame_->GetTexture(), &frame_->GetCropRect(), nullptr);
|
rt->DrawTexture(frame_->GetTexture(), &frame_->GetCropRect(), &GetBounds());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,8 @@ namespace kiwano
|
||||||
const uint32_t BLUE_MASK = 0xff << BLUE_SHIFT;
|
const uint32_t BLUE_MASK = 0xff << BLUE_SHIFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Color Color::Transparent = Color(0.f, 0.f, 0.f, 0.f);
|
||||||
|
|
||||||
Color::Color()
|
Color::Color()
|
||||||
: r(0)
|
: r(0)
|
||||||
, g(0)
|
, g(0)
|
||||||
|
|
@ -72,4 +74,4 @@ namespace kiwano
|
||||||
, a(alpha)
|
, a(alpha)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -112,6 +112,8 @@ namespace kiwano
|
||||||
YellowGreen = 0x9ACD32
|
YellowGreen = 0x9ACD32
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const Color Transparent;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
float r;
|
float r;
|
||||||
float g;
|
float g;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue