Преглед на файлове

2D Physics tweaks, matrix now rebuilt on concatenated matrix request

Ivan Safrin преди 13 години
родител
ревизия
b94e900cf6

+ 1 - 1
Core/Contents/Include/PolyEntity.h

@@ -92,7 +92,7 @@ namespace Polycode {
 			* Returns the entity's matrix multiplied by its parent's concatenated matrix. This, in effect, returns the entity's actual world transformation.
 			* Returns the entity's matrix multiplied by its parent's concatenated matrix. This, in effect, returns the entity's actual world transformation.
 			@return Entity's concatenated matrix.
 			@return Entity's concatenated matrix.
 			*/
 			*/
-			Matrix4 getConcatenatedMatrix() const;
+			Matrix4 getConcatenatedMatrix();
 			
 			
 			/** 
 			/** 
 			* Returns Same as getConcatenatedMatrix(), but contains only roll information for rotation. Used internally for billboards.
 			* Returns Same as getConcatenatedMatrix(), but contains only roll information for rotation. Used internally for billboards.

+ 1 - 1
Core/Contents/Include/PolyScreenEntity.h

@@ -104,7 +104,7 @@ class _PolyExport ScreenEntity : public Entity, public EventDispatcher {
 		virtual void onKeyDown(PolyKEY key, wchar_t charCode){}
 		virtual void onKeyDown(PolyKEY key, wchar_t charCode){}
 		virtual void onKeyUp(PolyKEY key, wchar_t charCode){}
 		virtual void onKeyUp(PolyKEY key, wchar_t charCode){}
 		
 		
-		bool hitTest(Number x, Number y) const;
+		bool hitTest(Number x, Number y);
 	
 	
 		Matrix4 buildPositionMatrix();
 		Matrix4 buildPositionMatrix();
 		void adjustMatrixForChildren();
 		void adjustMatrixForChildren();

+ 4 - 0
Core/Contents/Include/PolyScreenSprite.h

@@ -59,6 +59,8 @@ class _PolyExport ScreenSprite : public ScreenShape
 		*/
 		*/
 		void addAnimation(const String& name, const String& frames, Number speed);
 		void addAnimation(const String& name, const String& frames, Number speed);
 		
 		
+		void showFrame(unsigned int frameIndex);
+		
 		/**
 		/**
 		* Play back a previously created animation by name.
 		* Play back a previously created animation by name.
 		* @param name Name of the animation to play.
 		* @param name Name of the animation to play.
@@ -70,6 +72,8 @@ class _PolyExport ScreenSprite : public ScreenShape
 		
 		
 		void Pause(bool val);
 		void Pause(bool val);
 		
 		
+		void updateSprite();
+		
 	protected:
 	protected:
 	
 	
 		bool paused;
 		bool paused;

+ 4 - 1
Core/Contents/Source/PolyEntity.cpp

@@ -438,7 +438,10 @@ Vector3 Entity::getScale() const {
 	return scale;
 	return scale;
 }
 }
 
 
-Matrix4 Entity::getConcatenatedMatrix() const {
+Matrix4 Entity::getConcatenatedMatrix() {
+	if(matrixDirty)
+		rebuildTransformMatrix();
+
 	if(parentEntity != NULL) 
 	if(parentEntity != NULL) 
 		return transformMatrix * parentEntity->getConcatenatedMatrix();
 		return transformMatrix * parentEntity->getConcatenatedMatrix();
 	else
 	else

+ 1 - 1
Core/Contents/Source/PolyScreenEntity.cpp

@@ -186,7 +186,7 @@ bool isPointInsidePolygon2D(Polycode::Polygon *poly, const Vector2 &p) {
 		return true;
 		return true;
 }
 }
 
 
-bool ScreenEntity::hitTest(const Number x, const Number y) const {
+bool ScreenEntity::hitTest(const Number x, const Number y) {
 
 
 	Vector3 v;	
 	Vector3 v;	
 	Polygon testPoly;
 	Polygon testPoly;

+ 19 - 4
Core/Contents/Source/PolyScreenSprite.cpp

@@ -93,6 +93,16 @@ void ScreenSprite::Pause(bool val) {
 	paused = val;
 	paused = val;
 }
 }
 
 
+void ScreenSprite::showFrame(unsigned int frameIndex) {
+	if(!currentAnimation)
+		return;
+
+	if(frameIndex < currentAnimation->numFrames) {
+		currentFrame = frameIndex;
+		updateSprite();
+	}
+}
+
 void ScreenSprite::Update() {
 void ScreenSprite::Update() {
 	if(!currentAnimation)
 	if(!currentAnimation)
 		return;
 		return;
@@ -115,6 +125,14 @@ void ScreenSprite::Update() {
 		}
 		}
 	}
 	}
 	
 	
+	updateSprite();
+			
+	lastTick = newTick;
+		
+	}
+}
+
+void ScreenSprite::updateSprite() {
 	Number xOffset = currentAnimation->framesOffsets[currentFrame].x;
 	Number xOffset = currentAnimation->framesOffsets[currentFrame].x;
 	Number yOffset = 1.0f - currentAnimation->framesOffsets[currentFrame].y - spriteUVHeight;
 	Number yOffset = 1.0f - currentAnimation->framesOffsets[currentFrame].y - spriteUVHeight;
 	
 	
@@ -126,8 +144,5 @@ void ScreenSprite::Update() {
 	imagePolygon->getVertex(3)->setTexCoord(xOffset, yOffset);	
 	imagePolygon->getVertex(3)->setTexCoord(xOffset, yOffset);	
 		
 		
 	mesh->arrayDirtyMap[RenderDataArray::TEXCOORD_DATA_ARRAY] = true;
 	mesh->arrayDirtyMap[RenderDataArray::TEXCOORD_DATA_ARRAY] = true;
-		
-	lastTick = newTick;
-		
-	}
+
 }
 }

+ 24 - 1
Modules/Contents/2DPhysics/Include/PolyPhysicsScreen.h

@@ -176,6 +176,21 @@ public:
 	* @return The physics entity wrapper.
 	* @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);
+
+	/**
+	* Tracks a ScreenEntity as a physics enabled child. 
+	* @param newEntity Screen entity to add.
+	* @param entType Physics entity type to add as. Possible values are PhysicsScreenEntity::ENTITY_RECT, PhysicsScreenEntity::ENTITY_CIRCLE and PhysicsScreenEntity::ENTITY_MESH. If the type is ENTITY_MESH, the ScreenEntity passed must be a ScreenMesh!
+	* @param isStatic If this parameter is true, the body is static (doesn't move on its own).
+	* @param friction Friction of the physics entity. Friction controls how entities drag along each other.
+	* @param density Density of the physics entity. Density controls how heavy the entity is.
+	* @param restitution Restitution of the physics entity. Restitution controls how bouncy the entity is.
+	* @param isSensor If this is set to true, the entity won't collide with other entities, but its collision will register.
+	* @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);
+
 	
 	
 	/**
 	/**
 	* Removes a physics child from the screen.
 	* Removes a physics child from the screen.
@@ -188,13 +203,21 @@ public:
 	
 	
 	
 	
 	/**
 	/**
-	* Begins tracking collisions for a ScreenEntity.
+	* Begins tracking collisions for a ScreenEntity and adds it to the scene.
 	* @param newEntity Entity to track collisions for.
 	* @param newEntity Entity to track collisions for.
 	* @param entType Physics shape of the entity. Possible values are PhysicsScreenEntity::ENTITY_RECT or PhysicsScreenEntity::ENTITY_CIRCLE.
 	* @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.
 	* @param entityToRemove Entity to remove from the screen.
 	*/	
 	*/	
 	PhysicsScreenEntity *addCollisionChild(ScreenEntity *newEntity, int entType);
 	PhysicsScreenEntity *addCollisionChild(ScreenEntity *newEntity, int entType);
 	
 	
+	/**
+	* Begins tracking collisions for a ScreenEntity.
+	* @param newEntity Entity to track collisions for.
+	* @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);	
+	
 	/**
 	/**
 	* Removes an existing joint.
 	* Removes an existing joint.
 	* @param joint Joint to remove.
 	* @param joint Joint to remove.

+ 0 - 3
Modules/Contents/2DPhysics/Include/PolyPhysicsScreenEntity.h

@@ -78,9 +78,6 @@ namespace Polycode {
 		protected:
 		protected:
 		
 		
 		Number worldScale;
 		Number worldScale;
-		Vector2 lastPosition;
-		Number lastRotation;
-			
 		ScreenEntity *screenEntity;
 		ScreenEntity *screenEntity;
 	};
 	};
 
 

+ 12 - 0
Modules/Contents/2DPhysics/Source/PolyPhysicsScreen.cpp

@@ -316,6 +316,13 @@ PhysicsScreenEntity *PhysicsScreen::addCollisionChild(ScreenEntity *newEntity, i
 	return ret;
 	return ret;
 }
 }
 
 
+PhysicsScreenEntity *PhysicsScreen::trackCollisionChild(ScreenEntity *newEntity, int entType) {
+	PhysicsScreenEntity *ret;
+	ret = trackPhysicsChild(newEntity, entType, false, 0,0.0,0, true);
+	ret->collisionOnly = true; 
+	return ret;
+}
+
 void PhysicsScreen::setTransform(ScreenEntity *ent, Vector2 pos, Number angle) {
 void PhysicsScreen::setTransform(ScreenEntity *ent, Vector2 pos, Number angle) {
 	PhysicsScreenEntity *pEnt = getPhysicsByScreenEntity(ent);
 	PhysicsScreenEntity *pEnt = getPhysicsByScreenEntity(ent);
 	if(pEnt == NULL)
 	if(pEnt == NULL)
@@ -433,6 +440,10 @@ void PhysicsScreen::destroyMouseJoint(b2MouseJoint *mJoint) {
 
 
 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) {
 	addChild(newEntity);
 	addChild(newEntity);
+	return trackPhysicsChild(newEntity, entType, isSensor, friction, density, restitution, isSensor, fixedRotation);
+}
+
+PhysicsScreenEntity *PhysicsScreen::trackPhysicsChild(ScreenEntity *newEntity, int entType, bool isStatic, Number friction, Number density, Number restitution, bool isSensor, bool fixedRotation) {
 	newEntity->setPositionMode(ScreenEntity::POSITION_CENTER);
 	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);
 	physicsChildren.push_back(newPhysicsEntity);
 	physicsChildren.push_back(newPhysicsEntity);
@@ -440,6 +451,7 @@ PhysicsScreenEntity *PhysicsScreen::addPhysicsChild(ScreenEntity *newEntity, int
 	return newPhysicsEntity;
 	return newPhysicsEntity;
 }
 }
 
 
+
 void PhysicsScreen::removePhysicsChild(ScreenEntity *entityToRemove) {
 void PhysicsScreen::removePhysicsChild(ScreenEntity *entityToRemove) {
 	PhysicsScreenEntity *physicsEntityToRemove = getPhysicsByScreenEntity(entityToRemove);
 	PhysicsScreenEntity *physicsEntityToRemove = getPhysicsByScreenEntity(entityToRemove);
 	if(!physicsEntityToRemove) {
 	if(!physicsEntityToRemove) {

+ 20 - 28
Modules/Contents/2DPhysics/Source/PolyPhysicsScreenEntity.cpp

@@ -35,7 +35,7 @@ PhysicsScreenEntity::PhysicsScreenEntity(ScreenEntity *entity, b2World *world, N
 	
 	
 	this->worldScale = worldScale;
 	this->worldScale = worldScale;
 	
 	
-	Vector3 entityScale = entity->getScale();
+	Vector3 entityScale = entity->getCompoundScale();
 	
 	
 	screenEntity = entity;
 	screenEntity = entity;
 	
 	
@@ -109,9 +109,6 @@ PhysicsScreenEntity::PhysicsScreenEntity(ScreenEntity *entity, b2World *world, N
 	
 	
 	fixture = body->CreateFixture(&fDef);	
 	fixture = body->CreateFixture(&fDef);	
 	
 	
-	lastPosition.x = screenEntity->getPosition2D().x;
-	lastPosition.y = screenEntity->getPosition2D().y;
-
 	collisionOnly = false;
 	collisionOnly = false;
 	
 	
 }
 }
@@ -135,34 +132,29 @@ void PhysicsScreenEntity::setTransform(Vector2 pos, Number angle) {
 }
 }
 
 
 void PhysicsScreenEntity::Update() {
 void PhysicsScreenEntity::Update() {
-	b2Vec2 position = body->GetPosition();
-	Number angle = body->GetAngle();
-
-	
-	if(collisionOnly) {
-		body->SetTransform(position, screenEntity->getRotation()*(PI/180.0f));		
-	} else {
-		screenEntity->setRotation(angle*(180.0f/PI));	
-	}
-	
 	if(collisionOnly) {
 	if(collisionOnly) {
+		Matrix4 matrix = screenEntity->getConcatenatedMatrix();
 		b2Vec2 newPos;
 		b2Vec2 newPos;
-		newPos.x = screenEntity->getPosition2D().x/worldScale; 
-		newPos.y = screenEntity->getPosition2D().y/worldScale;				
-		body->SetTransform(newPos, screenEntity->getRotation()*(PI/180.0f));
-		position.x = screenEntity->getPosition2D().x/worldScale; 
-		position.y = screenEntity->getPosition2D().y/worldScale; 				
+		Number newRotation;
+		
+		Vector3 pos = matrix.getPosition();
+		newPos.x = pos.x/worldScale;
+		newPos.y = pos.y/worldScale;		
+
+		Number rx,ry,rz;
+
+		matrix.getEulerAngles(&rx, &ry, &rz);
+		newRotation = rz;
+
+		body->SetAwake(true);
+		body->SetTransform(newPos, newRotation * TORADIANS);
 	} else {
 	} else {
+		b2Vec2 position = body->GetPosition();
+		Number angle = body->GetAngle();	
+		screenEntity->setRotation(angle*(180.0f/PI));	
 		screenEntity->setPosition(position.x*worldScale, position.y*worldScale);
 		screenEntity->setPosition(position.x*worldScale, position.y*worldScale);
-	}
-	
-	screenEntity->dirtyMatrix(true);
-	screenEntity->rebuildTransformMatrix();
-	
-	lastPosition.x = position.x*worldScale;
-	lastPosition.y = position.y*worldScale;	
-	
-	lastRotation = angle * (180.0f/PI);
+		screenEntity->rebuildTransformMatrix();		
+	}	
 }
 }
 
 
 PhysicsScreenEntity::~PhysicsScreenEntity() {
 PhysicsScreenEntity::~PhysicsScreenEntity() {