Game Development Community

Figured out how to move emitters, can't control ROTATION

by Jay Barbeau · in Technical Issues · 01/18/2007 (11:10 am) · 3 replies

I'm using a Beam Emitter Particle emitter with just squares as the particle. I set up the parameters so the particles are emitted regularly all at the same angle. It gives a dotted line effect emanating from the player which the emitter follows.

I had been searching for a way to move and control a particle emitter. I tried a Mounted Emitter, but went away from that because of the extra complexity in parameters that I didn't need. So I figured out how to just move an emitter relative to the players World Coordinates.

In getting this to work, I found out that the way the PE code is designed, setTransform() sets the data, but there was no mechanism for setting the "IsDirty" bit, so emitters won't update unless you use a trick. That is call setScale like this:

%emit.setScale(%emit.scale);

then the transform is updated and used. Several posts in this forum relate to this issue, but this trick isn't posted as an answer. I may go back and answer these posts sometime.

Now THE REAL ISSUE with Emitters I'm trying to solve...ROTATION. Specifically, I want to rotate the emitter that follows a player around the Z - axis. This should be simple I thought. Set the rotation part of the transform matrix like this:

0 0 1 %rotationvalue

This is Quaternion format x,y,z of the vector to rotate about and %rotationvalue. I have a rotation test function that increments %rotationvalue and sets the emitter transform. I should see it rotating about the z-axis, but it doesn't. In fact, no matter what I do, I can't get it to rotate about the Z-axis.

I can get it to PARTIALLY rotate around the X or Y axis like this:

0 1 0 %rotationvalue
1 0 0 %rotationvalue

I say partially, because it seems to rotate 180 degrees, and then it goes to a weird angle which is I think the equivalent of this rotation even though the data isn't this:

1 1 0 %rotationvalue=0

I say that because I have the emitter attached to the player, and when I spawn the player If I look right to about 45 degrees, I can see the emitter trail with a 0 Z-component.

So what's going on? and How do I get the Emitter to rotate 360 degrees around the player? I need to be able to point the Emitter in any direction on the X-Y plane.

Does anyone have any ideas?

#1
01/18/2007 (4:57 pm)
I've done some more experimenting. I found that these values in the Particle Emitter Data block

datablock ParticleEmitterData(followEmitter){
thetaMin = "0";
thetaMax = "0";
phiReferenceVel = "0";
phiVariance = "0";
}

need to be 0 specifically thetaMin and thetaMax.

I had set these to 90 because that gave me an emitter pointing horizontally which is what I want. However when the thetas are 90, then the rotations don't work all the way..... that's why it goes to a weird angle while rotating.

With the datablock like this, now I can rotate about the X and Y axises correctly,
1 0 0 %rotateangle
0 1 0 %rotateangle

BUT IT STILL DOESN'T WORK ROTATING ABOUT THE Z-AXIS.
0 0 1 %rotateangle


Why?

Just my luck that the axis I want doesn't work.

Almost got it! Any ideas?
#2
01/19/2007 (4:06 pm)
I've solved it!

I'm not sure exactly why you can't rotate an emitter in Quaternion format directly:
0 0 1 %rotateangle
this doesn't work. If anyone knows why, please post it here. It must have something to do with the way emitters work.

To make an emitter rotate around the z-axis, I rotate the emitter around the y or x axis by 90 degrees, and then use THAT axis to rotate the emitter, since they work OK. I also discovered that %rotateangle is in radians. I thought it was in degrees from some of the documentation and comments I found.

To combine the y and z rotation, I use Euler format for the rotation. For those of you who are new to this, Eulers describe a rotation in angles only. X-rotation, Y-rotation, and Z-rotations. Where Quaternion is a vector described by x,y,z and a rotation around that vector -- X, Y, Z, %rotationangle.

Here's the code I created to do this:

function eulerToQuat_Radians(%euler)
{
%matrix = MatrixCreateFromEuler(%euler);
%xvec = getWord(%matrix, 3); //get the parts of the matrix you need
%yvec = getWord(%matrix, 4);
%zvec = getWord(%matrix, 5);
%ang = getWord(%matrix, 6); //this is in radians
return %xvec @ " " @ %yvec @ " " @ %zvec @ " " @ %ang;
}


// in a scheduled (every 10 ms) function I have this code:

// 1.57 is pi/2 or 90 degrees I'm rotating the emitter 90 degrees around the y-axis
// because the axis rotation of an emitter works fine for the x or y axis,
// but not the z (something to do with the angles of the emitters code theta and phi)
// by orienting the emitter on its side, I can rotate it around the z axis (world coords)
// and THAT'S what I wanted to do!
%matrix = eulerToQuat_Radians( "0 1.57 " @ $rd); // these 3 values are eulers
// or angles for the x,y,z axis. in radians
%qx = getword(%matrix,0);
%qy = getword(%matrix,1);
%qz = getword(%matrix,2);
%qa = getword(%matrix,3);

// lx, ly, lz are the location of emitter, I use the Player.getPosition or .getTransform
// qx, qy, qz are the Quaternion vector (rotation occurs around this vector)
// qa is the rotation angle in radians
%emit.setTransform(%lx SPC %ly SPC %lz SPC %qx SPC %qy SPC %qz SPC %qa);

%emit.setScale(%emit.scale); // trick to force transform to be used


I want to control my emitters in a very specific way. I want to set the exact angle in the world
XY plane from the Player for any particle emitted. This works very well, and I didn't have to use a Mounted Emitter.

Comments please, about Z-axis in Quaternion format or anything else.
#3
01/19/2007 (4:11 pm)
Interesting. i'd love to hear anyone's thoughts about the z-quaternion.