Update physics

This commit is contained in:
Nomango 2019-12-31 16:01:41 +08:00
parent 1e530411ae
commit b0b02ddf62
30 changed files with 1011 additions and 379 deletions

View File

@ -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);
} }

View File

@ -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_; }
} }
} }

View File

@ -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)

View File

@ -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; }
} }
} }

View File

@ -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();
} }
} }

View File

@ -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);
}; };

View File

@ -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_);

View File

@ -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; }
} }
} }

View File

@ -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());

View File

@ -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(); }
} }
} }

View File

@ -35,12 +35,7 @@ namespace kiwano
{ {
} }
b2Shape* Shape::GetB2Shape() b2Shape* Shape::GetB2Shape() const
{
return shape_;
}
const b2Shape* Shape::GetB2Shape() const
{ {
return shape_; return shape_;
} }

View File

@ -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_;
}; };
/** @} */
} }
} }

View File

@ -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);

View File

@ -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;
}
} }
} }

View File

@ -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); }
} }
} }

View File

@ -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
{ {

View File

@ -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_; }

View File

@ -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;

View File

@ -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_;

View File

@ -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; }

View File

@ -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_; }

View File

@ -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)
{ {

View File

@ -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_; }

View File

@ -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)

View File

@ -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_; }

View File

@ -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 ///< 圆角样式
}; };
/** @} */
} }

View File

@ -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;

View File

@ -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)
{ {

View File

@ -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_;
}; };
/** @} */
} }

View File

@ -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_;
}; };
/** @} */
} }