From 7bb7dfa8a48bd13e7576bedcd1fe7c50575e82a4 Mon Sep 17 00:00:00 2001 From: Nomango Date: Tue, 29 Oct 2019 18:01:31 +0800 Subject: [PATCH] Add physics Joints --- src/kiwano-physics/Joint.cpp | 304 ++++++++++++++++++++++++++++- src/kiwano-physics/Joint.h | 368 +++++++++++++++++++++++++++++++++-- 2 files changed, 648 insertions(+), 24 deletions(-) diff --git a/src/kiwano-physics/Joint.cpp b/src/kiwano-physics/Joint.cpp index fc51719b..8a91bfbb 100644 --- a/src/kiwano-physics/Joint.cpp +++ b/src/kiwano-physics/Joint.cpp @@ -104,12 +104,12 @@ namespace kiwano { } - DistanceJointPtr DistanceJoint::Create(World* world, Param const& param) + DistanceJointPtr DistanceJoint::Create(World* world, DistanceJoint::Param const& param) { KGE_ASSERT(param.body_a && param.body_b); b2DistanceJointDef def; - def.Initialize(param.body_a->GetB2Body(), param.body_b->GetB2Body(), world->Stage2World(param.local_anchor_a), world->Stage2World(param.local_anchor_b)); + def.Initialize(param.body_a->GetB2Body(), param.body_b->GetB2Body(), world->Stage2World(param.anchor_a), world->Stage2World(param.anchor_b)); def.frequencyHz = param.frequency_hz; def.dampingRatio = param.damping_ratio; @@ -146,7 +146,7 @@ namespace kiwano { } - FrictionJointPtr FrictionJoint::Create(World* world, Param const& param) + FrictionJointPtr FrictionJoint::Create(World* world, FrictionJoint::Param const& param) { KGE_ASSERT(param.body_a && param.body_b); @@ -200,7 +200,7 @@ namespace kiwano { } - GearJointPtr GearJoint::Create(World* world, Param const& param) + GearJointPtr GearJoint::Create(World* world, GearJoint::Param const& param) { KGE_ASSERT(param.joint_a && param.joint_b); @@ -242,7 +242,7 @@ namespace kiwano { } - MotorJointPtr MotorJoint::Create(World* world, Param const& param) + MotorJointPtr MotorJoint::Create(World* world, MotorJoint::Param const& param) { KGE_ASSERT(param.body_a && param.body_b); @@ -280,6 +280,291 @@ namespace kiwano return world_->World2Stage(raw_joint_->GetMaxTorque()); } + // + // PrismaticJoint + // + + PrismaticJoint::PrismaticJoint() + : Joint() + , raw_joint_(nullptr) + { + } + + PrismaticJoint::PrismaticJoint(World* world, b2PrismaticJointDef* def) + : Joint(world, def) + , raw_joint_(nullptr) + { + } + + PrismaticJointPtr PrismaticJoint::Create(World* world, PrismaticJoint::Param const& param) + { + KGE_ASSERT(param.body_a && param.body_b); + + b2PrismaticJointDef def; + def.Initialize(param.body_a->GetB2Body(), param.body_b->GetB2Body(), world->Stage2World(param.anchor), Stage2World(param.axis)); + def.enableLimit = param.enable_limit; + def.lowerTranslation = world->Stage2World(param.lower_translation); + def.upperTranslation = world->Stage2World(param.upper_translation); + def.enableMotor = param.enable_motor; + def.maxMotorForce = param.max_motor_force; + def.motorSpeed = world->Stage2World(param.motor_speed); + + PrismaticJointPtr joint = new PrismaticJoint(world, &def); + joint->raw_joint_ = static_cast(joint->GetB2Joint()); + return joint; + } + + float PrismaticJoint::GetJointTranslation() const + { + KGE_ASSERT(raw_joint_ && world_); + return world_->World2Stage(raw_joint_->GetJointTranslation()); + } + + float PrismaticJoint::GetJointSpeed() const + { + KGE_ASSERT(raw_joint_ && world_); + return world_->World2Stage(raw_joint_->GetJointSpeed()); + } + + float PrismaticJoint::GetLowerLimit() const + { + KGE_ASSERT(raw_joint_ && world_); + return world_->World2Stage(raw_joint_->GetLowerLimit()); + } + + float PrismaticJoint::GetUpperLimit() const + { + KGE_ASSERT(raw_joint_ && world_); + return world_->World2Stage(raw_joint_->GetUpperLimit()); + } + + void PrismaticJoint::SetLimits(float lower, float upper) + { + KGE_ASSERT(raw_joint_ && world_); + raw_joint_->SetLimits(world_->Stage2World(lower), world_->Stage2World(upper)); + } + + // + // PulleyJoint + // + + PulleyJoint::PulleyJoint() + : Joint() + , raw_joint_(nullptr) + { + } + + PulleyJoint::PulleyJoint(World* world, b2PulleyJointDef* def) + : Joint(world, def) + , raw_joint_(nullptr) + { + } + + PulleyJointPtr PulleyJoint::Create(World* world, PulleyJoint::Param const& param) + { + KGE_ASSERT(param.body_a && param.body_b); + + b2PulleyJointDef def; + def.Initialize(param.body_a->GetB2Body(), param.body_b->GetB2Body(), world->Stage2World(param.ground_anchor_a), world->Stage2World(param.ground_anchor_b), + world->Stage2World(param.anchor_a), world->Stage2World(param.anchor_b), param.ratio); + + PulleyJointPtr joint = new PulleyJoint(world, &def); + joint->raw_joint_ = static_cast(joint->GetB2Joint()); + return joint; + } + + Point PulleyJoint::GetGroundAnchorA() const + { + KGE_ASSERT(raw_joint_ && world_); + return world_->World2Stage(raw_joint_->GetGroundAnchorA()); + } + + Point PulleyJoint::GetGroundAnchorB() const + { + KGE_ASSERT(raw_joint_ && world_); + return world_->World2Stage(raw_joint_->GetGroundAnchorB()); + } + + float PulleyJoint::GetRatio() const + { + KGE_ASSERT(raw_joint_); + return raw_joint_->GetRatio(); + } + + float PulleyJoint::GetLengthA() const + { + KGE_ASSERT(raw_joint_ && world_); + return world_->World2Stage(raw_joint_->GetLengthA()); + } + + float PulleyJoint::GetLengthB() const + { + KGE_ASSERT(raw_joint_ && world_); + return world_->World2Stage(raw_joint_->GetLengthB()); + } + + float PulleyJoint::GetCurrentLengthA() const + { + KGE_ASSERT(raw_joint_ && world_); + return world_->World2Stage(raw_joint_->GetCurrentLengthA()); + } + + float PulleyJoint::GetCurrentLengthB() const + { + KGE_ASSERT(raw_joint_ && world_); + return world_->World2Stage(raw_joint_->GetCurrentLengthB()); + } + + // + // RevoluteJoint + // + + RevoluteJoint::RevoluteJoint() + : Joint() + , raw_joint_(nullptr) + { + } + + RevoluteJoint::RevoluteJoint(World* world, b2RevoluteJointDef* def) + : Joint(world, def) + , raw_joint_(nullptr) + { + } + + RevoluteJointPtr RevoluteJoint::Create(World* world, RevoluteJoint::Param const& param) + { + KGE_ASSERT(param.body_a && param.body_b); + + b2RevoluteJointDef def; + def.Initialize(param.body_a->GetB2Body(), param.body_b->GetB2Body(), world->Stage2World(param.anchor)); + def.enableLimit = param.enable_limit; + def.lowerAngle = math::Angle2Radian(param.lower_angle); + def.upperAngle = math::Angle2Radian(param.upper_angle); + def.enableMotor = param.enable_motor; + def.maxMotorTorque = world->Stage2World(param.max_motor_torque); + def.motorSpeed = math::Angle2Radian(param.motor_speed); + + RevoluteJointPtr joint = new RevoluteJoint(world, &def); + joint->raw_joint_ = static_cast(joint->GetB2Joint()); + return joint; + } + + float RevoluteJoint::GetJointAngle() const + { + KGE_ASSERT(raw_joint_ && world_); + return math::Radian2Angle(raw_joint_->GetJointAngle()); + } + + float RevoluteJoint::GetJointSpeed() const + { + KGE_ASSERT(raw_joint_ && world_); + return math::Radian2Angle(raw_joint_->GetJointSpeed()); + } + + float RevoluteJoint::GetLowerLimit() const + { + KGE_ASSERT(raw_joint_ && world_); + return math::Radian2Angle(raw_joint_->GetLowerLimit()); + } + + float RevoluteJoint::GetUpperLimit() const + { + KGE_ASSERT(raw_joint_ && world_); + return math::Radian2Angle(raw_joint_->GetUpperLimit()); + } + + void RevoluteJoint::SetLimits(float lower, float upper) + { + KGE_ASSERT(raw_joint_ && world_); + raw_joint_->SetLimits(math::Angle2Radian(lower), math::Angle2Radian(upper)); + } + + void RevoluteJoint::SetMaxMotorTorque(float torque) + { + KGE_ASSERT(raw_joint_ && world_); + raw_joint_->SetMaxMotorTorque(world_->Stage2World(torque)); + } + + float RevoluteJoint::GetMaxMotorTorque() const + { + KGE_ASSERT(raw_joint_ && world_); + return world_->World2Stage(raw_joint_->GetMaxMotorTorque()); + } + + // + // RopeJoint + // + + RopeJoint::RopeJoint() + : Joint() + , raw_joint_(nullptr) + { + } + + RopeJoint::RopeJoint(World* world, b2RopeJointDef* def) + : Joint(world, def) + , raw_joint_(nullptr) + { + } + + RopeJointPtr RopeJoint::Create(World* world, RopeJoint::Param const& param) + { + KGE_ASSERT(param.body_a && param.body_b); + + b2RopeJointDef 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.maxLength = world->Stage2World(param.max_length); + + RopeJointPtr joint = new RopeJoint(world, &def); + joint->raw_joint_ = static_cast(joint->GetB2Joint()); + return joint; + } + + void RopeJoint::SetMaxLength(float length) + { + KGE_ASSERT(raw_joint_ && world_); + raw_joint_->SetMaxLength(world_->Stage2World(length)); + } + + float RopeJoint::GetMaxLength() const + { + KGE_ASSERT(raw_joint_ && world_); + return world_->World2Stage(raw_joint_->GetMaxLength()); + } + + // + // WeldJoint + // + + WeldJoint::WeldJoint() + : Joint() + , raw_joint_(nullptr) + { + } + + WeldJoint::WeldJoint(World* world, b2WeldJointDef* def) + : Joint(world, def) + , raw_joint_(nullptr) + { + } + + WeldJointPtr WeldJoint::Create(World* world, WeldJoint::Param const& param) + { + KGE_ASSERT(param.body_a && param.body_b); + + b2WeldJointDef def; + def.Initialize(param.body_a->GetB2Body(), param.body_b->GetB2Body(), world->Stage2World(param.anchor)); + def.frequencyHz = param.frequency_hz; + def.dampingRatio = param.damping_ratio; + + WeldJointPtr joint = new WeldJoint(world, &def); + joint->raw_joint_ = static_cast(joint->GetB2Joint()); + return joint; + } + // // WheelJoint // @@ -296,12 +581,12 @@ namespace kiwano { } - WheelJointPtr WheelJoint::Create(World* world, Param const& param) + WheelJointPtr WheelJoint::Create(World* world, WheelJoint::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.Initialize(param.body_a->GetB2Body(), param.body_b->GetB2Body(), world->Stage2World(param.anchor), Stage2World(param.axis)); def.enableMotor = param.enable_motor; def.maxMotorTorque = world->Stage2World(param.max_motor_torque); def.motorSpeed = world->Stage2World(param.motor_speed); @@ -353,15 +638,14 @@ namespace kiwano { } - MouseJointPtr MouseJoint::Create(World* world, Param const& param) + MouseJointPtr MouseJoint::Create(World* world, MouseJoint::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.target = world->Stage2World(param.target); def.maxForce = param.max_force; def.frequencyHz = param.frequency_hz; def.dampingRatio = param.damping_ratio; diff --git a/src/kiwano-physics/Joint.h b/src/kiwano-physics/Joint.h index 96d093f0..861cd6ad 100644 --- a/src/kiwano-physics/Joint.h +++ b/src/kiwano-physics/Joint.h @@ -31,8 +31,13 @@ namespace kiwano 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); + KGE_DECLARE_SMART_PTR(PrismaticJoint); + KGE_DECLARE_SMART_PTR(PulleyJoint); + KGE_DECLARE_SMART_PTR(RevoluteJoint); + KGE_DECLARE_SMART_PTR(RopeJoint); + KGE_DECLARE_SMART_PTR(WeldJoint); + KGE_DECLARE_SMART_PTR(WheelJoint); // 关节 class KGE_API Joint @@ -93,22 +98,22 @@ namespace kiwano public: struct Param : public Joint::ParamBase { - Point local_anchor_a; - Point local_anchor_b; + Point anchor_a; + Point 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, + Point const& anchor_a, + Point const& anchor_b, float frequency_hz = 0.f, float damping_ratio = 0.f ) : ParamBase(body_a, body_b) - , local_anchor_a(local_anchor_a) - , local_anchor_b(local_anchor_b) + , anchor_a(anchor_a) + , anchor_b(anchor_b) , frequency_hz(frequency_hz) , damping_ratio(damping_ratio) {} @@ -116,12 +121,12 @@ namespace kiwano Param( BodyPtr body_a, BodyPtr body_b, - Point const& local_anchor_a, - Point const& local_anchor_b, + Point const& anchor_a, + Point const& 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) + : Param(body_a.get(), body_b.get(), anchor_a, anchor_b, frequency_hz, damping_ratio) {} }; @@ -297,6 +302,341 @@ namespace kiwano }; + // 平移关节 + class KGE_API PrismaticJoint + : public Joint + { + public: + struct Param : public Joint::ParamBase + { + Point anchor; + Vec2 axis; + bool enable_limit; + float lower_translation; + float upper_translation; + bool enable_motor; + float max_motor_force; + float motor_speed; + + Param( + Body* body_a, + Body* body_b, + Point const& anchor, + Vec2 const& axis, + bool enable_limit = false, + float lower_translation = 0.0f, + float upper_translation = 0.0f, + bool enable_motor = false, + float max_motor_force = 0.0f, + float motor_speed = 0.0f + ) + : ParamBase(body_a, body_b) + , anchor(anchor) + , axis(axis) + , enable_limit(enable_limit) + , lower_translation(lower_translation) + , upper_translation(upper_translation) + , enable_motor(enable_motor) + , max_motor_force(max_motor_force) + , motor_speed(motor_speed) + {} + + Param( + BodyPtr body_a, + BodyPtr body_b, + Point const& anchor, + Vec2 const& axis, + bool enable_limit = false, + float lower_translation = 0.0f, + float upper_translation = 0.0f, + bool enable_motor = false, + float max_motor_force = 0.0f, + float motor_speed = 0.0f + ) + : Param(body_a.get(), body_b.get(), anchor, axis, enable_limit, lower_translation, upper_translation, enable_motor, max_motor_force, motor_speed) + {} + }; + + PrismaticJoint(); + PrismaticJoint(World* world, b2PrismaticJointDef* def); + + static PrismaticJointPtr Create(World* world, Param const& param); + + float GetReferenceAngle() const { KGE_ASSERT(raw_joint_); return math::Radian2Angle(raw_joint_->GetReferenceAngle()); } + float GetJointTranslation() const; + float GetJointSpeed() const; + + bool IsLimitEnabled() const { KGE_ASSERT(raw_joint_); return raw_joint_->IsLimitEnabled(); } + void EnableLimit(bool flag) { KGE_ASSERT(raw_joint_); raw_joint_->EnableLimit(flag); } + + float GetLowerLimit() const; + float GetUpperLimit() const; + void SetLimits(float lower, float upper); + + bool IsMotorEnabled() const { KGE_ASSERT(raw_joint_); return raw_joint_->IsMotorEnabled(); } + void EnableMotor(bool flag) { KGE_ASSERT(raw_joint_); raw_joint_->EnableMotor(flag); } + + // 设置马达转速 [degree/s] + 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()); } + + // 设定最大马达力 [N] + void SetMaxMotorForce(float force) { KGE_ASSERT(raw_joint_); raw_joint_->SetMaxMotorForce(force); } + float GetMaxMotorForce() const { KGE_ASSERT(raw_joint_); return raw_joint_->GetMaxMotorForce(); } + + protected: + b2PrismaticJoint* raw_joint_; + }; + + + // 滑轮关节 + class KGE_API PulleyJoint + : public Joint + { + public: + struct Param : public Joint::ParamBase + { + Point anchor_a; + Point anchor_b; + Point ground_anchor_a; + Point ground_anchor_b; + float ratio; + + Param( + Body* body_a, + Body* body_b, + Point const& anchor_a, + Point const& anchor_b, + Point const& ground_anchor_a, + Point const& ground_anchor_b, + float ratio = 1.0f + ) + : ParamBase(body_a, body_b) + , anchor_a(anchor_a) + , anchor_b(anchor_b) + , ground_anchor_a(ground_anchor_a) + , ground_anchor_b(ground_anchor_b) + , ratio(ratio) + {} + + Param( + BodyPtr body_a, + BodyPtr body_b, + Point const& anchor_a, + Point const& anchor_b, + Point const& ground_anchor_a, + Point const& ground_anchor_b, + float ratio = 1.0f + ) + : Param(body_a.get(), body_b.get(), anchor_a, anchor_b, ground_anchor_a, ground_anchor_b, ratio) + {} + }; + + PulleyJoint(); + PulleyJoint(World* world, b2PulleyJointDef* def); + + static PulleyJointPtr Create(World* world, Param const& param); + + Point GetGroundAnchorA() const; + Point GetGroundAnchorB() const; + + float GetRatio() const; + + float GetLengthA() const; + float GetLengthB() const; + + float GetCurrentLengthA() const; + float GetCurrentLengthB() const; + + protected: + b2PulleyJoint* raw_joint_; + }; + + + // 旋转关节 + class KGE_API RevoluteJoint + : public Joint + { + public: + struct Param : public Joint::ParamBase + { + Point anchor; + bool enable_limit; + float lower_angle; + float upper_angle; + bool enable_motor; + float max_motor_torque; + float motor_speed; + + Param( + Body* body_a, + Body* body_b, + Point const& anchor, + bool enable_limit = false, + float lower_angle = 0.0f, + float upper_angle = 0.0f, + bool enable_motor = false, + float max_motor_torque = 0.0f, + float motor_speed = 0.0f + ) + : ParamBase(body_a, body_b) + , anchor(anchor) + , enable_limit(enable_limit) + , lower_angle(lower_angle) + , upper_angle(upper_angle) + , enable_motor(enable_motor) + , max_motor_torque(max_motor_torque) + , motor_speed(motor_speed) + {} + + Param( + BodyPtr body_a, + BodyPtr body_b, + Point const& anchor, + bool enable_limit = false, + float lower_angle = 0.0f, + float upper_angle = 0.0f, + bool enable_motor = false, + float max_motor_torque = 0.0f, + float motor_speed = 0.0f + ) + : Param(body_a.get(), body_b.get(), anchor, enable_limit, lower_angle, upper_angle, enable_motor, max_motor_torque, motor_speed) + {} + }; + + RevoluteJoint(); + RevoluteJoint(World* world, b2RevoluteJointDef* def); + + static RevoluteJointPtr Create(World* world, Param const& param); + + float GetReferenceAngle() const { KGE_ASSERT(raw_joint_); return math::Radian2Angle(raw_joint_->GetReferenceAngle()); } + float GetJointAngle() const; + float GetJointSpeed() const; + + bool IsLimitEnabled() const { KGE_ASSERT(raw_joint_); return raw_joint_->IsLimitEnabled(); } + void EnableLimit(bool flag) { KGE_ASSERT(raw_joint_); raw_joint_->EnableLimit(flag); } + + float GetLowerLimit() const; + float GetUpperLimit() const; + void SetLimits(float lower, float upper); + + bool IsMotorEnabled() const { KGE_ASSERT(raw_joint_); return raw_joint_->IsMotorEnabled(); } + void EnableMotor(bool flag) { KGE_ASSERT(raw_joint_); raw_joint_->EnableMotor(flag); } + + // 设置马达转速 [degree/s] + 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()); } + + // 设定最大马达转矩 [N/m] + void SetMaxMotorTorque(float torque); + float GetMaxMotorTorque() const; + + protected: + b2RevoluteJoint* raw_joint_; + }; + + + // 绳关节 + class KGE_API RopeJoint + : public Joint + { + public: + struct Param : public Joint::ParamBase + { + Point local_anchor_a; + Point local_anchor_b; + float max_length; + + Param( + Body* body_a, + Body* body_b, + Point const& local_anchor_a, + Point const& local_anchor_b, + float max_length = 0.f + ) + : ParamBase(body_a, body_b) + , local_anchor_a(local_anchor_a) + , local_anchor_b(local_anchor_b) + , max_length(max_length) + {} + + Param( + BodyPtr body_a, + BodyPtr body_b, + Point const& local_anchor_a, + Point const& local_anchor_b, + float max_length = 0.f + ) + : Param(body_a.get(), body_b.get(), local_anchor_a, local_anchor_b, max_length) + {} + }; + + RopeJoint(); + RopeJoint(World* world, b2RopeJointDef* def); + + static RopeJointPtr Create(World* world, Param const& param); + + void SetMaxLength(float length); + float GetMaxLength() const; + + protected: + b2RopeJoint* raw_joint_; + }; + + + // 焊接关节 + class KGE_API WeldJoint + : public Joint + { + public: + struct Param : public Joint::ParamBase + { + Point anchor; + float frequency_hz; + float damping_ratio; + + Param( + Body* body_a, + Body* body_b, + Point const& anchor, + float frequency_hz = 0.f, + float damping_ratio = 0.f + ) + : ParamBase(body_a, body_b) + , anchor(anchor) + , frequency_hz(frequency_hz) + , damping_ratio(damping_ratio) + {} + + Param( + BodyPtr body_a, + BodyPtr body_b, + Point const& anchor, + float frequency_hz = 0.f, + float damping_ratio = 0.f + ) + : Param(body_a.get(), body_b.get(), anchor, frequency_hz, damping_ratio) + {} + }; + + WeldJoint(); + WeldJoint(World* world, b2WeldJointDef* def); + + static WeldJointPtr Create(World* world, Param const& param); + + // 设置弹簧阻尼器频率 [赫兹] + 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: + b2WeldJoint* raw_joint_; + }; + + // 轮关节 class KGE_API WheelJoint : public Joint @@ -361,11 +701,11 @@ namespace kiwano bool IsMotorEnabled() const { KGE_ASSERT(raw_joint_); return raw_joint_->IsMotorEnabled(); } void EnableMotor(bool flag) { KGE_ASSERT(raw_joint_); raw_joint_->EnableMotor(flag); } - // 设置马达转速 [度/秒] + // 设置马达转速 [degree/s] 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()); } - // 设定最大马达转矩 + // 设定最大马达转矩 [N/m] void SetMaxMotorTorque(float torque); float GetMaxMotorTorque() const; @@ -425,11 +765,11 @@ namespace kiwano static MouseJointPtr Create(World* world, Param const& param); - // 设定最大摩擦力 + // 设定最大摩擦力 [N] void SetMaxForce(float force); float GetMaxForce() const; - // 设置响应速度 [赫兹] + // 设置响应速度 [hz] void SetFrequency(float hz) { KGE_ASSERT(raw_joint_); raw_joint_->SetFrequency(hz); } float GetFrequency() const { KGE_ASSERT(raw_joint_); return raw_joint_->GetFrequency(); }