Update physics
This commit is contained in:
parent
1e530411ae
commit
b0b02ddf62
|
|
@ -104,8 +104,7 @@ namespace kiwano
|
|||
{
|
||||
if (fixture.GetB2Fixture())
|
||||
{
|
||||
b2Fixture* ptr = const_cast<b2Fixture*>(fixture.GetB2Fixture());
|
||||
body_->DestroyFixture(ptr);
|
||||
body_->DestroyFixture(fixture.GetB2Fixture());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -254,7 +253,7 @@ namespace kiwano
|
|||
|
||||
void Body::Destroy()
|
||||
{
|
||||
if (world_)
|
||||
if (world_ && body_)
|
||||
{
|
||||
world_->RemoveBody(this);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,140 +30,283 @@ namespace kiwano
|
|||
{
|
||||
class World;
|
||||
|
||||
// 膠竟
|
||||
KGE_DECLARE_SMART_PTR(Body);
|
||||
|
||||
/**
|
||||
* \addtogroup Physics
|
||||
* @{
|
||||
*/
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 物体
|
||||
class KGE_API Body
|
||||
: public virtual RefCounter
|
||||
{
|
||||
public:
|
||||
/// \~chinese
|
||||
/// @brief 物体类型
|
||||
enum class Type
|
||||
{
|
||||
Static = 0,
|
||||
Kinematic,
|
||||
Dynamic,
|
||||
Static = 0, ///< 静态物体
|
||||
Kinematic, ///< 动力学物体
|
||||
Dynamic, ///< 动态物体
|
||||
};
|
||||
|
||||
Body();
|
||||
Body(b2Body* body, Actor* actor);
|
||||
Body(World* world, Actor* actor);
|
||||
Body(World* world, ActorPtr actor) : Body(world, actor.get()) {}
|
||||
Body(World* world, ActorPtr actor);
|
||||
virtual ~Body();
|
||||
|
||||
// 놓迦뺏
|
||||
/// \~chinese
|
||||
/// @brief 初始化
|
||||
/// @param[in] world 物理世界
|
||||
/// @param[in] actor 绑定的角色
|
||||
void Init(World* world, Actor* actor);
|
||||
|
||||
// 警속셸야
|
||||
/// \~chinese
|
||||
/// @brief 添加夹具
|
||||
/// @param shape 物体形状
|
||||
/// @param density 物体密度
|
||||
Fixture AddFixture(Shape* shape, const Fixture::Param& param);
|
||||
|
||||
// 警속近榴
|
||||
/// \~chinese
|
||||
/// @brief 添加圆形夹具
|
||||
/// @param radius 圆形半径
|
||||
/// @param density 物体密度
|
||||
Fixture AddCircleShape(float radius, float density = 0.f);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 添加盒形夹具
|
||||
/// @param size 盒大小
|
||||
/// @param density 物体密度
|
||||
Fixture AddBoxShape(Vec2 const& size, float density = 0.f);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 添加多边形夹具
|
||||
/// @param vertexs 多边形端点
|
||||
/// @param density 物体密度
|
||||
Fixture AddPolygonShape(Vector<Point> const& vertexs, float density = 0.f);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 添加线段形夹具
|
||||
/// @param p1 线段起点
|
||||
/// @param p2 线段终点
|
||||
/// @param density 物体密度
|
||||
Fixture AddEdgeShape(Point const& p1, Point const& p2, float density = 0.f);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 添加链条形夹具
|
||||
/// @param vertexs 链条端点
|
||||
/// @param loop 是否闭合
|
||||
/// @param density 物体密度
|
||||
Fixture AddChainShape(Vector<Point> const& vertexs, bool loop, float density = 0.f);
|
||||
|
||||
// 삿혤셸야
|
||||
Fixture GetFixtureList() const { KGE_ASSERT(body_); return Fixture(body_->GetFixtureList()); }
|
||||
/// \~chinese
|
||||
/// @brief 获取夹具列表
|
||||
FixtureList GetFixtureList() const;
|
||||
|
||||
// 盧뇜셸야
|
||||
/// \~chinese
|
||||
/// @brief 移除夹具
|
||||
void RemoveFixture(Fixture const& fixture);
|
||||
|
||||
// 삿혤쌈뇰긋
|
||||
ContactEdge GetContactList() const { KGE_ASSERT(body_); ContactEdge(body_->GetContactList()); }
|
||||
/// \~chinese
|
||||
/// @brief 获取接触边列表
|
||||
ContactEdgeList GetContactList() const;
|
||||
|
||||
// 잚깎쯤
|
||||
uint16_t GetCategoryBits() const { return category_bits_; }
|
||||
/// \~chinese
|
||||
/// @brief 获取类别码
|
||||
uint16_t GetCategoryBits() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置类别码
|
||||
void SetCategoryBits(uint16_t category_bits);
|
||||
|
||||
// 툭旒拿쯤
|
||||
uint16_t GetMaskBits() const { return mask_bits_; }
|
||||
/// \~chinese
|
||||
/// @brief 获取碰撞掩码
|
||||
uint16_t GetMaskBits() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置碰撞掩码
|
||||
void SetMaskBits(uint16_t mask_bits);
|
||||
|
||||
// 莉乞多
|
||||
int16_t GetGroupIndex() const { return group_index_; }
|
||||
/// \~chinese
|
||||
/// @brief 获取组索引
|
||||
int16_t GetGroupIndex() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置组索引
|
||||
void SetGroupIndex(int16_t index);
|
||||
|
||||
// 旗瘻실똑
|
||||
float GetBodyRotation() const { KGE_ASSERT(body_); return math::Radian2Degree(body_->GetAngle()); }
|
||||
void SetBodyRotation(float angle) { SetBodyTransform(GetBodyPosition(), angle); }
|
||||
/// \~chinese
|
||||
/// @brief 获取旋转角度
|
||||
float GetBodyRotation() const;
|
||||
|
||||
// 貫零
|
||||
/// \~chinese
|
||||
/// @brief 设置旋转角度
|
||||
void SetBodyRotation(float angle);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取物体位置
|
||||
Point GetBodyPosition() const;
|
||||
void SetBodyPosition(Point const& pos) { SetBodyTransform(pos, GetBodyRotation()); }
|
||||
|
||||
// 貫零뵨旗瘻긴뻣
|
||||
/// \~chinese
|
||||
/// @brief 设置物体位置
|
||||
void SetBodyPosition(Point const& pos);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 位置和旋转变换
|
||||
void SetBodyTransform(Point const& pos, float angle);
|
||||
|
||||
// 醴좆
|
||||
float GetMass() const { KGE_ASSERT(body_); return body_->GetMass(); }
|
||||
/// \~chinese
|
||||
/// @brief 获取质量 [kg]
|
||||
float GetMass() const;
|
||||
|
||||
// 발昑
|
||||
float GetInertia() const { KGE_ASSERT(body_); return body_->GetInertia(); }
|
||||
/// \~chinese
|
||||
/// @brief 获取惯性
|
||||
float GetInertia() const;
|
||||
|
||||
// 醴좆鑒앴
|
||||
/// \~chinese
|
||||
/// @brief 获取质量数据
|
||||
/// @param[out] mass 物体质量 [kg]
|
||||
/// @param[out] center 质心位置
|
||||
/// @param[out] inertia 惯性
|
||||
void GetMassData(float* mass, Point* center, float* inertia) const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置质量数据
|
||||
/// @param mass 物体质量 [kg]
|
||||
/// @param center 质心位置
|
||||
/// @param inertia 惯性
|
||||
void SetMassData(float mass, Point const& center, float inertia);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 重置质量数据
|
||||
void ResetMassData();
|
||||
|
||||
// 麟깃瘻뻣
|
||||
/// \~chinese
|
||||
/// @brief 获取世界坐标系上的点在物体上的位置
|
||||
Point GetLocalPoint(Point const& world) const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取物体上的点在世界坐标系的位置
|
||||
Point GetWorldPoint(Point const& local) const;
|
||||
|
||||
// 醴懃麟깃
|
||||
/// \~chinese
|
||||
/// @brief 获取物体质心相对于物体的位置
|
||||
Point GetLocalCenter() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取物体质心位置
|
||||
Point GetWorldCenter() const;
|
||||
|
||||
// 膠竟잚謹
|
||||
Type GetType() const { KGE_ASSERT(body_); return Type(body_->GetType()); }
|
||||
void SetType(Type type) { KGE_ASSERT(body_); body_->SetType(static_cast<b2BodyType>(type)); }
|
||||
/// \~chinese
|
||||
/// @brief 获取物体类型
|
||||
Type GetType() const;
|
||||
|
||||
// 路제凜綾
|
||||
float GetGravityScale() const { KGE_ASSERT(body_); return body_->GetGravityScale(); }
|
||||
void SetGravityScale(float scale) { KGE_ASSERT(body_); body_->SetGravityScale(scale); }
|
||||
/// \~chinese
|
||||
/// @brief 设置物体类型
|
||||
void SetType(Type type);
|
||||
|
||||
// 嘉제
|
||||
/// \~chinese
|
||||
/// @brief 获取物体受重力的比例
|
||||
float GetGravityScale() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置物体受重力的比例
|
||||
void SetGravityScale(float scale);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 施力
|
||||
/// @param force 力的大小和方向
|
||||
/// @param point 施力点
|
||||
/// @param wake 是否唤醒物体
|
||||
void ApplyForce(Vec2 const& force, Point const& point, bool wake = true);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 给物体中心施力
|
||||
/// @param force 力的大小和方向
|
||||
/// @param wake 是否唤醒物体
|
||||
void ApplyForceToCenter(Vec2 const& force, bool wake = true);
|
||||
|
||||
// 嘉속큉앤
|
||||
void ApplyTorque(float torque, bool wake = true);
|
||||
/// \~chinese
|
||||
/// @brief 施加扭矩
|
||||
/// @param torque 扭矩
|
||||
/// @param wake 是否唤醒物体
|
||||
void ApplyTorque(float torque, bool wake = false);
|
||||
|
||||
// 미땍旗瘻
|
||||
bool IsIgnoreRotation() const { KGE_ASSERT(body_); return body_->IsFixedRotation(); }
|
||||
void SetIgnoreRotation(bool flag) { KGE_ASSERT(body_); body_->SetFixedRotation(flag); }
|
||||
/// \~chinese
|
||||
/// @brief 旋转角度是否固定
|
||||
bool IsIgnoreRotation() const;
|
||||
|
||||
// 綾뎐
|
||||
bool IsBullet() const { KGE_ASSERT(body_); return body_->IsBullet(); }
|
||||
void SetBullet(bool flag) { KGE_ASSERT(body_); body_->SetBullet(flag); }
|
||||
/// \~chinese
|
||||
/// @brief 设置是否固定旋转角度
|
||||
void SetIgnoreRotation(bool flag);
|
||||
|
||||
// 金추
|
||||
bool IsAwake() const { KGE_ASSERT(body_); return body_->IsAwake(); }
|
||||
void SetAwake(bool flag) { KGE_ASSERT(body_); body_->SetAwake(flag); }
|
||||
bool IsSleepingAllowed() const { KGE_ASSERT(body_); return body_->IsSleepingAllowed(); }
|
||||
void SetSleepingAllowed(bool flag) { KGE_ASSERT(body_); body_->SetSleepingAllowed(flag); }
|
||||
/// \~chinese
|
||||
/// @brief 是否是子弹物体
|
||||
bool IsBullet() const;
|
||||
|
||||
// 삶땡榴檄
|
||||
bool IsActive() const { KGE_ASSERT(body_); return body_->IsActive(); }
|
||||
void SetActive(bool flag) { KGE_ASSERT(body_); body_->SetActive(flag); }
|
||||
/// \~chinese
|
||||
/// @brief 设置物体是否是子弹物体
|
||||
void SetBullet(bool flag);
|
||||
|
||||
Actor* GetActor() const { return actor_; }
|
||||
void SetActor(Actor* actor) { actor_ = actor; }
|
||||
/// \~chinese
|
||||
/// @brief 是否处于唤醒状态
|
||||
bool IsAwake() const;
|
||||
|
||||
b2Body* GetB2Body() { return body_; }
|
||||
const b2Body* GetB2Body() const { return body_; }
|
||||
void SetB2Body(b2Body* body);
|
||||
/// \~chinese
|
||||
/// @brief 设置唤醒状态
|
||||
void SetAwake(bool flag);
|
||||
|
||||
World* GetWorld() { return world_; }
|
||||
const World* GetWorld() const { return world_; }
|
||||
/// \~chinese
|
||||
/// @brief 是否启用休眠
|
||||
bool IsSleepingAllowed() const;
|
||||
|
||||
void Destroy();
|
||||
/// \~chinese
|
||||
/// @brief 设置是否允许休眠
|
||||
void SetSleepingAllowed(bool flag);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 是否启用
|
||||
bool IsActive() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置启用状态
|
||||
void SetActive(bool flag);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取物体所在物理世界
|
||||
World* GetWorld() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取物体绑定的角色
|
||||
Actor* GetActor() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置物体绑定的角色
|
||||
void SetActor(Actor* actor);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 将物体信息更新到角色
|
||||
void UpdateActor();
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 将角色信息更新到物体
|
||||
void UpdateFromActor();
|
||||
|
||||
b2Body* GetB2Body() const;
|
||||
void SetB2Body(b2Body* body);
|
||||
|
||||
private:
|
||||
/// \~chinese
|
||||
/// @brief 销毁物体
|
||||
void UpdateFixtureFilter(b2Fixture* fixture);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 销毁物体
|
||||
void Destroy();
|
||||
|
||||
private:
|
||||
Actor* actor_;
|
||||
World* world_;
|
||||
|
|
@ -173,5 +316,65 @@ namespace kiwano
|
|||
uint16_t mask_bits_;
|
||||
int16_t group_index_;
|
||||
};
|
||||
|
||||
/** @} */
|
||||
|
||||
inline Body::Body(World* world, ActorPtr actor) : Body(world, actor.get()) {}
|
||||
|
||||
inline FixtureList Body::GetFixtureList() const { KGE_ASSERT(body_); return FixtureList(Fixture(body_->GetFixtureList())); }
|
||||
|
||||
inline ContactEdgeList Body::GetContactList() const { KGE_ASSERT(body_); return ContactEdgeList(ContactEdge(body_->GetContactList())); }
|
||||
|
||||
inline uint16_t Body::GetCategoryBits() const { return category_bits_; }
|
||||
|
||||
inline uint16_t Body::GetMaskBits() const { return mask_bits_; }
|
||||
|
||||
inline int16_t Body::GetGroupIndex() const { return group_index_; }
|
||||
|
||||
inline float Body::GetBodyRotation() const { KGE_ASSERT(body_); return math::Radian2Degree(body_->GetAngle()); }
|
||||
|
||||
inline void Body::SetBodyRotation(float angle) { SetBodyTransform(GetBodyPosition(), angle); }
|
||||
|
||||
inline void Body::SetBodyPosition(Point const& pos) { SetBodyTransform(pos, GetBodyRotation()); }
|
||||
|
||||
inline float Body::GetMass() const { KGE_ASSERT(body_); return body_->GetMass(); }
|
||||
|
||||
inline float Body::GetInertia() const { KGE_ASSERT(body_); return body_->GetInertia(); }
|
||||
|
||||
inline Body::Type Body::GetType() const { KGE_ASSERT(body_); return Type(body_->GetType()); }
|
||||
|
||||
inline void Body::SetType(Type type) { KGE_ASSERT(body_); body_->SetType(static_cast<b2BodyType>(type)); }
|
||||
|
||||
inline float Body::GetGravityScale() const { KGE_ASSERT(body_); return body_->GetGravityScale(); }
|
||||
|
||||
inline void Body::SetGravityScale(float scale) { KGE_ASSERT(body_); body_->SetGravityScale(scale); }
|
||||
|
||||
inline bool Body::IsIgnoreRotation() const { KGE_ASSERT(body_); return body_->IsFixedRotation(); }
|
||||
|
||||
inline void Body::SetIgnoreRotation(bool flag) { KGE_ASSERT(body_); body_->SetFixedRotation(flag); }
|
||||
|
||||
inline bool Body::IsBullet() const { KGE_ASSERT(body_); return body_->IsBullet(); }
|
||||
|
||||
inline void Body::SetBullet(bool flag) { KGE_ASSERT(body_); body_->SetBullet(flag); }
|
||||
|
||||
inline bool Body::IsAwake() const { KGE_ASSERT(body_); return body_->IsAwake(); }
|
||||
|
||||
inline void Body::SetAwake(bool flag) { KGE_ASSERT(body_); body_->SetAwake(flag); }
|
||||
|
||||
inline bool Body::IsSleepingAllowed() const { KGE_ASSERT(body_); return body_->IsSleepingAllowed(); }
|
||||
|
||||
inline void Body::SetSleepingAllowed(bool flag) { KGE_ASSERT(body_); body_->SetSleepingAllowed(flag); }
|
||||
|
||||
inline bool Body::IsActive() const { KGE_ASSERT(body_); return body_->IsActive(); }
|
||||
|
||||
inline void Body::SetActive(bool flag) { KGE_ASSERT(body_); body_->SetActive(flag); }
|
||||
|
||||
inline Actor* Body::GetActor() const { return actor_; }
|
||||
|
||||
inline void Body::SetActor(Actor* actor) { actor_ = actor; }
|
||||
|
||||
inline b2Body* Body::GetB2Body() const { return body_; }
|
||||
|
||||
inline World* Body::GetWorld() const { return world_; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,40 +38,26 @@ namespace kiwano
|
|||
SetB2Contact(contact);
|
||||
}
|
||||
|
||||
Contact Contact::GetNext()
|
||||
{
|
||||
KGE_ASSERT(contact_);
|
||||
return Contact(contact_->GetNext());
|
||||
}
|
||||
|
||||
const Contact Contact::GetNext() const
|
||||
{
|
||||
KGE_ASSERT(contact_);
|
||||
return Contact(contact_->GetNext());
|
||||
}
|
||||
|
||||
Fixture Contact::GetFixtureA()
|
||||
Fixture Contact::GetFixtureA() const
|
||||
{
|
||||
KGE_ASSERT(contact_);
|
||||
return Fixture(contact_->GetFixtureA());
|
||||
}
|
||||
|
||||
const Fixture Contact::GetFixtureA() const
|
||||
{
|
||||
KGE_ASSERT(contact_);
|
||||
return Fixture(contact_->GetFixtureA());
|
||||
}
|
||||
|
||||
Fixture Contact::GetFixtureB()
|
||||
Fixture Contact::GetFixtureB() const
|
||||
{
|
||||
KGE_ASSERT(contact_);
|
||||
return Fixture(contact_->GetFixtureB());
|
||||
}
|
||||
|
||||
const Fixture Contact::GetFixtureB() const
|
||||
Body* Contact::GetBodyA() const
|
||||
{
|
||||
KGE_ASSERT(contact_);
|
||||
return Fixture(contact_->GetFixtureB());
|
||||
return GetFixtureA().GetBody();
|
||||
}
|
||||
|
||||
Body* Contact::GetBodyB() const
|
||||
{
|
||||
return GetFixtureB().GetBody();
|
||||
}
|
||||
|
||||
void Contact::SetTangentSpeed(float speed)
|
||||
|
|
|
|||
|
|
@ -28,85 +28,183 @@ namespace kiwano
|
|||
{
|
||||
class Body;
|
||||
|
||||
// 接触
|
||||
/**
|
||||
* \addtogroup Physics
|
||||
* @{
|
||||
*/
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 物理接触
|
||||
class KGE_API Contact
|
||||
{
|
||||
public:
|
||||
Contact();
|
||||
Contact(b2Contact* contact);
|
||||
|
||||
// 是否是接触
|
||||
bool IsTouching() const { KGE_ASSERT(contact_); return contact_->IsTouching(); }
|
||||
|
||||
// 启用或禁用 (仅作用于一个时间步)
|
||||
void SetEnabled(bool flag) { KGE_ASSERT(contact_); contact_->SetEnabled(flag); }
|
||||
bool IsEnabled() const { KGE_ASSERT(contact_); return contact_->IsEnabled(); }
|
||||
/// \~chinese
|
||||
/// @brief 是否有效
|
||||
bool IsValid() const;
|
||||
|
||||
// 获取下一接触
|
||||
Contact GetNext();
|
||||
const Contact GetNext() const;
|
||||
/// \~chinese
|
||||
/// @brief 是否是接触
|
||||
bool IsTouching() const;
|
||||
|
||||
// 夹具 A
|
||||
Fixture GetFixtureA();
|
||||
const Fixture GetFixtureA() const;
|
||||
/// \~chinese
|
||||
/// @brief 启用或禁用 (仅作用于一个时间步)
|
||||
void SetEnabled(bool flag);
|
||||
|
||||
// 夹具 B
|
||||
Fixture GetFixtureB();
|
||||
const Fixture GetFixtureB() const;
|
||||
/// \~chinese
|
||||
/// @brief 是否启用
|
||||
bool IsEnabled() const;
|
||||
|
||||
// 摩擦
|
||||
void SetFriction(float friction) { KGE_ASSERT(contact_); contact_->SetFriction(friction); }
|
||||
float GetFriction() const { KGE_ASSERT(contact_); return contact_->GetFriction(); }
|
||||
void ResetFriction() { KGE_ASSERT(contact_); contact_->ResetFriction(); }
|
||||
/// \~chinese
|
||||
/// @brief 获取物体A的夹具
|
||||
Fixture GetFixtureA() const;
|
||||
|
||||
// 弹性恢复
|
||||
void SetRestitution(float restitution) { KGE_ASSERT(contact_); contact_->SetRestitution(restitution); }
|
||||
float GetRestitution() const { KGE_ASSERT(contact_); return contact_->GetRestitution(); }
|
||||
void ResetRestitution() { KGE_ASSERT(contact_); contact_->ResetRestitution(); }
|
||||
/// \~chinese
|
||||
/// @brief 获取物体B的夹具
|
||||
Fixture GetFixtureB() const;
|
||||
|
||||
// 切线速度
|
||||
/// \~chinese
|
||||
/// @brief 获取物体A
|
||||
Body* GetBodyA() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取物体B
|
||||
Body* GetBodyB() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置摩擦力
|
||||
void SetFriction(float friction);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取摩擦力
|
||||
float GetFriction() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 重置摩擦力
|
||||
void ResetFriction();
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置弹性恢复
|
||||
void SetRestitution(float restitution);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取弹性恢复
|
||||
float GetRestitution() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 重置弹性恢复
|
||||
void ResetRestitution();
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置切线速度
|
||||
void SetTangentSpeed(float speed);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取切线速度
|
||||
float GetTangentSpeed() const;
|
||||
|
||||
b2Contact* GetB2Contact() { return contact_; }
|
||||
const b2Contact* GetB2Contact() const { return contact_; }
|
||||
void SetB2Contact(b2Contact* contact) { contact_ = contact; }
|
||||
b2Contact* GetB2Contact() const;
|
||||
void SetB2Contact(b2Contact* contact);
|
||||
|
||||
private:
|
||||
b2Contact* contact_;
|
||||
};
|
||||
|
||||
|
||||
// 接触边
|
||||
/// \~chinese
|
||||
/// @brief 接触边
|
||||
class KGE_API ContactEdge
|
||||
{
|
||||
public:
|
||||
ContactEdge();
|
||||
ContactEdge(b2ContactEdge* edge);
|
||||
|
||||
// 获取接触物体
|
||||
Body* GetOtherBody() { KGE_ASSERT(edge_); return static_cast<Body*>(edge_->other->GetUserData()); }
|
||||
const Body* GetOtherBody() const { KGE_ASSERT(edge_); return static_cast<Body*>(edge_->other->GetUserData()); }
|
||||
/// \~chinese
|
||||
/// @brief 是否有效
|
||||
bool IsValid() const;
|
||||
|
||||
// 获取接触
|
||||
Contact GetContact() { KGE_ASSERT(edge_); return Contact(edge_->contact); }
|
||||
const Contact GetContact() const { KGE_ASSERT(edge_); return Contact(edge_->contact); }
|
||||
/// \~chinese
|
||||
/// @brief 获取接触物体
|
||||
Body* GetOtherBody() const;
|
||||
|
||||
// 获取上一接触边
|
||||
ContactEdge GetPrev() { KGE_ASSERT(edge_); return ContactEdge(edge_->prev); }
|
||||
const ContactEdge GetPrev() const { KGE_ASSERT(edge_); return ContactEdge(edge_->prev); }
|
||||
/// \~chinese
|
||||
/// @brief 获取接触
|
||||
Contact GetContact() const;
|
||||
|
||||
// 获取下一接触边
|
||||
ContactEdge GetNext() { KGE_ASSERT(edge_); return ContactEdge(edge_->next); }
|
||||
const ContactEdge GetNext() const { KGE_ASSERT(edge_); return ContactEdge(edge_->next); }
|
||||
|
||||
b2ContactEdge* GetB2ContactEdge() { return edge_; }
|
||||
const b2ContactEdge* GetB2ContactEdge() const { return edge_; }
|
||||
void SetB2ContactEdge(b2ContactEdge* edge) { edge_ = edge; }
|
||||
b2ContactEdge* GetB2ContactEdge() const;
|
||||
void SetB2ContactEdge(b2ContactEdge* edge);
|
||||
|
||||
private:
|
||||
b2ContactEdge* edge_;
|
||||
};
|
||||
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 物理接触列表
|
||||
class ContactList
|
||||
: public List<Contact>
|
||||
{
|
||||
public:
|
||||
ContactList()
|
||||
{
|
||||
}
|
||||
|
||||
ContactList(const Contact& first)
|
||||
{
|
||||
Contact current = first;
|
||||
while (current.GetB2Contact())
|
||||
{
|
||||
push_back(current);
|
||||
current = current.GetB2Contact()->GetNext();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 物理接触边列表
|
||||
class ContactEdgeList
|
||||
: public List<ContactEdge>
|
||||
{
|
||||
public:
|
||||
ContactEdgeList()
|
||||
{
|
||||
}
|
||||
|
||||
ContactEdgeList(const ContactEdge& first)
|
||||
{
|
||||
ContactEdge current = first;
|
||||
while (current.GetB2ContactEdge())
|
||||
{
|
||||
push_back(current);
|
||||
current = current.GetB2ContactEdge()->next;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
inline bool Contact::IsValid() const { return contact_ != nullptr;}
|
||||
inline bool Contact::IsTouching() const { KGE_ASSERT(contact_); return contact_->IsTouching(); }
|
||||
inline void Contact::SetEnabled(bool flag) { KGE_ASSERT(contact_); contact_->SetEnabled(flag); }
|
||||
inline bool Contact::IsEnabled() const { KGE_ASSERT(contact_); return contact_->IsEnabled(); }
|
||||
inline void Contact::SetFriction(float friction) { KGE_ASSERT(contact_); contact_->SetFriction(friction); }
|
||||
inline float Contact::GetFriction() const { KGE_ASSERT(contact_); return contact_->GetFriction(); }
|
||||
inline void Contact::ResetFriction() { KGE_ASSERT(contact_); contact_->ResetFriction(); }
|
||||
inline void Contact::SetRestitution(float restitution) { KGE_ASSERT(contact_); contact_->SetRestitution(restitution); }
|
||||
inline float Contact::GetRestitution() const { KGE_ASSERT(contact_); return contact_->GetRestitution(); }
|
||||
inline void Contact::ResetRestitution() { KGE_ASSERT(contact_); contact_->ResetRestitution(); }
|
||||
inline b2Contact* Contact::GetB2Contact() const { return contact_; }
|
||||
inline void Contact::SetB2Contact(b2Contact* contact) { contact_ = contact; }
|
||||
|
||||
inline bool ContactEdge::IsValid() const { return edge_ != nullptr; }
|
||||
inline Body* ContactEdge::GetOtherBody() const { KGE_ASSERT(edge_); return static_cast<Body*>(edge_->other->GetUserData()); }
|
||||
inline Contact ContactEdge::GetContact() const { KGE_ASSERT(edge_); return Contact(edge_->contact); }
|
||||
inline b2ContactEdge* ContactEdge::GetB2ContactEdge() const { return edge_; }
|
||||
inline void ContactEdge::SetB2ContactEdge(b2ContactEdge* edge) { edge_ = edge; }
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,8 +26,6 @@ namespace kiwano
|
|||
{
|
||||
ContactBeginEvent::ContactBeginEvent()
|
||||
: Event(KGE_EVENT(ContactBeginEvent))
|
||||
, body_a(nullptr)
|
||||
, body_b(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -35,14 +33,10 @@ namespace kiwano
|
|||
: ContactBeginEvent()
|
||||
{
|
||||
this->contact = contact;
|
||||
body_a = this->contact.GetFixtureA().GetBody();
|
||||
body_b = this->contact.GetFixtureB().GetBody();
|
||||
}
|
||||
|
||||
ContactEndEvent::ContactEndEvent()
|
||||
: Event(KGE_EVENT(ContactEndEvent))
|
||||
, body_a(nullptr)
|
||||
, body_b(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -50,8 +44,6 @@ namespace kiwano
|
|||
: ContactEndEvent()
|
||||
{
|
||||
this->contact = contact;
|
||||
body_a = this->contact.GetFixtureA().GetBody();
|
||||
body_b = this->contact.GetFixtureB().GetBody();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,10 +38,9 @@ namespace kiwano
|
|||
{
|
||||
public:
|
||||
Contact contact; ///< 产生的接触
|
||||
Body* body_a; ///< 产生接触的物体A
|
||||
Body* body_b; ///< 产生接触的物体B
|
||||
|
||||
ContactBeginEvent();
|
||||
|
||||
ContactBeginEvent(Contact const& contact);
|
||||
};
|
||||
|
||||
|
|
@ -52,10 +51,9 @@ namespace kiwano
|
|||
{
|
||||
public:
|
||||
Contact contact; ///< 产生的接触
|
||||
Body* body_a; ///< 产生接触的物体A
|
||||
Body* body_b; ///< 产生接触的物体B
|
||||
|
||||
ContactEndEvent();
|
||||
|
||||
ContactEndEvent(Contact const& contact);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -58,30 +58,18 @@ namespace kiwano
|
|||
}
|
||||
}
|
||||
|
||||
Body* Fixture::GetBody()
|
||||
Body* Fixture::GetBody() const
|
||||
{
|
||||
KGE_ASSERT(fixture_);
|
||||
return static_cast<Body*>(fixture_->GetBody()->GetUserData());
|
||||
}
|
||||
|
||||
const Body* Fixture::GetBody() const
|
||||
{
|
||||
KGE_ASSERT(fixture_);
|
||||
return static_cast<const Body*>(fixture_->GetBody()->GetUserData());
|
||||
}
|
||||
|
||||
Shape Fixture::GetShape() const
|
||||
{
|
||||
KGE_ASSERT(fixture_);
|
||||
return Shape(fixture_->GetShape());
|
||||
}
|
||||
|
||||
Fixture Fixture::GetNext() const
|
||||
{
|
||||
KGE_ASSERT(fixture_);
|
||||
return Fixture(fixture_->GetNext());
|
||||
}
|
||||
|
||||
void Fixture::GetMassData(float* mass, Point* center, float* inertia) const
|
||||
{
|
||||
KGE_ASSERT(fixture_);
|
||||
|
|
|
|||
|
|
@ -28,16 +28,24 @@ namespace kiwano
|
|||
{
|
||||
class Body;
|
||||
|
||||
// 夹具
|
||||
/**
|
||||
* \addtogroup Physics
|
||||
* @{
|
||||
*/
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 物理夹具
|
||||
class Fixture
|
||||
{
|
||||
public:
|
||||
/// \~chinese
|
||||
/// @brief 夹具参数
|
||||
struct Param
|
||||
{
|
||||
float density = 0.f;
|
||||
float friction = 0.2f;
|
||||
float restitution = 0.f;
|
||||
bool is_sensor = false;
|
||||
float density = 0.f; ///< 密度
|
||||
float friction = 0.2f; ///< 摩擦力
|
||||
float restitution = 0.f; ///< 弹性恢复
|
||||
bool is_sensor = false; ///< 是否是接触传感器
|
||||
|
||||
Param() {}
|
||||
|
||||
|
|
@ -53,46 +61,99 @@ namespace kiwano
|
|||
Fixture(b2Fixture* fixture);
|
||||
Fixture(Body* body, Shape* shape, const Param& param);
|
||||
|
||||
// 物体
|
||||
Body* GetBody();
|
||||
const Body* GetBody() const;
|
||||
/// \~chinese
|
||||
/// @brief 是否有效
|
||||
bool IsValid() const;
|
||||
|
||||
// 形状
|
||||
/// \~chinese
|
||||
/// @brief 获取夹具所在的物体
|
||||
Body* GetBody() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 形状
|
||||
Shape GetShape() const;
|
||||
|
||||
// 下一夹具 (同一物体上)
|
||||
Fixture GetNext() const;
|
||||
/// \~chinese
|
||||
/// @brief 是否是接触传感器
|
||||
bool IsSensor() const;
|
||||
|
||||
// 接触传感器
|
||||
bool IsSensor() const { KGE_ASSERT(fixture_); return fixture_->IsSensor(); }
|
||||
void SetSensor(bool sensor) { KGE_ASSERT(fixture_); fixture_->SetSensor(sensor); }
|
||||
/// \~chinese
|
||||
/// @brief 设置夹具是否是接触传感器
|
||||
/// @details 接触传感器只会产生物理接触,而不会影响物体运动
|
||||
void SetSensor(bool sensor);
|
||||
|
||||
// 质量数据
|
||||
/// \~chinese
|
||||
/// @brief 获取夹具的质量数据
|
||||
void GetMassData(float* mass, Point* center, float* inertia) const;
|
||||
|
||||
// 密度
|
||||
float GetDensity() const { KGE_ASSERT(fixture_); return fixture_->GetDensity(); }
|
||||
void SetDensity(float density) { KGE_ASSERT(fixture_); fixture_->SetDensity(density); }
|
||||
/// \~chinese
|
||||
/// @brief 获取密度
|
||||
float GetDensity() const;
|
||||
|
||||
// 摩擦力
|
||||
float GetFriction() const { KGE_ASSERT(fixture_); return fixture_->GetFriction(); }
|
||||
void SetFriction(float friction) { KGE_ASSERT(fixture_); fixture_->SetFriction(friction); }
|
||||
/// \~chinese
|
||||
/// @brief 设置密度
|
||||
void SetDensity(float density);
|
||||
|
||||
// 弹性恢复
|
||||
float GetRestitution() const { KGE_ASSERT(fixture_); return fixture_->GetRestitution(); }
|
||||
void SetRestitution(float restitution) { KGE_ASSERT(fixture_); fixture_->SetRestitution(restitution); }
|
||||
/// \~chinese
|
||||
/// @brief 获取摩擦力 [N]
|
||||
float GetFriction() const;
|
||||
|
||||
// 点测试
|
||||
/// \~chinese
|
||||
/// @brief 设置摩擦力 [N]
|
||||
void SetFriction(float friction);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取弹性恢复
|
||||
float GetRestitution() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置弹性恢复
|
||||
void SetRestitution(float restitution);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 点测试
|
||||
bool TestPoint(const Point& p) const;
|
||||
|
||||
bool IsValid() const { return !!fixture_; }
|
||||
|
||||
b2Fixture* GetB2Fixture() { return fixture_; }
|
||||
const b2Fixture* GetB2Fixture() const { return fixture_; }
|
||||
void SetB2Fixture(b2Fixture* fixture) { fixture_ = fixture; }
|
||||
b2Fixture* GetB2Fixture() const;
|
||||
void SetB2Fixture(b2Fixture* fixture);
|
||||
|
||||
private:
|
||||
b2Fixture* fixture_;
|
||||
};
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 物理夹具列表
|
||||
class FixtureList
|
||||
: public List<Fixture>
|
||||
{
|
||||
public:
|
||||
FixtureList()
|
||||
{
|
||||
}
|
||||
|
||||
FixtureList(const Fixture& first)
|
||||
{
|
||||
Fixture current = first;
|
||||
while (current.GetB2Fixture())
|
||||
{
|
||||
push_back(current);
|
||||
current = current.GetB2Fixture()->GetNext();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/** @} */
|
||||
|
||||
inline bool Fixture::IsSensor() const { KGE_ASSERT(fixture_); return fixture_->IsSensor(); }
|
||||
inline void Fixture::SetSensor(bool sensor) { KGE_ASSERT(fixture_); fixture_->SetSensor(sensor); }
|
||||
inline float Fixture::GetDensity() const { KGE_ASSERT(fixture_); return fixture_->GetDensity(); }
|
||||
inline void Fixture::SetDensity(float density) { KGE_ASSERT(fixture_); fixture_->SetDensity(density); }
|
||||
inline float Fixture::GetFriction() const { KGE_ASSERT(fixture_); return fixture_->GetFriction(); }
|
||||
inline void Fixture::SetFriction(float friction) { KGE_ASSERT(fixture_); fixture_->SetFriction(friction); }
|
||||
inline float Fixture::GetRestitution() const { KGE_ASSERT(fixture_); return fixture_->GetRestitution(); }
|
||||
inline void Fixture::SetRestitution(float restitution) { KGE_ASSERT(fixture_); fixture_->SetRestitution(restitution); }
|
||||
inline bool Fixture::IsValid() const { return fixture_ != nullptr; }
|
||||
inline b2Fixture* Fixture::GetB2Fixture() const { return fixture_; }
|
||||
inline void Fixture::SetB2Fixture(b2Fixture* fixture) { fixture_ = fixture; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -260,6 +260,7 @@ namespace kiwano
|
|||
def.Initialize(param.body_a->GetB2Body(), param.body_b->GetB2Body());
|
||||
def.maxForce = param.max_force;
|
||||
def.maxTorque = world->Stage2World(param.max_torque);
|
||||
def.correctionFactor = param.correction_factor;
|
||||
|
||||
Init(world, &def);
|
||||
raw_joint_ = static_cast<b2MotorJoint*>(GetB2Joint());
|
||||
|
|
|
|||
|
|
@ -39,34 +39,51 @@ namespace kiwano
|
|||
KGE_DECLARE_SMART_PTR(WeldJoint);
|
||||
KGE_DECLARE_SMART_PTR(WheelJoint);
|
||||
|
||||
// 关节
|
||||
/**
|
||||
* \addtogroup Physics
|
||||
* @{
|
||||
*/
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 关节
|
||||
class KGE_API Joint
|
||||
: public virtual RefCounter
|
||||
{
|
||||
public:
|
||||
/// \~chinese
|
||||
/// @brief 关节类型
|
||||
enum class Type
|
||||
{
|
||||
Unknown = 0,
|
||||
Revolute,
|
||||
Prismatic,
|
||||
Distance,
|
||||
Pulley,
|
||||
Mouse,
|
||||
Gear,
|
||||
Wheel,
|
||||
Weld,
|
||||
Friction,
|
||||
Rope,
|
||||
Motor
|
||||
Unknown = 0, ///< 未知
|
||||
Revolute, ///< 旋转关节
|
||||
Prismatic, ///< 平移关节
|
||||
Distance, ///< 固定距离关节
|
||||
Pulley, ///< 滑轮关节
|
||||
Mouse, ///< 鼠标关节
|
||||
Gear, ///< 齿轮关节
|
||||
Wheel, ///< 轮关节
|
||||
Weld, ///< 焊接关节
|
||||
Friction, ///< 摩擦关节
|
||||
Rope, ///< 绳关节
|
||||
Motor ///< 马达关节
|
||||
};
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 关节基础参数
|
||||
struct ParamBase
|
||||
{
|
||||
Body* body_a;
|
||||
Body* body_b;
|
||||
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()) {}
|
||||
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();
|
||||
|
|
@ -76,15 +93,20 @@ namespace kiwano
|
|||
|
||||
void Init(World* world, b2JointDef* joint_def);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取关节连接的物体A
|
||||
BodyPtr GetBodyA() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取关节连接的物体B
|
||||
BodyPtr GetBodyB() const;
|
||||
|
||||
b2Joint* GetB2Joint() { return joint_; }
|
||||
const b2Joint* GetB2Joint() const { return joint_; }
|
||||
void SetB2Joint(b2Joint* joint);
|
||||
/// \~chinese
|
||||
/// @brief 获取物理世界
|
||||
World* GetWorld() const;
|
||||
|
||||
World* GetWorld() { return world_; }
|
||||
const World* GetWorld() const { return world_; }
|
||||
b2Joint* GetB2Joint() const;
|
||||
void SetB2Joint(b2Joint* joint);
|
||||
|
||||
private:
|
||||
b2Joint* joint_;
|
||||
|
|
@ -93,17 +115,20 @@ namespace kiwano
|
|||
};
|
||||
|
||||
|
||||
// 固定距离关节
|
||||
/// \~chinese
|
||||
/// @brief 固定距离关节
|
||||
class KGE_API DistanceJoint
|
||||
: public Joint
|
||||
{
|
||||
public:
|
||||
/// \~chinese
|
||||
/// @brief 固定距离关节参数
|
||||
struct Param : public Joint::ParamBase
|
||||
{
|
||||
Point anchor_a;
|
||||
Point anchor_b;
|
||||
float frequency_hz;
|
||||
float damping_ratio;
|
||||
Point anchor_a; ///< 物体A的锚点位置
|
||||
Point anchor_b; ///< 物体B的锚点位置
|
||||
float frequency_hz; ///< 弹簧阻尼器频率
|
||||
float damping_ratio; ///< 阻尼比
|
||||
|
||||
Param(
|
||||
Body* body_a,
|
||||
|
|
@ -136,23 +161,28 @@ namespace kiwano
|
|||
DistanceJoint(World* world, b2DistanceJointDef* def);
|
||||
DistanceJoint(World* world, Param const& param);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置关节长度
|
||||
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(); }
|
||||
/// \~chinese
|
||||
/// @brief 设置弹簧阻尼器频率 [赫兹]
|
||||
void SetFrequency(float hz);
|
||||
float GetFrequency() const;
|
||||
|
||||
// 设置阻尼比
|
||||
void SetDampingRatio(float ratio) { KGE_ASSERT(raw_joint_); raw_joint_->SetDampingRatio(ratio); }
|
||||
float GetDampingRatio() const { KGE_ASSERT(raw_joint_); return raw_joint_->GetDampingRatio(); }
|
||||
/// \~chinese
|
||||
/// @brief 设置阻尼比
|
||||
void SetDampingRatio(float ratio);
|
||||
float GetDampingRatio() const;
|
||||
|
||||
private:
|
||||
b2DistanceJoint* raw_joint_;
|
||||
};
|
||||
|
||||
|
||||
// 摩擦关节
|
||||
/// \~chinese
|
||||
/// @brief 摩擦关节
|
||||
class KGE_API FrictionJoint
|
||||
: public Joint
|
||||
{
|
||||
|
|
@ -191,11 +221,13 @@ namespace kiwano
|
|||
FrictionJoint(World* world, b2FrictionJointDef* def);
|
||||
FrictionJoint(World* world, Param const& param);
|
||||
|
||||
// 设定最大摩擦力
|
||||
/// \~chinese
|
||||
/// @brief 设定最大摩擦力
|
||||
void SetMaxForce(float force);
|
||||
float GetMaxForce() const;
|
||||
|
||||
// 设定最大转矩
|
||||
/// \~chinese
|
||||
/// @brief 设定最大转矩
|
||||
void SetMaxTorque(float torque);
|
||||
float GetMaxTorque() const;
|
||||
|
||||
|
|
@ -204,16 +236,19 @@ namespace kiwano
|
|||
};
|
||||
|
||||
|
||||
// 齿轮关节
|
||||
/// \~chinese
|
||||
/// @brief 齿轮关节
|
||||
class KGE_API GearJoint
|
||||
: public Joint
|
||||
{
|
||||
public:
|
||||
/// \~chinese
|
||||
/// @brief 齿轮关节参数
|
||||
struct Param : public Joint::ParamBase
|
||||
{
|
||||
JointPtr joint_a;
|
||||
JointPtr joint_b;
|
||||
float ratio;
|
||||
JointPtr joint_a; ///< 关节A
|
||||
JointPtr joint_b; ///< 关节B
|
||||
float ratio; ///< 齿轮传动比
|
||||
|
||||
Param(
|
||||
Joint* joint_a,
|
||||
|
|
@ -239,7 +274,8 @@ namespace kiwano
|
|||
GearJoint(World* world, b2GearJointDef* def);
|
||||
GearJoint(World* world, Param param);
|
||||
|
||||
// 设定齿轮传动比
|
||||
/// \~chinese
|
||||
/// @brief 设定齿轮传动比
|
||||
void SetRatio(float ratio);
|
||||
float GetRatio() const;
|
||||
|
||||
|
|
@ -248,16 +284,19 @@ namespace kiwano
|
|||
};
|
||||
|
||||
|
||||
// 马达关节
|
||||
/// \~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;
|
||||
float max_force; ///< 最大摩擦力
|
||||
float max_torque; ///< 最大转矩
|
||||
float correction_factor; ///< 位置矫正因子(范围 0-1)
|
||||
|
||||
Param(
|
||||
Body* body_a,
|
||||
|
|
@ -287,11 +326,13 @@ namespace kiwano
|
|||
MotorJoint(World* world, b2MotorJointDef* def);
|
||||
MotorJoint(World* world, Param const& param);
|
||||
|
||||
// 设定最大摩擦力
|
||||
/// \~chinese
|
||||
/// @brief 设定最大摩擦力
|
||||
void SetMaxForce(float force);
|
||||
float GetMaxForce() const;
|
||||
|
||||
// 设定最大转矩
|
||||
/// \~chinese
|
||||
/// @brief 设定最大转矩
|
||||
void SetMaxTorque(float torque);
|
||||
float GetMaxTorque() const;
|
||||
|
||||
|
|
@ -300,21 +341,24 @@ namespace kiwano
|
|||
};
|
||||
|
||||
|
||||
// 平移关节
|
||||
/// \~chinese
|
||||
/// @brief 平移关节
|
||||
class KGE_API PrismaticJoint
|
||||
: public Joint
|
||||
{
|
||||
public:
|
||||
/// \~chinese
|
||||
/// @brief 平移关节参数
|
||||
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;
|
||||
Point anchor; ///< 锚点位置
|
||||
Vec2 axis; ///< 平移轴向量
|
||||
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,
|
||||
|
|
@ -359,45 +403,64 @@ namespace kiwano
|
|||
PrismaticJoint(World* world, b2PrismaticJointDef* def);
|
||||
PrismaticJoint(World* world, Param const& param);
|
||||
|
||||
float GetReferenceAngle() const { KGE_ASSERT(raw_joint_); return math::Radian2Degree(raw_joint_->GetReferenceAngle()); }
|
||||
/// \~chinese
|
||||
/// @brief 获取参考角
|
||||
float GetReferenceAngle() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取关节转换
|
||||
float GetJointTranslation() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取关节速度
|
||||
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); }
|
||||
/// \~chinese
|
||||
/// @brief 是否启用关节限制
|
||||
bool IsLimitEnabled() const;
|
||||
void EnableLimit(bool flag);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置关节限制
|
||||
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); }
|
||||
/// \~chinese
|
||||
/// @brief 是否启用马达
|
||||
bool IsMotorEnabled() const;
|
||||
void EnableMotor(bool flag);
|
||||
|
||||
// 设置马达转速 [degree/s]
|
||||
void SetMotorSpeed(float speed) { KGE_ASSERT(raw_joint_); raw_joint_->SetMotorSpeed(math::Degree2Radian(speed)); }
|
||||
float GetMotorSpeed() const { KGE_ASSERT(raw_joint_); return math::Radian2Degree(raw_joint_->GetMotorSpeed()); }
|
||||
/// \~chinese
|
||||
/// @brief 设置马达转速 [degree/s]
|
||||
void SetMotorSpeed(float speed);
|
||||
float GetMotorSpeed() const;
|
||||
|
||||
// 设定最大马达力 [N]
|
||||
void SetMaxMotorForce(float force) { KGE_ASSERT(raw_joint_); raw_joint_->SetMaxMotorForce(force); }
|
||||
float GetMaxMotorForce() const { KGE_ASSERT(raw_joint_); return raw_joint_->GetMaxMotorForce(); }
|
||||
/// \~chinese
|
||||
/// @brief 设定最大马达力 [N]
|
||||
void SetMaxMotorForce(float force);
|
||||
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;
|
||||
Point anchor_b;
|
||||
Point ground_anchor_a;
|
||||
Point ground_anchor_b;
|
||||
float ratio;
|
||||
Point anchor_a; ///<
|
||||
Point anchor_b; ///<
|
||||
Point ground_anchor_a; ///<
|
||||
Point ground_anchor_b; ///<
|
||||
float ratio; ///<
|
||||
|
||||
Param(
|
||||
Body* body_a,
|
||||
|
|
@ -449,7 +512,8 @@ namespace kiwano
|
|||
};
|
||||
|
||||
|
||||
// 旋转关节
|
||||
/// \~chinese
|
||||
/// @brief 旋转关节
|
||||
class KGE_API RevoluteJoint
|
||||
: public Joint
|
||||
{
|
||||
|
|
@ -504,25 +568,27 @@ namespace kiwano
|
|||
RevoluteJoint(World* world, b2RevoluteJointDef* def);
|
||||
RevoluteJoint(World* world, Param const& param);
|
||||
|
||||
float GetReferenceAngle() const { KGE_ASSERT(raw_joint_); return math::Radian2Degree(raw_joint_->GetReferenceAngle()); }
|
||||
float GetReferenceAngle() const;
|
||||
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); }
|
||||
bool IsLimitEnabled() const;
|
||||
void EnableLimit(bool 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); }
|
||||
bool IsMotorEnabled() const;
|
||||
void EnableMotor(bool flag);
|
||||
|
||||
// 设置马达转速 [degree/s]
|
||||
void SetMotorSpeed(float speed) { KGE_ASSERT(raw_joint_); raw_joint_->SetMotorSpeed(math::Degree2Radian(speed)); }
|
||||
float GetMotorSpeed() const { KGE_ASSERT(raw_joint_); return math::Radian2Degree(raw_joint_->GetMotorSpeed()); }
|
||||
/// \~chinese
|
||||
/// @brief 设置马达转速 [degree/s]
|
||||
void SetMotorSpeed(float speed);
|
||||
float GetMotorSpeed() const;
|
||||
|
||||
// 设定最大马达转矩 [N/m]
|
||||
/// \~chinese
|
||||
/// @brief 设定最大马达转矩 [N/m]
|
||||
void SetMaxMotorTorque(float torque);
|
||||
float GetMaxMotorTorque() const;
|
||||
|
||||
|
|
@ -531,7 +597,8 @@ namespace kiwano
|
|||
};
|
||||
|
||||
|
||||
// 绳关节
|
||||
/// \~chinese
|
||||
/// @brief 绳关节
|
||||
class KGE_API RopeJoint
|
||||
: public Joint
|
||||
{
|
||||
|
|
@ -578,7 +645,8 @@ namespace kiwano
|
|||
};
|
||||
|
||||
|
||||
// 焊接关节
|
||||
/// \~chinese
|
||||
/// @brief 焊接关节
|
||||
class KGE_API WeldJoint
|
||||
: public Joint
|
||||
{
|
||||
|
|
@ -617,20 +685,23 @@ namespace kiwano
|
|||
WeldJoint(World* world, b2WeldJointDef* def);
|
||||
WeldJoint(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(); }
|
||||
/// \~chinese
|
||||
/// @brief 设置弹簧阻尼器频率 [赫兹]
|
||||
void SetFrequency(float hz);
|
||||
float GetFrequency() const;
|
||||
|
||||
// 设置阻尼比
|
||||
void SetDampingRatio(float ratio) { KGE_ASSERT(raw_joint_); raw_joint_->SetDampingRatio(ratio); }
|
||||
float GetDampingRatio() const { KGE_ASSERT(raw_joint_); return raw_joint_->GetDampingRatio(); }
|
||||
/// \~chinese
|
||||
/// @brief 设置阻尼比
|
||||
void SetDampingRatio(float ratio);
|
||||
float GetDampingRatio() const;
|
||||
|
||||
private:
|
||||
b2WeldJoint* raw_joint_;
|
||||
};
|
||||
|
||||
|
||||
// 轮关节
|
||||
/// \~chinese
|
||||
/// @brief 轮关节
|
||||
class KGE_API WheelJoint
|
||||
: public Joint
|
||||
{
|
||||
|
|
@ -687,33 +758,36 @@ namespace kiwano
|
|||
|
||||
float GetJointTranslation() const;
|
||||
float GetJointLinearSpeed() const;
|
||||
float GetJointAngle() const { KGE_ASSERT(raw_joint_); return math::Radian2Degree(raw_joint_->GetJointAngle()); }
|
||||
float GetJointAngularSpeed() const { KGE_ASSERT(raw_joint_); return math::Radian2Degree(raw_joint_->GetJointAngularSpeed()); }
|
||||
float GetJointAngle() const;
|
||||
float GetJointAngularSpeed() const;
|
||||
|
||||
bool IsMotorEnabled() const { KGE_ASSERT(raw_joint_); return raw_joint_->IsMotorEnabled(); }
|
||||
void EnableMotor(bool flag) { KGE_ASSERT(raw_joint_); raw_joint_->EnableMotor(flag); }
|
||||
bool IsMotorEnabled() const;
|
||||
void EnableMotor(bool flag);
|
||||
|
||||
// 设置马达转速 [degree/s]
|
||||
void SetMotorSpeed(float speed) { KGE_ASSERT(raw_joint_); raw_joint_->SetMotorSpeed(math::Degree2Radian(speed)); }
|
||||
float GetMotorSpeed() const { KGE_ASSERT(raw_joint_); return math::Radian2Degree(raw_joint_->GetMotorSpeed()); }
|
||||
/// \~chinese
|
||||
/// @brief 设置马达转速 [degree/s]
|
||||
void SetMotorSpeed(float speed);
|
||||
float GetMotorSpeed() const;
|
||||
|
||||
// 设定最大马达转矩 [N/m]
|
||||
/// \~chinese
|
||||
/// @brief 设定最大马达转矩 [N/m]
|
||||
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 SetSpringFrequencyHz(float hz);
|
||||
float GetSpringFrequencyHz() const;
|
||||
|
||||
void SetSpringDampingRatio(float ratio) { KGE_ASSERT(raw_joint_); raw_joint_->SetSpringDampingRatio(ratio); }
|
||||
float GetSpringDampingRatio() const { KGE_ASSERT(raw_joint_); return raw_joint_->GetSpringDampingRatio(); }
|
||||
void SetSpringDampingRatio(float ratio);
|
||||
float GetSpringDampingRatio() const;
|
||||
|
||||
private:
|
||||
b2WheelJoint* raw_joint_;
|
||||
};
|
||||
|
||||
|
||||
// 鼠标关节
|
||||
// 用于使身体的某个点追踪世界上的指定点,例如让物体追踪鼠标位置
|
||||
/// \~chinese
|
||||
/// @brief 鼠标关节
|
||||
/// @details 用于使身体的某个点追踪世界上的指定点,例如让物体追踪鼠标位置
|
||||
class KGE_API MouseJoint
|
||||
: public Joint
|
||||
{
|
||||
|
|
@ -740,14 +814,7 @@ namespace kiwano
|
|||
, 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(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)
|
||||
{}
|
||||
};
|
||||
|
|
@ -756,20 +823,72 @@ namespace kiwano
|
|||
MouseJoint(World* world, b2MouseJointDef* def);
|
||||
MouseJoint(World* world, Param const& param);
|
||||
|
||||
// 设定最大摩擦力 [N]
|
||||
/// \~chinese
|
||||
/// @brief 设定最大摩擦力 [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(); }
|
||||
/// \~chinese
|
||||
/// @brief 设置响应速度 [hz]
|
||||
void SetFrequency(float hz);
|
||||
float GetFrequency() const;
|
||||
|
||||
// 设置阻尼比
|
||||
void SetDampingRatio(float ratio) { KGE_ASSERT(raw_joint_); raw_joint_->SetDampingRatio(ratio); }
|
||||
float GetDampingRatio() const { KGE_ASSERT(raw_joint_); return raw_joint_->GetDampingRatio(); }
|
||||
/// \~chinese
|
||||
/// @brief 设置阻尼比
|
||||
void SetDampingRatio(float ratio);
|
||||
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 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(); }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,12 +35,7 @@ namespace kiwano
|
|||
{
|
||||
}
|
||||
|
||||
b2Shape* Shape::GetB2Shape()
|
||||
{
|
||||
return shape_;
|
||||
}
|
||||
|
||||
const b2Shape* Shape::GetB2Shape() const
|
||||
b2Shape* Shape::GetB2Shape() const
|
||||
{
|
||||
return shape_;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,25 +26,35 @@ namespace kiwano
|
|||
namespace physics
|
||||
{
|
||||
class World;
|
||||
class Fixture;
|
||||
|
||||
// 形状基类
|
||||
/**
|
||||
* \addtogroup Physics
|
||||
* @{
|
||||
*/
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 形状基类
|
||||
class KGE_API Shape
|
||||
{
|
||||
friend class Fixture;
|
||||
|
||||
public:
|
||||
Shape();
|
||||
Shape(b2Shape* shape);
|
||||
|
||||
b2Shape* GetB2Shape();
|
||||
const b2Shape* GetB2Shape() const;
|
||||
b2Shape* GetB2Shape() const;
|
||||
void SetB2Shape(b2Shape* shape);
|
||||
|
||||
private:
|
||||
virtual void FitWorld(World* world) {}
|
||||
|
||||
private:
|
||||
b2Shape* shape_;
|
||||
};
|
||||
|
||||
// 圆形形状
|
||||
/// \~chinese
|
||||
/// @brief 圆形形状
|
||||
class KGE_API CircleShape
|
||||
: public Shape
|
||||
{
|
||||
|
|
@ -55,6 +65,7 @@ namespace kiwano
|
|||
|
||||
void Set(float radius, Point const& offset = Point());
|
||||
|
||||
private:
|
||||
void FitWorld(World* world) override;
|
||||
|
||||
private:
|
||||
|
|
@ -63,7 +74,8 @@ namespace kiwano
|
|||
b2CircleShape circle_;
|
||||
};
|
||||
|
||||
// 盒子形状
|
||||
/// \~chinese
|
||||
/// @brief 盒子形状
|
||||
class KGE_API BoxShape
|
||||
: public Shape
|
||||
{
|
||||
|
|
@ -74,6 +86,7 @@ namespace kiwano
|
|||
|
||||
void Set(Vec2 const& size, Point const& offset = Point(), float rotation = 0.f);
|
||||
|
||||
private:
|
||||
void FitWorld(World* world) override;
|
||||
|
||||
private:
|
||||
|
|
@ -83,7 +96,8 @@ namespace kiwano
|
|||
b2PolygonShape polygon_;
|
||||
};
|
||||
|
||||
// 多边形形状
|
||||
/// \~chinese
|
||||
/// @brief 多边形形状
|
||||
class KGE_API PolygonShape
|
||||
: public Shape
|
||||
{
|
||||
|
|
@ -94,6 +108,7 @@ namespace kiwano
|
|||
|
||||
void Set(Vector<Point> const& vertexs);
|
||||
|
||||
private:
|
||||
void FitWorld(World* world) override;
|
||||
|
||||
private:
|
||||
|
|
@ -101,7 +116,8 @@ namespace kiwano
|
|||
b2PolygonShape polygon_;
|
||||
};
|
||||
|
||||
// 线段形状, 用于表示一条边
|
||||
/// \~chinese
|
||||
/// @brief 线段形状, 用于表示一条边
|
||||
class KGE_API EdgeShape
|
||||
: public Shape
|
||||
{
|
||||
|
|
@ -112,6 +128,7 @@ namespace kiwano
|
|||
|
||||
void Set(Point const& p1, Point const& p2);
|
||||
|
||||
private:
|
||||
void FitWorld(World* world) override;
|
||||
|
||||
private:
|
||||
|
|
@ -119,7 +136,8 @@ namespace kiwano
|
|||
b2EdgeShape edge_;
|
||||
};
|
||||
|
||||
// 链式形状
|
||||
/// \~chinese
|
||||
/// @brief 链式形状
|
||||
class KGE_API ChainShape
|
||||
: public Shape
|
||||
{
|
||||
|
|
@ -130,6 +148,7 @@ namespace kiwano
|
|||
|
||||
void Set(Vector<Point> const& vertexs, bool loop = false);
|
||||
|
||||
private:
|
||||
void FitWorld(World* world) override;
|
||||
|
||||
private:
|
||||
|
|
@ -137,5 +156,7 @@ namespace kiwano
|
|||
Vector<Point> vertexs_;
|
||||
b2ChainShape chain_;
|
||||
};
|
||||
|
||||
/** @} */
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ namespace kiwano
|
|||
{
|
||||
namespace
|
||||
{
|
||||
const float DefaultGlobalScale = 100.f; // 100 pixels per meters
|
||||
const float default_global_scale = 100.f; // 100 pixels per meters
|
||||
}
|
||||
|
||||
class World::DestructionListener : public b2DestructionListener
|
||||
|
|
@ -85,7 +85,7 @@ namespace kiwano
|
|||
: world_(b2Vec2(0, 10.0f))
|
||||
, vel_iter_(6)
|
||||
, pos_iter_(2)
|
||||
, global_scale_(DefaultGlobalScale)
|
||||
, global_scale_(default_global_scale)
|
||||
, destruction_listener_(nullptr)
|
||||
, contact_listener_(nullptr)
|
||||
, removing_joint_(false)
|
||||
|
|
@ -227,34 +227,18 @@ namespace kiwano
|
|||
|
||||
void World::Update(Duration dt)
|
||||
{
|
||||
{
|
||||
b2Body* b2body = world_.GetBodyList();
|
||||
while (b2body)
|
||||
{
|
||||
Body* body = static_cast<Body*>(b2body->GetUserData());
|
||||
if (body && body->GetType() != Body::Type::Static)
|
||||
{
|
||||
body->UpdateFromActor();
|
||||
}
|
||||
|
||||
b2body = b2body->GetNext();
|
||||
}
|
||||
}
|
||||
|
||||
world_.Step(dt.Seconds(), vel_iter_, pos_iter_);
|
||||
|
||||
b2Body* b2body = world_.GetBodyList();
|
||||
while (b2body)
|
||||
{
|
||||
b2Body* b2body = world_.GetBodyList();
|
||||
while (b2body)
|
||||
Body* body = static_cast<Body*>(b2body->GetUserData());
|
||||
if (body && body->GetType() != Body::Type::Static)
|
||||
{
|
||||
Body* body = static_cast<Body*>(b2body->GetUserData());
|
||||
if (body && body->GetType() != Body::Type::Static)
|
||||
{
|
||||
body->UpdateActor();
|
||||
}
|
||||
|
||||
b2body = b2body->GetNext();
|
||||
body->UpdateActor();
|
||||
}
|
||||
|
||||
b2body = b2body->GetNext();
|
||||
}
|
||||
|
||||
Stage::Update(dt);
|
||||
|
|
|
|||
|
|
@ -26,7 +26,22 @@ namespace kiwano
|
|||
{
|
||||
namespace physics
|
||||
{
|
||||
// 物理世界
|
||||
KGE_DECLARE_SMART_PTR(World);
|
||||
|
||||
/**
|
||||
* \~chinese
|
||||
* \defgroup Physics 物理引擎
|
||||
*/
|
||||
|
||||
/**
|
||||
* \addtogroup Physics
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \~chinese
|
||||
* @brief 物理世界
|
||||
*/
|
||||
class KGE_API World
|
||||
: public Stage
|
||||
{
|
||||
|
|
@ -38,54 +53,82 @@ namespace kiwano
|
|||
|
||||
virtual ~World();
|
||||
|
||||
// 获取重力
|
||||
/// \~chinese
|
||||
/// @brief 获取重力 [N]
|
||||
Vec2 GetGravity() const;
|
||||
|
||||
// 设置重力
|
||||
/// \~chinese
|
||||
/// @brief 设置重力 [N]
|
||||
void SetGravity(Vec2 gravity);
|
||||
|
||||
// 获取全局缩放比例
|
||||
inline float GetGlobalScale() const { return global_scale_; }
|
||||
/// \~chinese
|
||||
/// @brief 获取全局缩放比例
|
||||
/// @details 缩放比例是指由物理世界的单位米转换到屏幕像素的比例,默认比例为1:100
|
||||
float GetGlobalScale() const;
|
||||
|
||||
// 设置全局缩放比例
|
||||
inline void SetGlobalScale(float scale) { global_scale_ = scale; }
|
||||
/// \~chinese
|
||||
/// @brief 设置全局缩放比例
|
||||
/// @details 缩放比例是指由物理世界的单位米转换到屏幕像素的比例,默认比例为1:100
|
||||
void SetGlobalScale(float scale);
|
||||
|
||||
// 游戏世界单位转换为物理世界单位
|
||||
inline float World2Stage(float value) const { return value * GetGlobalScale(); }
|
||||
inline Point World2Stage(const b2Vec2& pos) const { return Point(World2Stage(pos.x), World2Stage(pos.y)); }
|
||||
/// \~chinese
|
||||
/// @brief 游戏世界单位转换为物理世界单位
|
||||
/// @details 根据全局缩放比例将物理世界的单位米转换为像素单位
|
||||
float World2Stage(float value) const;
|
||||
|
||||
// 物理世界单位转换为游戏世界单位
|
||||
inline float Stage2World(float value) const { return value / GetGlobalScale(); }
|
||||
inline b2Vec2 Stage2World(const Point& pos) const { return b2Vec2(Stage2World(pos.x), Stage2World(pos.y)); }
|
||||
/// \~chinese
|
||||
/// @brief 游戏世界单位转换为物理世界单位
|
||||
/// @details 根据全局缩放比例将物理世界的单位米转换为像素单位
|
||||
Vec2 World2Stage(const b2Vec2& pos) const;
|
||||
|
||||
// 设置速度迭代次数, 默认为 6
|
||||
inline void SetVelocityIterations(int vel_iter) { vel_iter_ = vel_iter; }
|
||||
/// \~chinese
|
||||
/// @brief 物理世界单位转换为游戏世界单位
|
||||
/// @details 根据全局缩放比例将像素单位转换为物理世界的单位米
|
||||
float Stage2World(float value) const;
|
||||
|
||||
// 设置位置迭代次数, 默认为 2
|
||||
inline void SetPositionIterations(int pos_iter) { pos_iter_ = pos_iter; }
|
||||
/// \~chinese
|
||||
/// @brief 物理世界单位转换为游戏世界单位
|
||||
/// @details 根据全局缩放比例将像素单位转换为物理世界的单位米
|
||||
b2Vec2 Stage2World(const Vec2& pos) const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置速度迭代次数, 默认为 6
|
||||
void SetVelocityIterations(int vel_iter);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置位置迭代次数, 默认为 2
|
||||
void SetPositionIterations(int pos_iter);
|
||||
|
||||
b2World* GetB2World();
|
||||
|
||||
const b2World* GetB2World() const;
|
||||
|
||||
private:
|
||||
// 移除物体
|
||||
/// \~chinese
|
||||
/// @brief 移除物体
|
||||
void RemoveBody(Body* body);
|
||||
|
||||
// 移除所有物体
|
||||
/// \~chinese
|
||||
/// @brief 移除所有物体
|
||||
void RemoveAllBodies();
|
||||
|
||||
// 添加关节
|
||||
/// \~chinese
|
||||
/// @brief 添加关节
|
||||
void AddJoint(Joint* joint);
|
||||
|
||||
// 移除关节
|
||||
/// \~chinese
|
||||
/// @brief 移除关节
|
||||
void RemoveJoint(Joint* joint);
|
||||
|
||||
// 移除所有关节
|
||||
/// \~chinese
|
||||
/// @brief 移除所有关节
|
||||
void RemoveAllJoints();
|
||||
|
||||
// 关节被移除
|
||||
/// \~chinese
|
||||
/// @brief 关节被移除
|
||||
void JointRemoved(b2Joint* joint);
|
||||
|
||||
protected:
|
||||
void Update(Duration dt) override;
|
||||
|
||||
private:
|
||||
|
|
@ -106,6 +149,47 @@ namespace kiwano
|
|||
Vector<Joint*> joints_;
|
||||
};
|
||||
|
||||
KGE_DECLARE_SMART_PTR(World);
|
||||
|
||||
/** @} */
|
||||
|
||||
inline float World::GetGlobalScale() const
|
||||
{
|
||||
return global_scale_;
|
||||
}
|
||||
|
||||
inline void World::SetGlobalScale(float scale)
|
||||
{
|
||||
global_scale_ = scale;
|
||||
}
|
||||
|
||||
inline float World::World2Stage(float value) const
|
||||
{
|
||||
return value * GetGlobalScale();
|
||||
}
|
||||
|
||||
inline Vec2 World::World2Stage(const b2Vec2& pos) const
|
||||
{
|
||||
return Point(World2Stage(pos.x), World2Stage(pos.y));
|
||||
}
|
||||
|
||||
inline float World::Stage2World(float value) const
|
||||
{
|
||||
return value / GetGlobalScale();
|
||||
}
|
||||
|
||||
inline b2Vec2 World::Stage2World(const Vec2& pos) const
|
||||
{
|
||||
return b2Vec2(Stage2World(pos.x), Stage2World(pos.y));
|
||||
}
|
||||
|
||||
inline void World::SetVelocityIterations(int vel_iter)
|
||||
{
|
||||
vel_iter_ = vel_iter;
|
||||
}
|
||||
|
||||
inline void World::SetPositionIterations(int pos_iter)
|
||||
{
|
||||
pos_iter_ = pos_iter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ namespace kiwano
|
|||
{
|
||||
namespace physics
|
||||
{
|
||||
inline b2Vec2 Stage2World(const Point& pos) { return b2Vec2(pos.x, pos.y); }
|
||||
inline Point World2Stage(const b2Vec2& pos) { return Point(pos.x, pos.y); }
|
||||
inline b2Vec2 Stage2World(const Vec2& pos) { return b2Vec2(pos.x, pos.y); }
|
||||
inline Vec2 World2Stage(const b2Vec2& pos) { return Vec2(pos.x, pos.y); }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,14 +82,14 @@ namespace kiwano
|
|||
};
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 事件特性:判断是否是事件类型
|
||||
/// @brief 事件特性:判断指定类型是否是事件
|
||||
template <typename _Ty>
|
||||
struct IsEvent : public std::bool_constant<std::is_base_of<Event, _Ty>::value || std::is_same<Event, _Ty>::value>
|
||||
{
|
||||
};
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 事件特性:判断是否是事件类型
|
||||
/// @brief 事件特性:判断一个事件能否安全转换到另一事件类型
|
||||
template <typename _Ty, typename = typename std::enable_if<IsEvent<_Ty>::value, int>::type>
|
||||
struct IsEventType
|
||||
{
|
||||
|
|
|
|||
|
|
@ -29,6 +29,11 @@ namespace kiwano
|
|||
|
||||
KGE_DECLARE_SMART_PTR(Brush);
|
||||
|
||||
/**
|
||||
* \addtogroup Render
|
||||
* @{
|
||||
*/
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 渐变转换点
|
||||
struct GradientStop
|
||||
|
|
@ -141,6 +146,8 @@ namespace kiwano
|
|||
ComPtr<ID2D1Brush> raw_;
|
||||
};
|
||||
|
||||
/** @} */
|
||||
|
||||
inline Brush::Type Brush::GetType() const { return type_; }
|
||||
|
||||
inline ComPtr<ID2D1Brush> Brush::GetBrush() const { return raw_; }
|
||||
|
|
|
|||
|
|
@ -24,6 +24,11 @@
|
|||
|
||||
namespace kiwano
|
||||
{
|
||||
/**
|
||||
* \addtogroup Render
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*
|
||||
* \~chinese
|
||||
* @brief ÑÕÉ«
|
||||
|
|
@ -128,6 +133,8 @@ namespace kiwano
|
|||
float a; ///< AlphaÖµ
|
||||
};
|
||||
|
||||
/** @} */
|
||||
|
||||
inline bool Color::operator== (const Color& rhs) const
|
||||
{
|
||||
return r == rhs.r && g == rhs.g && b == rhs.b && a == rhs.a;
|
||||
|
|
|
|||
|
|
@ -30,6 +30,11 @@ namespace kiwano
|
|||
|
||||
class Renderer;
|
||||
|
||||
/**
|
||||
* \addtogroup Render
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \~chinese
|
||||
* @brief ×ÖÌå
|
||||
|
|
@ -67,6 +72,8 @@ namespace kiwano
|
|||
ComPtr<IDWriteFontCollection> collection_;
|
||||
};
|
||||
|
||||
/** @} */
|
||||
|
||||
inline ComPtr<IDWriteFontCollection> Font::GetCollection() const
|
||||
{
|
||||
return collection_;
|
||||
|
|
|
|||
|
|
@ -27,6 +27,11 @@ namespace kiwano
|
|||
class Renderer;
|
||||
class GeometrySink;
|
||||
|
||||
/**
|
||||
* \addtogroup Render
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \~chinese
|
||||
* @brief 섯부近榴
|
||||
|
|
@ -117,6 +122,8 @@ namespace kiwano
|
|||
ComPtr<ID2D1Geometry> geo_;
|
||||
};
|
||||
|
||||
/** @} */
|
||||
|
||||
inline ComPtr<ID2D1Geometry> Geometry::GetGeometry() const { return geo_; }
|
||||
|
||||
inline void Geometry::SetGeometry(ComPtr<ID2D1Geometry> geometry) { geo_ = geometry; }
|
||||
|
|
|
|||
|
|
@ -26,6 +26,11 @@ namespace kiwano
|
|||
class RenderTarget;
|
||||
class Renderer;
|
||||
|
||||
/**
|
||||
* \addtogroup Render
|
||||
* @{
|
||||
*/
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 几何形状组合方式
|
||||
enum class CombineMode
|
||||
|
|
@ -142,6 +147,8 @@ namespace kiwano
|
|||
ComPtr<ID2D1PathGeometry> path_geo_;
|
||||
ComPtr<ID2D1GeometrySink> sink_;
|
||||
};
|
||||
|
||||
/** @} */
|
||||
|
||||
inline ComPtr<ID2D1PathGeometry> GeometrySink::GetPathGeometry() const { return path_geo_; }
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,11 @@ namespace kiwano
|
|||
|
||||
KGE_DECLARE_SMART_PTR(GifImage);
|
||||
|
||||
/**
|
||||
* \addtogroup Render
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \~chinese
|
||||
* @brief GIFͼÏñ
|
||||
|
|
@ -107,6 +112,8 @@ namespace kiwano
|
|||
ComPtr<IWICBitmapDecoder> decoder_;
|
||||
};
|
||||
|
||||
/** @} */
|
||||
|
||||
inline GifImage::Frame::Frame()
|
||||
: disposal_type(DisposalType::Unknown)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -25,6 +25,11 @@ namespace kiwano
|
|||
{
|
||||
class RenderTarget;
|
||||
|
||||
/**
|
||||
* \addtogroup Render
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \~chinese
|
||||
* @brief 图层区域
|
||||
|
|
@ -85,6 +90,8 @@ namespace kiwano
|
|||
ComPtr<ID2D1Layer> layer_;
|
||||
};
|
||||
|
||||
/** @} */
|
||||
|
||||
inline bool LayerArea::IsValid() const { return layer_ != nullptr; }
|
||||
|
||||
inline Rect const& LayerArea::GetAreaRect() const { return area_; }
|
||||
|
|
|
|||
|
|
@ -35,6 +35,11 @@ namespace kiwano
|
|||
KGE_DECLARE_SMART_PTR(RenderTarget);
|
||||
KGE_DECLARE_SMART_PTR(TextureRenderTarget);
|
||||
|
||||
/**
|
||||
* \addtogroup Render
|
||||
* @{
|
||||
*/
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 文字抗锯齿模式
|
||||
enum class TextAntialiasMode
|
||||
|
|
@ -347,6 +352,8 @@ namespace kiwano
|
|||
ComPtr<ID2D1BitmapRenderTarget> bitmap_rt_;
|
||||
};
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
inline RenderTarget::Status::Status()
|
||||
: primitives(0)
|
||||
|
|
|
|||
|
|
@ -41,6 +41,16 @@ namespace kiwano
|
|||
typedef ID3D11DeviceResources ID3DDeviceResources;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \~chinese
|
||||
* \defgroup Render äÖȾÒýÇæ
|
||||
*/
|
||||
|
||||
/**
|
||||
* \addtogroup Render
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \~chinese
|
||||
* @brief äÖȾÉèÖÃ
|
||||
|
|
@ -315,6 +325,8 @@ namespace kiwano
|
|||
ComPtr<IResourceFontCollectionLoader> res_font_collection_loader_;
|
||||
};
|
||||
|
||||
/** @} */
|
||||
|
||||
inline HWND Renderer::GetTargetWindow() const { return hwnd_; }
|
||||
|
||||
inline Size const& Renderer::GetOutputSize() const { return output_size_; }
|
||||
|
|
|
|||
|
|
@ -22,6 +22,11 @@
|
|||
|
||||
namespace kiwano
|
||||
{
|
||||
/**
|
||||
* \addtogroup Render
|
||||
* @{
|
||||
*/
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 线条样式
|
||||
/// @details 线条样式表示渲染目标在绘制线条时,如何处理两条线相交部分
|
||||
|
|
@ -31,4 +36,6 @@ namespace kiwano
|
|||
Bevel = 1, ///< 斜角样式
|
||||
Round = 2 ///< 圆角样式
|
||||
};
|
||||
|
||||
/** @} */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,11 @@ namespace kiwano
|
|||
class RenderTarget;
|
||||
class Renderer;
|
||||
|
||||
/**
|
||||
* \addtogroup Render
|
||||
* @{
|
||||
*/
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 文本布局
|
||||
class KGE_API TextLayout
|
||||
|
|
@ -171,6 +176,8 @@ namespace kiwano
|
|||
TextStyle style_;
|
||||
};
|
||||
|
||||
/** @} */
|
||||
|
||||
inline bool TextLayout::IsValid() const
|
||||
{
|
||||
return text_layout_ != nullptr;
|
||||
|
|
|
|||
|
|
@ -26,6 +26,11 @@
|
|||
|
||||
namespace kiwano
|
||||
{
|
||||
/**
|
||||
* \addtogroup Render
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \~chinese
|
||||
* @brief 文本对齐方式
|
||||
|
|
@ -94,6 +99,8 @@ namespace kiwano
|
|||
TextStyle(const String& font_family, float font_size, uint32_t font_weight = FontWeight::Normal);
|
||||
};
|
||||
|
||||
/** @} */
|
||||
|
||||
inline TextStyle::TextStyle()
|
||||
: TextStyle(String(), 18, FontWeight::Normal)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -28,6 +28,13 @@ namespace kiwano
|
|||
class TextureRenderTarget;
|
||||
class Renderer;
|
||||
|
||||
KGE_DECLARE_SMART_PTR(Texture);
|
||||
|
||||
/**
|
||||
* \addtogroup Render
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \~chinese
|
||||
* @brief 插值模式
|
||||
|
|
@ -39,8 +46,6 @@ namespace kiwano
|
|||
Nearest, ///< 最邻近插值,取最邻近的像素点的颜色值
|
||||
};
|
||||
|
||||
KGE_DECLARE_SMART_PTR(Texture);
|
||||
|
||||
/**
|
||||
* \~chinese
|
||||
* @brief 纹理
|
||||
|
|
@ -140,4 +145,6 @@ namespace kiwano
|
|||
|
||||
static InterpolationMode default_interpolation_mode_;
|
||||
};
|
||||
|
||||
/** @} */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,11 @@
|
|||
|
||||
namespace kiwano
|
||||
{
|
||||
/**
|
||||
* \addtogroup Render
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* \~chinese
|
||||
* @brief 纹理缓存
|
||||
|
|
@ -82,4 +87,6 @@ namespace kiwano
|
|||
using GifImageMap = UnorderedMap<size_t, GifImagePtr>;
|
||||
GifImageMap gif_texture_cache_;
|
||||
};
|
||||
|
||||
/** @} */
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue