Browse Source

Improving the particle emitter

Panagiotis Christopoulos Charitos 15 years ago
parent
commit
bdf9d8fafc

+ 16 - 106
src/Main.cpp

@@ -68,123 +68,37 @@ void initPhysics()
 
 	btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.)));
 
-	btTransform groundTransform;
+	Transform groundTransform;
 	groundTransform.setIdentity();
-	groundTransform.setOrigin(btVector3(0,-50, 0));
+	groundTransform.setOrigin(Vec3(0,-50, 0));
 
-	//We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here:
-	{
-		btScalar mass(0.);
-
-		//rigidbody is dynamic if and only if mass is non zero, otherwise static
-		bool isDynamic = (mass != 0.f);
-
-		btVector3 localInertia(0, 0, 0);
-		if (isDynamic)
-			groundShape->calculateLocalInertia(mass,localInertia);
-
-		//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
-		btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);
-		btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia);
-		btRigidBody* body = new btRigidBody(rbInfo);
-
-		//add the body to the dynamics world
-		dynamicsWorld->addRigidBody(body);
-	}
+	new RigidBody(0.0, groundTransform, groundShape, NULL, Physics::CG_MAP, Physics::CG_ALL);
 
 
 	{
-		//create a few dynamic rigidbodies
-		// Re-using the same collision is better for memory usage and performance
-
 		btCollisionShape* colShape = new btBoxShape(btVector3(SCALING*1,SCALING*1,SCALING*1));
-		//btCollisionShape* colShape = new btSphereShape(btScalar(1.));
-
-		// Create Dynamic Objects
-		btTransform startTransform;
-		startTransform.setIdentity();
-
-		btScalar	mass(1.0);
-
-		btVector3 localInertia(0, 0, 0);
-		colShape->calculateLocalInertia(mass,localInertia);
 
 		float start_x = START_POS_X - ARRAY_SIZE_X/2;
 		float start_y = START_POS_Y;
 		float start_z = START_POS_Z - ARRAY_SIZE_Z/2;
 
-		btRigidBody* body;
 		for (int k=0;k<ARRAY_SIZE_Y;k++)
 		{
 			for (int i=0;i<ARRAY_SIZE_X;i++)
 			{
 				for(int j = 0;j<ARRAY_SIZE_Z;j++)
 				{
-					startTransform.setOrigin(SCALING*btVector3(
-										btScalar(2.0*i + start_x),
-										btScalar(20+2.0*k + start_y),
-										btScalar(2.0*j + start_z)));
-
-
 					//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
 					MeshNode* crate = new MeshNode;
 					crate->init("models/crate0/crate0.mesh");
 					crate->getLocalTransform().setScale(1.11);
 
 					Transform trf(SCALING*Vec3(2.0*i + start_x, 20+2.0*k + start_y, 2.0*j + start_z), Mat3::getIdentity(), 1.0);
-					body = app->getScene()->getPhysics()->createNewRigidBody(mass, trf, colShape, crate);
-
-					//MotionState* myMotionState = new MotionState(startTransform, *crate);
-					//btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,colShape,localInertia);
-					//btRigidBody* body = new btRigidBody(rbInfo);
-					//body = new btRigidBody(rbInfo);
-
-					//if(i=2) body->setActivationState(ISLAND_SLEEPING);
-
-					//body->setActivationState(ISLAND_SLEEPING);
-
-
-					//dynamicsWorld->addRigidBody(body);
-					//body->setGravity(toBt(Vec3(Util::randRange(-1.0, 1.0), Util::randRange(-1.0, 1.0), Util::randRange(-1.0, 1.0))));
-					//boxes.push_back(body);
+					new RigidBody(1.0, trf, colShape, crate, Physics::CG_MAP, Physics::CG_ALL);
 				}
 			}
 		}
 	}
-
-
-	//dynamicsWorld->setDebugDrawer(&debugDrawer);
-
-
-
-	/*for(int i=0; i<app->getScene()->getPhysics()->getDynamicsWorld()->getCollisionObjectArray().size();i++)
-	{
-		btCollisionObject* colObj = app->getScene()->getPhysics()->getDynamicsWorld()->getCollisionObjectArray()[i];
-		btRigidBody* body = btRigidBody::upcast(colObj);
-		if(body)
-		{
-			if(body->getMotionState())
-			{
-				MotionState* myMotionState = (MotionState*)body->getMotionState();
-				myMotionState->m_graphicsWorldTrans = myMotionState->m_startWorldTrans;
-				body->setCenterOfMassTransform(myMotionState->m_graphicsWorldTrans);
-				colObj->setInterpolationWorldTransform(myMotionState->m_startWorldTrans);
-				colObj->forceActivationState(ACTIVE_TAG);
-				colObj->activate();
-				colObj->setDeactivationTime(0);
-				//colObj->setActivationState(WANTS_DEACTIVATION);
-			}
-			//removed cached contact points (this is not necessary if all objects have been removed from the dynamics world)
-			//m_dynamicsWorld->getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(colObj->getBroadphaseHandle(),getDynamicsWorld()->getDispatcher());
-
-			btRigidBody* body = btRigidBody::upcast(colObj);
-			if (body && !body->isStaticObject())
-			{
-				btRigidBody::upcast(colObj)->setLinearVelocity(btVector3(0, 0, 0));
-				btRigidBody::upcast(colObj)->setAngularVelocity(btVector3(0, 0, 0));
-			}
-		}
-	}*/
 }
 
 
