Magic_Game/src/kiwano-physics/Joint.h

1113 lines
29 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Copyright (c) 2018-2019 Kiwano - Nomango
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#pragma once
#include <kiwano-physics/Body.h>
#include <kiwano-physics/helper.h>
namespace kiwano
{
namespace physics
{
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(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);
/**
* \addtogroup Physics
* @{
*/
/// \~chinese
/// @brief 关节
class KGE_API Joint : public virtual ObjectBase
{
public:
/// \~chinese
/// @brief 关节类型
enum class Type
{
Unknown = 0, ///< 未知
Revolute, ///< 旋转关节
Prismatic, ///< 平移关节
Distance, ///< 固定距离关节
Pulley, ///< 滑轮关节
Mouse, ///< 鼠标关节
Gear, ///< 齿轮关节
Wheel, ///< 轮关节
Weld, ///< 焊接关节
Friction, ///< 摩擦关节
Rope, ///< 绳关节
Motor ///< 马达关节
};
/// \~chinese
/// @brief 关节基础参数
struct ParamBase
{
Body* body_a; ///< 关节连接的物体A
Body* body_b; ///< 关节连接的物体B
ParamBase(Body* body_a, Body* body_b)
: body_a(body_a)
, body_b(body_b)
{
}
ParamBase(BodyPtr body_a, BodyPtr body_b)
: body_a(body_a.get())
, body_b(body_b.get())
{
}
};
Joint();
virtual ~Joint();
/// \~chinese
/// @brief 初始化关节
bool InitJoint(World* world, b2JointDef* joint_def);
/// \~chinese
/// @brief 获取关节连接的物体A
BodyPtr GetBodyA() const;
/// \~chinese
/// @brief 获取关节连接的物体B
BodyPtr GetBodyB() const;
/// \~chinese
/// @brief 获取物理世界
World* GetWorld() const;
/// \~chinese
/// @brief 销毁关节
void Destroy();
b2Joint* GetB2Joint() const;
void SetB2Joint(b2Joint* joint);
private:
b2Joint* joint_;
World* world_;
Type type_;
};
/// \~chinese
/// @brief 固定距离关节
class KGE_API DistanceJoint : public Joint
{
public:
/// \~chinese
/// @brief 固定距离关节参数
struct Param : public Joint::ParamBase
{
Point anchor_a; ///< 关节在物体A上的连接点
Point anchor_b; ///< 关节在物体B上的连接点
float frequency_hz; ///< 响应速度,数值越高关节响应的速度越快,看上去越坚固
float damping_ratio; ///< 阻尼率,值越大关节运动阻尼越大
Param(Body* body_a, Body* body_b, Point const& anchor_a, Point const& anchor_b, float frequency_hz = 0.f,
float damping_ratio = 0.f)
: ParamBase(body_a, body_b)
, anchor_a(anchor_a)
, anchor_b(anchor_b)
, frequency_hz(frequency_hz)
, damping_ratio(damping_ratio)
{
}
Param(BodyPtr body_a, BodyPtr body_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(), anchor_a, anchor_b, frequency_hz, damping_ratio)
{
}
};
DistanceJoint();
/// \~chinese
/// @brief 初始化关节
bool InitJoint(World* world, Param const& param);
/// \~chinese
/// @brief 设置关节长度
void SetLength(float length);
/// \~chinese
/// @brief 获取关节长度
float GetLength() const;
/// \~chinese
/// @brief 设置弹簧响应速度 [赫兹]
void SetFrequency(float hz);
/// \~chinese
/// @brief 获取弹簧响应速度 [赫兹]
float GetFrequency() const;
/// \~chinese
/// @brief 设置阻尼率
void SetDampingRatio(float ratio);
/// \~chinese
/// @brief 获取阻尼率
float GetDampingRatio() const;
private:
b2DistanceJoint* raw_joint_;
};
/// \~chinese
/// @brief 摩擦关节
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();
/// \~chinese
/// @brief 初始化关节
bool InitJoint(World* world, Param const& param);
/// \~chinese
/// @brief 设置最大摩擦力
void SetMaxForce(float force);
/// \~chinese
/// @brief 获取最大摩擦力
float GetMaxForce() const;
/// \~chinese
/// @brief 设置最大转矩
void SetMaxTorque(float torque);
/// \~chinese
/// @brief 获取最大转矩
float GetMaxTorque() const;
private:
b2FrictionJoint* raw_joint_;
};
/// \~chinese
/// @brief 齿轮关节
class KGE_API GearJoint : public Joint
{
public:
/// \~chinese
/// @brief 齿轮关节参数
struct Param : public Joint::ParamBase
{
Joint* joint_a; ///< 关节A旋转关节/平移关节)
Joint* joint_b; ///< 关节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();
/// \~chinese
/// @brief 初始化关节
bool InitJoint(World* world, Param const& param);
/// \~chinese
/// @brief 设定齿轮传动比
void SetRatio(float ratio);
/// \~chinese
/// @brief 获取齿轮传动比
float GetRatio() const;
private:
b2GearJoint* raw_joint_;
};
/// \~chinese
/// @brief 马达关节
class KGE_API MotorJoint : public Joint
{
public:
/// \~chinese
/// @brief 马达关节参数
struct Param : public Joint::ParamBase
{
float max_force; ///< 最大摩擦力
float max_torque; ///< 最大转矩
float correction_factor; ///< 位置矫正因子(范围 0-1
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();
/// \~chinese
/// @brief 初始化关节
bool InitJoint(World* world, Param const& param);
/// \~chinese
/// @brief 设置最大摩擦力
void SetMaxForce(float force);
/// \~chinese
/// @brief 获取最大摩擦力
float GetMaxForce() const;
/// \~chinese
/// @brief 设置最大转矩
void SetMaxTorque(float torque);
/// \~chinese
/// @brief 获取最大转矩
float GetMaxTorque() const;
private:
b2MotorJoint* raw_joint_;
};
/// \~chinese
/// @brief 平移关节
class KGE_API PrismaticJoint : public Joint
{
public:
/// \~chinese
/// @brief 平移关节参数
struct Param : public Joint::ParamBase
{
Point anchor; ///< 关节位置
Vec2 axis; ///< 物体A滑动的方向
bool enable_limit; ///< 是否启用限制
float lower_translation; ///< 移动的最小限制,与方向同向为正,反向为负,启用限制后才有效果
float upper_translation; ///< 移动的最大限制,与方向同向为正,反向为负,启用限制后才有效果
bool enable_motor; ///< 是否启用马达
float max_motor_force; ///< 最大马达力 [N]
float motor_speed; ///< 马达转速 [degree/s]
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();
/// \~chinese
/// @brief 初始化关节
bool InitJoint(World* world, Param const& param);
/// \~chinese
/// @brief 获取参考角
float GetReferenceAngle() const;
/// \~chinese
/// @brief 获取关节转换
float GetJointTranslation() const;
/// \~chinese
/// @brief 获取关节速度
float GetJointSpeed() const;
/// \~chinese
/// @brief 是否启用关节限制
bool IsLimitEnabled() const;
/// \~chinese
/// @brief 设置是否启用关节限制
void EnableLimit(bool flag);
/// \~chinese
/// @brief 获取平移最小限制
float GetLowerLimit() const;
/// \~chinese
/// @brief 获取平移最大限制
float GetUpperLimit() const;
/// \~chinese
/// @brief 设置关节限制
void SetLimits(float lower, float upper);
/// \~chinese
/// @brief 是否启用马达
bool IsMotorEnabled() const;
/// \~chinese
/// @brief 设置是否启用马达
void EnableMotor(bool flag);
/// \~chinese
/// @brief 设置马达转速 [degree/s]
void SetMotorSpeed(float speed);
/// \~chinese
/// @brief 获取马达转速 [degree/s]
float GetMotorSpeed() const;
/// \~chinese
/// @brief 设置最大马达力 [N]
void SetMaxMotorForce(float force);
/// \~chinese
/// @brief 获取最大马达力 [N]
float GetMaxMotorForce() const;
private:
b2PrismaticJoint* raw_joint_;
};
/// \~chinese
/// @brief 滑轮关节
class KGE_API PulleyJoint : public Joint
{
public:
/// \~chinese
/// @brief 滑轮关节参数
struct Param : public Joint::ParamBase
{
Point anchor_a; ///< 关节在物体A上的作用点
Point anchor_b; ///< 关节在物体B上的作用点
Point ground_anchor_a; ///< 物体A对应的滑轮的位置
Point ground_anchor_b; ///< 物体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();
/// \~chinese
/// @brief 初始化关节
bool InitJoint(World* world, Param const& param);
/// \~chinese
/// @brief 物体A对应的滑轮的位置
Point GetGroundAnchorA() const;
/// \~chinese
/// @brief 物体B对应的滑轮的位置
Point GetGroundAnchorB() const;
/// \~chinese
/// @brief 获取滑轮传动比
float GetRatio() const;
/// \~chinese
/// @brief 获取物体A与滑轮的距离
float GetLengthA() const;
/// \~chinese
/// @brief 获取物体B与滑轮的距离
float GetLengthB() const;
/// \~chinese
/// @brief 获取物体A与滑轮的当前距离
float GetCurrentLengthA() const;
/// \~chinese
/// @brief 获取物体B与滑轮的当前距离
float GetCurrentLengthB() const;
private:
b2PulleyJoint* raw_joint_;
};
/// \~chinese
/// @brief 旋转关节
class KGE_API RevoluteJoint : public Joint
{
public:
/// \~chinese
/// @brief 旋转关节参数
struct Param : public Joint::ParamBase
{
Point anchor; ///< 关节位置
bool enable_limit; ///< 是否启用限制
float lower_angle; ///< 移动的最小限制,与方向同向为正,反向为负,启用限制后才有效果
float upper_angle; ///< 移动的最大限制,与方向同向为正,反向为负,启用限制后才有效果
bool enable_motor; ///< 是否启用马达
float max_motor_torque; ///< 最大马达力 [N]
float motor_speed; ///< 马达转速 [degree/s]
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();
/// \~chinese
/// @brief 初始化关节
bool InitJoint(World* world, Param const& param);
/// \~chinese
/// @brief 获取参考角
float GetReferenceAngle() const;
/// \~chinese
/// @brief 获取关节角度
float GetJointAngle() const;
/// \~chinese
/// @brief 获取关节速度
float GetJointSpeed() const;
/// \~chinese
/// @brief 是否启用关节限制
bool IsLimitEnabled() const;
/// \~chinese
/// @brief 设置是否启用关节限制
void EnableLimit(bool flag);
/// \~chinese
/// @brief 获取平移最小限制
float GetLowerLimit() const;
/// \~chinese
/// @brief 获取平移最大限制
float GetUpperLimit() const;
/// \~chinese
/// @brief 设置关节限制
void SetLimits(float lower, float upper);
/// \~chinese
/// @brief 是否启用马达
bool IsMotorEnabled() const;
/// \~chinese
/// @brief 设置是否启用马达
void EnableMotor(bool flag);
/// \~chinese
/// @brief 设置马达转速 [degree/s]
void SetMotorSpeed(float speed);
/// \~chinese
/// @brief 获取马达转速 [degree/s]
float GetMotorSpeed() const;
/// \~chinese
/// @brief 设置最大马达转矩 [N/m]
void SetMaxMotorTorque(float torque);
/// \~chinese
/// @brief 获取最大马达转矩 [N/m]
float GetMaxMotorTorque() const;
private:
b2RevoluteJoint* raw_joint_;
};
/// \~chinese
/// @brief 绳关节
class KGE_API RopeJoint : public Joint
{
public:
/// \~chinese
/// @brief 绳关节参数
struct Param : public Joint::ParamBase
{
Point local_anchor_a; ///< 关节在物体A上的连接点
Point local_anchor_b; ///< 关节在物体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();
/// \~chinese
/// @brief 初始化关节
bool InitJoint(World* world, Param const& param);
/// \~chinese
/// @brief 设置关节最大长度
void SetMaxLength(float length);
/// \~chinese
/// @brief 获取关节最大长度
float GetMaxLength() const;
private:
b2RopeJoint* raw_joint_;
};
/// \~chinese
/// @brief 焊接关节
class KGE_API WeldJoint : public Joint
{
public:
/// \~chinese
/// @brief 焊接关节参数
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();
/// \~chinese
/// @brief 初始化关节
bool InitJoint(World* world, Param const& param);
/// \~chinese
/// @brief 获取物体B相对于物体A的角度
float GetReferenceAngle() const;
/// \~chinese
/// @brief 设置弹簧响应速度 [赫兹]
void SetFrequency(float hz);
/// \~chinese
/// @brief 获取弹簧响应速度 [赫兹]
float GetFrequency() const;
/// \~chinese
/// @brief 设置阻尼率
void SetDampingRatio(float ratio);
/// \~chinese
/// @brief 获取阻尼率
float GetDampingRatio() const;
private:
b2WeldJoint* raw_joint_;
};
/// \~chinese
/// @brief 轮关节
class KGE_API WheelJoint : public Joint
{
public:
/// \~chinese
/// @brief 轮关节参数
struct Param : public Joint::ParamBase
{
Point anchor; ///< 轮关节位置
Vec2 axis; ///< 物体A滑动方向
bool enable_motor; ///< 是否启用马达
float max_motor_torque; ///< 最大马达力 [N]
float motor_speed; ///< 马达转速 [degree/s]
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();
/// \~chinese
/// @brief 初始化关节
bool InitJoint(World* world, Param const& param);
/// \~chinese
/// @brief 获取关节当前的平移距离
float GetJointTranslation() const;
/// \~chinese
/// @brief 获取关节当前的线性速度
float GetJointLinearSpeed() const;
/// \~chinese
/// @brief 获取关节当前的角度
float GetJointAngle() const;
/// \~chinese
/// @brief 获取关节当前的旋转速度
float GetJointAngularSpeed() const;
/// \~chinese
/// @brief 是否启用马达
bool IsMotorEnabled() const;
/// \~chinese
/// @brief 设置是否启用马达
void EnableMotor(bool flag);
/// \~chinese
/// @brief 设置马达转速 [degree/s]
void SetMotorSpeed(float speed);
/// \~chinese
/// @brief 获取马达转速 [degree/s]
float GetMotorSpeed() const;
/// \~chinese
/// @brief 设置最大马达转矩 [N/m]
void SetMaxMotorTorque(float torque);
/// \~chinese
/// @brief 获取最大马达转矩 [N/m]
float GetMaxMotorTorque() const;
/// \~chinese
/// @brief 设置弹簧响应速度
void SetSpringFrequencyHz(float hz);
/// \~chinese
/// @brief 获取弹簧响应速度
float GetSpringFrequencyHz() const;
/// \~chinese
/// @brief 设置弹簧阻尼率
void SetSpringDampingRatio(float ratio);
/// \~chinese
/// @brief 获取弹簧阻尼率
float GetSpringDampingRatio() const;
private:
b2WheelJoint* raw_joint_;
};
/// \~chinese
/// @brief 鼠标关节
/// @details 用于使身体的某个点追踪世界上的指定点,例如让物体追踪鼠标位置
class KGE_API MouseJoint : public Joint
{
public:
/// \~chinese
/// @brief 鼠标关节参数
struct Param : public Joint::ParamBase
{
Point target; ///< 关节作用目标位置
float max_force; ///< 作用在物体A上的最大力
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();
/// \~chinese
/// @brief 初始化关节
bool InitJoint(World* world, Param const& param);
/// \~chinese
/// @brief 设定最大摩擦力 [N]
void SetMaxForce(float force);
/// \~chinese
/// @brief 获取最大摩擦力 [N]
float GetMaxForce() const;
/// \~chinese
/// @brief 设置响应速度 [hz]
void SetFrequency(float hz);
/// \~chinese
/// @brief 获取响应速度 [hz]
float GetFrequency() const;
/// \~chinese
/// @brief 设置阻尼率
void SetDampingRatio(float ratio);
/// \~chinese
/// @brief 获取阻尼率
float GetDampingRatio() const;
private:
b2MouseJoint* raw_joint_;
};
/** @} */
inline b2Joint* Joint::GetB2Joint() const
{
return joint_;
}
inline World* Joint::GetWorld() const
{
return world_;
}
inline void DistanceJoint::SetFrequency(float hz)
{
KGE_ASSERT(raw_joint_);
raw_joint_->SetFrequency(hz);
}
inline float DistanceJoint::GetFrequency() const
{
KGE_ASSERT(raw_joint_);
return raw_joint_->GetFrequency();
}
inline void DistanceJoint::SetDampingRatio(float ratio)
{
KGE_ASSERT(raw_joint_);
raw_joint_->SetDampingRatio(ratio);
}
inline float DistanceJoint::GetDampingRatio() const
{
KGE_ASSERT(raw_joint_);
return raw_joint_->GetDampingRatio();
}
inline float PrismaticJoint::GetReferenceAngle() const
{
KGE_ASSERT(raw_joint_);
return math::Radian2Degree(raw_joint_->GetReferenceAngle());
}
inline bool PrismaticJoint::IsLimitEnabled() const
{
KGE_ASSERT(raw_joint_);
return raw_joint_->IsLimitEnabled();
}
inline void PrismaticJoint::EnableLimit(bool flag)
{
KGE_ASSERT(raw_joint_);
raw_joint_->EnableLimit(flag);
}
inline bool PrismaticJoint::IsMotorEnabled() const
{
KGE_ASSERT(raw_joint_);
return raw_joint_->IsMotorEnabled();
}
inline void PrismaticJoint::EnableMotor(bool flag)
{
KGE_ASSERT(raw_joint_);
raw_joint_->EnableMotor(flag);
}
inline void PrismaticJoint::SetMotorSpeed(float speed)
{
KGE_ASSERT(raw_joint_);
raw_joint_->SetMotorSpeed(math::Degree2Radian(speed));
}
inline float PrismaticJoint::GetMotorSpeed() const
{
KGE_ASSERT(raw_joint_);
return math::Radian2Degree(raw_joint_->GetMotorSpeed());
}
inline void PrismaticJoint::SetMaxMotorForce(float force)
{
KGE_ASSERT(raw_joint_);
raw_joint_->SetMaxMotorForce(force);
}
inline float PrismaticJoint::GetMaxMotorForce() const
{
KGE_ASSERT(raw_joint_);
return raw_joint_->GetMaxMotorForce();
}
inline float RevoluteJoint::GetReferenceAngle() const
{
KGE_ASSERT(raw_joint_);
return math::Radian2Degree(raw_joint_->GetReferenceAngle());
}
inline bool RevoluteJoint::IsLimitEnabled() const
{
KGE_ASSERT(raw_joint_);
return raw_joint_->IsLimitEnabled();
}
inline void RevoluteJoint::EnableLimit(bool flag)
{
KGE_ASSERT(raw_joint_);
raw_joint_->EnableLimit(flag);
}
inline bool RevoluteJoint::IsMotorEnabled() const
{
KGE_ASSERT(raw_joint_);
return raw_joint_->IsMotorEnabled();
}
inline void RevoluteJoint::EnableMotor(bool flag)
{
KGE_ASSERT(raw_joint_);
raw_joint_->EnableMotor(flag);
}
inline void RevoluteJoint::SetMotorSpeed(float speed)
{
KGE_ASSERT(raw_joint_);
raw_joint_->SetMotorSpeed(math::Degree2Radian(speed));
}
inline float RevoluteJoint::GetMotorSpeed() const
{
KGE_ASSERT(raw_joint_);
return math::Radian2Degree(raw_joint_->GetMotorSpeed());
}
inline float WeldJoint::GetReferenceAngle() const
{
KGE_ASSERT(raw_joint_);
return math::Radian2Degree(raw_joint_->GetReferenceAngle());
}
inline void WeldJoint::SetFrequency(float hz)
{
KGE_ASSERT(raw_joint_);
raw_joint_->SetFrequency(hz);
}
inline float WeldJoint::GetFrequency() const
{
KGE_ASSERT(raw_joint_);
return raw_joint_->GetFrequency();
}
inline void WeldJoint::SetDampingRatio(float ratio)
{
KGE_ASSERT(raw_joint_);
raw_joint_->SetDampingRatio(ratio);
}
inline float WeldJoint::GetDampingRatio() const
{
KGE_ASSERT(raw_joint_);
return raw_joint_->GetDampingRatio();
}
inline float WheelJoint::GetJointAngle() const
{
KGE_ASSERT(raw_joint_);
return math::Radian2Degree(raw_joint_->GetJointAngle());
}
inline float WheelJoint::GetJointAngularSpeed() const
{
KGE_ASSERT(raw_joint_);
return math::Radian2Degree(raw_joint_->GetJointAngularSpeed());
}
inline bool WheelJoint::IsMotorEnabled() const
{
KGE_ASSERT(raw_joint_);
return raw_joint_->IsMotorEnabled();
}
inline void WheelJoint::EnableMotor(bool flag)
{
KGE_ASSERT(raw_joint_);
raw_joint_->EnableMotor(flag);
}
inline void WheelJoint::SetMotorSpeed(float speed)
{
KGE_ASSERT(raw_joint_);
raw_joint_->SetMotorSpeed(math::Degree2Radian(speed));
}
inline float WheelJoint::GetMotorSpeed() const
{
KGE_ASSERT(raw_joint_);
return math::Radian2Degree(raw_joint_->GetMotorSpeed());
}
inline void WheelJoint::SetSpringFrequencyHz(float hz)
{
KGE_ASSERT(raw_joint_);
raw_joint_->SetSpringFrequencyHz(hz);
}
inline float WheelJoint::GetSpringFrequencyHz() const
{
KGE_ASSERT(raw_joint_);
return raw_joint_->GetSpringFrequencyHz();
}
inline void WheelJoint::SetSpringDampingRatio(float ratio)
{
KGE_ASSERT(raw_joint_);
raw_joint_->SetSpringDampingRatio(ratio);
}
inline float WheelJoint::GetSpringDampingRatio() const
{
KGE_ASSERT(raw_joint_);
return raw_joint_->GetSpringDampingRatio();
}
inline void MouseJoint::SetFrequency(float hz)
{
KGE_ASSERT(raw_joint_);
raw_joint_->SetFrequency(hz);
}
inline float MouseJoint::GetFrequency() const
{
KGE_ASSERT(raw_joint_);
return raw_joint_->GetFrequency();
}
inline void MouseJoint::SetDampingRatio(float ratio)
{
KGE_ASSERT(raw_joint_);
raw_joint_->SetDampingRatio(ratio);
}
inline float MouseJoint::GetDampingRatio() const
{
KGE_ASSERT(raw_joint_);
return raw_joint_->GetDampingRatio();
}
} // namespace physics
} // namespace kiwano