Precipitation

Problems building or running the engine, queries about how to use features etc.
User avatar
Grom
Hobgoblin
Posts: 523
Joined: Fri Jan 06, 2006 6:35 pm

Precipitation

Post by Grom »

I am experimenting with using the particle engine of Ogre to add precipitation to my game. My method at the moment is to use the Examples/Rain script and attach the Particle system to a node that is attached way above my camera node. This does move the particle system around along with the movement of the camera, but since moving the particle system just means moving the emitter, the new rain generated at the new position takes a moment to fall where the camera moves to. This results in the rain trailing behind the camera as it moves around.

I've been thinking about this and can't figure out a good way to solve the problem. Making the Emitter box arbitrarily big is a waste of processing power. Somehow I think I need to keep the emitter box the right speed ahead of the camera so as to always be raining on it. Any suggestions on how to do this?
Captain Nemo
Greenskin
Posts: 134
Joined: Sun May 02, 2004 5:06 pm
Location: Kassel, Germany

Post by Captain Nemo »

Here is a snippet from my own code. The particle system is attached to a child scene node of the camera, just as you described. If a particle is further away from the camera than some specified distance I mirror it along its direction vector to the camera. E.g. if the particle is in front of the camera I position it behind the camera, if it's to the left I position it to the right etc.

This code also changes the size of the particles to avoid them becoming too large if they are close to the camera.


Code: Select all

bool XXX::frameStarted(const FrameEvent& evt)
{  
	const float maxDist  = 250.0;
	const float mirrorDist = maxDist*0.99;
	const float dimFactor = 0.8*0.005*0.005;	
	const float maxDist2 = maxDist*maxDist;
	Camera* cam = mCamera->getCamera();
	const Vector3& camPos = cam->getWorldPosition();

	ParticleIterator pit = mParticleSystem->_getIterator();
	
	while (!pit.end()) 
	{
		Particle* particle = pit.getNext();
		Vector3& pos = particle->position;
		particle->timeToLive = 999999.0f;
		Vector3 pDir = pos-camPos;
		float dist = pDir.squaredLength();
		float dim = dist*dimFactor;
		particle->setDimensions(dim, dim);
		
		if (dist > maxDist2) {
			pDir.normalise();
			Vector3 p = camPos-pDir*mirrorDist;		
			particle->position = p;
		}
	}			
	
	return true;	 
}
Hope this helps.
http://www.aridocean.com
The Marine Life Simulation
User avatar
raicuandi
Gargoyle
Posts: 1092
Joined: Wed Nov 09, 2005 12:56 pm
Location: Adelaide, Australia

Post by raicuandi »

Why does that piece of code seems so familiar to me?
Captain Nemo
Greenskin
Posts: 134
Joined: Sun May 02, 2004 5:06 pm
Location: Kassel, Germany

Post by Captain Nemo »

:?: :?: :?:
http://www.aridocean.com
The Marine Life Simulation
themoebius
Kobold
Posts: 39
Joined: Sat Mar 04, 2006 5:43 pm

Post by themoebius »

Hey guys, I'm not too expert on how this particle system stuff works as its the first time I'm trying to impliment anything like that, but I copied the code here and I just don't see anything on the screen. I have a feeling there's a bit more to it, but I'm not sure what.... should the ParticleSystem load some kind of template instead of being blank?

I initialized a particle system in the constructor:

Code: Select all

mpSpaceDustParticle = mpSceneManager->createParticleSystem("Stardust");
particleNode = mpSceneManager->getRootSceneNode()->createChildSceneNode("SpaceDustParticle");
particleNode->attachObject(mpSpaceDustParticle);
and every frameStarted iteration I call renderSpaceDust(), which looks like this:

Code: Select all

void cRenderer::renderSpaceDust(){
	const float maxDist  = 250.0; 
	const float mirrorDist = maxDist*0.99; 
	const float dimFactor = 0.8*0.005*0.005;    
	const float maxDist2 = maxDist*maxDist; 
	//Camera* cam = mCamera->getCamera(); 
	const Vector3& camPos = mainCam->getWorldPosition(); 

	ParticleIterator pit = mpSpaceDustParticle->_getIterator(); 
    
	while (!pit.end()) 
	{ 
		Particle* particle = pit.getNext(); 
		Vector3& pos = particle->position; 
		particle->timeToLive = 999999.0f; 
		Vector3 pDir = pos-camPos; 
		float dist = pDir.squaredLength(); 
		float dim = dist*dimFactor; 
		particle->setDimensions(dim, dim); 
		
		if (dist > maxDist2) { 
			pDir.normalise(); 
			Vector3 p = camPos-pDir*mirrorDist;       
			particle->position = p; 
		}
	}          
}
It compiles fine, but I don't see any spacedust... What am I missing?

Thanks.
themoebius
Kobold
Posts: 39
Joined: Sat Mar 04, 2006 5:43 pm

Post by themoebius »

