More Advanced Particle Stuff.

se5a

01-02-2014 23:06:31

So I'm trying to replicate this:

http://www.ogre3d.org/tikiwiki/tiki-ind ... ust+Effect

I can sort of follow whats going on there, however I don't see why it's a bool, or why it's wanting a frameEvent when it doesn't even use evt in the code.

I tried creating it as a void and calling it each frame, however I then get an
"System.AccessViolationException" "Attempted to read or write protected memory" error.

my version of the code is here: https://bitbucket.org/se5a/mogreoids/sr ... ult#cl-524

tafkag

03-02-2014 11:04:30

however I don't see why it's a bool, or why it's wanting a frameEvent when it doesn't even use evt in the code.

It's a hook to the root's FrameStarted event.


_root.FrameStarted += new FrameListener.FrameStartedHandler(FrameStarted);

[...]

private bool FrameStarted(FrameEvent evt)
{
// called at the beginning of every frame
}

se5a

03-02-2014 17:52:25

oh right, ofcourse. *facepalm*

thanks. I should have seen that.

se5a

03-02-2014 19:58:30

I still get an "Attempted to read or write protected memory" error.

I'm not sure how to troubleshoot this at all, since it stops at my
mRoot.StartRendering(); line.

here's my code:



private void CreateFrameListeners()
{
mRoot.FrameRenderingQueued += new FrameListener.FrameRenderingQueuedHandler(ProcessBufferedInput);
mRoot.FrameStarted += new FrameListener.FrameStartedHandler(doDust);
}

private bool doDust(FrameEvent evt)
{
float maxDist = 250.0f;
float mirrorDist = maxDist * 0.99F;
float dimFactor = 0.8f * 0.005f * 0.005f;
float maxDist2 = maxDist * maxDist;
//Camera cam =

Vector3 camPos = camera.Position;
ParticleSystem psys = sceneMgr.GetParticleSystem("spaceDust");
ParticleIterator pit = psys._getIterator();
while (!pit.End())
{
Particle particle = pit.Next;
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;
}


Edit:
ok by commenting out half the lines of the above method, then uncommenting them one by one, I found it crashed when I uncommented
Particle particle = pit.Next;
seems I can't get the ParticleIterator.Next in mogre? is this a mogre bug/missing feture or should I be doing it another way?

se5a

03-02-2014 20:48:19

Ok so playing around a bit more (thank god for intellisense) I've come up with this:


private bool doDust(FrameEvent evt)
{
float maxDist = 250.0f;
float mirrorDist = maxDist * 0.99F;
float dimFactor = 0.8f * 0.005f * 0.005f;
float maxDist2 = maxDist * maxDist;

Vector3 camPos = camera.Position;
ParticleSystem psys = sceneMgr.GetParticleSystem("spaceDust");
uint numpart = psys.NumParticles;
for (uint i = 0; i < numpart; i++)
{
Particle particle = psys.GetParticle(i);
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;
}


it doesn't crash, though I'm not seeing anything either, need to play around a bit more, I might just have the particles too small to be visible.

Edit: ok ParticleSystem.NumParticles is always 0 which is why I'm not seeing anything. I guess I want something else there. or maybe I want to place the particle system before this gets called...

Edit2:
Yes. I need to set it to a node first, then it *has* particles to iterate through.
however it's not acting anything like it should, and seems to loose the texture and turn into little white squares after a bit. more experiments to do....

Edit3:
ok fixed the texture problem. stupid transition from ogre particle lab to project and path problems.
I think my problem now, is that this was designed for the camera to be pointing forward not down, and I need to switch some axes somewhere.

se5a

03-02-2014 22:36:36

Ok it's all working now.
here's the complete current doDust function in case someone else comes along and wants to try doing the same thing:



private bool doDust(FrameEvent evt)
{
float maxDist = 250.0f;
float mirrorDist = maxDist * 0.99F;
float dimFactor = 0.00001f; // 0.8f * 0.005f * 0.005f;
float maxDist2 = maxDist * maxDist;

Vector3 camPos = CameraMan.Position;
ParticleSystem psys = sceneMgr.GetParticleSystem("spaceDust");
uint numpart = psys.NumParticles;
for (uint i = 0; i < numpart; i++)
{
Particle particle = psys.GetParticle(i);
Vector3 pos = particle.position;
particle.timeToLive = 999999.0f;

while (pos.x - camPos.x > maxDist)
pos.x -= maxDist * 2;
while (pos.x - camPos.x < -maxDist)
pos.x += maxDist * 2;
while (pos.y - camPos.y > maxDist)
pos.y -= maxDist * 2;
while (pos.y - camPos.y < -maxDist)
pos.y += maxDist * 2;
while (pos.z - camPos.z > maxDist)
pos.z -= maxDist * 2;
while (pos.z - camPos.z < -maxDist)
pos.z += maxDist * 2;

Vector3 pDir = pos - camPos;
float dist = pDir.SquaredLength;
float dim = dist * dimFactor;
particle.SetDimensions(dim, dim);
particle.position = pos; // the origional C++ code is using a reference to the particle position, we have to set the position
}
return true;
}


note, none of this is original code, other than me converting to Mogeroids. this is all Captain Nemo and zenic's code from here:
http://www.ogre3d.org/forums/viewtopic.php?t=19122

edit, ok not quite working. so close though. seems that you can go 'outside' the box that we're placing the particles in. not sure how this is happening.
Edit2: and I think I figured that out. I had "local_space false" in the particle system. I think that needs to be true.

Beauty

10-02-2014 16:24:02

I think my problem now, is that this was designed for the camera to be pointing forward not down, and I need to switch some axes somewhere.

You can use the method Camera.LookAt(targetWorldPosition) to point the camera to the wanted direction.

The position can be for example the world position of a scene node, which you get by SceneNode._getDerivedPosition().

se5a

13-02-2014 04:33:53

yeah that is what I'm doing already.
still not quite sure what I'm doing wrong. I've posted in the origional ogre thread hoping to get some insite.

BrainScan

13-02-2014 04:55:00

Have you tried Camera.DerivedPosition instead of Camera.Position? It looks like the original example was using world position.

se5a

13-02-2014 07:57:40

Ooohh I see what you're saying, by getting camera.position I'm getting the position of the camera relitive to it's parent node, when I want the position ralitive to the world.
I'll have a mess around with it and see what I come up with.

Except nope, I am using the world position. CameraMan is a node that the camera is attached to.
with the particle system set to localspace = false, the dust particles apear to move way too fast, and then disapear, as if I've gone outside the 'box' that the particles are in.
(I did try Vector3 camPos = sceneMgr.GetCamera("Camera").DerivedPosition; to test and it's giving the same result as Vector3 camPos = CameraMan.Position;)

another thing, which may or may not be related, is that particles that are further away look bigger, and those closer look smaller.

BrainScan

13-02-2014 08:18:03

It also looks like you're not setting the particles position anywhere. The original wiki entry was setting the position back to the particle but I don't see anything in your code snippet that sets the position back to the particle.

se5a

13-02-2014 08:38:58

Ah I see, I'm creating a new Vector3 there not a reference to the particle.position. that fixes the going out of the box thing.