Просмотр исходного кода

Revert "Physics entities can now use multiple fixtures"

This reverts commit 79bc2e8ed1bd78514fa326ab0c8fb5385ee12b40.
Paul Smith 13 лет назад
Родитель
Сommit
91d48c36de

+ 5 - 5
Modules/Contents/2DPhysics/Include/PolyPhysicsScreen.h

@@ -175,7 +175,7 @@ public:
 	* @param fixedRotation If this is set to true, the entity will always have a locked rotation.
 	* @return The physics entity wrapper.
 	*/
-	PhysicsScreenEntity *addPhysicsChild(ScreenEntity *newEntity, int entType, bool isStatic, Number friction=0.1, Number density=1, Number restitution = 0, bool isSensor = false, bool fixedRotation = false);
+	PhysicsScreenEntity *addPhysicsChild(ScreenEntity *newEntity, int entType, bool isStatic, Number friction=0.1, Number density=1, Number restitution = 0, bool isSensor = false, bool fixedRotation = false, int groupIndex = 0);
 
 	/**
 	* Tracks a ScreenEntity as a physics enabled child. 
@@ -189,7 +189,7 @@ public:
 	* @param fixedRotation If this is set to true, the entity will always have a locked rotation.
 	* @return The physics entity wrapper.
 	*/
-	PhysicsScreenEntity *trackPhysicsChild(ScreenEntity *newEntity, int entType, bool isStatic, Number friction=0.1, Number density=1, Number restitution = 0, bool isSensor = false, bool fixedRotation = false);
+	PhysicsScreenEntity *trackPhysicsChild(ScreenEntity *newEntity, int entType, bool isStatic, Number friction=0.1, Number density=1, Number restitution = 0, bool isSensor = false, bool fixedRotation = false, int groupIndex = 0);
 
 	
 	/**
@@ -199,7 +199,7 @@ public:
 	void removePhysicsChild(ScreenEntity *entityToRemove);
 	
 	
-	ScreenEntity* removeChild(ScreenEntity *entityToRemove);
+	void removeChild(ScreenEntity *entityToRemove);
 	
 	
 	/**
@@ -208,7 +208,7 @@ public:
 	* @param entType Physics shape of the entity. Possible values are PhysicsScreenEntity::ENTITY_RECT or PhysicsScreenEntity::ENTITY_CIRCLE.
 	* @param entityToRemove Entity to remove from the screen.
 	*/	
-	PhysicsScreenEntity *addCollisionChild(ScreenEntity *newEntity, int entType);
+	PhysicsScreenEntity *addCollisionChild(ScreenEntity *newEntity, int entType, int groupIndex = 0);
 	
 	/**
 	* Begins tracking collisions for a ScreenEntity.
@@ -216,7 +216,7 @@ public:
 	* @param entType Physics shape of the entity. Possible values are PhysicsScreenEntity::ENTITY_RECT or PhysicsScreenEntity::ENTITY_CIRCLE.
 	* @param entityToRemove Entity to remove from the screen.
 	*/	
-	PhysicsScreenEntity *trackCollisionChild(ScreenEntity *newEntity, int entType);	
+	PhysicsScreenEntity *trackCollisionChild(ScreenEntity *newEntity, int entType, int groupIndex = 0);	
 	
 	/**
 	* Removes an existing joint.

+ 7 - 12
Modules/Contents/2DPhysics/Include/PolyPhysicsScreenEntity.h

@@ -58,16 +58,10 @@ namespace Polycode {
 			
 			void setVelocity(Number fx, Number fy);	
 			void setVelocityX( Number fx);	
-			void setVelocityY(Number fy);
+			void setVelocityY(Number fy);				
 			
 			void applyImpulse(Number fx, Number fy);
-
-
-			b2Fixture* getFixture();						// Gets the last fixture selected (automatically set on creation)			
-			b2Fixture* getFixture(unsigned short index);	// Gets a specific fixture if there is more than one
-			
-															// You do not need a shape pointer
-
+				
 			/**
 			* Rectangular physics entity
 			*/ 
@@ -81,9 +75,10 @@ namespace Polycode {
 			*/ 						
 			static const int ENTITY_MESH = 3;
 		
-			b2Body *body;
-			b2Fixture *fixture;
-
+			b2Fixture *fixture;		
+			b2Body* body;
+			b2Shape *shape;
+			
 			bool collisionOnly;
 		
 		protected:
@@ -92,4 +87,4 @@ namespace Polycode {
 		ScreenEntity *screenEntity;
 	};
 
-}
+}

+ 30 - 60
Modules/Contents/2DPhysics/Source/PolyPhysicsScreen.cpp

@@ -274,51 +274,34 @@ void PhysicsScreen::setVelocity(ScreenEntity *ent, Number fx, Number fy) {
 	PhysicsScreenEntity *pEnt = getPhysicsByScreenEntity(ent);
 	if(pEnt == NULL)
 		return;
-	
-	pEnt->body->SetAwake(true);
-	b2Vec2 f = pEnt->body->GetLinearVelocity();
-	if(fx != 0)
-		f.x = fx;
-	if(fy != 0)
-		f.y = fy;
-	
-	pEnt->body->SetLinearVelocity(f);
+	pEnt->setVelocity(fx, fy);	
 }
 
 void PhysicsScreen::setVelocityX(ScreenEntity *ent, Number fx) {
 	PhysicsScreenEntity *pEnt = getPhysicsByScreenEntity(ent);
 	if(pEnt == NULL)
 		return;
-	
-	pEnt->body->SetAwake(true);
-	b2Vec2 f = pEnt->body->GetLinearVelocity();
-	f.x = fx;	
-	pEnt->body->SetLinearVelocity(f);
-	
+	pEnt->setVelocityX(fx);
 }
 
 void PhysicsScreen::setVelocityY(ScreenEntity *ent, Number fy) {
 	PhysicsScreenEntity *pEnt = getPhysicsByScreenEntity(ent);
 	if(pEnt == NULL)
 		return;
-	
-	pEnt->body->SetAwake(true);
-	b2Vec2 f = pEnt->body->GetLinearVelocity();
-	f.y = fy;	
-	pEnt->body->SetLinearVelocity(f);	
+	pEnt->setVelocityY(fy);
 }
 
 
-PhysicsScreenEntity *PhysicsScreen::addCollisionChild(ScreenEntity *newEntity, int entType) {
+PhysicsScreenEntity *PhysicsScreen::addCollisionChild(ScreenEntity *newEntity, int entType, int groupIndex) {
 	PhysicsScreenEntity *ret;
-	ret = addPhysicsChild(newEntity, entType, false, 0,0.0,0, true);
+	ret = addPhysicsChild(newEntity, entType, false, 0,0.0,0, true, groupIndex);
 	ret->collisionOnly = true; 
 	return ret;
 }
 
-PhysicsScreenEntity *PhysicsScreen::trackCollisionChild(ScreenEntity *newEntity, int entType) {
+PhysicsScreenEntity *PhysicsScreen::trackCollisionChild(ScreenEntity *newEntity, int entType, int groupIndex) {
 	PhysicsScreenEntity *ret;
-	ret = trackPhysicsChild(newEntity, entType, false, 0,0.0,0, true);
+	ret = trackPhysicsChild(newEntity, entType, false, 0,0.0,0, true, groupIndex);
 	ret->collisionOnly = true; 
 	return ret;
 }
@@ -346,11 +329,7 @@ void PhysicsScreen::applyImpulse(ScreenEntity *ent, Number fx, Number fy) {
 	PhysicsScreenEntity *pEnt = getPhysicsByScreenEntity(ent);
 	if(pEnt == NULL)
 		return;
-	
-	pEnt->body->SetAwake(true);
-	b2Vec2 f =  b2Vec2(fx,fy);
-	b2Vec2 p = pEnt->body->GetWorldPoint(b2Vec2(0.0f, 0.0f));	
-	pEnt->body->ApplyLinearImpulse(f, p);	
+	pEnt->applyImpulse(fx, fy);
 }
 
 
@@ -405,11 +384,9 @@ ScreenEntity *PhysicsScreen::getEntityAtPosition(Number x, Number y) {
 	
 	for(int i=0;i<physicsChildren.size();i++) {
 		PhysicsScreenEntity *ent = physicsChildren[i];
-		if(ent->fixture) {
-			for (b2Fixture* f = ent->body->GetFixtureList(); f; f = f->GetNext()) {		// This has been changed to accept multiple fixtures
-				if(f->TestPoint(mousePosition)) {										// Fixtures have a Testpoint function that requires just a b2Vec
-					return ent->getScreenEntity();
-				}
+		if(ent->shape) {
+			if(ent->shape->TestPoint(ent->body->GetTransform(), mousePosition)) {
+				return ent->getScreenEntity();
 			}
 		}
 	}	
@@ -426,13 +403,11 @@ bool PhysicsScreen::testEntityAtPosition(ScreenEntity *ent, Number x, Number y)
 	mousePosition.x = x/worldScale;
 	mousePosition.y = y/worldScale;
 	
-	if(pEnt->fixture) {
-		for (b2Fixture* f = pEnt->body->GetFixtureList(); f; f = f->GetNext()) {	// This has been changed to accept multiple fixtures
-			if(f->TestPoint(mousePosition))											// Fixtures have a Testpoint function that requires just a b2Vec
-				return true;
-			else
-				return false;
-		}
+	if(pEnt->shape) {
+		if(pEnt->shape->TestPoint(pEnt->body->GetTransform(), mousePosition))
+			return true;
+		else
+			return false;
 	}
 	return false;
 }
@@ -442,14 +417,14 @@ void PhysicsScreen::destroyMouseJoint(b2MouseJoint *mJoint) {
 		mJoint = NULL;
 }
 
-PhysicsScreenEntity *PhysicsScreen::addPhysicsChild(ScreenEntity *newEntity, int entType, bool isStatic, Number friction, Number density, Number restitution, bool isSensor, bool fixedRotation) {
+PhysicsScreenEntity *PhysicsScreen::addPhysicsChild(ScreenEntity *newEntity, int entType, bool isStatic, Number friction, Number density, Number restitution, bool isSensor, bool fixedRotation, int groupIndex) {
 	addChild(newEntity);
-	return trackPhysicsChild(newEntity, entType, isSensor, friction, density, restitution, isSensor, fixedRotation);
+	return trackPhysicsChild(newEntity, entType, isStatic, friction, density, restitution, isSensor, fixedRotation, groupIndex);
 }
 
-PhysicsScreenEntity *PhysicsScreen::trackPhysicsChild(ScreenEntity *newEntity, int entType, bool isStatic, Number friction, Number density, Number restitution, bool isSensor, bool fixedRotation) {
+PhysicsScreenEntity *PhysicsScreen::trackPhysicsChild(ScreenEntity *newEntity, int entType, bool isStatic, Number friction, Number density, Number restitution, bool isSensor, bool fixedRotation, int groupIndex) {
 	newEntity->setPositionMode(ScreenEntity::POSITION_CENTER);
-	PhysicsScreenEntity *newPhysicsEntity = new PhysicsScreenEntity(newEntity, world, worldScale, entType, isStatic, friction, density, restitution, isSensor,fixedRotation);
+	PhysicsScreenEntity *newPhysicsEntity = new PhysicsScreenEntity(newEntity, world, worldScale, entType, isStatic, friction, density, restitution, isSensor,fixedRotation, groupIndex);
 	physicsChildren.push_back(newPhysicsEntity);
 	newPhysicsEntity->body->SetAwake(true);
 	return newPhysicsEntity;
@@ -470,13 +445,12 @@ void PhysicsScreen::removePhysicsChild(ScreenEntity *entityToRemove) {
 	Screen::removeChild(entityToRemove);	
 }
 
-ScreenEntity* PhysicsScreen::removeChild(ScreenEntity *entityToRemove) {
+void PhysicsScreen::removeChild(ScreenEntity *entityToRemove) {
 	if(getPhysicsByScreenEntity(entityToRemove)) {
 		removePhysicsChild(entityToRemove);
 	} else {
 		Screen::removeChild(entityToRemove);	
 	}
-	return entityToRemove;
 }
 
 
@@ -490,27 +464,23 @@ PhysicsScreen::~PhysicsScreen() {
 	}
 	delete world;	
 }
-																							
-PhysicsScreenEntity *PhysicsScreen::getPhysicsEntityByFixture(b2Fixture *fixture) {			// I have made changes so it will search through body fixturelists
-	for(int i=0; i < physicsChildren.size(); i++) {											
-		for (b2Fixture* f = physicsChildren[i]->body->GetFixtureList(); f; f = f->GetNext()) {
-			if(f == fixture)
-				return physicsChildren[i];
-		}
+
+PhysicsScreenEntity *PhysicsScreen::getPhysicsEntityByFixture(b2Fixture *fixture) {
+	for(int i=0; i < physicsChildren.size(); i++) {
+		if(physicsChildren[i]->fixture == fixture)
+			return physicsChildren[i];
 	}
 	return NULL;	
 }
 
-PhysicsScreenEntity *PhysicsScreen::getPhysicsEntityByShape(b2Shape *shape) {				// I have made changes so it will search through body fixturelists
+PhysicsScreenEntity *PhysicsScreen::getPhysicsEntityByShape(b2Shape *shape) {
 	for(int i=0; i < physicsChildren.size(); i++) {
-		for (b2Fixture *f = physicsChildren[i]->body->GetFixtureList(); f; f = f->GetNext()) {
-			if(f->GetShape() == shape)
-				return physicsChildren[i];
-		}
+		if(physicsChildren[i]->shape == shape)
+			return physicsChildren[i];
 	}
 	return NULL;
 }
-
+	
 void PhysicsScreen::handleEvent(Event *event) {	
 	Screen::handleEvent(event);
 }

+ 82 - 127
Modules/Contents/2DPhysics/Source/PolyPhysicsScreenEntity.cpp

@@ -31,98 +31,90 @@ THE SOFTWARE.
 
 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)
-{
-	screenEntity = entity;
-
-	Vector3 entityScale = entity->getCompoundScale();
+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;
-	collisionOnly = false;
-
 	
-	// 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);
+	Vector3 entityScale = entity->getCompoundScale();
 	
-	// Create fixture definition---------------------------------------------
+	screenEntity = entity;
+	
+	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;	
+	
+	if(isStatic) {
+		bodyDef->type = b2_staticBody;		
+	} else {
+		bodyDef->type = b2_dynamicBody;	
+	}
+	body = world->CreateBody(bodyDef);
+	delete bodyDef;
+		
 	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_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
+		case ENTITY_MESH:
+		{
+			b2PolygonShape *b2shape = new b2PolygonShape;			
+			
 			ScreenMesh* screenMesh = dynamic_cast<ScreenMesh*>(entity);
-		
-			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");
+			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++;
 					}
 				}
-			}
-			else {
+				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;
+		}
+		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) {
@@ -149,26 +141,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));
 }
@@ -199,49 +191,12 @@ void PhysicsScreenEntity::Update() {
 	}	
 }
 
-
-
-
-
-//========================================
-//Add on functions for 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;
+PhysicsScreenEntity::~PhysicsScreenEntity() {
+	if (body) {
+		if (fixture) {	
+			body->DestroyFixture(fixture);
+		}	
+		body->GetWorld()->DestroyBody(body);	
 	}
-
-	Logger::log("Fixturelist is for mesh only\n");
-	return fixture = NULL;	
+	delete shape;
 }
-
-
-
-// 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
-}