Magic_Game/src/kiwano-physics/World.cpp

188 lines
4.0 KiB
C++
Raw Normal View History

2019-10-18 11:50:46 +08:00
// Copyright (c) 2018-2019 Kiwano - Nomango
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#include "World.h"
namespace kiwano
{
namespace physics
{
World::World()
: world_(b2Vec2(0, 10))
, vel_iter_(6)
, pos_iter_(2)
, global_scale_(100.f)
{
}
World::World(Vec2 gravity)
: world_(b2Vec2(gravity.x, gravity.y))
, vel_iter_(6)
, pos_iter_(2)
, global_scale_(100.f)
{
}
World::~World()
{
2019-10-21 11:15:22 +08:00
// Make sure b2World was destroyed after b2Body
2019-10-18 11:50:46 +08:00
RemoveAllChildren();
2019-10-21 11:15:22 +08:00
RemoveAllBodies();
RemoveAllJoints();
}
BodyPtr World::CreateBody(ActorPtr actor)
{
return CreateBody(actor.get());
2019-10-18 11:50:46 +08:00
}
BodyPtr World::CreateBody(Actor* actor)
{
2019-10-23 16:49:34 +08:00
BodyPtr body = Body::Create(this, actor);
2019-10-21 11:15:22 +08:00
bodies_.push_back(body.get());
2019-10-18 11:50:46 +08:00
return body;
}
JointPtr World::CreateJoint(b2JointDef* joint_def)
{
JointPtr joint = new Joint(this, joint_def);
2019-10-21 11:15:22 +08:00
joints_.push_back(joint.get());
2019-10-18 11:50:46 +08:00
return joint;
}
void World::RemoveBody(Body* body)
{
if (body)
{
auto iter = std::find(bodies_.begin(), bodies_.end(), body);
if (iter != bodies_.end())
{
bodies_.erase(iter);
2019-10-22 16:49:34 +08:00
}
2019-10-18 11:50:46 +08:00
2019-10-22 16:49:34 +08:00
if (body->GetB2Body())
{
world_.DestroyBody(body->GetB2Body());
2019-10-18 11:50:46 +08:00
}
}
}
void World::RemoveAllBodies()
{
2019-10-21 11:15:22 +08:00
if (world_.GetBodyCount())
{
b2Body* body = world_.GetBodyList();
while (body)
{
b2Body* next = body->GetNext();
world_.DestroyBody(body);
body = next;
}
}
2019-10-18 11:50:46 +08:00
bodies_.clear();
}
void World::RemoveJoint(Joint* joint)
{
if (joint)
{
auto iter = std::find(joints_.begin(), joints_.end(), joint);
if (iter != joints_.end())
{
joints_.erase(iter);
2019-10-22 16:49:34 +08:00
}
2019-10-18 11:50:46 +08:00
2019-10-22 16:49:34 +08:00
if (joint->GetB2Joint())
{
world_.DestroyJoint(joint->GetB2Joint());
2019-10-18 11:50:46 +08:00
}
}
}
void World::RemoveAllJoints()
{
2019-10-21 11:15:22 +08:00
if (world_.GetJointCount())
{
b2Joint* joint = world_.GetJointList();
while (joint)
{
b2Joint* next = joint->GetNext();
world_.DestroyJoint(joint);
joint = next;
}
}
2019-10-18 11:50:46 +08:00
joints_.clear();
}
b2World* World::GetB2World()
{
return &world_;
}
const b2World* World::GetB2World() const
{
return &world_;
}
Vec2 World::GetGravity() const
{
b2Vec2 g = world_.GetGravity();
return Vec2(g.x, g.y);
}
void World::SetGravity(Vec2 gravity)
{
world_.SetGravity(b2Vec2(gravity.x, gravity.y));
}
void World::Update(Duration dt)
{
Stage::Update(dt);
2019-10-23 16:49:34 +08:00
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();
}
2019-10-18 11:50:46 +08:00
world_.Step(dt.Seconds(), vel_iter_, pos_iter_);
2019-10-23 16:49:34 +08:00
b2body = world_.GetBodyList();
2019-10-18 11:50:46 +08:00
while (b2body)
{
Body* body = static_cast<Body*>(b2body->GetUserData());
2019-10-23 16:49:34 +08:00
if (body && body->GetType() != Body::Type::Static)
2019-10-18 11:50:46 +08:00
{
body->UpdateActor();
}
b2body = b2body->GetNext();
}
}
}
}