[deploy] Add box2d debug draw
This commit is contained in:
parent
c3018315d8
commit
7b6397b49c
|
|
@ -97,26 +97,26 @@ FixturePtr Fixture::CreateEdge(const Param& param, const Point& p1, const Point&
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
FixturePtr Fixture::CreateChain(const Param& param, const Vector<Point>& vertexs, bool loop)
|
FixturePtr Fixture::CreateChain(const Param& param, const Vector<Point>& vertices, bool loop)
|
||||||
{
|
{
|
||||||
FixturePtr ptr = new (std::nothrow) Fixture;
|
FixturePtr ptr = new (std::nothrow) Fixture;
|
||||||
if (ptr)
|
if (ptr)
|
||||||
{
|
{
|
||||||
Vector<b2Vec2> b2vertexs;
|
Vector<b2Vec2> b2vertices;
|
||||||
b2vertexs.reserve(vertexs.size());
|
b2vertices.reserve(vertices.size());
|
||||||
for (const auto& v : vertexs)
|
for (const auto& v : vertices)
|
||||||
{
|
{
|
||||||
b2vertexs.push_back(global::LocalToWorld(v));
|
b2vertices.push_back(global::LocalToWorld(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto shape = std::make_unique<b2ChainShape>();
|
auto shape = std::make_unique<b2ChainShape>();
|
||||||
if (loop)
|
if (loop)
|
||||||
{
|
{
|
||||||
shape->CreateLoop(&b2vertexs[0], static_cast<int32>(b2vertexs.size()));
|
shape->CreateLoop(&b2vertices[0], static_cast<int32>(b2vertices.size()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
shape->CreateChain(&b2vertexs[0], static_cast<int32>(b2vertexs.size()));
|
shape->CreateChain(&b2vertices[0], static_cast<int32>(b2vertices.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr->shape_ = std::move(shape);
|
ptr->shape_ = std::move(shape);
|
||||||
|
|
|
||||||
|
|
@ -93,7 +93,7 @@ public:
|
||||||
/// @param param 夹具参数
|
/// @param param 夹具参数
|
||||||
/// @param vertexs 链条顶点
|
/// @param vertexs 链条顶点
|
||||||
/// @param loop 是否连接链条的起点和终点
|
/// @param loop 是否连接链条的起点和终点
|
||||||
static FixturePtr CreateChain(const Param& param, const Vector<Point>& vertexs, bool loop = false);
|
static FixturePtr CreateChain(const Param& param, const Vector<Point>& vertices, bool loop = false);
|
||||||
|
|
||||||
Fixture();
|
Fixture();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ Joint::~Joint()
|
||||||
|
|
||||||
bool Joint::Init(PhysicWorld* world)
|
bool Joint::Init(PhysicWorld* world)
|
||||||
{
|
{
|
||||||
return false;
|
return joint_ != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Joint::Init(PhysicWorld* world, b2JointDef* joint_def)
|
bool Joint::Init(PhysicWorld* world, b2JointDef* joint_def)
|
||||||
|
|
@ -50,8 +50,6 @@ bool Joint::Init(PhysicWorld* world, b2JointDef* joint_def)
|
||||||
KGE_ASSERT(joint_ == nullptr);
|
KGE_ASSERT(joint_ == nullptr);
|
||||||
KGE_ASSERT(world);
|
KGE_ASSERT(world);
|
||||||
|
|
||||||
Destroy();
|
|
||||||
|
|
||||||
world_ = world;
|
world_ = world;
|
||||||
|
|
||||||
b2World* b2world = world_->GetB2World();
|
b2World* b2world = world_->GetB2World();
|
||||||
|
|
@ -131,8 +129,9 @@ bool DistanceJoint::Init(PhysicWorld* world)
|
||||||
b2DistanceJointDef def;
|
b2DistanceJointDef def;
|
||||||
def.Initialize(param_.body_a->GetB2Body(), param_.body_b->GetB2Body(), global::LocalToWorld(param_.anchor_a),
|
def.Initialize(param_.body_a->GetB2Body(), param_.body_b->GetB2Body(), global::LocalToWorld(param_.anchor_a),
|
||||||
global::LocalToWorld(param_.anchor_b));
|
global::LocalToWorld(param_.anchor_b));
|
||||||
def.frequencyHz = param_.frequency_hz;
|
def.frequencyHz = param_.frequency_hz;
|
||||||
def.dampingRatio = param_.damping_ratio;
|
def.dampingRatio = param_.damping_ratio;
|
||||||
|
def.collideConnected = param_.collide_connected;
|
||||||
|
|
||||||
Joint::Init(world, &def);
|
Joint::Init(world, &def);
|
||||||
raw_joint_ = static_cast<b2DistanceJoint*>(GetB2Joint());
|
raw_joint_ = static_cast<b2DistanceJoint*>(GetB2Joint());
|
||||||
|
|
@ -176,8 +175,9 @@ bool FrictionJoint::Init(PhysicWorld* world)
|
||||||
|
|
||||||
b2FrictionJointDef def;
|
b2FrictionJointDef def;
|
||||||
def.Initialize(param_.body_a->GetB2Body(), param_.body_b->GetB2Body(), global::LocalToWorld(param_.anchor));
|
def.Initialize(param_.body_a->GetB2Body(), param_.body_b->GetB2Body(), global::LocalToWorld(param_.anchor));
|
||||||
def.maxForce = param_.max_force;
|
def.maxForce = param_.max_force;
|
||||||
def.maxTorque = global::LocalToWorld(param_.max_torque);
|
def.maxTorque = global::LocalToWorld(param_.max_torque);
|
||||||
|
def.collideConnected = param_.collide_connected;
|
||||||
|
|
||||||
Joint::Init(world, &def);
|
Joint::Init(world, &def);
|
||||||
raw_joint_ = static_cast<b2FrictionJoint*>(GetB2Joint());
|
raw_joint_ = static_cast<b2FrictionJoint*>(GetB2Joint());
|
||||||
|
|
@ -232,9 +232,10 @@ bool GearJoint::Init(PhysicWorld* world)
|
||||||
KGE_ASSERT(param_.joint_a && param_.joint_b);
|
KGE_ASSERT(param_.joint_a && param_.joint_b);
|
||||||
|
|
||||||
b2GearJointDef def;
|
b2GearJointDef def;
|
||||||
def.joint1 = param_.joint_a->GetB2Joint();
|
def.joint1 = param_.joint_a->GetB2Joint();
|
||||||
def.joint2 = param_.joint_b->GetB2Joint();
|
def.joint2 = param_.joint_b->GetB2Joint();
|
||||||
def.ratio = param_.ratio;
|
def.ratio = param_.ratio;
|
||||||
|
def.collideConnected = param_.collide_connected;
|
||||||
|
|
||||||
Joint::Init(world, &def);
|
Joint::Init(world, &def);
|
||||||
raw_joint_ = static_cast<b2GearJoint*>(GetB2Joint());
|
raw_joint_ = static_cast<b2GearJoint*>(GetB2Joint());
|
||||||
|
|
@ -281,6 +282,7 @@ bool MotorJoint::Init(PhysicWorld* world)
|
||||||
def.maxForce = param_.max_force;
|
def.maxForce = param_.max_force;
|
||||||
def.maxTorque = global::LocalToWorld(param_.max_torque);
|
def.maxTorque = global::LocalToWorld(param_.max_torque);
|
||||||
def.correctionFactor = param_.correction_factor;
|
def.correctionFactor = param_.correction_factor;
|
||||||
|
def.collideConnected = param_.collide_connected;
|
||||||
|
|
||||||
Joint::Init(world, &def);
|
Joint::Init(world, &def);
|
||||||
raw_joint_ = static_cast<b2MotorJoint*>(GetB2Joint());
|
raw_joint_ = static_cast<b2MotorJoint*>(GetB2Joint());
|
||||||
|
|
@ -343,6 +345,7 @@ bool PrismaticJoint::Init(PhysicWorld* world)
|
||||||
def.enableMotor = param_.enable_motor;
|
def.enableMotor = param_.enable_motor;
|
||||||
def.maxMotorForce = param_.max_motor_force;
|
def.maxMotorForce = param_.max_motor_force;
|
||||||
def.motorSpeed = global::LocalToWorld(param_.motor_speed);
|
def.motorSpeed = global::LocalToWorld(param_.motor_speed);
|
||||||
|
def.collideConnected = param_.collide_connected;
|
||||||
|
|
||||||
Joint::Init(world, &def);
|
Joint::Init(world, &def);
|
||||||
raw_joint_ = static_cast<b2PrismaticJoint*>(GetB2Joint());
|
raw_joint_ = static_cast<b2PrismaticJoint*>(GetB2Joint());
|
||||||
|
|
@ -406,6 +409,7 @@ bool PulleyJoint::Init(PhysicWorld* world)
|
||||||
def.Initialize(param_.body_a->GetB2Body(), param_.body_b->GetB2Body(), global::LocalToWorld(param_.ground_anchor_a),
|
def.Initialize(param_.body_a->GetB2Body(), param_.body_b->GetB2Body(), global::LocalToWorld(param_.ground_anchor_a),
|
||||||
global::LocalToWorld(param_.ground_anchor_b), global::LocalToWorld(param_.anchor_a),
|
global::LocalToWorld(param_.ground_anchor_b), global::LocalToWorld(param_.anchor_a),
|
||||||
global::LocalToWorld(param_.anchor_b), param_.ratio);
|
global::LocalToWorld(param_.anchor_b), param_.ratio);
|
||||||
|
def.collideConnected = param_.collide_connected;
|
||||||
|
|
||||||
Joint::Init(world, &def);
|
Joint::Init(world, &def);
|
||||||
raw_joint_ = static_cast<b2PulleyJoint*>(GetB2Joint());
|
raw_joint_ = static_cast<b2PulleyJoint*>(GetB2Joint());
|
||||||
|
|
@ -479,12 +483,13 @@ bool RevoluteJoint::Init(PhysicWorld* world)
|
||||||
|
|
||||||
b2RevoluteJointDef def;
|
b2RevoluteJointDef def;
|
||||||
def.Initialize(param_.body_a->GetB2Body(), param_.body_b->GetB2Body(), global::LocalToWorld(param_.anchor));
|
def.Initialize(param_.body_a->GetB2Body(), param_.body_b->GetB2Body(), global::LocalToWorld(param_.anchor));
|
||||||
def.enableLimit = param_.enable_limit;
|
def.enableLimit = param_.enable_limit;
|
||||||
def.lowerAngle = math::Degree2Radian(param_.lower_angle);
|
def.lowerAngle = math::Degree2Radian(param_.lower_angle);
|
||||||
def.upperAngle = math::Degree2Radian(param_.upper_angle);
|
def.upperAngle = math::Degree2Radian(param_.upper_angle);
|
||||||
def.enableMotor = param_.enable_motor;
|
def.enableMotor = param_.enable_motor;
|
||||||
def.maxMotorTorque = global::LocalToWorld(param_.max_motor_torque);
|
def.maxMotorTorque = global::LocalToWorld(param_.max_motor_torque);
|
||||||
def.motorSpeed = math::Degree2Radian(param_.motor_speed);
|
def.motorSpeed = math::Degree2Radian(param_.motor_speed);
|
||||||
|
def.collideConnected = param_.collide_connected;
|
||||||
|
|
||||||
Joint::Init(world, &def);
|
Joint::Init(world, &def);
|
||||||
raw_joint_ = static_cast<b2RevoluteJoint*>(GetB2Joint());
|
raw_joint_ = static_cast<b2RevoluteJoint*>(GetB2Joint());
|
||||||
|
|
@ -557,11 +562,12 @@ bool RopeJoint::Init(PhysicWorld* world)
|
||||||
KGE_ASSERT(param_.body_a && param_.body_b);
|
KGE_ASSERT(param_.body_a && param_.body_b);
|
||||||
|
|
||||||
b2RopeJointDef def;
|
b2RopeJointDef def;
|
||||||
def.bodyA = param_.body_a->GetB2Body();
|
def.bodyA = param_.body_a->GetB2Body();
|
||||||
def.bodyB = param_.body_b->GetB2Body();
|
def.bodyB = param_.body_b->GetB2Body();
|
||||||
def.localAnchorA = global::LocalToWorld(param_.local_anchor_a);
|
def.localAnchorA = global::LocalToWorld(param_.local_anchor_a);
|
||||||
def.localAnchorB = global::LocalToWorld(param_.local_anchor_b);
|
def.localAnchorB = global::LocalToWorld(param_.local_anchor_b);
|
||||||
def.maxLength = global::LocalToWorld(param_.max_length);
|
def.maxLength = global::LocalToWorld(param_.max_length);
|
||||||
|
def.collideConnected = param_.collide_connected;
|
||||||
|
|
||||||
Joint::Init(world, &def);
|
Joint::Init(world, &def);
|
||||||
raw_joint_ = static_cast<b2RopeJoint*>(GetB2Joint());
|
raw_joint_ = static_cast<b2RopeJoint*>(GetB2Joint());
|
||||||
|
|
@ -605,8 +611,9 @@ bool WeldJoint::Init(PhysicWorld* world)
|
||||||
|
|
||||||
b2WeldJointDef def;
|
b2WeldJointDef def;
|
||||||
def.Initialize(param_.body_a->GetB2Body(), param_.body_b->GetB2Body(), global::LocalToWorld(param_.anchor));
|
def.Initialize(param_.body_a->GetB2Body(), param_.body_b->GetB2Body(), global::LocalToWorld(param_.anchor));
|
||||||
def.frequencyHz = param_.frequency_hz;
|
def.frequencyHz = param_.frequency_hz;
|
||||||
def.dampingRatio = param_.damping_ratio;
|
def.dampingRatio = param_.damping_ratio;
|
||||||
|
def.collideConnected = param_.collide_connected;
|
||||||
|
|
||||||
Joint::Init(world, &def);
|
Joint::Init(world, &def);
|
||||||
raw_joint_ = static_cast<b2WeldJoint*>(GetB2Joint());
|
raw_joint_ = static_cast<b2WeldJoint*>(GetB2Joint());
|
||||||
|
|
@ -639,11 +646,12 @@ bool WheelJoint::Init(PhysicWorld* world)
|
||||||
b2WheelJointDef def;
|
b2WheelJointDef def;
|
||||||
def.Initialize(param_.body_a->GetB2Body(), param_.body_b->GetB2Body(), global::LocalToWorld(param_.anchor),
|
def.Initialize(param_.body_a->GetB2Body(), param_.body_b->GetB2Body(), global::LocalToWorld(param_.anchor),
|
||||||
b2Vec2(param_.axis.x, param_.axis.y));
|
b2Vec2(param_.axis.x, param_.axis.y));
|
||||||
def.enableMotor = param_.enable_motor;
|
def.enableMotor = param_.enable_motor;
|
||||||
def.maxMotorTorque = global::LocalToWorld(param_.max_motor_torque);
|
def.maxMotorTorque = global::LocalToWorld(param_.max_motor_torque);
|
||||||
def.motorSpeed = global::LocalToWorld(param_.motor_speed);
|
def.motorSpeed = global::LocalToWorld(param_.motor_speed);
|
||||||
def.frequencyHz = param_.frequency_hz;
|
def.frequencyHz = param_.frequency_hz;
|
||||||
def.dampingRatio = param_.damping_ratio;
|
def.dampingRatio = param_.damping_ratio;
|
||||||
|
def.collideConnected = param_.collide_connected;
|
||||||
|
|
||||||
Joint::Init(world, &def);
|
Joint::Init(world, &def);
|
||||||
raw_joint_ = static_cast<b2WheelJoint*>(GetB2Joint());
|
raw_joint_ = static_cast<b2WheelJoint*>(GetB2Joint());
|
||||||
|
|
@ -698,12 +706,13 @@ bool MouseJoint::Init(PhysicWorld* world)
|
||||||
KGE_ASSERT(param_.body_a && param_.body_b);
|
KGE_ASSERT(param_.body_a && param_.body_b);
|
||||||
|
|
||||||
b2MouseJointDef def;
|
b2MouseJointDef def;
|
||||||
def.bodyA = param_.body_a->GetB2Body();
|
def.bodyA = param_.body_a->GetB2Body();
|
||||||
def.bodyB = param_.body_b->GetB2Body();
|
def.bodyB = param_.body_b->GetB2Body();
|
||||||
def.target = global::LocalToWorld(param_.target);
|
def.target = global::LocalToWorld(param_.target);
|
||||||
def.maxForce = param_.max_force;
|
def.maxForce = param_.max_force;
|
||||||
def.frequencyHz = param_.frequency_hz;
|
def.frequencyHz = param_.frequency_hz;
|
||||||
def.dampingRatio = param_.damping_ratio;
|
def.dampingRatio = param_.damping_ratio;
|
||||||
|
def.collideConnected = param_.collide_connected;
|
||||||
|
|
||||||
Joint::Init(world, &def);
|
Joint::Init(world, &def);
|
||||||
raw_joint_ = static_cast<b2MouseJoint*>(GetB2Joint());
|
raw_joint_ = static_cast<b2MouseJoint*>(GetB2Joint());
|
||||||
|
|
|
||||||
|
|
@ -70,18 +70,19 @@ public:
|
||||||
/// @brief 关节基础参数
|
/// @brief 关节基础参数
|
||||||
struct ParamBase
|
struct ParamBase
|
||||||
{
|
{
|
||||||
PhysicBody* body_a; ///< 关节连接的物体A
|
PhysicBody* body_a; ///< 关节连接的物体A
|
||||||
PhysicBody* body_b; ///< 关节连接的物体B
|
PhysicBody* body_b; ///< 关节连接的物体B
|
||||||
|
bool collide_connected; // 关节连接的物体是否允许碰撞
|
||||||
|
|
||||||
ParamBase(PhysicBody* body_a, PhysicBody* body_b)
|
ParamBase(PhysicBody* body_a, PhysicBody* body_b)
|
||||||
: body_a(body_a)
|
: body_a(body_a)
|
||||||
, body_b(body_b)
|
, body_b(body_b)
|
||||||
|
, collide_connected(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
ParamBase(PhysicBodyPtr body_a, PhysicBodyPtr body_b)
|
ParamBase(PhysicBodyPtr body_a, PhysicBodyPtr body_b)
|
||||||
: body_a(body_a.Get())
|
: ParamBase(body_a.Get(), body_b.Get())
|
||||||
, body_b(body_b.Get())
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -226,9 +226,9 @@ Fixture* PhysicBody::AddEdgeShape(const Point& p1, const Point& p2, float densit
|
||||||
return fixture.Get();
|
return fixture.Get();
|
||||||
}
|
}
|
||||||
|
|
||||||
Fixture* PhysicBody::AddChainShape(const Vector<Point>& vertexs, bool loop, float density, float friction)
|
Fixture* PhysicBody::AddChainShape(const Vector<Point>& vertices, bool loop, float density, float friction)
|
||||||
{
|
{
|
||||||
FixturePtr fixture = Fixture::CreateChain(Fixture::Param(density, friction), vertexs, loop);
|
FixturePtr fixture = Fixture::CreateChain(Fixture::Param(density, friction), vertices, loop);
|
||||||
AddFixture(fixture);
|
AddFixture(fixture);
|
||||||
return fixture.Get();
|
return fixture.Get();
|
||||||
}
|
}
|
||||||
|
|
@ -356,12 +356,24 @@ Point PhysicBody::GetLocalPoint(const Point& world) const
|
||||||
return global::WorldToLocal(body_->GetLocalPoint(global::LocalToWorld(world)));
|
return global::WorldToLocal(body_->GetLocalPoint(global::LocalToWorld(world)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vec2 PhysicBody::GetLocalVector(const Vec2& world) const
|
||||||
|
{
|
||||||
|
KGE_ASSERT(body_);
|
||||||
|
return global::WorldToLocal(body_->GetLocalVector(global::LocalToWorld(world)));
|
||||||
|
}
|
||||||
|
|
||||||
Point PhysicBody::GetWorldPoint(const Point& local) const
|
Point PhysicBody::GetWorldPoint(const Point& local) const
|
||||||
{
|
{
|
||||||
KGE_ASSERT(body_);
|
KGE_ASSERT(body_);
|
||||||
return global::WorldToLocal(body_->GetWorldPoint(global::LocalToWorld(local)));
|
return global::WorldToLocal(body_->GetWorldPoint(global::LocalToWorld(local)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vec2 PhysicBody::GetWorldVector(const Vec2& local) const
|
||||||
|
{
|
||||||
|
KGE_ASSERT(body_);
|
||||||
|
return global::WorldToLocal(body_->GetWorldVector(global::LocalToWorld(local)));
|
||||||
|
}
|
||||||
|
|
||||||
Point PhysicBody::GetLocalCenter() const
|
Point PhysicBody::GetLocalCenter() const
|
||||||
{
|
{
|
||||||
KGE_ASSERT(body_);
|
KGE_ASSERT(body_);
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,7 @@ public:
|
||||||
/// @param vertexs 链条端点
|
/// @param vertexs 链条端点
|
||||||
/// @param loop 是否闭合
|
/// @param loop 是否闭合
|
||||||
/// @param density 物体密度
|
/// @param density 物体密度
|
||||||
Fixture* AddChainShape(const Vector<Point>& vertexs, bool loop, float density, float friction = 0.2f);
|
Fixture* AddChainShape(const Vector<Point>& vertices, bool loop, float density, float friction = 0.2f);
|
||||||
|
|
||||||
/// \~chinese
|
/// \~chinese
|
||||||
/// @brief 移除夹具
|
/// @brief 移除夹具
|
||||||
|
|
@ -203,10 +203,18 @@ public:
|
||||||
/// @brief 获取世界坐标系上的点在物体上的位置
|
/// @brief 获取世界坐标系上的点在物体上的位置
|
||||||
Point GetLocalPoint(const Point& world) const;
|
Point GetLocalPoint(const Point& world) const;
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 将世界坐标系中的向量转换到物体坐标系下
|
||||||
|
Vec2 GetLocalVector(const Vec2& world) const;
|
||||||
|
|
||||||
/// \~chinese
|
/// \~chinese
|
||||||
/// @brief 获取物体上的点在世界坐标系的位置
|
/// @brief 获取物体上的点在世界坐标系的位置
|
||||||
Point GetWorldPoint(const Point& local) const;
|
Point GetWorldPoint(const Point& local) const;
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 将物体坐标系中的向量转换到世界坐标系下
|
||||||
|
Vec2 GetWorldVector(const Vec2& local) const;
|
||||||
|
|
||||||
/// \~chinese
|
/// \~chinese
|
||||||
/// @brief 获取物体质心相对于物体的位置
|
/// @brief 获取物体质心相对于物体的位置
|
||||||
Point GetLocalCenter() const;
|
Point GetLocalCenter() const;
|
||||||
|
|
@ -231,6 +239,22 @@ public:
|
||||||
/// @brief 设置物体受重力的比例
|
/// @brief 设置物体受重力的比例
|
||||||
void SetGravityScale(float scale);
|
void SetGravityScale(float scale);
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 获取线性阻尼
|
||||||
|
float GetLinearDamping() const;
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 设置线性阻尼
|
||||||
|
void SetLinearDamping(float damping);
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 获取旋转阻尼
|
||||||
|
float GetAngularDamping() const;
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 设置旋转阻尼
|
||||||
|
void SetAngularDamping(float damping);
|
||||||
|
|
||||||
/// \~chinese
|
/// \~chinese
|
||||||
/// @brief 施力
|
/// @brief 施力
|
||||||
/// @param force 力的大小和方向
|
/// @param force 力的大小和方向
|
||||||
|
|
@ -443,6 +467,30 @@ inline void PhysicBody::SetGravityScale(float scale)
|
||||||
body_->SetGravityScale(scale);
|
body_->SetGravityScale(scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline float PhysicBody::GetLinearDamping() const
|
||||||
|
{
|
||||||
|
KGE_ASSERT(body_);
|
||||||
|
return body_->GetLinearDamping();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void PhysicBody::SetLinearDamping(float damping)
|
||||||
|
{
|
||||||
|
KGE_ASSERT(body_);
|
||||||
|
body_->SetLinearDamping(damping);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float PhysicBody::GetAngularDamping() const
|
||||||
|
{
|
||||||
|
KGE_ASSERT(body_);
|
||||||
|
return body_->GetAngularDamping();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void PhysicBody::SetAngularDamping(float damping)
|
||||||
|
{
|
||||||
|
KGE_ASSERT(body_);
|
||||||
|
body_->SetAngularDamping(damping);
|
||||||
|
}
|
||||||
|
|
||||||
inline bool PhysicBody::IsIgnoreRotation() const
|
inline bool PhysicBody::IsIgnoreRotation() const
|
||||||
{
|
{
|
||||||
KGE_ASSERT(body_);
|
KGE_ASSERT(body_);
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,124 @@ namespace kiwano
|
||||||
namespace physics
|
namespace physics
|
||||||
{
|
{
|
||||||
|
|
||||||
|
class PhysicWorld::DebugDrawer : public b2Draw
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DebugDrawer(const Size& size)
|
||||||
|
{
|
||||||
|
canvas_ = Canvas::Create(size);
|
||||||
|
|
||||||
|
fill_brush_ = Brush::Create(Color::White);
|
||||||
|
line_brush_ = Brush::Create(Color::White);
|
||||||
|
|
||||||
|
canvas_->SetFillBrush(fill_brush_);
|
||||||
|
canvas_->SetStrokeBrush(line_brush_);
|
||||||
|
|
||||||
|
b2Draw::SetFlags(b2Draw::e_shapeBit | b2Draw::e_jointBit | b2Draw::e_jointBit | b2Draw::e_centerOfMassBit);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BeginDraw()
|
||||||
|
{
|
||||||
|
canvas_->BeginDraw();
|
||||||
|
canvas_->Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EndDraw()
|
||||||
|
{
|
||||||
|
canvas_->EndDraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Render(RenderContext& ctx)
|
||||||
|
{
|
||||||
|
canvas_->OnRender(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetFillColor(const b2Color& color)
|
||||||
|
{
|
||||||
|
fill_brush_->SetColor(reinterpret_cast<const Color&>(color));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetLineColor(const b2Color& color)
|
||||||
|
{
|
||||||
|
line_brush_->SetColor(reinterpret_cast<const Color&>(color));
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color) override
|
||||||
|
{
|
||||||
|
SetLineColor(color);
|
||||||
|
|
||||||
|
b2Vec2 p1 = vertices[vertexCount - 1];
|
||||||
|
for (int32 i = 0; i < vertexCount; ++i)
|
||||||
|
{
|
||||||
|
b2Vec2 p2 = vertices[i];
|
||||||
|
canvas_->DrawLine(global::WorldToLocal(p1), global::WorldToLocal(p2));
|
||||||
|
p1 = p2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawSolidPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color) override
|
||||||
|
{
|
||||||
|
ShapeMaker maker;
|
||||||
|
maker.BeginPath(global::WorldToLocal(vertices[0]));
|
||||||
|
for (int32 i = 1; i < vertexCount; ++i)
|
||||||
|
{
|
||||||
|
maker.AddLine(global::WorldToLocal(vertices[i]));
|
||||||
|
}
|
||||||
|
maker.EndPath(true);
|
||||||
|
|
||||||
|
SetFillColor(color);
|
||||||
|
canvas_->FillShape(maker.GetShape());
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawCircle(const b2Vec2& center, float32 radius, const b2Color& color) override
|
||||||
|
{
|
||||||
|
SetLineColor(color);
|
||||||
|
canvas_->DrawCircle(global::WorldToLocal(center), global::WorldToLocal(radius));
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawSolidCircle(const b2Vec2& center, float32 radius, const b2Vec2& axis, const b2Color& color) override
|
||||||
|
{
|
||||||
|
SetFillColor(color);
|
||||||
|
canvas_->FillCircle(global::WorldToLocal(center), global::WorldToLocal(radius));
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawSegment(const b2Vec2& p1, const b2Vec2& p2, const b2Color& color) override
|
||||||
|
{
|
||||||
|
SetLineColor(color);
|
||||||
|
canvas_->DrawLine(global::WorldToLocal(p1), global::WorldToLocal(p2));
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawTransform(const b2Transform& xf) override
|
||||||
|
{
|
||||||
|
const float k_axisScale = 0.4f;
|
||||||
|
|
||||||
|
b2Color red(1.0f, 0.0f, 0.0f);
|
||||||
|
b2Color green(0.0f, 1.0f, 0.0f);
|
||||||
|
b2Vec2 p1 = xf.p, p2;
|
||||||
|
|
||||||
|
p2 = p1 + k_axisScale * xf.q.GetXAxis();
|
||||||
|
|
||||||
|
SetLineColor(red);
|
||||||
|
canvas_->DrawLine(global::WorldToLocal(p1), global::WorldToLocal(p2));
|
||||||
|
|
||||||
|
p2 = p1 + k_axisScale * xf.q.GetYAxis();
|
||||||
|
|
||||||
|
SetLineColor(green);
|
||||||
|
canvas_->DrawLine(global::WorldToLocal(p1), global::WorldToLocal(p2));
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawPoint(const b2Vec2& p, float32 size, const b2Color& color) override
|
||||||
|
{
|
||||||
|
SetFillColor(color);
|
||||||
|
canvas_->FillCircle(global::WorldToLocal(p), global::WorldToLocal(size));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
CanvasPtr canvas_;
|
||||||
|
BrushPtr fill_brush_;
|
||||||
|
BrushPtr line_brush_;
|
||||||
|
};
|
||||||
|
|
||||||
class DestructionListener : public b2DestructionListener
|
class DestructionListener : public b2DestructionListener
|
||||||
{
|
{
|
||||||
Function<void(b2Joint*)> joint_destruction_callback_;
|
Function<void(b2Joint*)> joint_destruction_callback_;
|
||||||
|
|
@ -254,6 +372,18 @@ void PhysicWorld::OnUpdate(Duration dt)
|
||||||
AfterSimulation(world_actor, Matrix3x2(), 0.0f);
|
AfterSimulation(world_actor, Matrix3x2(), 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PhysicWorld::OnRender(RenderContext& ctx)
|
||||||
|
{
|
||||||
|
if (drawer_)
|
||||||
|
{
|
||||||
|
drawer_->BeginDraw();
|
||||||
|
world_.DrawDebugData();
|
||||||
|
drawer_->EndDraw();
|
||||||
|
|
||||||
|
drawer_->Render(ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PhysicWorld::DispatchEvent(Event* evt)
|
void PhysicWorld::DispatchEvent(Event* evt)
|
||||||
{
|
{
|
||||||
Actor* actor = GetBoundActor();
|
Actor* actor = GetBoundActor();
|
||||||
|
|
@ -309,5 +439,23 @@ void PhysicWorld::AfterSimulation(Actor* parent, const Matrix3x2& parent_to_worl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PhysicWorld::ShowDebugInfo(bool show)
|
||||||
|
{
|
||||||
|
if (show)
|
||||||
|
{
|
||||||
|
if (!drawer_)
|
||||||
|
{
|
||||||
|
Size size = Renderer::GetInstance().GetOutputSize();
|
||||||
|
drawer_ = std::unique_ptr<DebugDrawer>(new DebugDrawer(size));
|
||||||
|
|
||||||
|
world_.SetDebugDraw(drawer_.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
drawer_.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace physics
|
} // namespace physics
|
||||||
} // namespace kiwano
|
} // namespace kiwano
|
||||||
|
|
|
||||||
|
|
@ -112,6 +112,10 @@ public:
|
||||||
/// @brief 设置位置迭代次数, 默认为 2
|
/// @brief 设置位置迭代次数, 默认为 2
|
||||||
void SetPositionIterations(int pos_iter);
|
void SetPositionIterations(int pos_iter);
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 设置是否绘制调试信息
|
||||||
|
void ShowDebugInfo(bool show);
|
||||||
|
|
||||||
/// \~chinese
|
/// \~chinese
|
||||||
/// @brief 获取b2World
|
/// @brief 获取b2World
|
||||||
b2World* GetB2World();
|
b2World* GetB2World();
|
||||||
|
|
@ -129,6 +133,10 @@ protected:
|
||||||
/// @brief 更新组件
|
/// @brief 更新组件
|
||||||
void OnUpdate(Duration dt) override;
|
void OnUpdate(Duration dt) override;
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 渲染组件
|
||||||
|
void OnRender(RenderContext& ctx) override;
|
||||||
|
|
||||||
/// \~chinese
|
/// \~chinese
|
||||||
/// @brief 分发物理世界事件
|
/// @brief 分发物理世界事件
|
||||||
void DispatchEvent(Event* evt);
|
void DispatchEvent(Event* evt);
|
||||||
|
|
@ -146,9 +154,13 @@ protected:
|
||||||
void AfterSimulation(Actor* parent, const Matrix3x2& parent_to_world, float parent_rotation);
|
void AfterSimulation(Actor* parent, const Matrix3x2& parent_to_world, float parent_rotation);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
b2World world_;
|
bool debug_;
|
||||||
int vel_iter_;
|
int vel_iter_;
|
||||||
int pos_iter_;
|
int pos_iter_;
|
||||||
|
b2World world_;
|
||||||
|
|
||||||
|
class DebugDrawer;
|
||||||
|
std::unique_ptr<DebugDrawer> drawer_;
|
||||||
|
|
||||||
List<PhysicBodyPtr> bodies_;
|
List<PhysicBodyPtr> bodies_;
|
||||||
List<JointPtr> joints_;
|
List<JointPtr> joints_;
|
||||||
|
|
|
||||||
|
|
@ -112,6 +112,7 @@ void Actor::Render(RenderContext& ctx)
|
||||||
if (CheckVisibility(ctx))
|
if (CheckVisibility(ctx))
|
||||||
{
|
{
|
||||||
PrepareToRender(ctx);
|
PrepareToRender(ctx);
|
||||||
|
RenderComponents(ctx);
|
||||||
OnRender(ctx);
|
OnRender(ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -131,6 +132,7 @@ void Actor::Render(RenderContext& ctx)
|
||||||
if (CheckVisibility(ctx))
|
if (CheckVisibility(ctx))
|
||||||
{
|
{
|
||||||
PrepareToRender(ctx);
|
PrepareToRender(ctx);
|
||||||
|
RenderComponents(ctx);
|
||||||
OnRender(ctx);
|
OnRender(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -299,6 +301,23 @@ void Actor::UpdateComponents(Duration dt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Actor::RenderComponents(RenderContext& ctx)
|
||||||
|
{
|
||||||
|
if (!components_.IsEmpty())
|
||||||
|
{
|
||||||
|
ComponentPtr next;
|
||||||
|
for (auto component = components_.GetFirst(); component; component = next)
|
||||||
|
{
|
||||||
|
next = component->GetNext();
|
||||||
|
|
||||||
|
if (component->IsEnable())
|
||||||
|
{
|
||||||
|
component->OnRender(ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const Matrix3x2& Actor::GetTransformMatrix() const
|
const Matrix3x2& Actor::GetTransformMatrix() const
|
||||||
{
|
{
|
||||||
UpdateTransform();
|
UpdateTransform();
|
||||||
|
|
|
||||||
|
|
@ -495,6 +495,10 @@ protected:
|
||||||
/// @brief 更新组件
|
/// @brief 更新组件
|
||||||
void UpdateComponents(Duration dt);
|
void UpdateComponents(Duration dt);
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 渲染组件
|
||||||
|
void RenderComponents(RenderContext& ctx);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool visible_;
|
bool visible_;
|
||||||
bool update_pausing_;
|
bool update_pausing_;
|
||||||
|
|
|
||||||
|
|
@ -32,8 +32,6 @@ CanvasPtr Canvas::Create(const Size& size)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ptr->stroke_brush_ = Brush::Create(Color::White);
|
|
||||||
ptr->fill_brush_ = Brush::Create(Color::White);
|
|
||||||
ptr->ResizeAndClear(size);
|
ptr->ResizeAndClear(size);
|
||||||
}
|
}
|
||||||
catch (std::exception)
|
catch (std::exception)
|
||||||
|
|
@ -64,7 +62,6 @@ void Canvas::OnRender(RenderContext& ctx)
|
||||||
{
|
{
|
||||||
if (texture_cached_)
|
if (texture_cached_)
|
||||||
{
|
{
|
||||||
PrepareToRender(ctx);
|
|
||||||
ctx.DrawTexture(*texture_cached_, nullptr, &GetBounds());
|
ctx.DrawTexture(*texture_cached_, nullptr, &GetBounds());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@
|
||||||
#include <kiwano/core/Time.h>
|
#include <kiwano/core/Time.h>
|
||||||
#include <kiwano/core/ObjectBase.h>
|
#include <kiwano/core/ObjectBase.h>
|
||||||
#include <kiwano/core/IntrusiveList.h>
|
#include <kiwano/core/IntrusiveList.h>
|
||||||
|
#include <kiwano/render/RenderContext.h>
|
||||||
|
|
||||||
namespace kiwano
|
namespace kiwano
|
||||||
{
|
{
|
||||||
|
|
@ -80,6 +81,10 @@ protected:
|
||||||
/// @brief 更新组件
|
/// @brief 更新组件
|
||||||
virtual void OnUpdate(Duration dt);
|
virtual void OnUpdate(Duration dt);
|
||||||
|
|
||||||
|
/// \~chinese
|
||||||
|
/// @brief 渲染组件
|
||||||
|
virtual void OnRender(RenderContext& ctx);
|
||||||
|
|
||||||
/// \~chinese
|
/// \~chinese
|
||||||
/// @brief 处理角色事件
|
/// @brief 处理角色事件
|
||||||
virtual void HandleEvent(Event* evt);
|
virtual void HandleEvent(Event* evt);
|
||||||
|
|
@ -109,9 +114,14 @@ inline void Component::OnUpdate(Duration dt)
|
||||||
KGE_NOT_USED(dt);
|
KGE_NOT_USED(dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Component::HandleEvent(Event* event)
|
inline void Component::OnRender(RenderContext& ctx)
|
||||||
{
|
{
|
||||||
KGE_NOT_USED(event);
|
KGE_NOT_USED(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Component::HandleEvent(Event* evt)
|
||||||
|
{
|
||||||
|
KGE_NOT_USED(evt);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace kiwano
|
} // namespace kiwano
|
||||||
|
|
|
||||||
|
|
@ -110,8 +110,6 @@ void GifSprite::OnRender(RenderContext& ctx)
|
||||||
{
|
{
|
||||||
if (frame_to_render_ && CheckVisibility(ctx))
|
if (frame_to_render_ && CheckVisibility(ctx))
|
||||||
{
|
{
|
||||||
PrepareToRender(ctx);
|
|
||||||
|
|
||||||
ctx.DrawTexture(*frame_to_render_, nullptr, &GetBounds());
|
ctx.DrawTexture(*frame_to_render_, nullptr, &GetBounds());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue