Update physics
This commit is contained in:
		
							parent
							
								
									d6b95e3b40
								
							
						
					
					
						commit
						f7844c1ac9
					
				|  | @ -61,13 +61,13 @@ PhysicBody* Contact::GetBodyB() const | |||
| void Contact::SetTangentSpeed(float speed) | ||||
| { | ||||
|     KGE_ASSERT(contact_); | ||||
|     contact_->SetTangentSpeed(global::ToMeters(speed)); | ||||
|     contact_->SetTangentSpeed(global::LocalToWorld(speed)); | ||||
| } | ||||
| 
 | ||||
| float Contact::GetTangentSpeed() const | ||||
| { | ||||
|     KGE_ASSERT(contact_); | ||||
|     return global::ToPixels(contact_->GetTangentSpeed()); | ||||
|     return global::WorldToLocal(contact_->GetTangentSpeed()); | ||||
| } | ||||
| 
 | ||||
| }  // namespace physics
 | ||||
|  |  | |||
|  | @ -33,8 +33,8 @@ FixturePtr Fixture::CreateCircle(const Param& param, float radius, const Point& | |||
|     if (ptr) | ||||
|     { | ||||
|         auto shape      = std::make_unique<b2CircleShape>(); | ||||
|         shape->m_radius = global::ToMeters(radius); | ||||
|         shape->m_p      = global::ToMeters(offset); | ||||
|         shape->m_radius = global::LocalToWorld(radius); | ||||
|         shape->m_p      = global::LocalToWorld(offset); | ||||
| 
 | ||||
|         ptr->shape_ = std::move(shape); | ||||
|         ptr->param_ = param; | ||||
|  | @ -47,8 +47,8 @@ FixturePtr Fixture::CreateRect(const Param& param, const Size& size, const Point | |||
|     FixturePtr ptr = new (std::nothrow) Fixture; | ||||
|     if (ptr) | ||||
|     { | ||||
|         b2Vec2 b2size   = global::ToMeters(size); | ||||
|         b2Vec2 b2offset = global::ToMeters(offset); | ||||
|         b2Vec2 b2size   = global::LocalToWorld(size); | ||||
|         b2Vec2 b2offset = global::LocalToWorld(offset); | ||||
| 
 | ||||
|         auto shape = std::make_unique<b2PolygonShape>(); | ||||
|         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()); | ||||
|         for (const auto& v : vertexs) | ||||
|         { | ||||
|             b2vertexs.push_back(global::ToMeters(v)); | ||||
|             b2vertexs.push_back(global::LocalToWorld(v)); | ||||
|         } | ||||
| 
 | ||||
|         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; | ||||
|     if (ptr) | ||||
|     { | ||||
|         b2Vec2 start = global::ToMeters(p1); | ||||
|         b2Vec2 end   = global::ToMeters(p2); | ||||
|         b2Vec2 start = global::LocalToWorld(p1); | ||||
|         b2Vec2 end   = global::LocalToWorld(p2); | ||||
| 
 | ||||
|         auto shape = std::make_unique<b2EdgeShape>(); | ||||
|         shape->Set(start, end); | ||||
|  | @ -106,7 +106,7 @@ FixturePtr Fixture::CreateChain(const Param& param, const Vector<Point>& vertexs | |||
|         b2vertexs.reserve(vertexs.size()); | ||||
|         for (const auto& v : vertexs) | ||||
|         { | ||||
|             b2vertexs.push_back(global::ToMeters(v)); | ||||
|             b2vertexs.push_back(global::LocalToWorld(v)); | ||||
|         } | ||||
| 
 | ||||
|         auto shape = std::make_unique<b2ChainShape>(); | ||||
|  | @ -189,7 +189,7 @@ void Fixture::GetMassData(float* mass, Point* center, float* inertia) const | |||
|     if (mass) | ||||
|         *mass = data.mass; | ||||
|     if (center) | ||||
|         *center = global::ToPixels(data.center); | ||||
|         *center = global::WorldToLocal(data.center); | ||||
|     if (inertia) | ||||
|         *inertia = data.I; | ||||
| } | ||||
|  | @ -197,7 +197,7 @@ void Fixture::GetMassData(float* mass, Point* center, float* inertia) const | |||
| bool Fixture::TestPoint(const Point& p) const | ||||
| { | ||||
|     KGE_ASSERT(fixture_); | ||||
|     return fixture_->TestPoint(global::ToMeters(p)); | ||||
|     return fixture_->TestPoint(global::LocalToWorld(p)); | ||||
| } | ||||
| 
 | ||||
| void Fixture::Destroy() | ||||
|  |  | |||
|  | @ -43,24 +43,24 @@ void SetScale(float scale) | |||
|     global_scale = scale; | ||||
| } | ||||
| 
 | ||||
| float ToPixels(float value) | ||||
| float WorldToLocal(float value) | ||||
| { | ||||
|     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; | ||||
| } | ||||
| 
 | ||||
| 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
 | ||||
|  |  | |||
|  | @ -48,22 +48,22 @@ void SetScale(float scale); | |||
| /// \~chinese
 | ||||
| /// @brief 游戏世界单位转换为物理世界单位
 | ||||
| /// @details 根据全局缩放比例将物理世界的单位米转换为像素单位
 | ||||
| float ToPixels(float value); | ||||
| float WorldToLocal(float value); | ||||
| 
 | ||||
| /// \~chinese
 | ||||
| /// @brief 游戏世界单位转换为物理世界单位
 | ||||
| /// @details 根据全局缩放比例将物理世界的单位米转换为像素单位
 | ||||
| Vec2 ToPixels(const b2Vec2& pos); | ||||
| Vec2 WorldToLocal(const b2Vec2& pos); | ||||
| 
 | ||||
| /// \~chinese
 | ||||
| /// @brief 物理世界单位转换为游戏世界单位
 | ||||
| /// @details 根据全局缩放比例将像素单位转换为物理世界的单位米
 | ||||
| float ToMeters(float value); | ||||
| float LocalToWorld(float value); | ||||
| 
 | ||||
| /// \~chinese
 | ||||
| /// @brief 物理世界单位转换为游戏世界单位
 | ||||
| /// @details 根据全局缩放比例将像素单位转换为物理世界的单位米
 | ||||
| b2Vec2 ToMeters(const Vec2& pos); | ||||
| b2Vec2 LocalToWorld(const Vec2& pos); | ||||
| 
 | ||||
| }  // namespace global
 | ||||
| }  // namespace physics
 | ||||
|  |  | |||
|  | @ -129,8 +129,8 @@ bool DistanceJoint::Init(PhysicWorld* world) | |||
|     KGE_ASSERT(param_.body_a && param_.body_b); | ||||
| 
 | ||||
|     b2DistanceJointDef def; | ||||
|     def.Initialize(param_.body_a->GetB2Body(), param_.body_b->GetB2Body(), global::ToMeters(param_.anchor_a), | ||||
|                    global::ToMeters(param_.anchor_b)); | ||||
|     def.Initialize(param_.body_a->GetB2Body(), param_.body_b->GetB2Body(), global::LocalToWorld(param_.anchor_a), | ||||
|                    global::LocalToWorld(param_.anchor_b)); | ||||
|     def.frequencyHz  = param_.frequency_hz; | ||||
|     def.dampingRatio = param_.damping_ratio; | ||||
| 
 | ||||
|  | @ -142,13 +142,13 @@ bool DistanceJoint::Init(PhysicWorld* world) | |||
| void DistanceJoint::SetLength(float length) | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_); | ||||
|     raw_joint_->SetLength(global::ToMeters(length)); | ||||
|     raw_joint_->SetLength(global::LocalToWorld(length)); | ||||
| } | ||||
| 
 | ||||
| float DistanceJoint::GetLength() const | ||||
| { | ||||
|     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); | ||||
| 
 | ||||
|     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.maxTorque = global::ToMeters(param_.max_torque); | ||||
|     def.maxTorque = global::LocalToWorld(param_.max_torque); | ||||
| 
 | ||||
|     Joint::Init(world, &def); | ||||
|     raw_joint_ = static_cast<b2FrictionJoint*>(GetB2Joint()); | ||||
|  | @ -199,13 +199,13 @@ float FrictionJoint::GetMaxForce() const | |||
| void FrictionJoint::SetMaxTorque(float length) | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_); | ||||
|     raw_joint_->SetMaxTorque(global::ToMeters(length)); | ||||
|     raw_joint_->SetMaxTorque(global::LocalToWorld(length)); | ||||
| } | ||||
| 
 | ||||
| float FrictionJoint::GetMaxTorque() const | ||||
| { | ||||
|     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; | ||||
|     def.Initialize(param_.body_a->GetB2Body(), param_.body_b->GetB2Body()); | ||||
|     def.maxForce         = param_.max_force; | ||||
|     def.maxTorque        = global::ToMeters(param_.max_torque); | ||||
|     def.maxTorque        = global::LocalToWorld(param_.max_torque); | ||||
|     def.correctionFactor = param_.correction_factor; | ||||
| 
 | ||||
|     Joint::Init(world, &def); | ||||
|  | @ -302,13 +302,13 @@ float MotorJoint::GetMaxForce() const | |||
| void MotorJoint::SetMaxTorque(float length) | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_); | ||||
|     raw_joint_->SetMaxTorque(global::ToMeters(length)); | ||||
|     raw_joint_->SetMaxTorque(global::LocalToWorld(length)); | ||||
| } | ||||
| 
 | ||||
| float MotorJoint::GetMaxTorque() const | ||||
| { | ||||
|     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); | ||||
| 
 | ||||
|     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)); | ||||
|     def.enableLimit      = param_.enable_limit; | ||||
|     def.lowerTranslation = global::ToMeters(param_.lower_translation); | ||||
|     def.upperTranslation = global::ToMeters(param_.upper_translation); | ||||
|     def.lowerTranslation = global::LocalToWorld(param_.lower_translation); | ||||
|     def.upperTranslation = global::LocalToWorld(param_.upper_translation); | ||||
|     def.enableMotor      = param_.enable_motor; | ||||
|     def.maxMotorForce    = param_.max_motor_force; | ||||
|     def.motorSpeed       = global::ToMeters(param_.motor_speed); | ||||
|     def.motorSpeed       = global::LocalToWorld(param_.motor_speed); | ||||
| 
 | ||||
|     Joint::Init(world, &def); | ||||
|     raw_joint_ = static_cast<b2PrismaticJoint*>(GetB2Joint()); | ||||
|  | @ -352,31 +352,31 @@ bool PrismaticJoint::Init(PhysicWorld* world) | |||
| float PrismaticJoint::GetJointTranslation() const | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_); | ||||
|     return global::ToPixels(raw_joint_->GetJointTranslation()); | ||||
|     return global::WorldToLocal(raw_joint_->GetJointTranslation()); | ||||
| } | ||||
| 
 | ||||
| float PrismaticJoint::GetJointSpeed() const | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_); | ||||
|     return global::ToPixels(raw_joint_->GetJointSpeed()); | ||||
|     return global::WorldToLocal(raw_joint_->GetJointSpeed()); | ||||
| } | ||||
| 
 | ||||
| float PrismaticJoint::GetLowerLimit() const | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_); | ||||
|     return global::ToPixels(raw_joint_->GetLowerLimit()); | ||||
|     return global::WorldToLocal(raw_joint_->GetLowerLimit()); | ||||
| } | ||||
| 
 | ||||
| float PrismaticJoint::GetUpperLimit() const | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_); | ||||
|     return global::ToPixels(raw_joint_->GetUpperLimit()); | ||||
|     return global::WorldToLocal(raw_joint_->GetUpperLimit()); | ||||
| } | ||||
| 
 | ||||
| void PrismaticJoint::SetLimits(float lower, float upper) | ||||
| { | ||||
|     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); | ||||
| 
 | ||||
|     b2PulleyJointDef def; | ||||
|     def.Initialize(param_.body_a->GetB2Body(), param_.body_b->GetB2Body(), global::ToMeters(param_.ground_anchor_a), | ||||
|                    global::ToMeters(param_.ground_anchor_b), global::ToMeters(param_.anchor_a), | ||||
|                    global::ToMeters(param_.anchor_b), param_.ratio); | ||||
|     def.Initialize(param_.body_a->GetB2Body(), param_.body_b->GetB2Body(), global::LocalToWorld(param_.ground_anchor_a), | ||||
|                    global::LocalToWorld(param_.ground_anchor_b), global::LocalToWorld(param_.anchor_a), | ||||
|                    global::LocalToWorld(param_.anchor_b), param_.ratio); | ||||
| 
 | ||||
|     Joint::Init(world, &def); | ||||
|     raw_joint_ = static_cast<b2PulleyJoint*>(GetB2Joint()); | ||||
|  | @ -415,13 +415,13 @@ bool PulleyJoint::Init(PhysicWorld* world) | |||
| Point PulleyJoint::GetGroundAnchorA() const | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_); | ||||
|     return global::ToPixels(raw_joint_->GetGroundAnchorA()); | ||||
|     return global::WorldToLocal(raw_joint_->GetGroundAnchorA()); | ||||
| } | ||||
| 
 | ||||
| Point PulleyJoint::GetGroundAnchorB() const | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_); | ||||
|     return global::ToPixels(raw_joint_->GetGroundAnchorB()); | ||||
|     return global::WorldToLocal(raw_joint_->GetGroundAnchorB()); | ||||
| } | ||||
| 
 | ||||
| float PulleyJoint::GetRatio() const | ||||
|  | @ -433,25 +433,25 @@ float PulleyJoint::GetRatio() const | |||
| float PulleyJoint::GetLengthA() const | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_); | ||||
|     return global::ToPixels(raw_joint_->GetLengthA()); | ||||
|     return global::WorldToLocal(raw_joint_->GetLengthA()); | ||||
| } | ||||
| 
 | ||||
| float PulleyJoint::GetLengthB() const | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_); | ||||
|     return global::ToPixels(raw_joint_->GetLengthB()); | ||||
|     return global::WorldToLocal(raw_joint_->GetLengthB()); | ||||
| } | ||||
| 
 | ||||
| float PulleyJoint::GetCurrentLengthA() const | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_); | ||||
|     return global::ToPixels(raw_joint_->GetCurrentLengthA()); | ||||
|     return global::WorldToLocal(raw_joint_->GetCurrentLengthA()); | ||||
| } | ||||
| 
 | ||||
| float PulleyJoint::GetCurrentLengthB() const | ||||
| { | ||||
|     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); | ||||
| 
 | ||||
|     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.lowerAngle     = math::Degree2Radian(param_.lower_angle); | ||||
|     def.upperAngle     = math::Degree2Radian(param_.upper_angle); | ||||
|     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); | ||||
| 
 | ||||
|     Joint::Init(world, &def); | ||||
|  | @ -524,13 +524,13 @@ void RevoluteJoint::SetLimits(float lower, float upper) | |||
| void RevoluteJoint::SetMaxMotorTorque(float torque) | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_); | ||||
|     raw_joint_->SetMaxMotorTorque(global::ToMeters(torque)); | ||||
|     raw_joint_->SetMaxMotorTorque(global::LocalToWorld(torque)); | ||||
| } | ||||
| 
 | ||||
| float RevoluteJoint::GetMaxMotorTorque() const | ||||
| { | ||||
|     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; | ||||
|     def.bodyA        = param_.body_a->GetB2Body(); | ||||
|     def.bodyB        = param_.body_b->GetB2Body(); | ||||
|     def.localAnchorA = global::ToMeters(param_.local_anchor_a); | ||||
|     def.localAnchorB = global::ToMeters(param_.local_anchor_b); | ||||
|     def.maxLength    = global::ToMeters(param_.max_length); | ||||
|     def.localAnchorA = global::LocalToWorld(param_.local_anchor_a); | ||||
|     def.localAnchorB = global::LocalToWorld(param_.local_anchor_b); | ||||
|     def.maxLength    = global::LocalToWorld(param_.max_length); | ||||
| 
 | ||||
|     Joint::Init(world, &def); | ||||
|     raw_joint_ = static_cast<b2RopeJoint*>(GetB2Joint()); | ||||
|  | @ -571,13 +571,13 @@ bool RopeJoint::Init(PhysicWorld* world) | |||
| void RopeJoint::SetMaxLength(float length) | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_); | ||||
|     raw_joint_->SetMaxLength(global::ToMeters(length)); | ||||
|     raw_joint_->SetMaxLength(global::LocalToWorld(length)); | ||||
| } | ||||
| 
 | ||||
| float RopeJoint::GetMaxLength() const | ||||
| { | ||||
|     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); | ||||
| 
 | ||||
|     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.dampingRatio = param_.damping_ratio; | ||||
| 
 | ||||
|  | @ -637,11 +637,11 @@ bool WheelJoint::Init(PhysicWorld* world) | |||
|     KGE_ASSERT(param_.body_a && param_.body_b); | ||||
| 
 | ||||
