bool Solver::checkStability(std::vector<Block> blocks) { b2Vec2 gravity = b2Vec2(0, -10); b2World world = b2World(gravity); world.SetAllowSleeping(true); world.SetWarmStarting(true); { // Floor b2FixtureDef fd; b2PolygonShape sd; sd.SetAsBox((float32) 50 - 0.01, (float32) 10 - 0.01); fd.friction = 0.01; fd.shape = &sd; b2BodyDef bd; bd.position = b2Vec2(0.0f, -10.0f); world.CreateBody(&bd)->CreateFixture(&fd); } { // Blocks for (int i = 0; i < (int) blocks.size(); i++) { Block c = blocks[i]; b2FixtureDef fd; b2PolygonShape sd; sd.SetAsBox(c.width/2.f - 0.01, c.height/2.f - 0.01); fd.shape = &sd; fd.density = 25.0f; fd.friction = .01f; b2BodyDef bd; bd.type = b2_dynamicBody; bd.angle = 0; bd.position = b2Vec2(c.x, c.y); b2Body* myBody = world.CreateBody(&bd); myBody->CreateFixture(&fd); } } b2Vec2 p[world.GetBodyCount()]; b2Body *c = world.GetBodyList(); for (int i = 0; i < world.GetBodyCount(); i++) { p[i] = b2Vec2(); p[i].x = c->GetPosition().x; p[i].y = c->GetPosition().y; c = c->GetNext(); } for (int i = 0; i < 180; i++) world.Step(1.f/60.0f, 8, 3); c = world.GetBodyList(); for (int i = 0; i < world.GetBodyCount(); i++) { if ((p[i] - c->GetPosition()).Length() > 0.1 || c->IsAwake()) return false; c = c->GetNext(); } return true; }
demography :: demography(): World(b2World(b2Vec2(0,0))) {}
/** @date 03.04.2014 Part of the Vege Zombies survival game. This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. */ #include "GameObject.h" b2World GameObject::boxWorld = b2World (b2Vec2 (0.0f, 0.0f)); unsigned long long GameObject::GLOBAL_ID = 1; GameObject::GameObject () { } GameObject::~GameObject () { detachAllChilds (); } void GameObject::attachChild (ObjectPtr child) { child->parent = this; // Caller is parent for attached child. children.push_back (std::move (child)); // Insert new child. } void GameObject::detachChild (const GameObject& node) { // Lambda-expression search for child; return true if found. auto found = std::find_if (children.begin (), children.end (), [&] (ObjectPtr& p) -> bool { return p == &node; }); assert (found != children.end ());
int main( void ) { std::cout << "¡¡¡Start Masteroids server!!!" << std::endl; // prints !!!UDP server!!! /* * Variables */ std::clock_t last_time = clock(); std::clock_t last_frame = clock(); float t_delta = 0; float animate = 0.0; int frames_per_second = 0; int last_frames_per_second = 0; float time_step = 1.0 / 160.0; int velocity_iterator = 6; int position_iterator = 2; int number_of_inital_asteroids = 200; /* * Configure UPD server */ int server_port = MASTEROIDS_SERVER_PORT; const std::string server_addres = MASTEROIDS_SERVER_IP; udp_server masteroids_server = udp_server(server_addres, server_port); /* * Configure lists: clients, asteroids */ // List of Clients std::list< Client > client_list(); // list with numberOfInitialAsteroids default build std::list< Asteroids > asteroid_list(); // world conditions b2Vec2 gravity = b2Vec2( 0.0, 0.0 ); b2ContactFilter* contacListener = new b2ContactFilter(); MasteroidsDestructorListerner* destructorListener = new MasteroidsDestructorListerner(); b2World world = b2World( gravity ); world.SetContactFilter( contacListener ); world.SetDestructionListener( destructorListener ); for ( int asteroid_it = 0; asteroid_it << number_of_inital_asteroids ; asteroid_it++ ) { Asteroids new_asteroid = Asteroids( ); asteroid_list().push_back( new_asteroid ); } return ( 0 ); }
namespace Dodge { float32_t Box2dPhysics::m_timeStep = 1.f / 60.f; float32_t Box2dPhysics::m_worldUnitsPerMetre = 0.01f; int Box2dPhysics::m_v_iterations = 6; int Box2dPhysics::m_p_iterations = 4; EventManager Box2dPhysics::m_eventManager; set<long> Box2dPhysics::m_ignore; b2Vec2 Box2dPhysics::m_gravity = b2Vec2(0.f, -9.8f); b2World Box2dPhysics::m_world = b2World(m_gravity); Box2dContactListener Box2dPhysics::m_contactListener; bool Box2dPhysics::m_isInitialised = false; //=========================================== // Box2dPhysics::Box2dPhysics //=========================================== Box2dPhysics::Box2dPhysics(const Box2dPhysics& copy, Entity* entity) : EntityPhysics(copy, entity), m_init(false), m_entity(entity), m_body(NULL), m_opts(copy.m_opts) { init(); } //=========================================== // Box2dPhysics::Box2dPhysics //=========================================== Box2dPhysics::Box2dPhysics(Entity* entity) : EntityPhysics(entity), m_init(false), m_entity(entity), m_body(NULL), m_opts(false, false, 1.f, 0.3f) { init(); } //=========================================== // Box2dPhysics::Box2dPhysics //=========================================== Box2dPhysics::Box2dPhysics(Entity* entity, const EntityPhysics::options_t& options) : EntityPhysics(entity, options), m_init(false), m_entity(entity), m_body(NULL), m_opts(options) { init(); } //=========================================== // Box2dPhysics::Box2dPhysics //=========================================== Box2dPhysics::Box2dPhysics(Entity* entity, const XmlNode data) : EntityPhysics(entity, data), m_init(false), m_entity(entity), m_body(NULL), m_opts(false, false, 1.f, 0.3f) { init(); try { XML_NODE_CHECK(data, Box2dPhysics); XmlAttribute attr = data.firstAttribute(); XML_ATTR_CHECK(attr, dynamic); m_opts.dynamic = attr.getBool(); attr = attr.nextAttribute(); XML_ATTR_CHECK(attr, fixedAngle); m_opts.fixedAngle = attr.getBool(); attr = attr.nextAttribute(); XML_ATTR_CHECK(attr, density); m_opts.density = attr.getFloat(); attr = attr.nextAttribute(); XML_ATTR_CHECK(attr, friction); m_opts.friction = attr.getFloat(); } catch (XmlException& e) { e.prepend("Error parsing XML for instance of class Box2dPhysics; "); throw; } } //=========================================== // Box2dPhysics::init //=========================================== void Box2dPhysics::init() { if (!m_isInitialised) { m_world.SetContactListener(&m_contactListener); m_isInitialised = true; } } //=========================================== // Box2dPhysics::assignData //=========================================== void Box2dPhysics::assignData(const XmlNode data) { if (data.isNull() || data.name() != "Box2dPhysics") return; try { XmlAttribute attr = data.firstAttribute(); if (!attr.isNull() && attr.name() == "dynamic") { m_opts.dynamic = attr.getBool(); attr = attr.nextAttribute(); } if (!attr.isNull() && attr.name() == "fixedAngle") { m_opts.fixedAngle = attr.getBool(); attr = attr.nextAttribute(); } if (!attr.isNull() && attr.name() == "density") { m_opts.density = attr.getFloat(); attr = attr.nextAttribute(); } if (!attr.isNull() && attr.name() == "friction") { m_opts.friction = attr.getFloat(); } } catch (XmlException& e) { e.prepend("Error parsing XML for instance of class Box2dPhysics ;"); throw; } } //=========================================== // Box2dPhysics::getSize //=========================================== size_t Box2dPhysics::getSize() const { return sizeof(Box2dPhysics); // TODO Not accurate } #ifdef DEBUG //=========================================== // Box2dPhysics::dbg_print //=========================================== void Box2dPhysics::dbg_print(std::ostream& out, int tab) const { // TODO } #endif //=========================================== // Box2dPhysics::setEntity //=========================================== void Box2dPhysics::setEntity(Entity* entity) { m_entity = entity; } //=========================================== // Box2dPhysics::addToWorld //=========================================== void Box2dPhysics::addToWorld() { constructBody(); m_init = true; } //=========================================== // Box2dPhysics::removeFromWorld //=========================================== void Box2dPhysics::removeFromWorld() { if (m_init) { if (m_body) m_world.DestroyBody(m_body); m_body = NULL; m_numFixtures = 0; m_init = false; } } //=========================================== // Box2dPhysics::shapeToBox2dBody //=========================================== void Box2dPhysics::shapeToBox2dBody(const Shape& shape, const EntityPhysics::options_t& opts, b2Body* body, uint_t* nFixtures) const { static long ellipseStr = internString("Ellipse"); static long lineSegmentStr = internString("LineSegment"); static long polygonStr = internString("Polygon"); static long quadStr = internString("Quad"); string msg("Error constructing Box2D body from Shape"); *nFixtures = 0; if (shape.typeId() == ellipseStr) { throw PhysicsException(msg + "; Ellipse not yet supported", __FILE__, __LINE__); } else if (shape.typeId() == lineSegmentStr) { throw PhysicsException(msg + "; LineSegment not yet supported", __FILE__, __LINE__); } else if (shape.typeId() == polygonStr) { // TODO: Currently assumes convex const Polygon& poly = static_cast<const Polygon&>(shape); b2Vec2* verts = new b2Vec2[poly.getNumVertices()]; for (int i = 0; i < poly.getNumVertices(); ++i) { verts[i] = b2Vec2(poly.getVertex(i).x / m_worldUnitsPerMetre, poly.getVertex(i).y / m_worldUnitsPerMetre); } b2PolygonShape b2Poly; b2Poly.Set(verts, poly.getNumVertices()); b2FixtureDef fdef; fdef.shape = &b2Poly; fdef.density = opts.density; fdef.friction = opts.friction; body->CreateFixture(&fdef); ++(*nFixtures); } else if (shape.typeId() == quadStr) { throw PhysicsException(msg + "; Quad not yet supported", __FILE__, __LINE__); } else throw PhysicsException(msg + "Unknown shape type", __FILE__, __LINE__); } //=========================================== // Box2dPhysics::constructBody //=========================================== void Box2dPhysics::constructBody() { if (m_body) { m_world.DestroyBody(m_body); m_numFixtures = 0; } b2BodyDef bdef; bdef.awake = false; if (m_opts.dynamic) bdef.type = b2_dynamicBody; bdef.fixedRotation = m_opts.fixedAngle; m_body = m_world.CreateBody(&bdef); m_body->SetUserData(m_entity); float32_t rot = m_entity->getRotation_abs(); Vec2f pos = m_entity->getTranslation_abs(); // Contruct the body with the unrotated shape, then set the body's angle to the entity's rotation. unique_ptr<Shape> shape(dynamic_cast<Shape*>(m_entity->getShape().clone())); assert(shape); shape->rotate(-rot); shapeToBox2dBody(*shape, m_opts, m_body, &m_numFixtures); m_body->SetTransform(b2Vec2(pos.x / m_worldUnitsPerMetre, pos.y / m_worldUnitsPerMetre), DEG_TO_RAD(rot)); m_body->SetAwake(true); } //=========================================== // Box2dPhysics::makeDynamic //=========================================== void Box2dPhysics::makeDynamic() { if (!m_init) throw PhysicsException("Instance of Box2dPhysics is not initialised", __FILE__, __LINE__); if (m_body->GetType() == b2_dynamicBody) return; m_opts.dynamic = true; constructBody(); } //=========================================== // Box2dPhysics::makeStatic //=========================================== void Box2dPhysics::makeStatic() { if (!m_init) throw PhysicsException("Instance of Box2dPhysics is not initialised", __FILE__, __LINE__); if (m_body->GetType() != b2_dynamicBody) return; m_opts.dynamic = false; constructBody(); } //=========================================== // Box2dPhysics::loadSettings //=========================================== void Box2dPhysics::loadSettings(const string& file) { KvpParser parser; parser.parseFile(file); if (parser.getMetaData(0).compare("Box2D") != 0) throw PhysicsException("Error loading settings; File is not for this implementation (Box2D)", __FILE__, __LINE__); string val = parser.getValue("fps"); if (val.empty()) throw PhysicsException("Error loading settings; Expected 'fps' value", __FILE__, __LINE__); m_timeStep = 1.f / static_cast<float32_t>(atof(val.data())); val = parser.getValue("worldUnitsPerMetre"); if (val.empty()) throw PhysicsException("Error loading settings; Expected 'worldUnitsPerMetre' value", __FILE__, __LINE__); m_worldUnitsPerMetre = static_cast<float32_t>(atof(val.data())); val = parser.getValue("vIterations"); if (val.empty()) throw PhysicsException("Error loading settings; Expected 'vIterations' value", __FILE__, __LINE__); m_v_iterations = atoi(val.data()); val = parser.getValue("pIterations"); if (val.empty()) throw PhysicsException("Error loading settings; Expected 'pIterations' value", __FILE__, __LINE__); m_p_iterations = atoi(val.data()); } //=========================================== // Box2dPhysics::onEvent //=========================================== void Box2dPhysics::onEvent(const EEvent* event) { static long entityRotationStr = internString("entityRotation"); static long entityShapeStr = internString("entityShape"); static long entityTranslationStr = internString("entityTranslation"); if (!m_init) return; if (event->getType() != entityRotationStr && event->getType() != entityShapeStr && event->getType() != entityTranslationStr) return; if (m_ignore.find(event->getId()) == m_ignore.end()) { updatePos(event); } else { m_ignore.erase(event->getId()); } } //=========================================== // Box2dPhysics::updatePos //=========================================== void Box2dPhysics::updatePos(const EEvent* ev) { static long entityRotationStr = internString("entityRotation"); static long entityShapeStr = internString("entityShape"); static long entityTranslationStr = internString("entityTranslation"); if (!m_init) throw PhysicsException("Instance of Box2dPhysics is not initialised", __FILE__, __LINE__); if (ev->getType() == entityTranslationStr) { const EEntityTranslation* event = static_cast<const EEntityTranslation*>(ev); b2Vec2 p = m_body->GetPosition(); // Update position float32_t x = event->newTransl_abs.x - event->oldTransl_abs.x; float32_t y = event->newTransl_abs.y - event->oldTransl_abs.y; m_body->SetTransform(b2Vec2(p.x + x / m_worldUnitsPerMetre, p.y + y / m_worldUnitsPerMetre), m_body->GetAngle()); } else if (ev->getType() == entityRotationStr) { const EEntityRotation* event = static_cast<const EEntityRotation*>(ev); float32_t a = m_body->GetAngle(); float32_t r = DEG_TO_RAD(event->newRotation_abs - event->oldRotation_abs); m_body->SetTransform(m_body->GetPosition(), a + r); } else if (ev->getType() == entityShapeStr) { const EEntityShape* event = static_cast<const EEntityShape*>(ev); unique_ptr<Shape> oldShape(dynamic_cast<Shape*>(event->oldShape.get()->clone())); unique_ptr<Shape> newShape(dynamic_cast<Shape*>(event->newShape.get()->clone())); oldShape->rotate(-event->oldRotation_abs); newShape->rotate(-event->newRotation_abs); // Update shape if (oldShape == NULL || *oldShape != *newShape) { for (unsigned int i = 0; i < m_numFixtures; ++i) m_body->DestroyFixture(m_body->GetFixtureList()); shapeToBox2dBody(*newShape, m_opts, m_body, &m_numFixtures); } } // Wake bodies /* b2Body* body = m_world.GetBodyList(); while (body != NULL) { body->SetAwake(true); body = body->GetNext(); }*/ } //=========================================== // Box2dPhysics::update //=========================================== void Box2dPhysics::update() { if (!m_opts.dynamic) return; Vec2f pos(m_body->GetPosition()(0) * m_worldUnitsPerMetre, m_body->GetPosition()(1) * m_worldUnitsPerMetre); float32_t a = RAD_TO_DEG(m_body->GetAngle()); if (pos != m_entity->getTranslation_abs() || a != m_entity->getRotation_abs()) { Range oldBounds = m_entity->getBoundary(); Vec2f oldTransl = m_entity->getTranslation(); Vec2f oldTransl_abs = m_entity->getTranslation_abs(); float32_t oldRot = m_entity->getRotation(); float32_t oldRot_abs = m_entity->getRotation_abs(); m_entity->setSilent(true); m_entity->setTranslation_abs(pos); m_entity->setRotation_abs(a); m_entity->setSilent(false); EEvent* event1 = new EEntityBoundingBox(m_entity->getSharedPtr(), oldBounds, m_entity->getBoundary()); EEvent* event2 = new EEntityTranslation(m_entity->getSharedPtr(), oldTransl, oldTransl_abs, m_entity->getTranslation(), m_entity->getTranslation_abs()); EEvent* event3 = new EEntityRotation(m_entity->getSharedPtr(), oldRot, oldRot_abs, m_entity->getRotation(), m_entity->getRotation_abs()); m_ignore.insert(event1->getId()); m_ignore.insert(event2->getId()); m_ignore.insert(event3->getId()); m_entity->onEvent(event1); m_entity->onEvent(event2); m_entity->onEvent(event3); m_eventManager.queueEvent(event1); m_eventManager.queueEvent(event2); m_eventManager.queueEvent(event3); } } //=========================================== // Box2dPhysics::step // // Update b2Body positions //=========================================== void Box2dPhysics::step() { m_world.Step(m_timeStep, m_v_iterations, m_p_iterations); m_world.ClearForces(); } //=========================================== // Box2dPhysics::setLinearVelocity //=========================================== void Box2dPhysics::setLinearVelocity(const Vec2f& v) { if (!m_init) throw PhysicsException("Instance of Box2dPhysics is not initialised", __FILE__, __LINE__); m_body->SetLinearVelocity(b2Vec2(v.x, v.y)); } //=========================================== // Box2dPhysics::getLinearVelocity //=========================================== Vec2f Box2dPhysics::getLinearVelocity() const { if (!m_init) throw PhysicsException("Instance of Box2dPhysics is not initialised", __FILE__, __LINE__); return Vec2f(m_body->GetLinearVelocity().x, m_body->GetLinearVelocity().y); } //=========================================== // Box2dPhysics::applyLinearImpulse //=========================================== void Box2dPhysics::applyLinearImpulse(const Vec2f& impulse, const Vec2f& p) { if (!m_init) throw PhysicsException("Instance of Box2dPhysics is not initialised", __FILE__, __LINE__); m_body->ApplyLinearImpulse(b2Vec2(impulse.x, impulse.y), b2Vec2(static_cast<float>(p.x) / m_worldUnitsPerMetre, static_cast<float>(p.y) / m_worldUnitsPerMetre)); } //=========================================== // Box2dPhysics::applyLinearImpulse //=========================================== void Box2dPhysics::applyLinearImpulse(const Vec2f& impulse) { if (!m_init) throw PhysicsException("Instance of Box2dPhysics is not initialised", __FILE__, __LINE__); applyLinearImpulse(impulse, Vec2f(m_body->GetWorldCenter().x * m_worldUnitsPerMetre, m_body->GetWorldCenter().y * m_worldUnitsPerMetre)); } //=========================================== // Box2dPhysics::applyForce //=========================================== void Box2dPhysics::applyForce(const Vec2f& force, const Vec2f& p) { if (!m_init) throw PhysicsException("Instance of Box2dPhysics is not initialised", __FILE__, __LINE__); m_body->ApplyForce(b2Vec2(force.x, force.y), b2Vec2(static_cast<float>(p.x) / m_worldUnitsPerMetre, static_cast<float>(p.y) / m_worldUnitsPerMetre)); } //=========================================== // Box2dPhysics::applyForce //=========================================== void Box2dPhysics::applyForce(const Vec2f& force) { if (!m_init) throw PhysicsException("Instance of Box2dPhysics is not initialised", __FILE__, __LINE__); applyForce(force, Vec2f(m_body->GetWorldCenter().x * m_worldUnitsPerMetre, m_body->GetWorldCenter().y * m_worldUnitsPerMetre)); } }