|
|
@@ -33,88 +33,92 @@ using namespace Polycode;
|
|
|
|
|
|
PhysicsScreenEntity::PhysicsScreenEntity(ScreenEntity *entity, b2World *world, Number worldScale, int entType, bool isStatic, Number friction, Number density, Number restitution, bool isSensor, bool fixedRotation, int groupIndex) {
|
|
|
|
|
|
- this->worldScale = worldScale;
|
|
|
-
|
|
|
- Vector3 entityScale = entity->getCompoundScale();
|
|
|
-
|
|
|
screenEntity = entity;
|
|
|
+
|
|
|
+ Vector3 entityScale = entity->getCompoundScale();
|
|
|
+ this->worldScale = worldScale;
|
|
|
+ collisionOnly = false;
|
|
|
+
|
|
|
|
|
|
- shape = NULL;
|
|
|
-
|
|
|
- b2BodyDef *bodyDef = new b2BodyDef();
|
|
|
-
|
|
|
- Matrix4 compoundMatrix = screenEntity->getConcatenatedMatrix();
|
|
|
-
|
|
|
- bodyDef->position.Set(compoundMatrix.getPosition().x/worldScale, compoundMatrix.getPosition().y/worldScale);
|
|
|
- bodyDef->angle = screenEntity->getRotation()*(PI/180.0f);
|
|
|
- bodyDef->bullet = isSensor;
|
|
|
- bodyDef->fixedRotation = fixedRotation;
|
|
|
+ // Create body definition---------------------------------------
|
|
|
+ b2BodyDef bodyDef;
|
|
|
+ bodyDef.position.Set(screenEntity->getPosition2D().x/worldScale, screenEntity->getPosition2D().y/worldScale);
|
|
|
+ bodyDef.angle = screenEntity->getRotation()*(PI/180.0f);
|
|
|
+ bodyDef.bullet = isSensor;
|
|
|
+ bodyDef.fixedRotation = fixedRotation;
|
|
|
+ if(isStatic)
|
|
|
+ bodyDef.type = b2_staticBody;
|
|
|
+ else
|
|
|
+ bodyDef.type = b2_dynamicBody;
|
|
|
+
|
|
|
+ // Create the body
|
|
|
+ body = world->CreateBody(&bodyDef);
|
|
|
|
|
|
- if(isStatic) {
|
|
|
- bodyDef->type = b2_staticBody;
|
|
|
- } else {
|
|
|
- bodyDef->type = b2_dynamicBody;
|
|
|
- }
|
|
|
- body = world->CreateBody(bodyDef);
|
|
|
- delete bodyDef;
|
|
|
-
|
|
|
+ // Create fixture definition---------------------------------------------
|
|
|
b2FixtureDef fDef;
|
|
|
fDef.friction = friction;
|
|
|
fDef.restitution = restitution;
|
|
|
fDef.density = density;
|
|
|
fDef.isSensor = isSensor;
|
|
|
fDef.filter.groupIndex = groupIndex;
|
|
|
-
|
|
|
+
|
|
|
+ // Create Shape definition (Circle/Rectangle/Polygon)---------------------------
|
|
|
switch(entType) {
|
|
|
- case ENTITY_MESH:
|
|
|
- {
|
|
|
- b2PolygonShape *b2shape = new b2PolygonShape;
|
|
|
-
|
|
|
+ case ENTITY_CIRCLE: {
|
|
|
+ b2CircleShape Shape;
|
|
|
+ // Set fixture shape to shape definition
|
|
|
+ fDef.shape = &Shape;
|
|
|
+ // Create the shape
|
|
|
+ Shape.m_radius = screenEntity->getWidth()/(worldScale*2.0f);
|
|
|
+ // Create the fixture
|
|
|
+ fixture = body->CreateFixture(&fDef);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case ENTITY_RECT: {
|
|
|
+ b2PolygonShape Shape;
|
|
|
+ // Set fixture shape to shape definition
|
|
|
+ fDef.shape = &Shape;
|
|
|
+ // Create the shape
|
|
|
+ Shape.SetAsBox(screenEntity->getWidth()/(worldScale*2.0f) * entityScale.x, screenEntity->getHeight()/(worldScale*2.0f) * entityScale.y);
|
|
|
+ // Create the fixture
|
|
|
+ fixture = body->CreateFixture(&fDef);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case ENTITY_MESH: {
|
|
|
+ b2PolygonShape Shape;
|
|
|
+ // Set fixture shape to shape definition
|
|
|
+ fDef.shape = &Shape;
|
|
|
+ // Get the screenmesh of the entity
|
|
|
ScreenMesh* screenMesh = dynamic_cast<ScreenMesh*>(entity);
|
|
|
- if(screenMesh != NULL) {
|
|
|
- b2Vec2 *vertices = (b2Vec2*)malloc(sizeof(b2Vec2) * screenMesh->getMesh()->getVertexCount());
|
|
|
-
|
|
|
- int index = 0;
|
|
|
- for(int i=0; i < screenMesh->getMesh()->getPolygonCount(); i++) {
|
|
|
- Polycode::Polygon *poly = screenMesh->getMesh()->getPolygon(i);
|
|
|
- for(int j = 0; j < poly->getVertexCount(); j++) {
|
|
|
- vertices[index].x = poly->getVertex(j)->x/worldScale;
|
|
|
- vertices[index].y = poly->getVertex(j)->y/worldScale;
|
|
|
- index++;
|
|
|
+
|
|
|
+ if(screenMesh) {
|
|
|
+ for(short i=0, polycount=screenMesh->getMesh()->getPolygonCount(); i < polycount; i++) {
|
|
|
+ // Get the next polygon
|
|
|
+ Polygon* poly = screenMesh->getMesh()->getPolygon(i);
|
|
|
+ // Get the vertex count of current polygon
|
|
|
+ unsigned short vertexcount = poly->getVertexCount();
|
|
|
+
|
|
|
+ if (vertexcount >= 3 && vertexcount <= 8) {
|
|
|
+ // Create new vertices array based on vertexcount
|
|
|
+ b2Vec2* vertices = new b2Vec2[vertexcount];
|
|
|
+ // and copy from the screenmesh
|
|
|
+ for(short index=0; index < vertexcount; index++) {
|
|
|
+ vertices[index].x = poly->getVertex(index)->x/worldScale;
|
|
|
+ vertices[index].y = poly->getVertex(index)->y/worldScale;
|
|
|
+ }
|
|
|
+ // Create the shape
|
|
|
+ Shape.Set(vertices, vertexcount);
|
|
|
+ // Create the fixture
|
|
|
+ fixture = body->CreateFixture(&fDef);
|
|
|
+
|
|
|
+ delete []vertices;
|
|
|
}
|
|
|
+ else { Logger::log("Between 3 and 8 vertices allowed per polygon\n"); }
|
|
|
}
|
|
|
- b2shape->Set(vertices, screenMesh->getMesh()->getVertexCount());
|
|
|
- free(vertices);
|
|
|
- } else {
|
|
|
- Logger::log("Tried to make a mesh collision object from a non-mesh\n");
|
|
|
}
|
|
|
-
|
|
|
- fDef.shape = b2shape;
|
|
|
- shape = b2shape;
|
|
|
+ else { Logger::log("Tried to make a mesh collision object from a non-mesh\n"); }
|
|
|
}
|
|
|
- break;
|
|
|
- case ENTITY_RECT:
|
|
|
- {
|
|
|
- b2PolygonShape *b2shape = new b2PolygonShape;
|
|
|
- b2shape->SetAsBox(screenEntity->getWidth()/(worldScale*2.0f) * entityScale.x, screenEntity->getHeight()/(worldScale*2.0f) * entityScale.y);
|
|
|
- fDef.shape = b2shape;
|
|
|
- shape = b2shape;
|
|
|
- }
|
|
|
- break;
|
|
|
- case ENTITY_CIRCLE:
|
|
|
- {
|
|
|
- b2CircleShape *b2shape = new b2CircleShape;
|
|
|
- b2shape->m_radius = screenEntity->getWidth()/(worldScale*2.0f);
|
|
|
- fDef.shape = b2shape;
|
|
|
- shape = b2shape;
|
|
|
- }
|
|
|
- break;
|
|
|
}
|
|
|
-
|
|
|
- fixture = body->CreateFixture(&fDef);
|
|
|
-
|
|
|
- collisionOnly = false;
|
|
|
-
|
|
|
}
|
|
|
|
|
|
void PhysicsScreenEntity::applyTorque(Number torque) {
|
|
|
@@ -141,26 +145,26 @@ void PhysicsScreenEntity::setVelocity(Number fx, Number fy) {
|
|
|
}
|
|
|
|
|
|
void PhysicsScreenEntity::setVelocityX( Number fx) {
|
|
|
- body->SetAwake(true);
|
|
|
+ body->SetAwake(true);
|
|
|
b2Vec2 f = body->GetLinearVelocity();
|
|
|
- f.x = fx;
|
|
|
+ f.x = fx;
|
|
|
body->SetLinearVelocity(f);
|
|
|
}
|
|
|
|
|
|
void PhysicsScreenEntity::setVelocityY(Number fy) {
|
|
|
body->SetAwake(true);
|
|
|
b2Vec2 f = body->GetLinearVelocity();
|
|
|
- f.y = fy;
|
|
|
- body->SetLinearVelocity(f);
|
|
|
+ f.y = fy;
|
|
|
+ body->SetLinearVelocity(f);
|
|
|
}
|
|
|
|
|
|
-void PhysicsScreenEntity::applyImpulse(Number fx, Number fy) {
|
|
|
+void PhysicsScreenEntity::applyImpulse(Number fx, Number fy) {
|
|
|
body->SetAwake(true);
|
|
|
b2Vec2 f = b2Vec2(fx,fy);
|
|
|
- b2Vec2 p = body->GetWorldPoint(b2Vec2(0.0f, 0.0f));
|
|
|
- body->ApplyLinearImpulse(f, p);
|
|
|
+ b2Vec2 p = body->GetWorldPoint(b2Vec2(0.0f, 0.0f));
|
|
|
+ body->ApplyLinearImpulse(f, p);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
void PhysicsScreenEntity::setTransform(Vector2 pos, Number angle) {
|
|
|
body->SetTransform(b2Vec2(pos.x/worldScale, pos.y/worldScale), angle*(PI/180.0f));
|
|
|
}
|
|
|
@@ -191,12 +195,49 @@ void PhysicsScreenEntity::Update() {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-PhysicsScreenEntity::~PhysicsScreenEntity() {
|
|
|
- if (body) {
|
|
|
- if (fixture) {
|
|
|
- body->DestroyFixture(fixture);
|
|
|
- }
|
|
|
- body->GetWorld()->DestroyBody(body);
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+//==============================================
|
|
|
+//Add on functions to access the fixture library
|
|
|
+//==============================================
|
|
|
+
|
|
|
+
|
|
|
+// Gets the last fixture selected
|
|
|
+b2Fixture* PhysicsScreenEntity::getFixture() { return fixture; }
|
|
|
+
|
|
|
+
|
|
|
+// Returns specific fixture based on index starting from 0
|
|
|
+b2Fixture* PhysicsScreenEntity::getFixture(unsigned short index) {
|
|
|
+ if(fixture) {
|
|
|
+ short i = 0;
|
|
|
+ for (b2Fixture* f = body->GetFixtureList(); f; f = f->GetNext()) {
|
|
|
+ if (i = index) {
|
|
|
+ fixture = f;
|
|
|
+ return fixture;
|
|
|
+ }
|
|
|
+ else {i++;}
|
|
|
+ }
|
|
|
+
|
|
|
+ Logger::log("That fixture index does not exist\n");
|
|
|
+ return fixture = NULL;
|
|
|
}
|
|
|
- delete shape;
|
|
|
+
|
|
|
+ Logger::log("Fixturelist is for mesh only\n");
|
|
|
+ return fixture = NULL;
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+// I believe that at runtime you are not supposed to edit Shapes; However you still can
|
|
|
+// by getting a fixture(above) and then adding "->GetShape()" on the end to get the fixtures shape
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+// Slight change to the destructor
|
|
|
+PhysicsScreenEntity::~PhysicsScreenEntity()
|
|
|
+{
|
|
|
+ if(body)
|
|
|
+ body->GetWorld()->DestroyBody(body); // DestroyBody deletes fixtures and shapes automaticaly according to box2d documentation
|
|
|
+}
|