@@ -241,7 +155,7 @@ void init()
 	spot_lights[1]->setLocalTransform(Transform(Vec3(-2.3, 6.3, 2.9), Mat3(Euler(toRad(-70), toRad(-20), 0.0)), 1.0));
 
 	// horse
-	horse = new MeshNode();
+	/*horse = new MeshNode();
 	horse->init("meshes/horse/horse.mesh");
 	//horse->init("models/head/head.mesh");
 	horse->setLocalTransform(Transform(Vec3(-2, 0, 1), Mat3(Euler(-M::PI/2, 0.0, 0.0)), 0.5));
@@ -250,7 +164,7 @@ void init()
 	sarge = new MeshNode();
 	sarge->init("meshes/sphere/sphere16.mesh");
 	//sarge->setLocalTransform(Vec3(0, -2.8, 1.0), Mat3(Euler(-M::PI/2, 0.0, 0.0)), 1.1);
-	sarge->setLocalTransform(Transform(Vec3(0, 2.0, 2.0), Mat3::getIdentity(), 0.4));
+	sarge->setLocalTransform(Transform(Vec3(0, 2.0, 2.0), Mat3::getIdentity(), 0.4));*/
 	
 	// floor
 	floor__ = new MeshNode();
@@ -258,11 +172,11 @@ void init()
 	floor__->setLocalTransform(Transform(Vec3(0.0, -0.19, 0.0), Mat3(Euler(-M::PI/2, 0.0, 0.0)), 0.8));
 
 	// imp	
-	imp = new SkelModelNode();
+	/*imp = new SkelModelNode();
 	imp->init("models/imp/imp.smdl");
 	imp->setLocalTransform(Transform(Vec3(0.0, 2.11, 0.0), Mat3(Euler(-M::PI/2, 0.0, 0.0)), 0.7));
 	imp->meshNodes[0]->meshSkelCtrl->skelNode->skelAnimCtrl->skelAnim.loadRsrc("models/imp/walk.imp.anim");
-	imp->meshNodes[0]->meshSkelCtrl->skelNode->skelAnimCtrl->step = 0.8;
+	imp->meshNodes[0]->meshSkelCtrl->skelNode->skelAnimCtrl->step = 0.8;*/
 
 	// cave map
 	/*for(int i=1; i<21; i++)
@@ -306,6 +220,7 @@ void mainLoop()
 	INFO("Entering main loop");
 
 	int ticks = App::getTicks();
+	float secs = 0.0;
 	do
 	{
 		int ticks_ = App::getTicks();
@@ -367,12 +282,12 @@ void mainLoop()
 		//static_cast<btRigidBody*>(dynamicsWorld->getCollisionObjectArray()[1])->getMotionState()->setWorldTransform(toBt(point_lights[0]->transformationWspace));
 		//dynamicsWorld->getCollisionObjectArray()[3]->setWorldTransform(toBt(point_lights[0]->transformationWspace));
 
-		app->getScene()->updateAllControllers();
-		app->getScene()->updateAllWorldStuff();
+		secs = app->getTicks() / 1000.0 - secs;
 
-		//partEmitter->update();
+		app->getScene()->getPhysics()->getDynamicsWorld()->stepSimulation(secs);
 
-		app->getScene()->getPhysics()->getDynamicsWorld()->stepSimulation(app->timerTick);
+		app->getScene()->updateAllControllers();
+		app->getScene()->updateAllWorldStuff();
 
 		app->getMainRenderer()->render(*app->getActiveCam());
 
@@ -392,8 +307,9 @@ void mainLoop()
 		if(I::keys[SDL_SCANCODE_F12] == 1)  app->getMainRenderer()->takeScreenshot("gfx/screenshot.jpg");
 
 		/*char str[128];
-		sprintf(str, "capt/%06d.jpg", R::framesNum);
-		R::takeScreenshot(str);*/
+		static string scrFile = (app->getSettingsPath() / "capt" / "%06d.jpg").string();
+		sprintf(str, scrFile.c_str(), app->getMainRenderer()->getFramesNum());
+		app->getMainRenderer()->takeScreenshot(str);*/
 
 		// std stuff follow
 		app->swapBuffers();
