Update kiwano::physics
This commit is contained in:
parent
2c4258c087
commit
ae5d985238
|
|
@ -41,20 +41,6 @@ namespace kiwano
|
|||
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()
|
||||
{
|
||||
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_);
|
||||
|
||||
if (shape)
|
||||
{
|
||||
return Fixture(this, shape, prop);
|
||||
return Fixture::Create(this, shape, density, friction, restitution);
|
||||
}
|
||||
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)
|
||||
|
|
@ -120,6 +124,24 @@ namespace kiwano
|
|||
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)
|
||||
{
|
||||
body_ = body;
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ namespace kiwano
|
|||
class World;
|
||||
|
||||
// 먼竟
|
||||
KGE_DECLARE_SMART_PTR(Body);
|
||||
class KGE_API Body
|
||||
: public ObjectBase
|
||||
{
|
||||
|
|
@ -43,16 +44,17 @@ namespace kiwano
|
|||
|
||||
Body();
|
||||
Body(b2Body* body, Actor* actor);
|
||||
Body(World* world, Actor* actor);
|
||||
virtual ~Body();
|
||||
|
||||
static BodyPtr Create(World* world, Actor* actor);
|
||||
|
||||
// 警속近榴
|
||||
Fixture AddShape(Shape* shape, Fixture::Property const& prop = Fixture::Property());
|
||||
Fixture AddCircleShape(float radius, Fixture::Property const& prop = Fixture::Property());
|
||||
Fixture AddBoxShape(Vec2 const& size, Fixture::Property const& prop = Fixture::Property());
|
||||
Fixture AddPolygonShape(Vector<Point> const& vertexs, Fixture::Property const& prop = Fixture::Property());
|
||||
Fixture AddEdgeShape(Point const& p1, Point const& p2, Fixture::Property const& prop = Fixture::Property());
|
||||
Fixture AddChainShape(Vector<Point> const& vertexs, bool loop = false, 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, float density = 0.f);
|
||||
Fixture AddBoxShape(Vec2 const& size, float density = 0.f);
|
||||
Fixture AddPolygonShape(Vector<Point> const& vertexs, float density = 0.f);
|
||||
Fixture AddEdgeShape(Point const& p1, Point const& p2, float density = 0.f);
|
||||
Fixture AddChainShape(Vector<Point> const& vertexs, bool loop, float density = 0.f);
|
||||
|
||||
// 삿혤셸야죗깊
|
||||
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()); }
|
||||
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_; }
|
||||
void SetIgnoreRotation(bool ignore_rotation) { ignore_rotation_ = ignore_rotation; }
|
||||
|
||||
|
|
@ -91,7 +98,5 @@ namespace kiwano
|
|||
World* world_;
|
||||
b2Body* body_;
|
||||
};
|
||||
|
||||
KGE_DECLARE_SMART_PTR(Body);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,8 +38,7 @@ namespace kiwano
|
|||
SetB2Fixture(fixture);
|
||||
}
|
||||
|
||||
Fixture::Fixture(Body* body, Shape* shape, Property const& prop)
|
||||
: Fixture()
|
||||
Fixture Fixture::Create(Body* body, Shape* shape, float density, float friction, float restitution)
|
||||
{
|
||||
KGE_ASSERT(body);
|
||||
|
||||
|
|
@ -49,12 +48,14 @@ namespace kiwano
|
|||
|
||||
b2Body* b2body = body->GetB2Body();
|
||||
b2FixtureDef fd;
|
||||
fd.density = prop.density;
|
||||
fd.friction = prop.friction;
|
||||
fd.restitution = prop.restitution;
|
||||
fd.density = density;
|
||||
fd.friction = friction;
|
||||
fd.restitution = restitution;
|
||||
fd.shape = shape->GetB2Shape();
|
||||
fixture_ = b2body->CreateFixture(&fd);
|
||||
auto fixture = b2body->CreateFixture(&fd);
|
||||
return Fixture(fixture);
|
||||
}
|
||||
return Fixture();
|
||||
}
|
||||
|
||||
Shape Fixture::GetShape() const
|
||||
|
|
|
|||
|
|
@ -32,34 +32,16 @@ namespace kiwano
|
|||
class Fixture
|
||||
{
|
||||
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(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;
|
||||
Fixture GetNext() const;
|
||||
|
||||
bool IsValid() const { return !!fixture_; }
|
||||
|
||||
b2Fixture* GetB2Fixture() { return fixture_; }
|
||||
const b2Fixture* GetB2Fixture() const { return 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
|
||||
};
|
||||
|
||||
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(b2Joint* joint);
|
||||
Joint(World* world, b2JointDef* joint_def);
|
||||
|
|
@ -67,5 +76,32 @@ namespace kiwano
|
|||
World* world_;
|
||||
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 body = new Body(this, actor);
|
||||
BodyPtr body = Body::Create(this, actor);
|
||||
bodies_.push_back(body.get());
|
||||
return body;
|
||||
}
|
||||
|
|
@ -156,13 +156,25 @@ namespace kiwano
|
|||
{
|
||||
Stage::Update(dt);
|
||||
|
||||
world_.Step(dt.Seconds(), vel_iter_, pos_iter_);
|
||||
|
||||
b2Body* b2body = world_.GetBodyList();
|
||||
while (b2body)
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ namespace kiwano
|
|||
{
|
||||
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 Color Color::Transparent = Color(0.f, 0.f, 0.f, 0.f);
|
||||
|
||||
Color::Color()
|
||||
: r(0)
|
||||
, g(0)
|
||||
|
|
@ -72,4 +74,4 @@ namespace kiwano
|
|||
, a(alpha)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -112,6 +112,8 @@ namespace kiwano
|
|||
YellowGreen = 0x9ACD32
|
||||
};
|
||||
|
||||
static const Color Transparent;
|
||||
|
||||
public:
|
||||
float r;
|
||||
float g;
|
||||
|
|
|
|||
Loading…
Reference in New Issue