diff --git a/src/kiwano-physics/Body.cpp b/src/kiwano-physics/Body.cpp index 2d4f4f89..18feed30 100644 --- a/src/kiwano-physics/Body.cpp +++ b/src/kiwano-physics/Body.cpp @@ -69,40 +69,35 @@ namespace kiwano UpdateFromActor(); } - PhysicFixture PhysicBody::AddShape(PhysicShape* shape, float density, float friction, float restitution) + PhysicFixture PhysicBody::AddFixture(PhysicShape* shape, const PhysicFixture::Param& param) { KGE_ASSERT(body_ && world_); - - if (shape) - { - return PhysicFixture::Create(this, shape, density, friction, restitution); - } - return PhysicFixture(); + return PhysicFixture(this, shape, param); } PhysicFixture PhysicBody::AddCircleShape(float radius, float density) { - return AddShape(&PhysicCircleShape(radius), density); + return AddFixture(&PhysicCircleShape(radius), PhysicFixture::Param(density)); } PhysicFixture PhysicBody::AddBoxShape(Vec2 const& size, float density) { - return AddShape(&PhysicBoxShape(size), density); + return AddFixture(&PhysicBoxShape(size), PhysicFixture::Param(density)); } PhysicFixture PhysicBody::AddPolygonShape(Vector const& vertexs, float density) { - return AddShape(&PhysicPolygonShape(vertexs), density); + return AddFixture(&PhysicPolygonShape(vertexs), PhysicFixture::Param(density)); } PhysicFixture PhysicBody::AddEdgeShape(Point const& p1, Point const& p2, float density) { - return AddShape(&PhysicEdgeShape(p1, p2), density); + return AddFixture(&PhysicEdgeShape(p1, p2), PhysicFixture::Param(density)); } PhysicFixture PhysicBody::AddChainShape(Vector const& vertexs, bool loop, float density) { - return AddShape(&PhysicChainShape(vertexs, loop), density); + return AddFixture(&PhysicChainShape(vertexs, loop), PhysicFixture::Param(density)); } void PhysicBody::RemoveFixture(PhysicFixture const& fixture) @@ -165,7 +160,7 @@ namespace kiwano } } - void PhysicBody::GetMassData(float* mass, Point* center, float* inertia) + void PhysicBody::GetMassData(float* mass, Point* center, float* inertia) const { KGE_ASSERT(body_ && world_); diff --git a/src/kiwano-physics/Body.h b/src/kiwano-physics/Body.h index 2b64e8b1..3b71e4da 100644 --- a/src/kiwano-physics/Body.h +++ b/src/kiwano-physics/Body.h @@ -52,8 +52,10 @@ namespace kiwano // 初始化 void Init(PhysicWorld* world, Actor* actor); + // 添加夹具 + PhysicFixture AddFixture(PhysicShape* shape, const PhysicFixture::Param& param); + // 添加形状 - PhysicFixture AddShape(PhysicShape* shape, float density = 0.f, float friction = 0.2f, float restitution = 0.f); PhysicFixture AddCircleShape(float radius, float density = 0.f); PhysicFixture AddBoxShape(Vec2 const& size, float density = 0.f); PhysicFixture AddPolygonShape(Vector const& vertexs, float density = 0.f); @@ -99,7 +101,7 @@ namespace kiwano float GetInertia() const { KGE_ASSERT(body_); return body_->GetInertia(); } // 质量数据 - void GetMassData(float* mass, Point* center, float* inertia); + void GetMassData(float* mass, Point* center, float* inertia) const; void SetMassData(float mass, Point const& center, float inertia); void ResetMassData(); diff --git a/src/kiwano-physics/ContactListener.h b/src/kiwano-physics/ContactListener.h index 4b67398d..55572af6 100644 --- a/src/kiwano-physics/ContactListener.h +++ b/src/kiwano-physics/ContactListener.h @@ -66,8 +66,8 @@ namespace kiwano friend class PhysicContactDispatcher; public: - using ContactBeginCallback = Function; - using ContactEndCallback = Function; + using ContactBeginCallback = Function; + using ContactEndCallback = Function; PhysicContactCallbackListener(); virtual ~PhysicContactCallbackListener(); diff --git a/src/kiwano-physics/Fixture.cpp b/src/kiwano-physics/Fixture.cpp index 864d6caa..35f264e6 100644 --- a/src/kiwano-physics/Fixture.cpp +++ b/src/kiwano-physics/Fixture.cpp @@ -38,7 +38,8 @@ namespace kiwano SetB2Fixture(fixture); } - PhysicFixture PhysicFixture::Create(PhysicBody* body, PhysicShape* shape, float density, float friction, float restitution) + PhysicFixture::PhysicFixture(PhysicBody* body, PhysicShape* shape, const Param& param) + : PhysicFixture() { KGE_ASSERT(body); @@ -48,14 +49,13 @@ namespace kiwano b2Body* b2body = body->GetB2Body(); b2FixtureDef fd; - fd.density = density; - fd.friction = friction; - fd.restitution = restitution; + fd.density = param.density; + fd.friction = param.friction; + fd.restitution = param.restitution; fd.shape = shape->GetB2Shape(); auto fixture = b2body->CreateFixture(&fd); - return PhysicFixture(fixture); + SetB2Fixture(fixture); } - return PhysicFixture(); } PhysicBody* PhysicFixture::GetBody() @@ -82,5 +82,36 @@ namespace kiwano return PhysicFixture(fixture_->GetNext()); } + void PhysicFixture::GetMassData(float* mass, Point* center, float* inertia) const + { + KGE_ASSERT(fixture_); + + const PhysicBody* body = GetBody(); + KGE_ASSERT(body); + + const PhysicWorld* world = body->GetWorld(); + KGE_ASSERT(world); + + b2MassData data; + fixture_->GetMassData(&data); + + if (mass) *mass = data.mass; + if (center) *center = world->World2Stage(data.center); + if (inertia) *inertia = data.I; + } + + bool PhysicFixture::TestPoint(const Point& p) const + { + KGE_ASSERT(fixture_); + + const PhysicBody* body = GetBody(); + KGE_ASSERT(body); + + const PhysicWorld* world = body->GetWorld(); + KGE_ASSERT(world); + + return fixture_->TestPoint(world->Stage2World(p)); + } + } } diff --git a/src/kiwano-physics/Fixture.h b/src/kiwano-physics/Fixture.h index 0d498045..85cb3895 100644 --- a/src/kiwano-physics/Fixture.h +++ b/src/kiwano-physics/Fixture.h @@ -32,10 +32,26 @@ namespace kiwano class PhysicFixture { public: + struct Param + { + float density = 0.f; + float friction = 0.2f; + float restitution = 0.f; + bool is_sensor = false; + + Param() {} + + Param(float density, float friction = 0.2f, float restitution = 0.f, bool is_sensor = false) + : density(density) + , friction(friction) + , restitution(restitution) + , is_sensor(is_sensor) + {} + }; + PhysicFixture(); PhysicFixture(b2Fixture* fixture); - - static PhysicFixture Create(PhysicBody* body, PhysicShape* shape, float density = 0.f, float friction = 0.2f, float restitution = 0.f); + PhysicFixture(PhysicBody* body, PhysicShape* shape, const Param& param); // 物体 PhysicBody* GetBody(); @@ -47,6 +63,28 @@ namespace kiwano // 下一夹具 (同一物体上) PhysicFixture GetNext() const; + // 接触传感器 + bool IsSensor() const { KGE_ASSERT(fixture_); return fixture_->IsSensor(); } + void SetSensor(bool sensor) { KGE_ASSERT(fixture_); fixture_->SetSensor(sensor); } + + // 质量数据 + void GetMassData(float* mass, Point* center, float* inertia) const; + + // 密度 + float GetDensity() const { KGE_ASSERT(fixture_); return fixture_->GetDensity(); } + void SetDensity(float density) { KGE_ASSERT(fixture_); fixture_->SetDensity(density); } + + // 摩擦力 + float GetFriction() const { KGE_ASSERT(fixture_); return fixture_->GetFriction(); } + void SetFriction(float friction) { KGE_ASSERT(fixture_); fixture_->SetFriction(friction); } + + // 弹性恢复 + float GetRestitution() const { KGE_ASSERT(fixture_); return fixture_->GetRestitution(); } + void SetRestitution(float restitution) { KGE_ASSERT(fixture_); fixture_->SetRestitution(restitution); } + + // 点测试 + bool TestPoint(const Point& p) const; + bool IsValid() const { return !!fixture_; } b2Fixture* GetB2Fixture() { return fixture_; }