@@ -411,12 +327,6 @@ void mainLoop()
 }
 
 
-ostream& operator<<(ostream& s, const Vec3& v)
-{
-	s << fixed << v.x << ' ' << v.y << ' ' << v.z;
-	return s;
-}
-
 //======================================================================================================================
 // main                                                                                                                =
 //======================================================================================================================

+ 6 - 5
src/Physics/BtAndAnkiConvertors.h

@@ -28,12 +28,13 @@ inline Quat toAnki(const btQuaternion& q)
 }
 
 
-inline Mat4 toAnki(const btTransform& t)
+inline Transform toAnki(const btTransform& t)
 {
-	Mat4 m;
-	t.getOpenGLMatrix(&m[0]);
-	m.transpose();
-	return m;
+	Transform out;
+	out.setRotation(toAnki(t.getBasis()));
+	out.setOrigin(toAnki(t.getOrigin()));
+	out.setScale(1.0);
+	return out;
 }
 
 

+ 9 - 6
src/Physics/MotionState.h

@@ -12,7 +12,7 @@
 class MotionState: public btMotionState
 {
 	public:
-		MotionState(const btTransform& initialTransform, SceneNode& node_);
+		MotionState(const btTransform& initialTransform, SceneNode* node_);
 
 		~MotionState() {}
 
@@ -24,7 +24,7 @@ class MotionState: public btMotionState
 
 	private:
 		btTransform worldTransform;
-		SceneNode& node;
+		SceneNode* node;
 };
 
 
@@ -32,7 +32,7 @@ class MotionState: public btMotionState
 // Inlines                                                                                                             =
 //======================================================================================================================
 
-inline MotionState::MotionState(const btTransform& initialTransform, SceneNode& node_):
+inline MotionState::MotionState(const btTransform& initialTransform, SceneNode* node_):
 	worldTransform(initialTransform),
 	node(node_)
 {}
@@ -52,11 +52,14 @@ inline const btTransform& MotionState::getWorldTransform() const
 
 inline void MotionState::setWorldTransform(const btTransform& worldTrans)
 {
-	float originalScale = node.getLocalTransform().getScale();
 	worldTransform = worldTrans;
 
-	node.setLocalTransform(Transform(toAnki(worldTrans)));
-	node.getLocalTransform().setScale(originalScale);
+	if(node)
+	{
+		float originalScale = node->getLocalTransform().getScale();
+		node->setLocalTransform(Transform(toAnki(worldTrans)));
+		node->getLocalTransform().setScale(originalScale);
+	}
 }
 
 

+ 0 - 70
src/Physics/Physics.cpp

@@ -19,73 +19,3 @@ Physics::Physics():
 	dynamicsWorld->setDebugDrawer(debugDrawer);
 	dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe);
 }
-
-
-//======================================================================================================================
-// createNewRigidBody                                                                                                  =
-//======================================================================================================================
-btRigidBody* Physics::createNewRigidBody(float mass, const Transform& startTransform, btCollisionShape* shape,
-                                         SceneNode* node, int group, int mask)
-{
-	DEBUG_ERR(shape==NULL || shape->getShapeType()==INVALID_SHAPE_PROXYTYPE);
-
-	//rigidbody is dynamic if and only if mass is non zero, otherwise static
-	bool isDynamic = (mass != 0.0);
-
-	btVector3 localInertia(0, 0, 0);
-	if(isDynamic)
-		shape->calculateLocalInertia(mass,localInertia);
-
-	btRigidBody::btRigidBodyConstructionInfo cInfo(mass, NULL, shape, localInertia);
-
-	btRigidBody* body = new btRigidBody(cInfo);
-
-	MotionState* myMotionState = new MotionState(toBt(startTransform), *node/*, body*/);
-
-	body->setMotionState(myMotionState);
-
-	body->setContactProcessingThreshold(defaultContactProcessingThreshold);
-
-	if(mask==-1 || group==-1)
-		dynamicsWorld->addRigidBody(body);
-	else
-		dynamicsWorld->addRigidBody(body, group, mask);
-
-	return body;
-}
-
-
-//======================================================================================================================
-// deleteRigidBody                                                                                                     =
-//======================================================================================================================
-void Physics::deleteRigidBody(btRigidBody* body)
-{
-	/*// find the body
-	btRigidBody* body1 = NULL;
-	btCollisionObject* obj;
-	int i;
-	for(i=0; i<dynamicsWorld->getNumCollisionObjects(); i++)
-	{
-		obj = dynamicsWorld->getCollisionObjectArray()[i];
-		body1 = btRigidBody::upcast(obj);
-
-		if(body1 == body)
-			break;
-	}
-
-	// check
-	if(body1 == NULL)
-	{
-		ERROR("Cannot find body 0x" << hex << body);
-		return;
-	}
-
-	// remove it from world
-	dynamicsWorld->removeCollisionObject(obj);
-
-	// delete motion state
-	if (body && body->getMotionState())
-	{
-		delete body->getMotionState();
-	}*/
-}

