Add physics::Joints
This commit is contained in:
parent
ae5d985238
commit
0484446bc1
|
|
@ -112,6 +112,12 @@ namespace kiwano
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Point Body::GetPosition() const
|
||||||
|
{
|
||||||
|
KGE_ASSERT(body_ && world_);
|
||||||
|
return world_->World2Stage(body_->GetPosition());
|
||||||
|
}
|
||||||
|
|
||||||
Point Body::GetLocalPoint(Point const& world) const
|
Point Body::GetLocalPoint(Point const& world) const
|
||||||
{
|
{
|
||||||
KGE_ASSERT(body_ && world_);
|
KGE_ASSERT(body_ && world_);
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,12 @@ namespace kiwano
|
||||||
// »ñÈ¡ÖÊÁ¿
|
// »ñÈ¡ÖÊÁ¿
|
||||||
float GetMass() const { KGE_ASSERT(body_); return body_->GetMass(); }
|
float GetMass() const { KGE_ASSERT(body_); return body_->GetMass(); }
|
||||||
|
|
||||||
|
// »ñÈ¡Ðýת½Ç¶È
|
||||||
|
float GetRotation() const { KGE_ASSERT(body_); return math::Radian2Angle(body_->GetAngle()); }
|
||||||
|
|
||||||
|
// »ñȡλÖÃ
|
||||||
|
Point GetPosition() const;
|
||||||
|
|
||||||
Point GetLocalPoint(Point const& world) const;
|
Point GetLocalPoint(Point const& world) const;
|
||||||
Point GetWorldPoint(Point const& local) const;
|
Point GetWorldPoint(Point const& local) const;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,8 @@ namespace kiwano
|
||||||
world_ = world;
|
world_ = world;
|
||||||
if (world_)
|
if (world_)
|
||||||
{
|
{
|
||||||
|
world_->AddJoint(this);
|
||||||
|
|
||||||
b2Joint* joint = world_->GetB2World()->CreateJoint(joint_def);
|
b2Joint* joint = world_->GetB2World()->CreateJoint(joint_def);
|
||||||
SetB2Joint(joint);
|
SetB2Joint(joint);
|
||||||
}
|
}
|
||||||
|
|
@ -92,11 +94,13 @@ namespace kiwano
|
||||||
|
|
||||||
DistanceJoint::DistanceJoint()
|
DistanceJoint::DistanceJoint()
|
||||||
: Joint()
|
: Joint()
|
||||||
|
, raw_joint_(nullptr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
DistanceJoint::DistanceJoint(World* world, b2DistanceJointDef* def)
|
DistanceJoint::DistanceJoint(World* world, b2DistanceJointDef* def)
|
||||||
: Joint(world, def)
|
: Joint(world, def)
|
||||||
|
, raw_joint_(nullptr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -105,14 +109,279 @@ namespace kiwano
|
||||||
KGE_ASSERT(param.body_a && param.body_b);
|
KGE_ASSERT(param.body_a && param.body_b);
|
||||||
|
|
||||||
b2DistanceJointDef def;
|
b2DistanceJointDef def;
|
||||||
def.bodyA = param.body_a->GetB2Body();
|
def.Initialize(param.body_a->GetB2Body(), param.body_b->GetB2Body(), world->Stage2World(param.local_anchor_a), world->Stage2World(param.local_anchor_b));
|
||||||
def.bodyB = param.body_b->GetB2Body();
|
def.frequencyHz = param.frequency_hz;
|
||||||
def.localAnchorA = world->Stage2World(param.local_anchor_a);
|
def.dampingRatio = param.damping_ratio;
|
||||||
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);
|
DistanceJointPtr joint = new DistanceJoint(world, &def);
|
||||||
|
joint->raw_joint_ = static_cast<b2DistanceJoint*>(joint->GetB2Joint());
|
||||||
return joint;
|
return joint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DistanceJoint::SetLength(float length)
|
||||||
|
{
|
||||||
|
KGE_ASSERT(raw_joint_ && world_);
|
||||||
|
raw_joint_->SetLength(world_->Stage2World(length));
|
||||||
|
}
|
||||||
|
|
||||||
|
float DistanceJoint::GetLength() const
|
||||||
|
{
|
||||||
|
KGE_ASSERT(raw_joint_ && world_);
|
||||||
|
return world_->World2Stage(raw_joint_->GetLength());
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// FrictionJoint
|
||||||
|
//
|
||||||
|
|
||||||
|
FrictionJoint::FrictionJoint()
|
||||||
|
: Joint()
|
||||||
|
, raw_joint_(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
FrictionJoint::FrictionJoint(World* world, b2FrictionJointDef* def)
|
||||||
|
: Joint(world, def)
|
||||||
|
, raw_joint_(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
FrictionJointPtr FrictionJoint::Create(World* world, Param const& param)
|
||||||
|
{
|
||||||
|
KGE_ASSERT(param.body_a && param.body_b);
|
||||||
|
|
||||||
|
b2FrictionJointDef def;
|
||||||
|
def.Initialize(param.body_a->GetB2Body(), param.body_b->GetB2Body(), world->Stage2World(param.anchor));
|
||||||
|
def.maxForce = param.max_force;
|
||||||
|
def.maxTorque = world->Stage2World(param.max_torque);
|
||||||
|
|
||||||
|
FrictionJointPtr joint = new FrictionJoint(world, &def);
|
||||||
|
joint->raw_joint_ = static_cast<b2FrictionJoint*>(joint->GetB2Joint());
|
||||||
|
return joint;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FrictionJoint::SetMaxForce(float length)
|
||||||
|
{
|
||||||
|
KGE_ASSERT(raw_joint_);
|
||||||
|
raw_joint_->SetMaxForce(length);
|
||||||
|
}
|
||||||
|
|
||||||
|
float FrictionJoint::GetMaxForce() const
|
||||||
|
{
|
||||||
|
KGE_ASSERT(raw_joint_);
|
||||||
|
return raw_joint_->GetMaxForce();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FrictionJoint::SetMaxTorque(float length)
|
||||||
|
{
|
||||||
|
KGE_ASSERT(raw_joint_ && world_);
|
||||||
|
raw_joint_->SetMaxTorque(world_->Stage2World(length));
|
||||||
|
}
|
||||||
|
|
||||||
|
float FrictionJoint::GetMaxTorque() const
|
||||||
|
{
|
||||||
|
KGE_ASSERT(raw_joint_ && world_);
|
||||||
|
return world_->World2Stage(raw_joint_->GetMaxTorque());
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// GearJoint
|
||||||
|
//
|
||||||
|
|
||||||
|
GearJoint::GearJoint()
|
||||||
|
: Joint()
|
||||||
|
, raw_joint_(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
GearJoint::GearJoint(World* world, b2GearJointDef* def)
|
||||||
|
: Joint(world, def)
|
||||||
|
, raw_joint_(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
GearJointPtr GearJoint::Create(World* world, Param const& param)
|
||||||
|
{
|
||||||
|
KGE_ASSERT(param.joint_a && param.joint_b);
|
||||||
|
|
||||||
|
b2GearJointDef def;
|
||||||
|
def.joint1 = param.joint_a->GetB2Joint();
|
||||||
|
def.joint2 = param.joint_b->GetB2Joint();
|
||||||
|
def.ratio = param.ratio;
|
||||||
|
|
||||||
|
GearJointPtr joint = new GearJoint(world, &def);
|
||||||
|
joint->raw_joint_ = static_cast<b2GearJoint*>(joint->GetB2Joint());
|
||||||
|
return joint;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GearJoint::SetRatio(float ratio)
|
||||||
|
{
|
||||||
|
KGE_ASSERT(raw_joint_);
|
||||||
|
raw_joint_->SetRatio(ratio);
|
||||||
|
}
|
||||||
|
|
||||||
|
float GearJoint::GetRatio() const
|
||||||
|
{
|
||||||
|
KGE_ASSERT(raw_joint_);
|
||||||
|
return raw_joint_->GetRatio();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// MotorJoint
|
||||||
|
//
|
||||||
|
|
||||||
|
MotorJoint::MotorJoint()
|
||||||
|
: Joint()
|
||||||
|
, raw_joint_(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
MotorJoint::MotorJoint(World* world, b2MotorJointDef* def)
|
||||||
|
: Joint(world, def)
|
||||||
|
, raw_joint_(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
MotorJointPtr MotorJoint::Create(World* world, Param const& param)
|
||||||
|
{
|
||||||
|
KGE_ASSERT(param.body_a && param.body_b);
|
||||||
|
|
||||||
|
b2MotorJointDef def;
|
||||||
|
def.Initialize(param.body_a->GetB2Body(), param.body_b->GetB2Body());
|
||||||
|
def.maxForce = param.max_force;
|
||||||
|
def.maxTorque = world->Stage2World(param.max_torque);
|
||||||
|
|
||||||
|
MotorJointPtr joint = new MotorJoint(world, &def);
|
||||||
|
joint->raw_joint_ = static_cast<b2MotorJoint*>(joint->GetB2Joint());
|
||||||
|
return joint;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MotorJoint::SetMaxForce(float length)
|
||||||
|
{
|
||||||
|
KGE_ASSERT(raw_joint_);
|
||||||
|
raw_joint_->SetMaxForce(length);
|
||||||
|
}
|
||||||
|
|
||||||
|
float MotorJoint::GetMaxForce() const
|
||||||
|
{
|
||||||
|
KGE_ASSERT(raw_joint_);
|
||||||
|
return raw_joint_->GetMaxForce();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MotorJoint::SetMaxTorque(float length)
|
||||||
|
{
|
||||||
|
KGE_ASSERT(raw_joint_ && world_);
|
||||||
|
raw_joint_->SetMaxTorque(world_->Stage2World(length));
|
||||||
|
}
|
||||||
|
|
||||||
|
float MotorJoint::GetMaxTorque() const
|
||||||
|
{
|
||||||
|
KGE_ASSERT(raw_joint_ && world_);
|
||||||
|
return world_->World2Stage(raw_joint_->GetMaxTorque());
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// WheelJoint
|
||||||
|
//
|
||||||
|
|
||||||
|
WheelJoint::WheelJoint()
|
||||||
|
: Joint()
|
||||||
|
, raw_joint_(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
WheelJoint::WheelJoint(World* world, b2WheelJointDef* def)
|
||||||
|
: Joint(world, def)
|
||||||
|
, raw_joint_(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
WheelJointPtr WheelJoint::Create(World* world, Param const& param)
|
||||||
|
{
|
||||||
|
KGE_ASSERT(param.body_a && param.body_b);
|
||||||
|
|
||||||
|
b2WheelJointDef def;
|
||||||
|
def.Initialize(param.body_a->GetB2Body(), param.body_b->GetB2Body(), world->Stage2World(param.anchor), world->Stage2World(param.axis));
|
||||||
|
def.enableMotor = param.enable_motor;
|
||||||
|
def.maxMotorTorque = world->Stage2World(param.max_motor_torque);
|
||||||
|
def.motorSpeed = world->Stage2World(param.motor_speed);
|
||||||
|
def.frequencyHz = param.frequency_hz;
|
||||||
|
def.dampingRatio = param.damping_ratio;
|
||||||
|
|
||||||
|
WheelJointPtr joint = new WheelJoint(world, &def);
|
||||||
|
joint->raw_joint_ = static_cast<b2WheelJoint*>(joint->GetB2Joint());
|
||||||
|
return joint;
|
||||||
|
}
|
||||||
|
|
||||||
|
float WheelJoint::GetJointTranslation() const
|
||||||
|
{
|
||||||
|
KGE_ASSERT(raw_joint_ && world_);
|
||||||
|
return world_->World2Stage(raw_joint_->GetJointTranslation());
|
||||||
|
}
|
||||||
|
|
||||||
|
float WheelJoint::GetJointLinearSpeed() const
|
||||||
|
{
|
||||||
|
KGE_ASSERT(raw_joint_ && world_);
|
||||||
|
return world_->World2Stage(raw_joint_->GetJointLinearSpeed());
|
||||||
|
}
|
||||||
|
|
||||||
|
void WheelJoint::SetMaxMotorTorque(float torque)
|
||||||
|
{
|
||||||
|
KGE_ASSERT(raw_joint_ && world_);
|
||||||
|
raw_joint_->SetMaxMotorTorque(world_->Stage2World(torque));
|
||||||
|
}
|
||||||
|
|
||||||
|
float WheelJoint::GetMaxMotorTorque() const
|
||||||
|
{
|
||||||
|
KGE_ASSERT(raw_joint_ && world_);
|
||||||
|
return world_->World2Stage(raw_joint_->GetMaxMotorTorque());
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// MouseJoint
|
||||||
|
//
|
||||||
|
|
||||||
|
MouseJoint::MouseJoint()
|
||||||
|
: Joint()
|
||||||
|
, raw_joint_(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseJoint::MouseJoint(World* world, b2MouseJointDef* def)
|
||||||
|
: Joint(world, def)
|
||||||
|
, raw_joint_(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseJointPtr MouseJoint::Create(World* world, Param const& param)
|
||||||
|
{
|
||||||
|
KGE_ASSERT(param.body_a && param.body_b);
|
||||||
|
KGE_ASSERT(param.body_a->GetWorld() && param.body_a->GetWorld() == param.body_b->GetWorld());
|
||||||
|
|
||||||
|
b2MouseJointDef def;
|
||||||
|
def.bodyA = param.body_a->GetB2Body();
|
||||||
|
def.bodyB = param.body_b->GetB2Body();
|
||||||
|
def.target = param.body_a->GetWorld()->Stage2World(param.target);
|
||||||
|
def.maxForce = param.max_force;
|
||||||
|
def.frequencyHz = param.frequency_hz;
|
||||||
|
def.dampingRatio = param.damping_ratio;
|
||||||
|
|
||||||
|
MouseJointPtr joint = new MouseJoint(world, &def);
|
||||||
|
joint->raw_joint_ = static_cast<b2MouseJoint*>(joint->GetB2Joint());
|
||||||
|
return joint;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MouseJoint::SetMaxForce(float length)
|
||||||
|
{
|
||||||
|
KGE_ASSERT(raw_joint_);
|
||||||
|
raw_joint_->SetMaxForce(length);
|
||||||
|
}
|
||||||
|
|
||||||
|
float MouseJoint::GetMaxForce() const
|
||||||
|
{
|
||||||
|
KGE_ASSERT(raw_joint_);
|
||||||
|
return raw_joint_->GetMaxForce();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,14 @@ namespace kiwano
|
||||||
namespace physics
|
namespace physics
|
||||||
{
|
{
|
||||||
KGE_DECLARE_SMART_PTR(Joint);
|
KGE_DECLARE_SMART_PTR(Joint);
|
||||||
|
KGE_DECLARE_SMART_PTR(DistanceJoint);
|
||||||
|
KGE_DECLARE_SMART_PTR(FrictionJoint);
|
||||||
|
KGE_DECLARE_SMART_PTR(GearJoint);
|
||||||
|
KGE_DECLARE_SMART_PTR(MotorJoint);
|
||||||
|
KGE_DECLARE_SMART_PTR(WheelJoint);
|
||||||
|
KGE_DECLARE_SMART_PTR(MouseJoint);
|
||||||
|
|
||||||
|
// 关节
|
||||||
class KGE_API Joint
|
class KGE_API Joint
|
||||||
: public ObjectBase
|
: public ObjectBase
|
||||||
{
|
{
|
||||||
|
|
@ -77,7 +85,8 @@ namespace kiwano
|
||||||
Type type_;
|
Type type_;
|
||||||
};
|
};
|
||||||
|
|
||||||
KGE_DECLARE_SMART_PTR(DistanceJoint);
|
|
||||||
|
// 固定距离关节
|
||||||
class KGE_API DistanceJoint
|
class KGE_API DistanceJoint
|
||||||
: public Joint
|
: public Joint
|
||||||
{
|
{
|
||||||
|
|
@ -86,15 +95,33 @@ namespace kiwano
|
||||||
{
|
{
|
||||||
Point local_anchor_a;
|
Point local_anchor_a;
|
||||||
Point local_anchor_b;
|
Point local_anchor_b;
|
||||||
|
float frequency_hz;
|
||||||
|
float damping_ratio;
|
||||||
|
|
||||||
Param(Body* body_a, Body* body_b, Point const& local_anchor_a, Point const& local_anchor_b)
|
Param(
|
||||||
|
Body* body_a,
|
||||||
|
Body* body_b,
|
||||||
|
Point const& local_anchor_a,
|
||||||
|
Point const& local_anchor_b,
|
||||||
|
float frequency_hz = 0.f,
|
||||||
|
float damping_ratio = 0.f
|
||||||
|
)
|
||||||
: ParamBase(body_a, body_b)
|
: ParamBase(body_a, body_b)
|
||||||
, local_anchor_a(local_anchor_a)
|
, local_anchor_a(local_anchor_a)
|
||||||
, local_anchor_b(local_anchor_b)
|
, local_anchor_b(local_anchor_b)
|
||||||
|
, frequency_hz(frequency_hz)
|
||||||
|
, damping_ratio(damping_ratio)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Param(BodyPtr body_a, BodyPtr body_b, Point const& local_anchor_a, Point const& local_anchor_b)
|
Param(
|
||||||
: Param(body_a.get(), body_b.get(), local_anchor_a, local_anchor_b)
|
BodyPtr body_a,
|
||||||
|
BodyPtr body_b,
|
||||||
|
Point const& local_anchor_a,
|
||||||
|
Point const& local_anchor_b,
|
||||||
|
float frequency_hz = 0.f,
|
||||||
|
float damping_ratio = 0.f
|
||||||
|
)
|
||||||
|
: Param(body_a.get(), body_b.get(), local_anchor_a, local_anchor_b, frequency_hz, damping_ratio)
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -102,6 +129,316 @@ namespace kiwano
|
||||||
DistanceJoint(World* world, b2DistanceJointDef* def);
|
DistanceJoint(World* world, b2DistanceJointDef* def);
|
||||||
|
|
||||||
static DistanceJointPtr Create(World* world, Param const& param);
|
static DistanceJointPtr Create(World* world, Param const& param);
|
||||||
|
|
||||||
|
void SetLength(float length);
|
||||||
|
float GetLength() const;
|
||||||
|
|
||||||
|
// 设置弹簧阻尼器频率 [赫兹]
|
||||||
|
void SetFrequency(float hz) { KGE_ASSERT(raw_joint_); raw_joint_->SetFrequency(hz); }
|
||||||
|
float GetFrequency() const { KGE_ASSERT(raw_joint_); return raw_joint_->GetFrequency(); }
|
||||||
|
|
||||||
|
// 设置阻尼比
|
||||||
|
void SetDampingRatio(float ratio) { KGE_ASSERT(raw_joint_); raw_joint_->SetDampingRatio(ratio); }
|
||||||
|
float GetDampingRatio() const { KGE_ASSERT(raw_joint_); return raw_joint_->GetDampingRatio(); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
b2DistanceJoint* raw_joint_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// 摩擦关节
|
||||||
|
class KGE_API FrictionJoint
|
||||||
|
: public Joint
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
struct Param : public Joint::ParamBase
|
||||||
|
{
|
||||||
|
Point anchor;
|
||||||
|
float max_force;
|
||||||
|
float max_torque;
|
||||||
|
|
||||||
|
Param(
|
||||||
|
Body* body_a,
|
||||||
|
Body* body_b,
|
||||||
|
Point const& anchor,
|
||||||
|
float max_force = 0.f,
|
||||||
|
float max_torque = 0.f
|
||||||
|
)
|
||||||
|
: ParamBase(body_a, body_b)
|
||||||
|
, anchor(anchor)
|
||||||
|
, max_force(max_force)
|
||||||
|
, max_torque(max_torque)
|
||||||
|
{}
|
||||||
|
|
||||||
|
Param(
|
||||||
|
BodyPtr body_a,
|
||||||
|
BodyPtr body_b,
|
||||||
|
Point const& anchor,
|
||||||
|
float max_force = 0.f,
|
||||||
|
float max_torque = 0.f
|
||||||
|
)
|
||||||
|
: Param(body_a.get(), body_b.get(), anchor, max_force, max_torque)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
FrictionJoint();
|
||||||
|
FrictionJoint(World* world, b2FrictionJointDef* def);
|
||||||
|
|
||||||
|
static FrictionJointPtr Create(World* world, Param const& param);
|
||||||
|
|
||||||
|
// 设定最大摩擦力
|
||||||
|
void SetMaxForce(float force);
|
||||||
|
float GetMaxForce() const;
|
||||||
|
|
||||||
|
// 设定最大转矩
|
||||||
|
void SetMaxTorque(float torque);
|
||||||
|
float GetMaxTorque() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
b2FrictionJoint* raw_joint_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// 齿轮关节
|
||||||
|
class KGE_API GearJoint
|
||||||
|
: public Joint
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
struct Param : public Joint::ParamBase
|
||||||
|
{
|
||||||
|
JointPtr joint_a;
|
||||||
|
JointPtr joint_b;
|
||||||
|
float ratio;
|
||||||
|
|
||||||
|
Param(
|
||||||
|
Joint* joint_a,
|
||||||
|
Joint* joint_b,
|
||||||
|
float ratio = 1.f
|
||||||
|
)
|
||||||
|
: ParamBase(nullptr, nullptr)
|
||||||
|
, joint_a(joint_a)
|
||||||
|
, joint_b(joint_b)
|
||||||
|
, ratio(ratio)
|
||||||
|
{}
|
||||||
|
|
||||||
|
Param(
|
||||||
|
JointPtr joint_a,
|
||||||
|
JointPtr joint_b,
|
||||||
|
float ratio = 1.f
|
||||||
|
)
|
||||||
|
: Param(joint_a.get(), joint_b.get(), ratio)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
GearJoint();
|
||||||
|
GearJoint(World* world, b2GearJointDef* def);
|
||||||
|
|
||||||
|
static GearJointPtr Create(World* world, Param const& param);
|
||||||
|
|
||||||
|
// 设定齿轮传动比
|
||||||
|
void SetRatio(float ratio);
|
||||||
|
float GetRatio() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
b2GearJoint* raw_joint_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// 马达关节
|
||||||
|
class KGE_API MotorJoint
|
||||||
|
: public Joint
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
struct Param : public Joint::ParamBase
|
||||||
|
{
|
||||||
|
float max_force;
|
||||||
|
float max_torque;
|
||||||
|
float correction_factor;
|
||||||
|
|
||||||
|
Param(
|
||||||
|
Body* body_a,
|
||||||
|
Body* body_b,
|
||||||
|
float max_force = 1.f,
|
||||||
|
float max_torque = 100.f,
|
||||||
|
float correction_factor = 0.3f
|
||||||
|
)
|
||||||
|
: ParamBase(body_a, body_b)
|
||||||
|
, max_force(max_force)
|
||||||
|
, max_torque(max_torque)
|
||||||
|
, correction_factor(correction_factor)
|
||||||
|
{}
|
||||||
|
|
||||||
|
Param(
|
||||||
|
BodyPtr body_a,
|
||||||
|
BodyPtr body_b,
|
||||||
|
float max_force = 0.f,
|
||||||
|
float max_torque = 0.f,
|
||||||
|
float correction_factor = 0.3f
|
||||||
|
)
|
||||||
|
: Param(body_a.get(), body_b.get(), max_force, max_torque, correction_factor)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
MotorJoint();
|
||||||
|
MotorJoint(World* world, b2MotorJointDef* def);
|
||||||
|
|
||||||
|
static MotorJointPtr Create(World* world, Param const& param);
|
||||||
|
|
||||||
|
// 设定最大摩擦力
|
||||||
|
void SetMaxForce(float force);
|
||||||
|
float GetMaxForce() const;
|
||||||
|
|
||||||
|
// 设定最大转矩
|
||||||
|
void SetMaxTorque(float torque);
|
||||||
|
float GetMaxTorque() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
b2MotorJoint* raw_joint_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// 轮关节
|
||||||
|
class KGE_API WheelJoint
|
||||||
|
: public Joint
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
struct Param : public Joint::ParamBase
|
||||||
|
{
|
||||||
|
Point anchor;
|
||||||
|
Vec2 axis;
|
||||||
|
bool enable_motor;
|
||||||
|
float max_motor_torque;
|
||||||
|
float motor_speed;
|
||||||
|
float frequency_hz;
|
||||||
|
float damping_ratio;
|
||||||
|
|
||||||
|
Param(
|
||||||
|
Body* body_a,
|
||||||
|
Body* body_b,
|
||||||
|
Point const& anchor,
|
||||||
|
Vec2 const& axis,
|
||||||
|
float frequency_hz = 2.0f,
|
||||||
|
float damping_ratio = 0.7f,
|
||||||
|
bool enable_motor = false,
|
||||||
|
float max_motor_torque = 0.0f,
|
||||||
|
float motor_speed = 0.0f
|
||||||
|
)
|
||||||
|
: ParamBase(body_a, body_b)
|
||||||
|
, anchor(anchor)
|
||||||
|
, axis(axis)
|
||||||
|
, enable_motor(enable_motor)
|
||||||
|
, max_motor_torque(max_motor_torque)
|
||||||
|
, motor_speed(motor_speed)
|
||||||
|
, frequency_hz(frequency_hz)
|
||||||
|
, damping_ratio(damping_ratio)
|
||||||
|
{}
|
||||||
|
|
||||||
|
Param(
|
||||||
|
BodyPtr body_a,
|
||||||
|
BodyPtr body_b,
|
||||||
|
Point const& anchor,
|
||||||
|
Vec2 const& axis,
|
||||||
|
float frequency_hz = 2.0f,
|
||||||
|
float damping_ratio = 0.7f,
|
||||||
|
bool enable_motor = false,
|
||||||
|
float max_motor_torque = 0.0f,
|
||||||
|
float motor_speed = 0.0f
|
||||||
|
)
|
||||||
|
: Param(body_a.get(), body_b.get(), anchor, axis, frequency_hz, damping_ratio, enable_motor, max_motor_torque, motor_speed)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
WheelJoint();
|
||||||
|
WheelJoint(World* world, b2WheelJointDef* def);
|
||||||
|
|
||||||
|
static WheelJointPtr Create(World* world, Param const& param);
|
||||||
|
|
||||||
|
float GetJointTranslation() const;
|
||||||
|
float GetJointLinearSpeed() const;
|
||||||
|
float GetJointAngle() const { KGE_ASSERT(raw_joint_); return math::Radian2Angle(raw_joint_->GetJointAngle()); }
|
||||||
|
float GetJointAngularSpeed() const { KGE_ASSERT(raw_joint_); return math::Radian2Angle(raw_joint_->GetJointAngularSpeed()); }
|
||||||
|
|
||||||
|
bool IsMotorEnabled() const { KGE_ASSERT(raw_joint_); return raw_joint_->IsMotorEnabled(); }
|
||||||
|
void EnableMotor(bool flag) { KGE_ASSERT(raw_joint_); raw_joint_->EnableMotor(flag); }
|
||||||
|
|
||||||
|
// 设置马达转速 [度/秒]
|
||||||
|
void SetMotorSpeed(float speed) { KGE_ASSERT(raw_joint_); raw_joint_->SetMotorSpeed(math::Angle2Radian(speed)); }
|
||||||
|
float GetMotorSpeed() const { KGE_ASSERT(raw_joint_); return math::Radian2Angle(raw_joint_->GetMotorSpeed()); }
|
||||||
|
|
||||||
|
// 设定最大马达转矩
|
||||||
|
void SetMaxMotorTorque(float torque);
|
||||||
|
float GetMaxMotorTorque() const;
|
||||||
|
|
||||||
|
void SetSpringFrequencyHz(float hz) { KGE_ASSERT(raw_joint_); raw_joint_->SetSpringFrequencyHz(hz); }
|
||||||
|
float GetSpringFrequencyHz() const { KGE_ASSERT(raw_joint_); return raw_joint_->GetSpringFrequencyHz(); }
|
||||||
|
|
||||||
|
void SetSpringDampingRatio(float ratio) { KGE_ASSERT(raw_joint_); raw_joint_->SetSpringDampingRatio(ratio); }
|
||||||
|
float GetSpringDampingRatio() const { KGE_ASSERT(raw_joint_); return raw_joint_->GetSpringDampingRatio(); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
b2WheelJoint* raw_joint_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// 鼠标关节
|
||||||
|
// 用于使身体的某个点追踪世界上的指定点,例如让物体追踪鼠标位置
|
||||||
|
class KGE_API MouseJoint
|
||||||
|
: public Joint
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
struct Param : public Joint::ParamBase
|
||||||
|
{
|
||||||
|
Point target;
|
||||||
|
float max_force;
|
||||||
|
float frequency_hz;
|
||||||
|
float damping_ratio;
|
||||||
|
|
||||||
|
Param(
|
||||||
|
Body* body_a,
|
||||||
|
Body* body_b,
|
||||||
|
Point const& target,
|
||||||
|
float max_force,
|
||||||
|
float frequency_hz = 5.0f,
|
||||||
|
float damping_ratio = 0.7f
|
||||||
|
)
|
||||||
|
: ParamBase(body_a, body_b)
|
||||||
|
, target(target)
|
||||||
|
, max_force(max_force)
|
||||||
|
, frequency_hz(frequency_hz)
|
||||||
|
, damping_ratio(damping_ratio)
|
||||||
|
{}
|
||||||
|
|
||||||
|
Param(
|
||||||
|
BodyPtr body_a,
|
||||||
|
BodyPtr body_b,
|
||||||
|
Point const& target,
|
||||||
|
float max_force,
|
||||||
|
float frequency_hz = 5.0f,
|
||||||
|
float damping_ratio = 0.7f
|
||||||
|
)
|
||||||
|
: Param(body_a.get(), body_b.get(), target, max_force, frequency_hz, damping_ratio)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
MouseJoint();
|
||||||
|
MouseJoint(World* world, b2MouseJointDef* def);
|
||||||
|
|
||||||
|
static MouseJointPtr Create(World* world, Param const& param);
|
||||||
|
|
||||||
|
// 设定最大摩擦力
|
||||||
|
void SetMaxForce(float force);
|
||||||
|
float GetMaxForce() const;
|
||||||
|
|
||||||
|
// 设置响应速度 [赫兹]
|
||||||
|
void SetFrequency(float hz) { KGE_ASSERT(raw_joint_); raw_joint_->SetFrequency(hz); }
|
||||||
|
float GetFrequency() const { KGE_ASSERT(raw_joint_); return raw_joint_->GetFrequency(); }
|
||||||
|
|
||||||
|
// 设置阻尼比
|
||||||
|
void SetDampingRatio(float ratio) { KGE_ASSERT(raw_joint_); raw_joint_->SetDampingRatio(ratio); }
|
||||||
|
float GetDampingRatio() const { KGE_ASSERT(raw_joint_); return raw_joint_->GetDampingRatio(); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
b2MouseJoint* raw_joint_;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,24 +24,56 @@ namespace kiwano
|
||||||
{
|
{
|
||||||
namespace physics
|
namespace physics
|
||||||
{
|
{
|
||||||
World::World()
|
namespace
|
||||||
: world_(b2Vec2(0, 10))
|
|
||||||
, vel_iter_(6)
|
|
||||||
, pos_iter_(2)
|
|
||||||
, global_scale_(100.f)
|
|
||||||
{
|
{
|
||||||
|
const float DefaultGlobalScale = 100.f; // 100 pixels per meters
|
||||||
}
|
}
|
||||||
|
|
||||||
World::World(Vec2 gravity)
|
class World::DestructionListener : public b2DestructionListener
|
||||||
: world_(b2Vec2(gravity.x, gravity.y))
|
{
|
||||||
|
World* world_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
DestructionListener(World* world)
|
||||||
|
: world_(world)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SayGoodbye(b2Joint* joint) override
|
||||||
|
{
|
||||||
|
if (world_)
|
||||||
|
{
|
||||||
|
world_->JointRemoved(joint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SayGoodbye(b2Fixture* fixture) override
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
World::World()
|
||||||
|
: world_(b2Vec2(0, 10.0f))
|
||||||
, vel_iter_(6)
|
, vel_iter_(6)
|
||||||
, pos_iter_(2)
|
, pos_iter_(2)
|
||||||
, global_scale_(100.f)
|
, global_scale_(DefaultGlobalScale)
|
||||||
|
, destruction_listener_(nullptr)
|
||||||
|
, removing_joint_(false)
|
||||||
{
|
{
|
||||||
|
destruction_listener_ = new DestructionListener(this);
|
||||||
|
world_.SetDestructionListener(destruction_listener_);
|
||||||
}
|
}
|
||||||
|
|
||||||
World::~World()
|
World::~World()
|
||||||
{
|
{
|
||||||
|
world_.SetDestructionListener(nullptr);
|
||||||
|
if (destruction_listener_)
|
||||||
|
{
|
||||||
|
delete destruction_listener_;
|
||||||
|
destruction_listener_ = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
// Make sure b2World was destroyed after b2Body
|
// Make sure b2World was destroyed after b2Body
|
||||||
RemoveAllChildren();
|
RemoveAllChildren();
|
||||||
RemoveAllBodies();
|
RemoveAllBodies();
|
||||||
|
|
@ -56,27 +88,13 @@ namespace kiwano
|
||||||
BodyPtr World::CreateBody(Actor* actor)
|
BodyPtr World::CreateBody(Actor* actor)
|
||||||
{
|
{
|
||||||
BodyPtr body = Body::Create(this, actor);
|
BodyPtr body = Body::Create(this, actor);
|
||||||
bodies_.push_back(body.get());
|
|
||||||
return body;
|
return body;
|
||||||
}
|
}
|
||||||
|
|
||||||
JointPtr World::CreateJoint(b2JointDef* joint_def)
|
|
||||||
{
|
|
||||||
JointPtr joint = new Joint(this, joint_def);
|
|
||||||
joints_.push_back(joint.get());
|
|
||||||
return joint;
|
|
||||||
}
|
|
||||||
|
|
||||||
void World::RemoveBody(Body* body)
|
void World::RemoveBody(Body* body)
|
||||||
{
|
{
|
||||||
if (body)
|
if (body)
|
||||||
{
|
{
|
||||||
auto iter = std::find(bodies_.begin(), bodies_.end(), body);
|
|
||||||
if (iter != bodies_.end())
|
|
||||||
{
|
|
||||||
bodies_.erase(iter);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (body->GetB2Body())
|
if (body->GetB2Body())
|
||||||
{
|
{
|
||||||
world_.DestroyBody(body->GetB2Body());
|
world_.DestroyBody(body->GetB2Body());
|
||||||
|
|
@ -96,7 +114,14 @@ namespace kiwano
|
||||||
body = next;
|
body = next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bodies_.clear();
|
}
|
||||||
|
|
||||||
|
void World::AddJoint(Joint* joint)
|
||||||
|
{
|
||||||
|
if (joint)
|
||||||
|
{
|
||||||
|
joints_.push_back(joint);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::RemoveJoint(Joint* joint)
|
void World::RemoveJoint(Joint* joint)
|
||||||
|
|
@ -107,11 +132,13 @@ namespace kiwano
|
||||||
if (iter != joints_.end())
|
if (iter != joints_.end())
|
||||||
{
|
{
|
||||||
joints_.erase(iter);
|
joints_.erase(iter);
|
||||||
}
|
|
||||||
|
|
||||||
if (joint->GetB2Joint())
|
if (joint->GetB2Joint())
|
||||||
{
|
{
|
||||||
world_.DestroyJoint(joint->GetB2Joint());
|
removing_joint_ = true;
|
||||||
|
world_.DestroyJoint(joint->GetB2Joint());
|
||||||
|
removing_joint_ = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -120,17 +147,38 @@ namespace kiwano
|
||||||
{
|
{
|
||||||
if (world_.GetJointCount())
|
if (world_.GetJointCount())
|
||||||
{
|
{
|
||||||
b2Joint* joint = world_.GetJointList();
|
removing_joint_ = true;
|
||||||
while (joint)
|
|
||||||
{
|
{
|
||||||
b2Joint* next = joint->GetNext();
|
b2Joint* joint = world_.GetJointList();
|
||||||
world_.DestroyJoint(joint);
|
while (joint)
|
||||||
joint = next;
|
{
|
||||||
|
b2Joint* next = joint->GetNext();
|
||||||
|
world_.DestroyJoint(joint);
|
||||||
|
joint = next;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
removing_joint_ = false;
|
||||||
}
|
}
|
||||||
joints_.clear();
|
joints_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void World::JointRemoved(b2Joint* joint)
|
||||||
|
{
|
||||||
|
if (!removing_joint_ && joint)
|
||||||
|
{
|
||||||
|
auto iter = std::find_if(
|
||||||
|
joints_.begin(),
|
||||||
|
joints_.end(),
|
||||||
|
[joint](Joint* j) -> bool { return j->GetB2Joint() == joint; }
|
||||||
|
);
|
||||||
|
|
||||||
|
if (iter != joints_.end())
|
||||||
|
{
|
||||||
|
joints_.erase(iter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
b2World* World::GetB2World()
|
b2World* World::GetB2World()
|
||||||
{
|
{
|
||||||
return &world_;
|
return &world_;
|
||||||
|
|
|
||||||
|
|
@ -36,17 +36,12 @@ namespace kiwano
|
||||||
public:
|
public:
|
||||||
World();
|
World();
|
||||||
|
|
||||||
World(Vec2 gravity);
|
|
||||||
|
|
||||||
virtual ~World();
|
virtual ~World();
|
||||||
|
|
||||||
// 创建刚体
|
// 创建刚体
|
||||||
BodyPtr CreateBody(ActorPtr actor);
|
BodyPtr CreateBody(ActorPtr actor);
|
||||||
BodyPtr CreateBody(Actor* actor);
|
BodyPtr CreateBody(Actor* actor);
|
||||||
|
|
||||||
// 创建关节
|
|
||||||
JointPtr CreateJoint(b2JointDef* joint_def);
|
|
||||||
|
|
||||||
// 获取重力
|
// 获取重力
|
||||||
Vec2 GetGravity() const;
|
Vec2 GetGravity() const;
|
||||||
|
|
||||||
|
|
@ -67,10 +62,10 @@ namespace kiwano
|
||||||
inline float Stage2World(float value) { return value / GetGlobalScale(); }
|
inline float Stage2World(float value) { return value / GetGlobalScale(); }
|
||||||
inline b2Vec2 Stage2World(const Point& pos) { return b2Vec2(Stage2World(pos.x), Stage2World(pos.y)); }
|
inline b2Vec2 Stage2World(const Point& pos) { return b2Vec2(Stage2World(pos.x), Stage2World(pos.y)); }
|
||||||
|
|
||||||
// 设置速度迭代次数
|
// 设置速度迭代次数, 默认为 6
|
||||||
inline void SetVelocityIterations(int vel_iter) { vel_iter_ = vel_iter; }
|
inline void SetVelocityIterations(int vel_iter) { vel_iter_ = vel_iter; }
|
||||||
|
|
||||||
// 设置位置迭代次数
|
// 设置位置迭代次数, 默认为 2
|
||||||
inline void SetPositionIterations(int pos_iter) { pos_iter_ = pos_iter; }
|
inline void SetPositionIterations(int pos_iter) { pos_iter_ = pos_iter; }
|
||||||
|
|
||||||
// 获取 Box2D 世界
|
// 获取 Box2D 世界
|
||||||
|
|
@ -86,21 +81,32 @@ namespace kiwano
|
||||||
// 移除所有刚体
|
// 移除所有刚体
|
||||||
void RemoveAllBodies();
|
void RemoveAllBodies();
|
||||||
|
|
||||||
|
// 添加关节
|
||||||
|
void AddJoint(Joint* joint);
|
||||||
|
|
||||||
// 移除关节
|
// 移除关节
|
||||||
void RemoveJoint(Joint* joint);
|
void RemoveJoint(Joint* joint);
|
||||||
|
|
||||||
// 移除所有关节
|
// 移除所有关节
|
||||||
void RemoveAllJoints();
|
void RemoveAllJoints();
|
||||||
|
|
||||||
|
// 关节被移除
|
||||||
|
void JointRemoved(b2Joint* joint);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void Update(Duration dt) override;
|
void Update(Duration dt) override;
|
||||||
|
|
||||||
|
class DestructionListener;
|
||||||
|
friend DestructionListener;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
b2World world_;
|
b2World world_;
|
||||||
int vel_iter_;
|
int vel_iter_;
|
||||||
int pos_iter_;
|
int pos_iter_;
|
||||||
float global_scale_;
|
float global_scale_;
|
||||||
Vector<Body*> bodies_;
|
DestructionListener* destruction_listener_;
|
||||||
|
|
||||||
|
bool removing_joint_;
|
||||||
Vector<Joint*> joints_;
|
Vector<Joint*> joints_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -525,7 +525,7 @@ namespace kiwano
|
||||||
return children;
|
return children;
|
||||||
}
|
}
|
||||||
|
|
||||||
ActorPtr Actor::GetChild(String const& name) const
|
Actor* Actor::GetChild(String const& name) const
|
||||||
{
|
{
|
||||||
size_t hash_code = std::hash<String>{}(name);
|
size_t hash_code = std::hash<String>{}(name);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -325,7 +325,7 @@ namespace kiwano
|
||||||
);
|
);
|
||||||
|
|
||||||
// 获取名称相同的子角色
|
// 获取名称相同的子角色
|
||||||
ActorPtr GetChild(
|
Actor* GetChild(
|
||||||
String const& name
|
String const& name
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,11 @@ namespace kiwano
|
||||||
}
|
}
|
||||||
|
|
||||||
Action* ActionManager::AddAction(ActionPtr action)
|
Action* ActionManager::AddAction(ActionPtr action)
|
||||||
|
{
|
||||||
|
return AddAction(action.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
Action* ActionManager::AddAction(Action* action)
|
||||||
{
|
{
|
||||||
KGE_ASSERT(action && "AddAction failed, NULL pointer exception");
|
KGE_ASSERT(action && "AddAction failed, NULL pointer exception");
|
||||||
|
|
||||||
|
|
@ -50,10 +55,10 @@ namespace kiwano
|
||||||
{
|
{
|
||||||
actions_.push_back(action);
|
actions_.push_back(action);
|
||||||
}
|
}
|
||||||
return action.get();
|
return action;
|
||||||
}
|
}
|
||||||
|
|
||||||
ActionPtr ActionManager::GetAction(String const & name)
|
Action* ActionManager::GetAction(String const & name)
|
||||||
{
|
{
|
||||||
if (actions_.empty())
|
if (actions_.empty())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
|
||||||
|
|
@ -32,9 +32,13 @@ namespace kiwano
|
||||||
Action* AddAction(
|
Action* AddAction(
|
||||||
ActionPtr action
|
ActionPtr action
|
||||||
);
|
);
|
||||||
|
// 添加动作
|
||||||
|
Action* AddAction(
|
||||||
|
Action* action
|
||||||
|
);
|
||||||
|
|
||||||
// 获取动作
|
// 获取动作
|
||||||
ActionPtr GetAction(
|
Action* GetAction(
|
||||||
String const& name
|
String const& name
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,11 @@ namespace kiwano
|
||||||
}
|
}
|
||||||
|
|
||||||
EventListener* EventDispatcher::AddListener(EventListenerPtr listener)
|
EventListener* EventDispatcher::AddListener(EventListenerPtr listener)
|
||||||
|
{
|
||||||
|
return AddListener(listener.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
EventListener* EventDispatcher::AddListener(EventListener* listener)
|
||||||
{
|
{
|
||||||
KGE_ASSERT(listener && "AddListener failed, NULL pointer exception");
|
KGE_ASSERT(listener && "AddListener failed, NULL pointer exception");
|
||||||
|
|
||||||
|
|
@ -48,7 +53,7 @@ namespace kiwano
|
||||||
{
|
{
|
||||||
listeners_.push_back(listener);
|
listeners_.push_back(listener);
|
||||||
}
|
}
|
||||||
return listener.get();
|
return listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
EventListener* EventDispatcher::AddListener(EventType type, EventListener::Callback callback, String const& name)
|
EventListener* EventDispatcher::AddListener(EventType type, EventListener::Callback callback, String const& name)
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,11 @@ namespace kiwano
|
||||||
EventListenerPtr listener
|
EventListenerPtr listener
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// 添加监听器
|
||||||
|
EventListener* AddListener(
|
||||||
|
EventListener* listener
|
||||||
|
);
|
||||||
|
|
||||||
// 添加监听器
|
// 添加监听器
|
||||||
EventListener* AddListener(
|
EventListener* AddListener(
|
||||||
EventType type,
|
EventType type,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue