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