+ 0 - 19
src/Physics/Physics.h

@@ -35,25 +35,6 @@ class Physics
 		DebugDrawer* debugDrawer;
 
 		Physics();
-
-		/**
-		 * Creates a new rigid body and adds it to the @ref dynamicsWorld. It allocates memory so the caller is responsible
-		 * for cleaning up
-		 * @param mass The mass of the rigid body. Put zero for static unmovable objects
-		 * @param startTransform The initial position and orientation
-		 * @param shape The collision shape
-		 * @param node The scene node the body moves
-		 * @param group The group of the body. Leave it blank if there is no group
-		 * @param mask The mask of the body. Leave it blank if there is no mask
-		 * @return A new rigid body
-		 */
-		btRigidBody* createNewRigidBody(float mass, const Transform& startTransform, btCollisionShape* shape,
-		                                SceneNode* node, int group = -1, int mask = -1);
-
-		/**
-		 * Removes the body from the world, deletes its motion state and deletes it
-		 */
-		void deleteRigidBody(btRigidBody* body);
 };
 
 #endif

+ 1 - 1
src/Physics/RigidBody.cpp

@@ -21,7 +21,7 @@ RigidBody::RigidBody(float mass, const Transform& startTransform, btCollisionSha
 	else
 		localInertia = btVector3(0.0, 0.0, 0.0);
 
-	motionState.reset(new MotionState(toBt(startTransform), *node));
+	motionState.reset(new MotionState(toBt(startTransform), node));
 
 	btRigidBody::btRigidBodyConstructionInfo cInfo(mass, motionState.get(), shape, localInertia);
 

+ 1 - 1
src/Resources/ParticleEmitterProps.cpp

@@ -69,7 +69,7 @@ bool ParticleEmitterProps::load(const char* filename)
 	startingPosMargin = Vec3(0.0, 0.0, 0.0);
 	size = 0.5;
 	maxNumOfParticles = 50;
-	emittionPeriod = 0.5;
+	emittionPeriod = 1.5;
 	particlesPerEmittion = 2;
 
 	// set some values

+ 5 - 3
src/Scene/ParticleEmitter.cpp

@@ -6,6 +6,9 @@
 #include "Util.h"
 
 
+btTransform ParticleEmitter::startingTrf(toBt(Mat3::getIdentity()), btVector3(10000000.0, 10000000.0, 10000000.0));
+
+
 //======================================================================================================================
 // render                                                                                                              =
 //======================================================================================================================
@@ -38,8 +41,6 @@ void ParticleEmitter::init(const char* filename)
 
 	// create the particles
 	collShape.reset(new btSphereShape(size));
-	Transform startTransform;
-	startTransform.setIdentity();
 
 	for(uint i = 0; i < maxNumOfParticles; i++)
 	{
@@ -48,7 +49,7 @@ void ParticleEmitter::init(const char* filename)
 
 		float mass = particleMass + Util::randFloat(particleMassMargin) * 2.0 - particleMassMargin;
 
-		RigidBody* body = new RigidBody(mass, startTransform, collShape.get(), particle, Physics::CG_PARTICLE,
+		RigidBody* body = new RigidBody(mass, toAnki(startingTrf), collShape.get(), particle, Physics::CG_PARTICLE,
 		                                Physics::CG_ALL ^ Physics::CG_PARTICLE); ///@todo add parent
 		body->forceActivationState(DISABLE_SIMULATION);
 
@@ -77,6 +78,7 @@ void ParticleEmitter::update()
 		{
 			//cout << "Killing " << i << " " << p.timeOfDeath << endl;
 			p.body->setActivationState(DISABLE_SIMULATION);
+			p.body->setWorldTransform(startingTrf);
 			p.timeOfDeath = -1.0;
 		}
 	}

+ 1 - 0
src/Scene/ParticleEmitter.h

@@ -40,6 +40,7 @@ class ParticleEmitter: public SceneNode, public ParticleEmitterPropsStruct
 		float timeOfPrevUpdate;
 		float timeOfPrevEmittion;
 		RsrcPtr<ParticleEmitterProps> particleEmitterProps; ///< The resource
+		static btTransform startingTrf;
 
 		void update();
 };