|     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)); | ||||
|     def.enableMotor    = param_.enable_motor; | ||||
|     def.maxMotorTorque = global::ToMeters(param_.max_motor_torque); | ||||
|     def.motorSpeed     = global::ToMeters(param_.motor_speed); | ||||
|     def.maxMotorTorque = global::LocalToWorld(param_.max_motor_torque); | ||||
|     def.motorSpeed     = global::LocalToWorld(param_.motor_speed); | ||||
|     def.frequencyHz    = param_.frequency_hz; | ||||
|     def.dampingRatio   = param_.damping_ratio; | ||||
| 
 | ||||
|  | @ -653,25 +653,25 @@ bool WheelJoint::Init(PhysicWorld* world) | |||
| float WheelJoint::GetJointTranslation() const | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_); | ||||
|     return global::ToMeters(raw_joint_->GetJointTranslation()); | ||||
|     return global::LocalToWorld(raw_joint_->GetJointTranslation()); | ||||
| } | ||||
| 
 | ||||
| float WheelJoint::GetJointLinearSpeed() const | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_); | ||||
|     return global::ToPixels(raw_joint_->GetJointLinearSpeed()); | ||||
|     return global::WorldToLocal(raw_joint_->GetJointLinearSpeed()); | ||||
| } | ||||
| 
 | ||||
| void WheelJoint::SetMaxMotorTorque(float torque) | ||||
| { | ||||
|     KGE_ASSERT(raw_joint_); | ||||
|     raw_joint_->SetMaxMotorTorque(global::ToMeters(torque)); | ||||
|     raw_joint_->SetMaxMotorTorque(global::LocalToWorld(torque)); | ||||
| } | ||||
| 
 | ||||
| float WheelJoint::GetMaxMotorTorque() const | ||||
| { | ||||
|     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; | ||||
|     def.bodyA        = param_.body_a->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.frequencyHz  = param_.frequency_hz; | ||||
|     def.dampingRatio = param_.damping_ratio; | ||||
|  |  | |||
|  | @ -26,26 +26,27 @@ namespace kiwano | |||
| 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) | ||||
|     { | ||||
|         return nullptr; | ||||
|     } | ||||
|     KGE_ASSERT(world); | ||||
| 
 | ||||
|     PhysicBodyPtr ptr = new (std::nothrow) PhysicBody; | ||||
|     if (ptr) | ||||
|     { | ||||
|         ptr->SetType(type); | ||||
|         actor->AddComponent(ptr); | ||||
|     } | ||||
|         if (ptr->Init(world)) | ||||
|         { | ||||
|             world->AddBody(ptr); | ||||
|             return ptr; | ||||
|         } | ||||
|     } | ||||
|     return nullptr; | ||||
| } | ||||
| 
 | ||||
| PhysicBody::PhysicBody() | ||||
|     : body_(nullptr) | ||||
|  | @ -55,6 +56,7 @@ PhysicBody::PhysicBody() | |||
|     , mask_bits_(0xFFFF) | ||||
|     , group_index_(0) | ||||
| { | ||||
|     SetName("KGE_PHYSIC_BODY"); | ||||
| } | ||||
| 
 | ||||
| PhysicBody::~PhysicBody() {} | ||||
|  | @ -62,7 +64,10 @@ PhysicBody::~PhysicBody() {} | |||
| void PhysicBody::InitComponent(Actor* actor) | ||||
| { | ||||
|     Component::InitComponent(actor); | ||||
|     UpdateFromActor(); | ||||
| 
 | ||||
|     actor->SetPhysicBody(this); | ||||
| 
 | ||||
|     UpdateFromActor(actor); | ||||
| } | ||||
| 
 | ||||
| void PhysicBody::DestroyComponent() | ||||
|  | @ -98,19 +103,90 @@ bool PhysicBody::Init(PhysicWorld* world) | |||
|     if (b2body) | ||||
|     { | ||||
|         SetB2Body(b2body); | ||||
|         UpdateFromActor(); | ||||
| 
 | ||||
|         // lazy init fixtures
 | ||||
|         for (auto fixture : fixtures_) | ||||
|         { | ||||
|             bool success = fixture->Init(this); | ||||
|             KGE_ASSERT(success); | ||||
|         } | ||||
|         return true; | ||||
|     } | ||||
|     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) | ||||
| { | ||||
|     if (fixture) | ||||
|  | @ -240,7 +316,7 @@ void PhysicBody::GetMassData(float* mass, Point* center, float* inertia) const | |||
|     if (mass) | ||||
|         *mass = data.mass; | ||||
|     if (center) | ||||
|         *center = global::ToPixels(data.center); | ||||
|         *center = global::WorldToLocal(data.center); | ||||
|     if (inertia) | ||||
|         *inertia = data.I; | ||||
| } | ||||
|  | @ -251,7 +327,7 @@ void PhysicBody::SetMassData(float mass, const Point& center, float inertia) | |||
| 
 | ||||
|     b2MassData data; | ||||
|     data.mass   = mass; | ||||
|     data.center = global::ToMeters(center); | ||||
|     data.center = global::LocalToWorld(center); | ||||
|     data.I      = inertia; | ||||
|     body_->SetMassData(&data); | ||||
| } | ||||
|  | @ -265,43 +341,43 @@ void PhysicBody::ResetMassData() | |||
| Point PhysicBody::GetPosition() const | ||||
| { | ||||
|     KGE_ASSERT(body_); | ||||
|     return global::ToPixels(body_->GetPosition()); | ||||
|     return global::WorldToLocal(body_->GetPosition()); | ||||
| } | ||||
| 
 | ||||
