Update physics

This commit is contained in:
Nomango 2020-02-22 17:24:31 +08:00
parent d6b95e3b40
commit f7844c1ac9
13 changed files with 339 additions and 176 deletions

View File

@ -61,13 +61,13 @@ PhysicBody* Contact::GetBodyB() const
void Contact::SetTangentSpeed(float speed) void Contact::SetTangentSpeed(float speed)
{ {
KGE_ASSERT(contact_); KGE_ASSERT(contact_);
contact_->SetTangentSpeed(global::ToMeters(speed)); contact_->SetTangentSpeed(global::LocalToWorld(speed));
} }
float Contact::GetTangentSpeed() const float Contact::GetTangentSpeed() const
{ {
KGE_ASSERT(contact_); KGE_ASSERT(contact_);
return global::ToPixels(contact_->GetTangentSpeed()); return global::WorldToLocal(contact_->GetTangentSpeed());
} }
} // namespace physics } // namespace physics

View File

@ -33,8 +33,8 @@ FixturePtr Fixture::CreateCircle(const Param& param, float radius, const Point&
if (ptr) if (ptr)
{ {
auto shape = std::make_unique<b2CircleShape>(); auto shape = std::make_unique<b2CircleShape>();
shape->m_radius = global::ToMeters(radius); shape->m_radius = global::LocalToWorld(radius);
shape->m_p = global::ToMeters(offset); shape->m_p = global::LocalToWorld(offset);
ptr->shape_ = std::move(shape); ptr->shape_ = std::move(shape);
ptr->param_ = param; ptr->param_ = param;
@ -47,8 +47,8 @@ FixturePtr Fixture::CreateRect(const Param& param, const Size& size, const Point
FixturePtr ptr = new (std::nothrow) Fixture; FixturePtr ptr = new (std::nothrow) Fixture;
if (ptr) if (ptr)
{ {
b2Vec2 b2size = global::ToMeters(size); b2Vec2 b2size = global::LocalToWorld(size);
b2Vec2 b2offset = global::ToMeters(offset); b2Vec2 b2offset = global::LocalToWorld(offset);
auto shape = std::make_unique<b2PolygonShape>(); auto shape = std::make_unique<b2PolygonShape>();
shape->SetAsBox(b2size.x / 2, b2size.y / 2, b2offset, math::Degree2Radian(rotation)); shape->SetAsBox(b2size.x / 2, b2size.y / 2, b2offset, math::Degree2Radian(rotation));
@ -68,7 +68,7 @@ FixturePtr Fixture::CreatePolygon(const Param& param, const Vector<Point>& verte
b2vertexs.reserve(vertexs.size()); b2vertexs.reserve(vertexs.size());
for (const auto& v : vertexs) for (const auto& v : vertexs)
{ {
b2vertexs.push_back(global::ToMeters(v)); b2vertexs.push_back(global::LocalToWorld(v));
} }
auto shape = std::make_unique<b2PolygonShape>(); auto shape = std::make_unique<b2PolygonShape>();
@ -85,8 +85,8 @@ FixturePtr Fixture::CreateEdge(const Param& param, const Point& p1, const Point&
FixturePtr ptr = new (std::nothrow) Fixture; FixturePtr ptr = new (std::nothrow) Fixture;
if (ptr) if (ptr)
{ {
b2Vec2 start = global::ToMeters(p1); b2Vec2 start = global::LocalToWorld(p1);
b2Vec2 end = global::ToMeters(p2); b2Vec2 end = global::LocalToWorld(p2);
auto shape = std::make_unique<b2EdgeShape>(); auto shape = std::make_unique<b2EdgeShape>();
shape->Set(start, end); shape->Set(start, end);
@ -106,7 +106,7 @@ FixturePtr Fixture::CreateChain(const Param& param, const Vector<Point>& vertexs
b2vertexs.reserve(vertexs.size()); b2vertexs.reserve(vertexs.size());
for (const auto& v : vertexs) for (const auto& v : vertexs)
{ {
b2vertexs.push_back(global::ToMeters(v)); b2vertexs.push_back(global::LocalToWorld(v));
} }
auto shape = std::make_unique<b2ChainShape>(); auto shape = std::make_unique<b2ChainShape>();
@ -189,7 +189,7 @@ void Fixture::GetMassData(float* mass, Point* center, float* inertia) const
if (mass) if (mass)
*mass = data.mass; *mass = data.mass;
if (center) if (center)
*center = global::ToPixels(data.center); *center = global::WorldToLocal(data.center);
if (inertia) if (inertia)
*inertia = data.I; *inertia = data.I;
} }
@ -197,7 +197,7 @@ void Fixture::GetMassData(float* mass, Point* center, float* inertia) const
bool Fixture::TestPoint(const Point& p) const bool Fixture::TestPoint(const Point& p) const
{ {
KGE_ASSERT(fixture_); KGE_ASSERT(fixture_);
return fixture_->TestPoint(global::ToMeters(p)); return fixture_->TestPoint(global::LocalToWorld(p));
} }
void Fixture::Destroy() void Fixture::Destroy()

View File

@ -43,24 +43,24 @@ void SetScale(float scale)
global_scale = scale; global_scale = scale;
} }
float ToPixels(float value) float WorldToLocal(float value)
{ {
return value * global_scale; return value * global_scale;
} }
Vec2 ToPixels(const b2Vec2& pos) Vec2 WorldToLocal(const b2Vec2& pos)
{ {
return Point(ToPixels(pos.x), ToPixels(pos.y)); return Point(WorldToLocal(pos.x), WorldToLocal(pos.y));
} }
float ToMeters(float value) float LocalToWorld(float value)
{ {
return value / global_scale; return value / global_scale;
} }
b2Vec2 ToMeters(const Vec2& pos) b2Vec2 LocalToWorld(const Vec2& pos)
{ {
return b2Vec2(ToMeters(pos.x), ToMeters(pos.y)); return b2Vec2(LocalToWorld(pos.x), LocalToWorld(pos.y));
} }
} // namespace global } // namespace global

View File

@ -48,22 +48,22 @@ void SetScale(float scale);
/// \~chinese /// \~chinese
/// @brief 游戏世界单位转换为物理世界单位 /// @brief 游戏世界单位转换为物理世界单位
/// @details 根据全局缩放比例将物理世界的单位米转换为像素单位 /// @details 根据全局缩放比例将物理世界的单位米转换为像素单位
float ToPixels(float value); float WorldToLocal(float value);
/// \~chinese /// \~chinese
/// @brief 游戏世界单位转换为物理世界单位 /// @brief 游戏世界单位转换为物理世界单位
/// @details 根据全局缩放比例将物理世界的单位米转换为像素单位 /// @details 根据全局缩放比例将物理世界的单位米转换为像素单位
Vec2 ToPixels(const b2Vec2& pos); Vec2 WorldToLocal(const b2Vec2& pos);
/// \~chinese /// \~chinese
/// @brief 物理世界单位转换为游戏世界单位 /// @brief 物理世界单位转换为游戏世界单位
/// @details 根据全局缩放比例将像素单位转换为物理世界的单位米 /// @details 根据全局缩放比例将像素单位转换为物理世界的单位米
float ToMeters(float value); float LocalToWorld(float value);
/// \~chinese /// \~chinese
/// @brief 物理世界单位转换为游戏世界单位 /// @brief 物理世界单位转换为游戏世界单位
/// @details 根据全局缩放比例将像素单位转换为物理世界的单位米 /// @details 根据全局缩放比例将像素单位转换为物理世界的单位米
b2Vec2 ToMeters(const Vec2& pos); b2Vec2 LocalToWorld(const Vec2& pos);
} // namespace global } // namespace global
} // namespace physics } // namespace physics

View File

@ -129,8 +129,8 @@ bool DistanceJoint::Init(PhysicWorld* world)
KGE_ASSERT(param_.body_a && param_.body_b); KGE_ASSERT(param_.body_a && param_.body_b);
b2DistanceJointDef def; b2DistanceJointDef def;
def.Initialize(param_.body_a->GetB2Body(), param_.body_b->GetB2Body(), global::ToMeters(param_.anchor_a), def.Initialize(param_.body_a->GetB2Body(), param_.body_b->GetB2Body(), global::LocalToWorld(param_.anchor_a),
global::ToMeters(param_.anchor_b)); global::LocalToWorld(param_.anchor_b));
def.frequencyHz = param_.frequency_hz; def.frequencyHz = param_.frequency_hz;
def.dampingRatio = param_.damping_ratio; def.dampingRatio = param_.damping_ratio;
@ -142,13 +142,13 @@ bool DistanceJoint::Init(PhysicWorld* world)
void DistanceJoint::SetLength(float length) void DistanceJoint::SetLength(float length)
{ {
KGE_ASSERT(raw_joint_); KGE_ASSERT(raw_joint_);
raw_joint_->SetLength(global::ToMeters(length)); raw_joint_->SetLength(global::LocalToWorld(length));
} }
float DistanceJoint::GetLength() const float DistanceJoint::GetLength() const
{ {
KGE_ASSERT(raw_joint_); KGE_ASSERT(raw_joint_);
return global::ToMeters(raw_joint_->GetLength()); return global::LocalToWorld(raw_joint_->GetLength());
} }
// //
@ -175,9 +175,9 @@ bool FrictionJoint::Init(PhysicWorld* world)
KGE_ASSERT(param_.body_a && param_.body_b); KGE_ASSERT(param_.body_a && param_.body_b);
b2FrictionJointDef def; b2FrictionJointDef def;
def.Initialize(param_.body_a->GetB2Body(), param_.body_b->GetB2Body(), global::ToMeters(param_.anchor)); def.Initialize(param_.body_a->GetB2Body(), param_.body_b->GetB2Body(), global::LocalToWorld(param_.anchor));
def.maxForce = param_.max_force; def.maxForce = param_.max_force;
def.maxTorque = global::ToMeters(param_.max_torque); def.maxTorque = global::LocalToWorld(param_.max_torque);
Joint::Init(world, &def); Joint::Init(world, &def);
raw_joint_ = static_cast<b2FrictionJoint*>(GetB2Joint()); raw_joint_ = static_cast<b2FrictionJoint*>(GetB2Joint());
@ -199,13 +199,13 @@ float FrictionJoint::GetMaxForce() const
void FrictionJoint::SetMaxTorque(float length) void FrictionJoint::SetMaxTorque(float length)
{ {
KGE_ASSERT(raw_joint_); KGE_ASSERT(raw_joint_);
raw_joint_->SetMaxTorque(global::ToMeters(length)); raw_joint_->SetMaxTorque(global::LocalToWorld(length));
} }
float FrictionJoint::GetMaxTorque() const float FrictionJoint::GetMaxTorque() const
{ {
KGE_ASSERT(raw_joint_); KGE_ASSERT(raw_joint_);
return global::ToPixels(raw_joint_->GetMaxTorque()); return global::WorldToLocal(raw_joint_->GetMaxTorque());
} }
// //
@ -279,7 +279,7 @@ bool MotorJoint::Init(PhysicWorld* world)
b2MotorJointDef def; b2MotorJointDef def;
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 = global::ToMeters(param_.max_torque); def.maxTorque = global::LocalToWorld(param_.max_torque);
def.correctionFactor = param_.correction_factor; def.correctionFactor = param_.correction_factor;
Joint::Init(world, &def); Joint::Init(world, &def);
@ -302,13 +302,13 @@ float MotorJoint::GetMaxForce() const
void MotorJoint::SetMaxTorque(float length) void MotorJoint::SetMaxTorque(float length)
{ {
KGE_ASSERT(raw_joint_); KGE_ASSERT(raw_joint_);
raw_joint_->SetMaxTorque(global::ToMeters(length)); raw_joint_->SetMaxTorque(global::LocalToWorld(length));
} }
float MotorJoint::GetMaxTorque() const float MotorJoint::GetMaxTorque() const
{ {
KGE_ASSERT(raw_joint_); KGE_ASSERT(raw_joint_);
return global::ToPixels(raw_joint_->GetMaxTorque()); return global::WorldToLocal(raw_joint_->GetMaxTorque());
} }
// //
@ -335,14 +335,14 @@ bool PrismaticJoint::Init(PhysicWorld* world)
KGE_ASSERT(param_.body_a && param_.body_b); KGE_ASSERT(param_.body_a && param_.body_b);
b2PrismaticJointDef def; b2PrismaticJointDef def;
def.Initialize(param_.body_a->GetB2Body(), param_.body_b->GetB2Body(), global::ToMeters(param_.anchor), def.Initialize(param_.body_a->GetB2Body(), param_.body_b->GetB2Body(), global::LocalToWorld(param_.anchor),
b2Vec2(param_.axis.x, param_.axis.y)); b2Vec2(param_.axis.x, param_.axis.y));
def.enableLimit = param_.enable_limit; def.enableLimit = param_.enable_limit;
def.lowerTranslation = global::ToMeters(param_.lower_translation); def.lowerTranslation = global::LocalToWorld(param_.lower_translation);
def.upperTranslation = global::ToMeters(param_.upper_translation); def.upperTranslation = global::LocalToWorld(param_.upper_translation);
def.enableMotor = param_.enable_motor; def.enableMotor = param_.enable_motor;
def.maxMotorForce = param_.max_motor_force; def.maxMotorForce = param_.max_motor_force;
def.motorSpeed = global::ToMeters(param_.motor_speed); def.motorSpeed = global::LocalToWorld(param_.motor_speed);
Joint::Init(world, &def); Joint::Init(world, &def);
raw_joint_ = static_cast<b2PrismaticJoint*>(GetB2Joint()); raw_joint_ = static_cast<b2PrismaticJoint*>(GetB2Joint());
@ -352,31 +352,31 @@ bool PrismaticJoint::Init(PhysicWorld* world)
float PrismaticJoint::GetJointTranslation() const float PrismaticJoint::GetJointTranslation() const
{ {
KGE_ASSERT(raw_joint_); KGE_ASSERT(raw_joint_);
return global::ToPixels(raw_joint_->GetJointTranslation()); return global::WorldToLocal(raw_joint_->GetJointTranslation());
} }
float PrismaticJoint::GetJointSpeed() const float PrismaticJoint::GetJointSpeed() const
{ {
KGE_ASSERT(raw_joint_); KGE_ASSERT(raw_joint_);
return global::ToPixels(raw_joint_->GetJointSpeed()); return global::WorldToLocal(raw_joint_->GetJointSpeed());
} }
float PrismaticJoint::GetLowerLimit() const float PrismaticJoint::GetLowerLimit() const
{ {
KGE_ASSERT(raw_joint_); KGE_ASSERT(raw_joint_);
return global::ToPixels(raw_joint_->GetLowerLimit()); return global::WorldToLocal(raw_joint_->GetLowerLimit());
} }
float PrismaticJoint::GetUpperLimit() const float PrismaticJoint::GetUpperLimit() const
{ {
KGE_ASSERT(raw_joint_); KGE_ASSERT(raw_joint_);
return global::ToPixels(raw_joint_->GetUpperLimit()); return global::WorldToLocal(raw_joint_->GetUpperLimit());
} }
void PrismaticJoint::SetLimits(float lower, float upper) void PrismaticJoint::SetLimits(float lower, float upper)
{ {
KGE_ASSERT(raw_joint_); KGE_ASSERT(raw_joint_);
raw_joint_->SetLimits(global::ToMeters(lower), global::ToMeters(upper)); raw_joint_->SetLimits(global::LocalToWorld(lower), global::LocalToWorld(upper));
} }
// //
@ -403,9 +403,9 @@ bool PulleyJoint::Init(PhysicWorld* world)
KGE_ASSERT(param_.body_a && param_.body_b); KGE_ASSERT(param_.body_a && param_.body_b);
b2PulleyJointDef def; b2PulleyJointDef def;
def.Initialize(param_.body_a->GetB2Body(), param_.body_b->GetB2Body(), global::ToMeters(param_.ground_anchor_a), def.Initialize(param_.body_a->GetB2Body(), param_.body_b->GetB2Body(), global::LocalToWorld(param_.ground_anchor_a),
global::ToMeters(param_.ground_anchor_b), global::ToMeters(param_.anchor_a), global::LocalToWorld(param_.ground_anchor_b), global::LocalToWorld(param_.anchor_a),
global::ToMeters(param_.anchor_b), param_.ratio); global::LocalToWorld(param_.anchor_b), param_.ratio);
Joint::Init(world, &def); Joint::Init(world, &def);
raw_joint_ = static_cast<b2PulleyJoint*>(GetB2Joint()); raw_joint_ = static_cast<b2PulleyJoint*>(GetB2Joint());
@ -415,13 +415,13 @@ bool PulleyJoint::Init(PhysicWorld* world)
Point PulleyJoint::GetGroundAnchorA() const Point PulleyJoint::GetGroundAnchorA() const
{ {
KGE_ASSERT(raw_joint_); KGE_ASSERT(raw_joint_);
return global::ToPixels(raw_joint_->GetGroundAnchorA()); return global::WorldToLocal(raw_joint_->GetGroundAnchorA());
} }
Point PulleyJoint::GetGroundAnchorB() const Point PulleyJoint::GetGroundAnchorB() const
{ {
KGE_ASSERT(raw_joint_); KGE_ASSERT(raw_joint_);
return global::ToPixels(raw_joint_->GetGroundAnchorB()); return global::WorldToLocal(raw_joint_->GetGroundAnchorB());
} }
float PulleyJoint::GetRatio() const float PulleyJoint::GetRatio() const
@ -433,25 +433,25 @@ float PulleyJoint::GetRatio() const
float PulleyJoint::GetLengthA() const float PulleyJoint::GetLengthA() const
{ {
KGE_ASSERT(raw_joint_); KGE_ASSERT(raw_joint_);
return global::ToPixels(raw_joint_->GetLengthA()); return global::WorldToLocal(raw_joint_->GetLengthA());
} }
float PulleyJoint::GetLengthB() const float PulleyJoint::GetLengthB() const
{ {
KGE_ASSERT(raw_joint_); KGE_ASSERT(raw_joint_);
return global::ToPixels(raw_joint_->GetLengthB()); return global::WorldToLocal(raw_joint_->GetLengthB());
} }
float PulleyJoint::GetCurrentLengthA() const float PulleyJoint::GetCurrentLengthA() const
{ {
KGE_ASSERT(raw_joint_); KGE_ASSERT(raw_joint_);
return global::ToPixels(raw_joint_->GetCurrentLengthA()); return global::WorldToLocal(raw_joint_->GetCurrentLengthA());
} }
float PulleyJoint::GetCurrentLengthB() const float PulleyJoint::GetCurrentLengthB() const
{ {
KGE_ASSERT(raw_joint_); KGE_ASSERT(raw_joint_);
return global::ToPixels(raw_joint_->GetCurrentLengthB()); return global::WorldToLocal(raw_joint_->GetCurrentLengthB());
} }
// //
@ -478,12 +478,12 @@ bool RevoluteJoint::Init(PhysicWorld* world)
KGE_ASSERT(param_.body_a && param_.body_b); KGE_ASSERT(param_.body_a && param_.body_b);
b2RevoluteJointDef def; b2RevoluteJointDef def;
def.Initialize(param_.body_a->GetB2Body(), param_.body_b->GetB2Body(), global::ToMeters(param_.anchor)); def.Initialize(param_.body_a->GetB2Body(), param_.body_b->GetB2Body(), global::LocalToWorld(param_.anchor));
def.enableLimit = param_.enable_limit; def.enableLimit = param_.enable_limit;
def.lowerAngle = math::Degree2Radian(param_.lower_angle); def.lowerAngle = math::Degree2Radian(param_.lower_angle);
def.upperAngle = math::Degree2Radian(param_.upper_angle); def.upperAngle = math::Degree2Radian(param_.upper_angle);
def.enableMotor = param_.enable_motor; def.enableMotor = param_.enable_motor;
def.maxMotorTorque = global::ToMeters(param_.max_motor_torque); def.maxMotorTorque = global::LocalToWorld(param_.max_motor_torque);
def.motorSpeed = math::Degree2Radian(param_.motor_speed); def.motorSpeed = math::Degree2Radian(param_.motor_speed);
Joint::Init(world, &def); Joint::Init(world, &def);
@ -524,13 +524,13 @@ void RevoluteJoint::SetLimits(float lower, float upper)
void RevoluteJoint::SetMaxMotorTorque(float torque) void RevoluteJoint::SetMaxMotorTorque(float torque)
{ {
KGE_ASSERT(raw_joint_); KGE_ASSERT(raw_joint_);
raw_joint_->SetMaxMotorTorque(global::ToMeters(torque)); raw_joint_->SetMaxMotorTorque(global::LocalToWorld(torque));
} }
float RevoluteJoint::GetMaxMotorTorque() const float RevoluteJoint::GetMaxMotorTorque() const
{ {
KGE_ASSERT(raw_joint_); KGE_ASSERT(raw_joint_);
return global::ToPixels(raw_joint_->GetMaxMotorTorque()); return global::WorldToLocal(raw_joint_->GetMaxMotorTorque());
} }
// //
@ -559,9 +559,9 @@ bool RopeJoint::Init(PhysicWorld* world)
b2RopeJointDef def; b2RopeJointDef def;
def.bodyA = param_.body_a->GetB2Body(); def.bodyA = param_.body_a->GetB2Body();
def.bodyB = param_.body_b->GetB2Body(); def.bodyB = param_.body_b->GetB2Body();
def.localAnchorA = global::ToMeters(param_.local_anchor_a); def.localAnchorA = global::LocalToWorld(param_.local_anchor_a);
def.localAnchorB = global::ToMeters(param_.local_anchor_b); def.localAnchorB = global::LocalToWorld(param_.local_anchor_b);
def.maxLength = global::ToMeters(param_.max_length); def.maxLength = global::LocalToWorld(param_.max_length);
Joint::Init(world, &def); Joint::Init(world, &def);
raw_joint_ = static_cast<b2RopeJoint*>(GetB2Joint()); raw_joint_ = static_cast<b2RopeJoint*>(GetB2Joint());
@ -571,13 +571,13 @@ bool RopeJoint::Init(PhysicWorld* world)
void RopeJoint::SetMaxLength(float length) void RopeJoint::SetMaxLength(float length)
{ {
KGE_ASSERT(raw_joint_); KGE_ASSERT(raw_joint_);
raw_joint_->SetMaxLength(global::ToMeters(length)); raw_joint_->SetMaxLength(global::LocalToWorld(length));
} }
float RopeJoint::GetMaxLength() const float RopeJoint::GetMaxLength() const
{ {
KGE_ASSERT(raw_joint_); KGE_ASSERT(raw_joint_);
return global::ToPixels(raw_joint_->GetMaxLength()); return global::WorldToLocal(raw_joint_->GetMaxLength());
} }
// //
@ -604,7 +604,7 @@ bool WeldJoint::Init(PhysicWorld* world)
KGE_ASSERT(param_.body_a && param_.body_b); KGE_ASSERT(param_.body_a && param_.body_b);
b2WeldJointDef def; b2WeldJointDef def;
def.Initialize(param_.body_a->GetB2Body(), param_.body_b->GetB2Body(), global::ToMeters(param_.anchor)); def.Initialize(param_.body_a->GetB2Body(), param_.body_b->GetB2Body(), global::LocalToWorld(param_.anchor));
def.frequencyHz = param_.frequency_hz; def.frequencyHz = param_.frequency_hz;
def.dampingRatio = param_.damping_ratio; def.dampingRatio = param_.damping_ratio;
@ -637,11 +637,11 @@ bool WheelJoint::Init(PhysicWorld* world)
KGE_ASSERT(param_.body_a && param_.body_b); KGE_ASSERT(param_.body_a && param_.body_b);
b2WheelJointDef def; b2WheelJointDef def;
def.Initialize(param_.body_a->GetB2Body(), param_.body_b->GetB2Body(), global::ToMeters(param_.anchor), def.Initialize(param_.body_a->GetB2Body(), param_.body_b->GetB2Body(), global::LocalToWorld(param_.anchor),
b2Vec2(param_.axis.x, param_.axis.y)); b2Vec2(param_.axis.x, param_.axis.y));
def.enableMotor = param_.enable_motor; def.enableMotor = param_.enable_motor;
def.maxMotorTorque = global::ToMeters(param_.max_motor_torque); def.maxMotorTorque = global::LocalToWorld(param_.max_motor_torque);
def.motorSpeed = global::ToMeters(param_.motor_speed); def.motorSpeed = global::LocalToWorld(param_.motor_speed);
def.frequencyHz = param_.frequency_hz; def.frequencyHz = param_.frequency_hz;
def.dampingRatio = param_.damping_ratio; def.dampingRatio = param_.damping_ratio;
@ -653,25 +653,25 @@ bool WheelJoint::Init(PhysicWorld* world)
float WheelJoint::GetJointTranslation() const float WheelJoint::GetJointTranslation() const
{ {
KGE_ASSERT(raw_joint_); KGE_ASSERT(raw_joint_);
return global::ToMeters(raw_joint_->GetJointTranslation()); return global::LocalToWorld(raw_joint_->GetJointTranslation());
} }
float WheelJoint::GetJointLinearSpeed() const float WheelJoint::GetJointLinearSpeed() const
{ {
KGE_ASSERT(raw_joint_); KGE_ASSERT(raw_joint_);
return global::ToPixels(raw_joint_->GetJointLinearSpeed()); return global::WorldToLocal(raw_joint_->GetJointLinearSpeed());
} }
void WheelJoint::SetMaxMotorTorque(float torque) void WheelJoint::SetMaxMotorTorque(float torque)
{ {
KGE_ASSERT(raw_joint_); KGE_ASSERT(raw_joint_);
raw_joint_->SetMaxMotorTorque(global::ToMeters(torque)); raw_joint_->SetMaxMotorTorque(global::LocalToWorld(torque));
} }
float WheelJoint::GetMaxMotorTorque() const float WheelJoint::GetMaxMotorTorque() const
{ {
KGE_ASSERT(raw_joint_); KGE_ASSERT(raw_joint_);
return global::ToPixels(raw_joint_->GetMaxMotorTorque()); return global::WorldToLocal(raw_joint_->GetMaxMotorTorque());
} }
// //
@ -700,7 +700,7 @@ bool MouseJoint::Init(PhysicWorld* world)
b2MouseJointDef def; b2MouseJointDef def;
def.bodyA = param_.body_a->GetB2Body(); def.bodyA = param_.body_a->GetB2Body();
def.bodyB = param_.body_b->GetB2Body(); def.bodyB = param_.body_b->GetB2Body();
def.target = global::ToMeters(param_.target); def.target = global::LocalToWorld(param_.target);
def.maxForce = param_.max_force; def.maxForce = param_.max_force;
def.frequencyHz = param_.frequency_hz; def.frequencyHz = param_.frequency_hz;
def.dampingRatio = param_.damping_ratio; def.dampingRatio = param_.damping_ratio;

View File

@ -26,25 +26,26 @@ namespace kiwano
namespace physics namespace physics
{ {
PhysicBodyPtr PhysicBody::Create(ActorPtr actor, Type type) PhysicBodyPtr PhysicBody::Create(PhysicWorldPtr world, Type type)
{ {
return PhysicBody::Create(actor.Get(), type); return PhysicBody::Create(world.Get(), type);
} }
PhysicBodyPtr PhysicBody::Create(Actor* actor, Type type) PhysicBodyPtr PhysicBody::Create(PhysicWorld* world, Type type)
{ {
if (!actor) KGE_ASSERT(world);
{
return nullptr;
}
PhysicBodyPtr ptr = new (std::nothrow) PhysicBody; PhysicBodyPtr ptr = new (std::nothrow) PhysicBody;
if (ptr) if (ptr)
{ {
ptr->SetType(type); ptr->SetType(type);
actor->AddComponent(ptr); if (ptr->Init(world))
{
world->AddBody(ptr);
return ptr;
}
} }
return ptr; return nullptr;
} }
PhysicBody::PhysicBody() PhysicBody::PhysicBody()
@ -55,6 +56,7 @@ PhysicBody::PhysicBody()
, mask_bits_(0xFFFF) , mask_bits_(0xFFFF)
, group_index_(0) , group_index_(0)
{ {
SetName("KGE_PHYSIC_BODY");
} }
PhysicBody::~PhysicBody() {} PhysicBody::~PhysicBody() {}
@ -62,7 +64,10 @@ PhysicBody::~PhysicBody() {}
void PhysicBody::InitComponent(Actor* actor) void PhysicBody::InitComponent(Actor* actor)
{ {
Component::InitComponent(actor); Component::InitComponent(actor);
UpdateFromActor();
actor->SetPhysicBody(this);
UpdateFromActor(actor);
} }
void PhysicBody::DestroyComponent() void PhysicBody::DestroyComponent()
@ -98,19 +103,90 @@ bool PhysicBody::Init(PhysicWorld* world)
if (b2body) if (b2body)
{ {
SetB2Body(b2body); SetB2Body(b2body);
UpdateFromActor();
// lazy init fixtures
for (auto fixture : fixtures_)
{
bool success = fixture->Init(this);
KGE_ASSERT(success);
}
return true; return true;
} }
return false; return false;
} }
void PhysicBody::Destroy()
{
RemoveAllFixtures();
if (body_ && world_)
{
b2World* b2world = world_->GetB2World();
b2world->DestroyBody(body_);
}
body_ = nullptr;
world_ = nullptr;
Component::RemoveFromActor();
}
void PhysicBody::BeforeSimulation(Actor* actor, const Matrix3x2& parent_to_world, const Matrix3x2& actor_to_world,
float parent_rotation)
{
UpdateFromActor(actor, actor_to_world, parent_rotation + actor->GetRotation());
/*if (actor->GetAnchor() != Vec2(0.5f, 0.5f))
{
Point position = parent_to_world.Invert().Transform(position_cached_);
offset_ = position - actor->GetPosition();
}*/
}
void PhysicBody::AfterSimulation(Actor* actor, const Matrix3x2& parent_to_world, float parent_rotation)
{
Point position_in_parent = GetPosition();
if (position_cached_ != position_in_parent)
{
/*position_in_parent = parent_to_world.Invert().Transform(position_in_parent);
actor->SetPosition(position_in_parent - offset_);*/
position_in_parent = parent_to_world.Invert().Transform(position_in_parent);
actor->SetPosition(position_in_parent);
}
actor->SetRotation(GetRotation() - parent_rotation);
}
void PhysicBody::UpdateFromActor(Actor* actor)
{
KGE_ASSERT(actor);
KGE_ASSERT(world_);
Actor* world_actor = world_->GetBoundActor();
if (world_actor)
{
float rotation = 0.0f;
Matrix3x2 transform_to_world;
Actor* ptr = actor;
while (ptr && ptr != world_actor)
{
rotation += ptr->GetRotation();
transform_to_world *= ptr->GetTransformMatrixToParent();
ptr = ptr->GetParent();
}
UpdateFromActor(actor, transform_to_world, rotation);
}
}
void PhysicBody::UpdateFromActor(Actor* actor, const Matrix3x2& actor_to_world, float rotation)
{
/*Point center = actor->GetSize() / 2;
Point position = actor_to_world.Transform(center);*/
Point anchor = actor->GetAnchor();
Point size = actor->GetSize();
Point position = actor_to_world.Transform(Point(anchor.x * size.x, anchor.y * size.y));
SetTransform(position, rotation);
position_cached_ = GetPosition();
}
void PhysicBody::AddFixture(FixturePtr fixture) void PhysicBody::AddFixture(FixturePtr fixture)
{ {
if (fixture) if (fixture)
@ -240,7 +316,7 @@ void PhysicBody::GetMassData(float* mass, Point* center, float* inertia) const
if (mass) if (mass)
*mass = data.mass; *mass = data.mass;
if (center) if (center)
*center = global::ToPixels(data.center); *center = global::WorldToLocal(data.center);
if (inertia) if (inertia)
*inertia = data.I; *inertia = data.I;
} }
@ -251,7 +327,7 @@ void PhysicBody::SetMassData(float mass, const Point& center, float inertia)
b2MassData data; b2MassData data;
data.mass = mass; data.mass = mass;
data.center = global::ToMeters(center); data.center = global::LocalToWorld(center);
data.I = inertia; data.I = inertia;
body_->SetMassData(&data); body_->SetMassData(&data);
} }
@ -265,43 +341,43 @@ void PhysicBody::ResetMassData()
Point PhysicBody::GetPosition() const Point PhysicBody::GetPosition() const
{ {
KGE_ASSERT(body_); KGE_ASSERT(body_);
return global::ToPixels(body_->GetPosition()); return global::WorldToLocal(body_->GetPosition());
} }
void PhysicBody::SetTransform(const Point& pos, float angle) void PhysicBody::SetTransform(const Point& pos, float angle)
{ {
KGE_ASSERT(body_); KGE_ASSERT(body_);
body_->SetTransform(global::ToMeters(pos), math::Degree2Radian(angle)); body_->SetTransform(global::LocalToWorld(pos), math::Degree2Radian(angle));
} }
Point PhysicBody::GetLocalPoint(const Point& world) const Point PhysicBody::GetLocalPoint(const Point& world) const
{ {
KGE_ASSERT(body_); KGE_ASSERT(body_);
return global::ToPixels(body_->GetLocalPoint(global::ToMeters(world))); return global::WorldToLocal(body_->GetLocalPoint(global::LocalToWorld(world)));
} }
Point PhysicBody::GetWorldPoint(const Point& local) const Point PhysicBody::GetWorldPoint(const Point& local) const
{ {
KGE_ASSERT(body_); KGE_ASSERT(body_);
return global::ToPixels(body_->GetWorldPoint(global::ToMeters(local))); return global::WorldToLocal(body_->GetWorldPoint(global::LocalToWorld(local)));
} }
Point PhysicBody::GetLocalCenter() const Point PhysicBody::GetLocalCenter() const
{ {
KGE_ASSERT(body_); KGE_ASSERT(body_);
return global::ToPixels(body_->GetLocalCenter()); return global::WorldToLocal(body_->GetLocalCenter());
} }
Point PhysicBody::GetWorldCenter() const Point PhysicBody::GetWorldCenter() const
{ {
KGE_ASSERT(body_); KGE_ASSERT(body_);
return global::ToPixels(body_->GetWorldCenter()); return global::WorldToLocal(body_->GetWorldCenter());
} }
void PhysicBody::ApplyForce(const Vec2& force, const Point& point, bool wake) void PhysicBody::ApplyForce(const Vec2& force, const Point& point, bool wake)
{ {
KGE_ASSERT(body_); KGE_ASSERT(body_);
body_->ApplyForce(b2Vec2(force.x, force.y), global::ToMeters(point), wake); body_->ApplyForce(b2Vec2(force.x, force.y), global::LocalToWorld(point), wake);
} }
void PhysicBody::ApplyForceToCenter(const Vec2& force, bool wake) void PhysicBody::ApplyForceToCenter(const Vec2& force, bool wake)
@ -326,45 +402,6 @@ void PhysicBody::SetB2Body(b2Body* body)
} }
} }
void PhysicBody::Destroy()
{
RemoveAllFixtures();
if (body_ && world_)
{
b2World* b2world = world_->GetB2World();
b2world->DestroyBody(body_);
}
body_ = nullptr;
world_ = nullptr;
Component::RemoveFromActor();
}
void PhysicBody::UpdateActor()
{
Actor* actor = GetBoundActor();
if (actor && body_)
{
Point position = global::ToPixels(body_->GetPosition());
float rotation = math::Radian2Degree(body_->GetAngle());
actor->SetPosition(position);
actor->SetRotation(rotation);
}
}
void PhysicBody::UpdateFromActor()
{
Actor* actor = GetBoundActor();
if (actor && body_)
{
b2Vec2 position = global::ToMeters(actor->GetPosition());
float angle = math::Degree2Radian(actor->GetRotation());
body_->SetTransform(position, angle);
}
}
void PhysicBody::UpdateFixtureFilter(b2Fixture* fixture) void PhysicBody::UpdateFixtureFilter(b2Fixture* fixture)
{ {
b2Filter filter; b2Filter filter;

View File

@ -27,6 +27,8 @@ namespace kiwano
namespace physics namespace physics
{ {
class PhysicWorld;
/** /**
* \addtogroup Physics * \addtogroup Physics
* @{ * @{
@ -36,6 +38,8 @@ namespace physics
/// @brief 物体 /// @brief 物体
class KGE_API PhysicBody : public Component class KGE_API PhysicBody : public Component
{ {
friend class PhysicWorld;
public: public:
/// \~chinese /// \~chinese
/// @brief 物体类型 /// @brief 物体类型
@ -48,15 +52,15 @@ public:
/// \~chinese /// \~chinese
/// @brief 初始化物体 /// @brief 初始化物体
/// @param actor 绑定该物体的角色 /// @param world 物理世界
/// @param type 物体类型 /// @param type 物体类型
static PhysicBodyPtr Create(ActorPtr actor, Type type); static PhysicBodyPtr Create(PhysicWorldPtr world, Type type);
/// \~chinese /// \~chinese
/// @brief 初始化物体 /// @brief 初始化物体
/// @param actor 绑定该物体的角色 /// @param world 物理世界
/// @param type 物体类型 /// @param type 物体类型
static PhysicBodyPtr Create(Actor* actor, Type type); static PhysicBodyPtr Create(PhysicWorld* world, Type type);
PhysicBody(); PhysicBody();
@ -290,14 +294,6 @@ public:
/// @brief 获取物体所在物理世界 /// @brief 获取物体所在物理世界
PhysicWorld* GetWorld() const; PhysicWorld* GetWorld() const;
/// \~chinese
/// @brief 将物体信息更新到角色
void UpdateActor();
/// \~chinese
/// @brief 将角色信息更新到物体
void UpdateFromActor();
/// \~chinese /// \~chinese
/// @brief 销毁物体 /// @brief 销毁物体
void Destroy(); void Destroy();
@ -319,21 +315,39 @@ protected:
/// @brief 销毁组件 /// @brief 销毁组件
void DestroyComponent() override; void DestroyComponent() override;
private: /// \~chinese
/// @brief 更新物体状态
void UpdateFromActor(Actor* actor);
/// \~chinese
/// @brief 更新物体状态
void UpdateFromActor(Actor* actor, const Matrix3x2& actor_to_world, float parent_rotation);
/// \~chinese /// \~chinese
/// @brief 更新夹具过滤器 /// @brief 更新夹具过滤器
void UpdateFixtureFilter(b2Fixture* fixture); void UpdateFixtureFilter(b2Fixture* fixture);
/// \~chinese
/// @brief 更新物理身体前
void BeforeSimulation(Actor* actor, const Matrix3x2& parent_to_world, const Matrix3x2& actor_to_world,
float parent_rotation);
/// \~chinese
/// @brief 更新物理身体后
void AfterSimulation(Actor* actorconst, const Matrix3x2& parent_to_world, float parent_rotation);
private: private:
PhysicWorld* world_; PhysicWorld* world_;
b2Body* body_; b2Body* body_;
uint16_t category_bits_;
uint16_t category_bits_; uint16_t mask_bits_;
uint16_t mask_bits_; int16_t group_index_;
int16_t group_index_;
PhysicBody::Type type_;
PhysicBody::Type type_;
Vector<FixturePtr> fixtures_; Vector<FixturePtr> fixtures_;
Point offset_;
Point position_cached_;
}; };
/** @} */ /** @} */

View File

@ -113,6 +113,8 @@ PhysicWorld::PhysicWorld()
, vel_iter_(6) , vel_iter_(6)
, pos_iter_(2) , pos_iter_(2)
{ {
SetName("KGE_PHYSIC_WORLD");
destroy_listener_ = std::make_unique<DestructionListener>(Closure(this, &PhysicWorld::JointRemoved)); destroy_listener_ = std::make_unique<DestructionListener>(Closure(this, &PhysicWorld::JointRemoved));
world_.SetDestructionListener(destroy_listener_.get()); world_.SetDestructionListener(destroy_listener_.get());
@ -134,9 +136,6 @@ void PhysicWorld::AddBody(PhysicBodyPtr body)
{ {
if (body) if (body)
{ {
bool success = body->Init(this);
KGE_ASSERT(success);
bodies_.push_back(body); bodies_.push_back(body);
} }
} }
@ -234,22 +233,25 @@ ContactList PhysicWorld::GetContactList()
return ContactList(contact); return ContactList(contact);
} }
void PhysicWorld::InitComponent(Actor* actor)
{
Component::InitComponent(actor);
// Update body status
Actor* world_actor = GetBoundActor();
BeforeSimulation(world_actor, Matrix3x2(), 0.0f);
}
void PhysicWorld::OnUpdate(Duration dt) void PhysicWorld::OnUpdate(Duration dt)
{ {
// Update bodies transform from actors Actor* world_actor = GetBoundActor();
for (auto& body : bodies_)
{
body->UpdateFromActor();
}
BeforeSimulation(world_actor, Matrix3x2(), 0.0f);
// Update physic world
world_.Step(dt.Seconds(), vel_iter_, pos_iter_); world_.Step(dt.Seconds(), vel_iter_, pos_iter_);
// Update actors transform from bodies AfterSimulation(world_actor, Matrix3x2(), 0.0f);
for (auto& body : bodies_)
{
if (body->GetType() != PhysicBody::Type::Static)
body->UpdateActor();
}
} }
void PhysicWorld::DispatchEvent(Event* evt) void PhysicWorld::DispatchEvent(Event* evt)
@ -274,5 +276,38 @@ void PhysicWorld::JointRemoved(b2Joint* b2joint)
} }
} }
void PhysicWorld::BeforeSimulation(Actor* parent, const Matrix3x2& parent_to_world, float parent_rotation)
{
for (auto child : parent->GetAllChildren())
{
Matrix3x2 child_to_world = child->GetTransformMatrixToParent() * parent_to_world;
PhysicBody* body = child->GetPhysicBody();
if (body)
{
body->BeforeSimulation(child.Get(), parent_to_world, child_to_world, parent_rotation);
}
float rotation = parent_rotation + child->GetRotation();
BeforeSimulation(child.Get(), child_to_world, rotation);
}
}
void PhysicWorld::AfterSimulation(Actor* parent, const Matrix3x2& parent_to_world, float parent_rotation)
{
for (auto child : parent->GetAllChildren())
{
PhysicBody* body = child->GetPhysicBody();
if (body)
{
body->AfterSimulation(child.Get(), parent_to_world, parent_rotation);
}
Matrix3x2 child_to_world = child->GetTransformMatrixToParent() * parent_to_world;
float rotation = parent_rotation + child->GetRotation();
AfterSimulation(child.Get(), child_to_world, rotation);
}
}
} // namespace physics } // namespace physics
} // namespace kiwano } // namespace kiwano

View File

@ -121,12 +121,30 @@ public:
const b2World* GetB2World() const; const b2World* GetB2World() const;
protected: protected:
/// \~chinese
/// @brief 初始化组件
void InitComponent(Actor* actor) override;
/// \~chinese
/// @brief 更新组件
void OnUpdate(Duration dt) override; void OnUpdate(Duration dt) override;
/// \~chinese
/// @brief 分发物理世界事件
void DispatchEvent(Event* evt); void DispatchEvent(Event* evt);
/// \~chinese
/// @brief 关节移除时的回调函数
void JointRemoved(b2Joint* b2joint); void JointRemoved(b2Joint* b2joint);
/// \~chinese
/// @brief 更新物理世界前
void BeforeSimulation(Actor* parent, const Matrix3x2& parent_to_world, float parent_rotation);
/// \~chinese
/// @brief 更新物理世界后
void AfterSimulation(Actor* parent, const Matrix3x2& parent_to_world, float parent_rotation);
private: private:
b2World world_; b2World world_;
int vel_iter_; int vel_iter_;

View File

@ -65,6 +65,7 @@ Actor::Actor()
, opacity_(1.f) , opacity_(1.f)
, displayed_opacity_(1.f) , displayed_opacity_(1.f)
, anchor_(default_anchor_x, default_anchor_y) , anchor_(default_anchor_x, default_anchor_y)
, physic_body_(nullptr)
{ {
} }
@ -315,6 +316,12 @@ const Matrix3x2& Actor::GetTransformInverseMatrix() const
return transform_matrix_inverse_; return transform_matrix_inverse_;
} }
const Matrix3x2& Actor::GetTransformMatrixToParent() const
{
UpdateTransform();
return transform_matrix_to_parent_;
}
void Actor::UpdateTransform() const void Actor::UpdateTransform() const
{ {
if (!dirty_transform_) if (!dirty_transform_)
@ -326,16 +333,18 @@ void Actor::UpdateTransform() const
if (is_fast_transform_) if (is_fast_transform_)
{ {
transform_matrix_ = Matrix3x2::Translation(transform_.position); transform_matrix_to_parent_ = Matrix3x2::Translation(transform_.position);
} }
else else
{ {
// matrix multiplication is optimized by expression template // matrix multiplication is optimized by expression template
transform_matrix_ = transform_.ToMatrix(); transform_matrix_to_parent_ = transform_.ToMatrix();
} }
transform_matrix_.Translate(Point{ -size_.x * anchor_.x, -size_.y * anchor_.y }); Point anchor_offset(-size_.x * anchor_.x, -size_.y * anchor_.y);
transform_matrix_to_parent_.Translate(anchor_offset);
transform_matrix_ = transform_matrix_to_parent_;
if (parent_) if (parent_)
{ {
transform_matrix_ *= parent_->transform_matrix_; transform_matrix_ *= parent_->transform_matrix_;
@ -727,8 +736,20 @@ bool Actor::ContainsPoint(const Point& point) const
if (size_.x == 0.f || size_.y == 0.f) if (size_.x == 0.f || size_.y == 0.f)
return false; return false;
Point local = ConvertToLocal(point);
return local.x >= 0 && local.y >= 0 && local.x <= size_.x && local.y <= size_.y;
}
Point Actor::ConvertToLocal(const Point& point) const
{
Point local = GetTransformInverseMatrix().Transform(point); Point local = GetTransformInverseMatrix().Transform(point);
return GetBounds().ContainsPoint(local); return local;
}
Point Actor::ConvertToWorld(const Point& point) const
{
Point world = GetTransformMatrix().Transform(point);
return world;
} }
} // namespace kiwano } // namespace kiwano

View File

@ -33,8 +33,12 @@ class Stage;
class Director; class Director;
class RenderContext; class RenderContext;
KGE_DECLARE_SMART_PTR(Actor); namespace physics
{
class PhysicBody;
}
KGE_DECLARE_SMART_PTR(Actor);
/// \~chinese /// \~chinese
/// @brief 角色列表 /// @brief 角色列表
@ -225,6 +229,10 @@ public:
/// @brief 获取二维变换的逆矩阵 /// @brief 获取二维变换的逆矩阵
const Matrix3x2& GetTransformInverseMatrix() const; const Matrix3x2& GetTransformInverseMatrix() const;
/// \~chinese
/// @brief 获取变换到父角色的二维变换矩阵
const Matrix3x2& GetTransformMatrixToParent() const;
/// \~chinese /// \~chinese
/// @brief 设置角色是否可见 /// @brief 设置角色是否可见
void SetVisible(bool val); void SetVisible(bool val);
@ -408,10 +416,26 @@ public:
/// @brief 获取更新时的回调函数 /// @brief 获取更新时的回调函数
UpdateCallback GetCallbackOnUpdate() const; UpdateCallback GetCallbackOnUpdate() const;
/// \~chinese
/// @brief 获取物理身体仅当kiwano-physics包启用时生效
physics::PhysicBody* GetPhysicBody() const;
/// \~chinese
/// @brief 设置物理身体仅当kiwano-physics包启用时生效
void SetPhysicBody(physics::PhysicBody* body);
/// \~chinese /// \~chinese
/// @brief 判断点是否在角色内 /// @brief 判断点是否在角色内
virtual bool ContainsPoint(const Point& point) const; virtual bool ContainsPoint(const Point& point) const;
/// \~chinese
/// @brief 将世界坐标系点转换为局部坐标系点
Point ConvertToLocal(const Point& point) const;
/// \~chinese
/// @brief 将局部坐标系点转换为世界坐标系点
Point ConvertToWorld(const Point& point) const;
/// \~chinese /// \~chinese
/// @brief 渲染角色边界 /// @brief 渲染角色边界
void ShowBorder(bool show); void ShowBorder(bool show);
@ -499,6 +523,9 @@ private:
mutable bool dirty_transform_inverse_; mutable bool dirty_transform_inverse_;
mutable Matrix3x2 transform_matrix_; mutable Matrix3x2 transform_matrix_;
mutable Matrix3x2 transform_matrix_inverse_; mutable Matrix3x2 transform_matrix_inverse_;
mutable Matrix3x2 transform_matrix_to_parent_;
physics::PhysicBody* physic_body_;
}; };
/** @} */ /** @} */
@ -683,6 +710,16 @@ inline Actor::UpdateCallback Actor::GetCallbackOnUpdate() const
return cb_update_; return cb_update_;
} }
inline physics::PhysicBody* Actor::GetPhysicBody() const
{
return physic_body_;
}
inline void Actor::SetPhysicBody(physics::PhysicBody* body)
{
physic_body_ = body;
}
inline void Actor::ShowBorder(bool show) inline void Actor::ShowBorder(bool show)
{ {
show_border_ = show; show_border_ = show;

View File

@ -47,6 +47,7 @@ ButtonPtr Button::Create(const Callback& click, const Callback& pressed, const C
Button::Button() Button::Button()
: status_(Status::Normal) : status_(Status::Normal)
{ {
SetName("KGE_BUTTON");
} }
Button::~Button() Button::~Button()

View File

@ -115,7 +115,7 @@ KGE_SUPPRESS_WARNING_POP
} }
template <typename _Lty, typename _Rty> template <typename _Lty, typename _Rty>
inline Matrix3x2T& operator=(MatrixMultiply<ValueType, _Lty, const _Rty>& other) inline Matrix3x2T& operator=(const MatrixMultiply<ValueType, _Lty, _Rty>& other)
{ {
Matrix3x2T result(other); Matrix3x2T result(other);
(*this) = result; (*this) = result;
@ -280,7 +280,7 @@ inline MatrixMultiply<_Ty, Matrix3x2T<_Ty>, Matrix3x2T<_Ty>> operator*(const Mat
template <typename _Ty, typename _Lty, typename _Rty> template <typename _Ty, typename _Lty, typename _Rty>
inline MatrixMultiply<_Ty, MatrixMultiply<_Ty, _Lty, _Rty>, Matrix3x2T<_Ty>> inline MatrixMultiply<_Ty, MatrixMultiply<_Ty, _Lty, _Rty>, Matrix3x2T<_Ty>>
operator*(MatrixMultiply<_Ty, _Lty, const _Rty>& lhs, const Matrix3x2T<_Ty>& rhs) operator*(const MatrixMultiply<_Ty, _Lty, _Rty>& lhs, const Matrix3x2T<_Ty>& rhs)
{ {
return MatrixMultiply<_Ty, MatrixMultiply<_Ty, _Lty, _Rty>, Matrix3x2T<_Ty>>(lhs, rhs); return MatrixMultiply<_Ty, MatrixMultiply<_Ty, _Lty, _Rty>, Matrix3x2T<_Ty>>(lhs, rhs);
} }