예제 #1
0
void debug_draw_shape(std::vector<debug_line>& lines, const rgba col, const b2PolygonShape& sh, vec2 pos) {
	const auto n = sh.GetVertexCount();

	for (int i = 0; i < n; ++i) {
		lines.emplace_back(col, pos + sh.GetVertex(i), pos + sh.GetVertex((i + 1) % n));
	}
}
예제 #2
0
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", &center.x);
			element->QueryFloatAttribute("y", &center.y);
			if (element->QueryFloatAttribute("angle", &rotation) == TIXML_SUCCESS)
				 rotation *= float(M_PI)/180.0f;
			break;
		}
	}

	shape.SetAsBox(w, h, center, rotation);
	return true;
}
예제 #3
0
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;
}
예제 #4
0
static void set_polygon_shape(	const World& trans,
								const float l, const float t, const float r, const float b,
								b2PolygonShape& out) {
	const b2Vec2	lt = trans.Ci2BoxTranslation(ci::Vec3f(l, t, 0.0f), nullptr); // using nullptr for the sprite will make the polygon be in world space
	const b2Vec2	rb = trans.Ci2BoxTranslation(ci::Vec3f(r, b, 0.0f), nullptr);
	b2Vec2			vtx[4];
	vtx[0].Set(lt.x, lt.y);
	vtx[1].Set(rb.x, lt.y);
	vtx[2].Set(rb.x, rb.y);
	vtx[3].Set(lt.x, rb.y);
	out.Set(vtx, 4);
}
예제 #5
0
bool CollidableTemplate::ConfigurePoly(const TiXmlElement *element, b2PolygonShape &shape)
{
	// process child elements
	for (const TiXmlElement *child = element->FirstChildElement(); child != NULL; child = child->NextSiblingElement())
	{
		ConfigurePolyItem(child, shape);
	}

	// update other properties
	shape.Set(shape.m_vertices, shape.m_vertexCount);

	return true;
}
예제 #6
0
bool CollidableTemplate::ConfigureEdge(const TiXmlElement *element, b2PolygonShape &shape)
{
	// process child elements
	for (const TiXmlElement *child = element->FirstChildElement(); child != NULL; child = child->NextSiblingElement())
	{
		const char *name = child->Value();
		switch (Hash(name))
		{
		case 0x154c1122 /* "vertex1" */:
			child->QueryFloatAttribute("x", &shape.m_vertices[0].x);
			child->QueryFloatAttribute("y", &shape.m_vertices[0].y);
			break;

		case 0x144c0f8f /* "vertex2" */:
			child->QueryFloatAttribute("x", &shape.m_vertices[1].x);
			child->QueryFloatAttribute("y", &shape.m_vertices[1].y);
			break;
		}
	}

	shape.SetAsEdge(shape.m_vertices[0], shape.m_vertices[1]);

	return true;
}
예제 #7
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);

}
예제 #8
0
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;
}
예제 #9
0
파일: main.cpp 프로젝트: gAndy50/Misc
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);
}
예제 #10
0
Polygon::Polygon(const b2PolygonShape& polygon) {
    reserve(polygon.GetVertexCount());
    for(int i = 0; i < polygon.GetVertexCount(); ++i) {
        append((Point) polygon.GetVertex(i));
    }
}