| void PhysicBody::SetTransform(const Point& pos, float angle) | ||||
| { | ||||
|     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 | ||||
| { | ||||
|     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 | ||||
| { | ||||
|     KGE_ASSERT(body_); | ||||
|     return global::ToPixels(body_->GetWorldPoint(global::ToMeters(local))); | ||||
|     return global::WorldToLocal(body_->GetWorldPoint(global::LocalToWorld(local))); | ||||
| } | ||||
| 
 | ||||
| Point PhysicBody::GetLocalCenter() const | ||||
| { | ||||
|     KGE_ASSERT(body_); | ||||
|     return global::ToPixels(body_->GetLocalCenter()); | ||||
|     return global::WorldToLocal(body_->GetLocalCenter()); | ||||
| } | ||||
| 
 | ||||
| Point PhysicBody::GetWorldCenter() const | ||||
| { | ||||
|     KGE_ASSERT(body_); | ||||
|     return global::ToPixels(body_->GetWorldCenter()); | ||||
|     return global::WorldToLocal(body_->GetWorldCenter()); | ||||
| } | ||||
| 
 | ||||
| void PhysicBody::ApplyForce(const Vec2& force, const Point& point, bool wake) | ||||
| { | ||||
|     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) | ||||
|  | @ -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) | ||||
| { | ||||
|     b2Filter filter; | ||||
|  |  | |||
|  | @ -27,6 +27,8 @@ namespace kiwano | |||
| namespace physics | ||||
| { | ||||
| 
 | ||||
| class PhysicWorld; | ||||
| 
 | ||||
| /**
 | ||||
|  * \addtogroup Physics | ||||
|  * @{ | ||||
|  | @ -36,6 +38,8 @@ namespace physics | |||
| /// @brief 物体
 | ||||
| class KGE_API PhysicBody : public Component | ||||
| { | ||||
|     friend class PhysicWorld; | ||||
| 
 | ||||
| public: | ||||
|     /// \~chinese
 | ||||
|     /// @brief 物体类型
 | ||||
|  | @ -48,15 +52,15 @@ public: | |||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 初始化物体
 | ||||
|     /// @param actor 绑定该物体的角色
 | ||||
|     /// @param world 物理世界
 | ||||
|     /// @param type 物体类型
 | ||||
|     static PhysicBodyPtr Create(ActorPtr actor, Type type); | ||||
|     static PhysicBodyPtr Create(PhysicWorldPtr world, Type type); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 初始化物体
 | ||||
|     /// @param actor 绑定该物体的角色
 | ||||
|     /// @param world 物理世界
 | ||||
|     /// @param type 物体类型
 | ||||
|     static PhysicBodyPtr Create(Actor* actor, Type type); | ||||
|     static PhysicBodyPtr Create(PhysicWorld* world, Type type); | ||||
| 
 | ||||
|     PhysicBody(); | ||||
| 
 | ||||
|  | @ -290,14 +294,6 @@ public: | |||
|     /// @brief 获取物体所在物理世界
 | ||||
|     PhysicWorld* GetWorld() const; | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 将物体信息更新到角色
 | ||||
|     void UpdateActor(); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 将角色信息更新到物体
 | ||||
|     void UpdateFromActor(); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 销毁物体
 | ||||
|     void Destroy(); | ||||
|  | @ -319,21 +315,39 @@ protected: | |||
|     /// @brief 销毁组件
 | ||||
|     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
 | ||||
|     /// @brief 更新夹具过滤器
 | ||||
|     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: | ||||
|     PhysicWorld* world_; | ||||
|     b2Body*      body_; | ||||
| 
 | ||||
|     uint16_t     category_bits_; | ||||
|     uint16_t     mask_bits_; | ||||
|     int16_t      group_index_; | ||||
|     PhysicBody::Type type_; | ||||
| 
 | ||||
|     PhysicBody::Type   type_; | ||||
|     Vector<FixturePtr> fixtures_; | ||||
| 
 | ||||
|     Point offset_; | ||||
|     Point position_cached_; | ||||
| }; | ||||
| 
 | ||||
| /** @} */ | ||||
|  |  | |||
|  | @ -113,6 +113,8 @@ PhysicWorld::PhysicWorld() | |||
|     , vel_iter_(6) | ||||
|     , pos_iter_(2) | ||||
| { | ||||
|     SetName("KGE_PHYSIC_WORLD"); | ||||
| 
 | ||||
|     destroy_listener_ = std::make_unique<DestructionListener>(Closure(this, &PhysicWorld::JointRemoved)); | ||||
|     world_.SetDestructionListener(destroy_listener_.get()); | ||||
| 
 | ||||
|  | @ -134,9 +136,6 @@ void PhysicWorld::AddBody(PhysicBodyPtr body) | |||
| { | ||||
|     if (body) | ||||
|     { | ||||
|         bool success = body->Init(this); | ||||
|         KGE_ASSERT(success); | ||||
| 
 | ||||
|         bodies_.push_back(body); | ||||
|     } | ||||
| } | ||||
|  | @ -234,22 +233,25 @@ ContactList PhysicWorld::GetContactList() | |||
|     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) | ||||
| { | ||||
|     // Update bodies transform from actors
 | ||||
|     for (auto& body : bodies_) | ||||
|     { | ||||
|         body->UpdateFromActor(); | ||||
|     } | ||||
|     Actor* world_actor = GetBoundActor(); | ||||
| 
 | ||||
|     BeforeSimulation(world_actor, Matrix3x2(), 0.0f); | ||||
| 
 | ||||
|     // Update physic world
 | ||||
|     world_.Step(dt.Seconds(), vel_iter_, pos_iter_); | ||||
| 
 | ||||
|     // Update actors transform from bodies
 | ||||
|     for (auto& body : bodies_) | ||||
|     { | ||||
|         if (body->GetType() != PhysicBody::Type::Static) | ||||
|             body->UpdateActor(); | ||||
|     } | ||||
|     AfterSimulation(world_actor, Matrix3x2(), 0.0f); | ||||
| } | ||||
| 
 | ||||
| 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 kiwano
 | ||||
|  |  | |||
|  | @ -121,12 +121,30 @@ public: | |||
|     const b2World* GetB2World() const; | ||||
| 
 | ||||
| protected: | ||||
|     /// \~chinese
 | ||||
|     /// @brief 初始化组件
 | ||||
|     void InitComponent(Actor* actor) override; | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 更新组件
 | ||||
|     void OnUpdate(Duration dt) override; | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 分发物理世界事件
 | ||||
|     void DispatchEvent(Event* evt); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 关节移除时的回调函数
 | ||||
|     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: | ||||
|     b2World world_; | ||||
|     int     vel_iter_; | ||||
|  |  | |||
|  | @ -65,6 +65,7 @@ Actor::Actor() | |||
|     , opacity_(1.f) | ||||
|     , displayed_opacity_(1.f) | ||||
|     , anchor_(default_anchor_x, default_anchor_y) | ||||
|     , physic_body_(nullptr) | ||||
| { | ||||
| } | ||||
| 
 | ||||
|  | @ -315,6 +316,12 @@ const Matrix3x2& Actor::GetTransformInverseMatrix() const | |||
|     return transform_matrix_inverse_; | ||||
| } | ||||
| 
 | ||||
| const Matrix3x2& Actor::GetTransformMatrixToParent() const | ||||
| { | ||||
|     UpdateTransform(); | ||||
|     return transform_matrix_to_parent_; | ||||
| } | ||||
| 
 | ||||
| void Actor::UpdateTransform() const | ||||
| { | ||||
|     if (!dirty_transform_) | ||||
|  | @ -326,16 +333,18 @@ void Actor::UpdateTransform() const | |||
| 
 | ||||
|     if (is_fast_transform_) | ||||
|     { | ||||
|         transform_matrix_ = Matrix3x2::Translation(transform_.position); | ||||
|         transform_matrix_to_parent_ = Matrix3x2::Translation(transform_.position); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         // 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_) | ||||
|     { | ||||
|         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) | ||||
|         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); | ||||
|     return GetBounds().ContainsPoint(local); | ||||
|     return local; | ||||
| } | ||||
| 
 | ||||
| Point Actor::ConvertToWorld(const Point& point) const | ||||
| { | ||||
|     Point world = GetTransformMatrix().Transform(point); | ||||
|     return world; | ||||
| } | ||||
| 
 | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -33,8 +33,12 @@ class Stage; | |||
| class Director; | ||||
| class RenderContext; | ||||
| 
 | ||||
| KGE_DECLARE_SMART_PTR(Actor); | ||||
| namespace physics | ||||
| { | ||||
| class PhysicBody; | ||||
| } | ||||
| 
 | ||||
| KGE_DECLARE_SMART_PTR(Actor); | ||||
| 
 | ||||
| /// \~chinese
 | ||||
| /// @brief 角色列表
 | ||||
|  | @ -225,6 +229,10 @@ public: | |||
|     /// @brief 获取二维变换的逆矩阵
 | ||||
|     const Matrix3x2& GetTransformInverseMatrix() const; | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 获取变换到父角色的二维变换矩阵
 | ||||
|     const Matrix3x2& GetTransformMatrixToParent() const; | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 设置角色是否可见
 | ||||
|     void SetVisible(bool val); | ||||
|  | @ -408,10 +416,26 @@ public: | |||
|     /// @brief 获取更新时的回调函数
 | ||||
|     UpdateCallback GetCallbackOnUpdate() const; | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 获取物理身体,仅当kiwano-physics包启用时生效
 | ||||
|     physics::PhysicBody* GetPhysicBody() const; | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 设置物理身体,仅当kiwano-physics包启用时生效
 | ||||
|     void SetPhysicBody(physics::PhysicBody* body); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 判断点是否在角色内
 | ||||
|     virtual bool ContainsPoint(const Point& point) const; | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 将世界坐标系点转换为局部坐标系点
 | ||||
|     Point ConvertToLocal(const Point& point) const; | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 将局部坐标系点转换为世界坐标系点
 | ||||
|     Point ConvertToWorld(const Point& point) const; | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 渲染角色边界
 | ||||
|     void ShowBorder(bool show); | ||||
|  | @ -499,6 +523,9 @@ private: | |||
|     mutable bool      dirty_transform_inverse_; | ||||
|     mutable Matrix3x2 transform_matrix_; | ||||
|     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_; | ||||
| } | ||||
| 
 | ||||
| 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) | ||||
| { | ||||
|     show_border_ = show; | ||||
|  |  | |||
|  | @ -47,6 +47,7 @@ ButtonPtr Button::Create(const Callback& click, const Callback& pressed, const C | |||
| Button::Button() | ||||
|     : status_(Status::Normal) | ||||
| { | ||||
|     SetName("KGE_BUTTON"); | ||||
| } | ||||
| 
 | ||||
| Button::~Button() | ||||
|  |  | |||
|  | @ -115,7 +115,7 @@ KGE_SUPPRESS_WARNING_POP | |||
|     } | ||||
| 
 | ||||
|     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); | ||||
|         (*this) = result; | ||||
|  | @ -280,7 +280,7 @@ inline MatrixMultiply<_Ty, Matrix3x2T<_Ty>, Matrix3x2T<_Ty>> operator*(const Mat | |||
| 
 | ||||
| template <typename _Ty, typename _Lty, typename _Rty> | ||||
| 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); | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue