bool CollidableTemplate::ConfigureBox(const TiXmlElement *element, b2PolygonShape &shape) { // half-width and half-height float w = 0, h = 0; element->QueryFloatAttribute("w", &w); element->QueryFloatAttribute("h", &h); // center and rotation b2Vec2 center(0.0f, 0.0f); float rotation = 0.0f; // process child elements for (const TiXmlElement *child = element->FirstChildElement(); child != NULL; child = child->NextSiblingElement()) { switch (Hash(child->Value())) { case 0x934f4e0a /* "position" */: element->QueryFloatAttribute("x", ¢er.x); element->QueryFloatAttribute("y", ¢er.y); if (element->QueryFloatAttribute("angle", &rotation) == TIXML_SUCCESS) rotation *= float(M_PI)/180.0f; break; } } shape.SetAsBox(w, h, center, rotation); return true; }
bool wyBox2DCollisionDetector::isCollided(wyRect& r1, wyRect& r2, wyBox2DCDResult* result) { // init transform 1 sRectTrans1.SetIdentity(); b2Vec2 v; v.x = pixel2Meter(r1.x + r1.width / 2); v.y = pixel2Meter(r1.y + r1.height / 2); sRectTrans1.Set(v, 0); // init transform 2 sRectTrans2.SetIdentity(); v.x = pixel2Meter(r2.x + r2.width / 2); v.y = pixel2Meter(r2.y + r2.height / 2); sRectTrans2.Set(v, 0); // init shape 1 sRectPoly1.SetAsBox(pixel2Meter(r1.width) / 2, pixel2Meter(r1.height) / 2); // init shape 2 sRectPoly2.SetAsBox(pixel2Meter(r2.width) / 2, pixel2Meter(r2.height) / 2); // collision detection b2Manifold manifold; b2CollidePolygons(&manifold, &sRectPoly1, sRectTrans1, &sRectPoly2, sRectTrans2); // to world coordinates if(manifold.pointCount > 0) { // write data back if(result) { // convert to world coordinate b2WorldManifold worldManifold; worldManifold.Initialize(&manifold, sRectTrans1, sRectPoly1.m_radius, sRectTrans2, sRectPoly2.m_radius); result->pointCount = manifold.pointCount; for(int i = 0; i < manifold.pointCount; i++) { result->points[i] = wyp(meter2Pixel(worldManifold.points[i].x), meter2Pixel(worldManifold.points[i].y)); } result->normal = wyp(worldManifold.normal.x, worldManifold.normal.y); } } return manifold.pointCount > 0; }
void CreateWorld() { // Define the gravity vector. b2Vec2 gravity(0.0f, 5.0f); // Construct a world object, which will hold and simulate the rigid bodies. world = new b2World(gravity); // Define the dynamic body. We set its position and call the body factory. b2BodyDef bodyDef; bodyDef.type = b2_dynamicBody; bodyDef.position.Set(cubeStart.x * SCALE + 25 ,cubeStart.y * SCALE + 50); b2Body* body = world->CreateBody(&bodyDef); bodyDef.awake = false; // Define another box shape for our dynamic body. b2PolygonShape dynamicBox; dynamicBox.SetAsBox(100.0f*0.5f, 10.0f*0.5f); // Define the dynamic body fixture. b2FixtureDef fixtureDef; fixtureDef.shape = &dynamicBox; fixtureDef.restitution = 0.01f; // Set the box density to be non-zero, so it will be dynamic. fixtureDef.density = 3.0f; // Override the default friction. fixtureDef.friction = 0.01f; // Add the shape to the body. body->CreateFixture(&fixtureDef); b2BodyDef bodyDefcircle; bodyDefcircle.type = b2_dynamicBody; bodyDefcircle.position.Set(25,100); b2Body* circleBody = world->CreateBody(&bodyDefcircle); b2FixtureDef circlefixtureDef; b2CircleShape dynamicCircle; dynamicCircle.m_radius = 20; dynamicCircle.m_p.Set(0,0); circlefixtureDef.shape = &dynamicCircle; circlefixtureDef.restitution = 0.1f; // Set the box density to be non-zero, so it will be dynamic. circlefixtureDef.density = 1.0f; // Override the default friction. circlefixtureDef.friction = 0.8f; // Add the shape to the body. circleBody->CreateFixture(&circlefixtureDef); b2RevoluteJointDef joint; joint.Initialize(body,circleBody, b2Vec2(25,100)); joint.enableMotor = true; joint.motorSpeed = 200; joint.maxMotorTorque = 100000; world->CreateJoint(&joint); b2BodyDef bodyDefcircle2; bodyDefcircle2.type = b2_dynamicBody; bodyDefcircle2.position.Set(125,100); b2Body* circleBody2 = world->CreateBody(&bodyDefcircle2); b2FixtureDef circlefixtureDef2; b2CircleShape dynamicCircle2; dynamicCircle2.m_radius = 20; dynamicCircle2.m_p.Set(0,0); circlefixtureDef2.shape = &dynamicCircle; circlefixtureDef2.restitution = 0.1f; // Set the box density to be non-zero, so it will be dynamic. circlefixtureDef2.density = 1.0f; // Override the default friction. circlefixtureDef2.friction = 0.8f; // Add the shape to the body. circleBody2->CreateFixture(&circlefixtureDef2); joint.Initialize(body,circleBody2, b2Vec2(125,100)); joint.enableMotor = true; joint.motorSpeed = 200; joint.maxMotorTorque = 100000; world->CreateJoint(&joint); }
bool wyBox2DCollisionDetector::isCollided(wyNode* node, wyRect& r, wyBox2DCDResult* result) { // init transform 2 sRectTrans2.SetIdentity(); b2Vec2 v; v.x = pixel2Meter(r.x + r.width / 2); v.y = pixel2Meter(r.y + r.height / 2); sRectTrans2.Set(v, 0); // init shape 2 sRectPoly2.SetAsBox(pixel2Meter(r.width) / 2, pixel2Meter(r.height) / 2); // get node hash, if not, add it wyNodeHash* hash = (wyNodeHash*)wyHashSetFind(m_nodeShapes, (size_t)node, node); if(hash == NULL) hash = addNode(node); // update node1 transform wyPoint pos = node->nodeToWorldSpace(wyp(node->getWidth() / 2, node->getHeight() / 2)); v.x = pixel2Meter(pos.x); v.y = pixel2Meter(pos.y); float angle = -wyMath::d2r(node->getRotation()); hash->transform.Set(v, angle); // collision detection bool reverseNormal = false; b2Manifold manifold; switch(hash->type) { case b2Shape::e_polygon: b2CollidePolygons(&manifold, &hash->poly, hash->transform, &sRectPoly2, sRectTrans2); break; case b2Shape::e_circle: b2CollidePolygonAndCircle(&manifold, &sRectPoly2, sRectTrans2, &hash->circle, hash->transform); reverseNormal = true; break; } // to world coordinates if(manifold.pointCount > 0) { // write data back if(result) { // convert to world coordinate b2WorldManifold worldManifold; if(reverseNormal) { worldManifold.Initialize(&manifold, sRectTrans2, sRectPoly2.m_radius, hash->transform, hash->type == b2Shape::e_polygon ? hash->poly.m_radius : hash->circle.m_radius); } else { worldManifold.Initialize(&manifold, hash->transform, hash->type == b2Shape::e_polygon ? hash->poly.m_radius : hash->circle.m_radius, sRectTrans2, sRectPoly2.m_radius); } // save contact points result->pointCount = manifold.pointCount; for(int i = 0; i < manifold.pointCount; i++) { result->points[i] = wyp(meter2Pixel(worldManifold.points[i].x), meter2Pixel(worldManifold.points[i].y)); } // save normal if(reverseNormal) result->normal = wyp(-worldManifold.normal.x, -worldManifold.normal.y); else result->normal = wyp(worldManifold.normal.x, worldManifold.normal.y); } } return manifold.pointCount > 0; }
void Init() { GameWin.create(sf::VideoMode(800, 600, 32), "Physics Test - [SFML & Box2D]"); if (!font.loadFromFile("arial.ttf")) { exit(0); } PauseText.setFont(font); pauseText = to_string(Paused); PauseText.setCharacterSize(10); PauseText.setString("PAUSED:" + pauseText); PauseText.setPosition(sf::Vector2f(700, 10)); PauseText.setFillColor(sf::Color::Yellow); box.setPosition(sf::Vector2f(15, 5)); box.setSize(sf::Vector2f(10, 10)); box.setFillColor(sf::Color(255, 0, 0)); box2.setPosition(sf::Vector2f(50, 5)); box2.setSize(sf::Vector2f(15, 15)); box2.setFillColor(sf::Color(0, 255, 0)); ground.setPosition(sf::Vector2f(0, 540)); ground.setSize(sf::Vector2f(800, 560)); ground.setFillColor(sf::Color(0, 0,255)); wall.setPosition(sf::Vector2f(1, 1)); wall.setSize(sf::Vector2f(10, 580)); wall.setFillColor(sf::Color(0, 0, 255)); wall2.setPosition(sf::Vector2f(790, 1)); wall2.setSize(sf::Vector2f(10, 580)); wall2.setFillColor(sf::Color(0, 0, 255)); World = new b2World(gravity); World->SetGravity(gravity); groundBodyDef.type = b2_staticBody; groundBodyDef.position.Set(0, 540); groundBody = World->CreateBody(&groundBodyDef); wallBodyDef.type = b2_staticBody; wallBodyDef.position.Set(10, 580); wallBody = World->CreateBody(&wallBodyDef); wallBodyDef2.type = b2_staticBody; wallBodyDef2.position.Set(790, 1); wallBody2 = World->CreateBody(&wallBodyDef2); ballBodyDef.type = b2_dynamicBody; ballVector.Set(10, 10); ballBodyDef.angularVelocity = 0.0f; ballBodyDef.linearVelocity = ballVector; ballBodyDef2.type = b2_dynamicBody; ballVector2.Set(15, 15); ballBodyDef2.angularVelocity = 0.0f; ballBodyDef2.linearVelocity = ballVector2; ballBodyDef.position.Set(15, 0); ballBodyDef.awake = true; Body = World->CreateBody(&ballBodyDef); ballBodyDef2.position.Set(30, 0); ballBodyDef2.awake = true; Body2 = World->CreateBody(&ballBodyDef2); boxShapeDef.shape = &groundBox; boxShapeDef.density = 2.0f; boxShapeDef.restitution = 0.5f; groundBox.SetAsBox(800, 0); groundBody->CreateFixture(&groundBox, 0); wallBoxDef.shape = &wallBox; wallBoxDef.density = 2.0f; wallBoxDef.restitution = 0.5f; wallBox.SetAsBox(1, 600); wallBody->CreateFixture(&wallBox, 0); wallBoxDef2.shape = &wallBox2; wallBoxDef2.density = 2.0f; wallBoxDef2.restitution = 0.5f; wallBox2.SetAsBox(1, 600); wallBody2->CreateFixture(&wallBox2, 0); dynamicBox.SetAsBox(10.0f, 10.0f); dynamicBox2.SetAsBox(10.0f, 10.0f); fixtureDef.shape = &dynamicBox; fixtureDef.density = 2.0f; fixtureDef.friction = 1.5f; fixtureDef.restitution = 0.9f; Body->CreateFixture(&fixtureDef); fixtureDef2.shape = &dynamicBox2; fixtureDef2.density = 5.0f; fixtureDef2.friction = 5.0f; fixtureDef2.restitution = 1.0f; Body2->CreateFixture(&fixtureDef2); timeStep = 1.0f / 600.0f; velIter = 1; posIter = 1; World->Step(timeStep, velIter, posIter); b2Vec2 pos = Body->GetPosition(); float angle = Body->GetAngle(); box.setPosition(pos.x, pos.y); box.setRotation(angle); b2Vec2 pos2 = Body2->GetPosition(); float angle2 = Body2->GetAngle(); box2.setPosition(pos2.x, pos2.y); box2.setRotation(angle2); }