I tried another one found on the wiki: http://www.ogre3d.org/wiki/index.php/ParticleExampleSun

and I changed the code a bit so it would work, but it shows up as a very small orange dot in the center of the screen. How can I make it a big glowing orange ball instead?

Code: Select all

ParticleSystem* sunParticle = mpSceneManager->createParticleSystem("Sun", "Space/Sun");
SceneNode* particleNode = mpSceneManager->getRootSceneNode()->createChildSceneNode("SunParticle");
particleNode->attachObject(sunParticle);
Captain Nemo
Greenskin
Posts: 134
Joined: Sun May 02, 2004 5:06 pm
Location: Kassel, Germany

Post by Captain Nemo »

My code above is designed to have particles follow the camera, and I attached the particle node to the camera node. Perhaps your particles start too far away from the camera.

For your second question, have you tried to increase the particle size in the particle script?
http://www.aridocean.com
The Marine Life Simulation
SAT
Halfling
Posts: 64
Joined: Thu Aug 11, 2005 2:01 am

Post by SAT »

Does anyone have a "stardust" .particle file?

Please post the code(s) :D
zenic
Gnoblar
Posts: 5
Joined: Sun Mar 13, 2005 12:43 pm
Location: Australia

Code

Post by zenic »

Captain Nemo,

thanks for posting the code, but there might be a problem with this approach. It is most pronounced if the camera moves rapidly: the particles start to bunch together.

The reason is that the code is placing the particle at the surface of a sphere around the camera. If the camera moves very quickly, that means a lot of particles all get placed there, which is what makes them bunch together.

Unfortunately, I don't yet have a "spherical" solution to this that doesnt involve tracking the last position of the camera. However, there is a "box" solution. It involves a few more particles, though. Basically, take an axis aligned box around the camera and reflect particles outside this box along the axes. This way the particles won't bunch up. When I get a moment I'll look into some code to do that.

SAT:

Code: Select all

Space/Dust

{

   material        Example/Flare

   particle_width  1

   particle_height 1

   cull_each       true

   quota           500

   billboard_type  point



   // Area emitter

   emitter Ellipsoid

   {

       emission_rate   50000

       velocity        0

       width           500

       height          500

       depth           500

   }

}

themoebius: It sounds to me like you haven't added an emitter.[/code]
SAT
Halfling
Posts: 64
Joined: Thu Aug 11, 2005 2:01 am

Post by SAT »

Thanks Zenic :D

I thought it would be more than that. Small .particle file.
Captain Nemo
Greenskin
Posts: 134
Joined: Sun May 02, 2004 5:06 pm
Location: Kassel, Germany

Post by Captain Nemo »

Thanks, zenic. I haven't observed this problem, because my camera is never moving very fast. If you have a better solution don't hesitate to post the code.
http://www.aridocean.com
The Marine Life Simulation
zenic
Gnoblar
Posts: 5
Joined: Sun Mar 13, 2005 12:43 pm
Location: Australia

Code

Post by zenic »

Ok, here is some code.

What it does is moves particles closer to you until they are within range. This means that you can go as fast as you want and it will still work fine. Also, you can arbitrarily move your camera somewhere and the dust/rain will magically follow you.

Quick note:
I haven't done much with OGRE before and my camera->getWorldPosition() is returning (0,0,0) every time, so in my own code I changed it to getRealPosition(), but that isn't quite right. If anyone has any hints as to why, I'd be appreciative!

NOTE: you now have to use a box emitter, not an ellipsoid, or you will get "dead" zones where there are no particles.

example particle file:

Code: Select all

Space/Dust
{
   material        Mine/Dust
   particle_width  1
   particle_height 1
   cull_each       false
   quota           500
   billboard_type  point

   // Area emitter
   emitter Box //Ellipsoid
   {
       emission_rate   50000
       velocity        0
       width           500
       height          500
       depth           500
   }
}

(Make sure that the width, height, depth are always the same as 2*maxDist!)

the updated framelistener:

Code: Select all

bool XXX::frameStarted(const FrameEvent& evt)
{ 
   const float maxDist  = 250.0;
   const float mirrorDist = maxDist*0.99;
   const float dimFactor = 0.8*0.005*0.005;   
   const float maxDist2 = maxDist*maxDist;
   Camera* cam = mCamera->getCamera();
   const Vector3& camPos = cam->getWorldPosition();

   const float twiceMaxDist = 2 * maxDist;

   ParticleIterator pit = mParticleSystem->_getIterator();
   
   while (!pit.end())
   {
      Particle* particle = pit.getNext();
      Vector3& pos = particle->position;
      particle->timeToLive = 999999.0f;

		// position particles near camera
		// (keep moving them toward camera until within range)
		while (pos.x - camPos.x > maxDist)
			pos.x -= twiceMaxDist;
		while (pos.x - camPos.x < -maxDist)
			pos.x += twiceMaxDist;
		while (pos.y - camPos.y > maxDist)
			pos.y -= twiceMaxDist;
		while (pos.y - camPos.y < -maxDist)
			pos.y += twiceMaxDist;
		while (pos.z - camPos.z > maxDist)
			pos.z -= twiceMaxDist;
		while (pos.z - camPos.z < -maxDist)
			pos.z += twiceMaxDist;

      Vector3 pDir = pos-camPos;
      float dist = pDir.squaredLength();
      float dim = dist*dimFactor;
      particle->setDimensions(dim, dim);
      
   }         
   
   return true;   
} 
so as you can see, I only added those while loops (and a const def for twiceMaxDist).

just for completeness, this is how I use it in the main code:

Code: Select all

	ParticleSystem* ps = mSceneMgr->createParticleSystem("Dust PS", "Space/Dust");
	SceneNode* node3 = camNode->createChildSceneNode( "DustParticles", mCamera->getRealPosition());
	node3->attachObject( ps );
	// listener for the space dust
	SpaceDust* psd = new SpaceDust(mCamera, ps);
	mRoot->addFrameListener(psd);
I hope this helps someone :)
Captain Nemo
Greenskin
Posts: 134
Joined: Sun May 02, 2004 5:06 pm
Location: Kassel, Germany

Post by Captain Nemo »

Thanks for the code!
http://www.aridocean.com
The Marine Life Simulation
natelion
Gnoblar
Posts: 1
Joined: Sat Dec 30, 2006 12:57 pm

_getIterator for MOGRE particle system

Post by natelion »

Is there anyone that happens to know the equivelant of the Particle System _getIterator for MOGRE?

Thank you in advance
User avatar
Kencho
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 4011
Joined: Fri Sep 19, 2003 6:28 pm
Location: Burgos, Spain
x 2

Post by Kencho »

Ask in the Ogre Addons MOGRE forum.
Image
se5a
Gnoblar
Posts: 14
Joined: Fri Oct 27, 2006 9:12 am

Re: Precipitation

Post by se5a »

apologies necroing such an old thread, but I'm struggling with this.
I'm close, but not quite there. the game has a camera looking down onto a ship, the camera and particlesystem is attached to a node which moves with the ship on a variable Z.
if the particlesystem is local_space false, the particles give somewhat the right effect (I think, though maybe they're moving too fast) but the ship (and camera) move outside the particle system box.
if the particlesystem is local_space true, the box moves with the camera, but the individual particles themselves don't seem to move.

just to clarify, I've got something pretty similar to what zenic has done.
RigoCL
Greenskin
Posts: 114
Joined: Mon Oct 14, 2013 1:41 am
Location: Chile
x 3

Re: Precipitation

Post by RigoCL »

Some months ago I was playing with the particle system a little and I remember that what worked for me was local_space=false for the particle system and two nodes, let's say father and son, son is where you attach the camera and is the node you rotate (when you want to rotate the camera), father is where the particle system is attached to and is the node you move (when you want to change camera's position).

Hope not to be wrong on what I remember.
Last edited by RigoCL on Mon Feb 10, 2014 3:30 am, edited 1 time in total.
Integrated: Ogre3D + dotScene (Blender loader) + MyGUI (UI) + RakNet (Client/Server) + Leap Motion (The future is here!) + StereoManager (3D Anaglyph red-cyan)
WIP: StereoManager (Real 3D) + CCS (Camera Control System) + Sound, experimenting with Android.
se5a
Gnoblar
Posts: 14
Joined: Fri Oct 27, 2006 9:12 am

Re: Precipitation

Post by se5a »

That would make sense, and I'll remmeber that for later.
except I'm not rotating the camera at all at this stage, so I don't think that's my problem.
code is here if interested:
https://bitbucket.org/se5a/mogreoids

the do_dust function/method is at the bottom of mogeroids.cs
se5a
Gnoblar
Posts: 14
Joined: Fri Oct 27, 2006 9:12 am

Re: Precipitation

Post by se5a »

actualy, isn't that going to give the same effect as attaching the camera and dust effect to the parent node, moving the node, and if the camera needs rotating, rotate the camera (not the node since the camera can be rotated and moved on it's own anyway)
se5a
Gnoblar
Posts: 14
Joined: Fri Oct 27, 2006 9:12 am

Re: Precipitation

Post by se5a »

somone pointed out to me in the Mogre forums that Camera.Position is going to be the position of the camera in relation to it's parent node if it's attached to a node, and that Camera.DerivedPosition will be the world position. I think this is what you were refering to RigoCL

it's still not solved my problem, however it has made me understand it a bit more.
se5a
Gnoblar
Posts: 14
Joined: Fri Oct 27, 2006 9:12 am

Re: Precipitation

Post by se5a »

Hah, the problem was that the origional cpp code uses Vector3& pos = particle->position; which creates a reference to the particle position. I added particle.position = pos at the end of my code which fixed most of my problems.