Game Development Community

dev|Pro Game Development Curriculum

Circular Particle Emission (TGB 1.7.5)

by Minion Productions · 05/11/2010 (10:59 am) · 0 comments

So, after some complaints we had with putting together particle effects for things that happen in a radius, I finally just sat down and made a new emission pattern for particle emitters- Circular, rather than a square area. There were a few lil' gotchas involved with the tweaks, though- Including what looked to be a bug inside the t2dVector.h file.

The Meat:

// Radius of circle radius (xMax - xMin)/2
            case CIRCLE:
            {
                // Fetch Local Clip Boundary.
                const t2dVector* pLocalClipBoundary = pParentEffectObject->getLocalClipBoundary();

                //
                F32 minX = pLocalClipBoundary[0].mX;
                F32 maxX = pLocalClipBoundary[1].mX;
                F32 minY = pLocalClipBoundary[0].mY;
                F32 maxY = pLocalClipBoundary[3].mY;

                t2dVector tempPos;
				t2dVector randOff;

                // Normalise.
                if ( minX > maxX )
                    mSwap( minX, maxX );
                // Normalise.
                if ( minY > maxY )
                    mSwap( minY, maxY );
				randOff.setPolar(mGetT2DRandomF(0.0f,360.0f), mGetT2DRandomF(0.0f, (maxX - minX) / 2.0f));

                // Normalised.
				tempPos.set(((minX + maxX) / 2) + randOff.mX, ((minY + maxY) / 2) + randOff.mY);
                // Rotate into Emitter-Space.
                //
                // NOTE:-   If we're attached to the emitter, then we keep the particle coordinates
                //          in local-space and use the hardware to render them in emitter-space.
                t2dSceneObject::transformPoint2D( (mAttachPositionToEmitter && mAttachRotationToEmitter) ? t2dMatrix::getIdentity() : pParentEffectObject->getRotationMatrix(), tempPos, mAttachPositionToEmitter ? t2dVector::getZero() : effectPos, pParticleNode->mPosition );

            } break;

This case needs to go into t2dParticleEmitter::configureParticle, in t2dParticleEmitter.cc, inside the switch( mEmitterType ) block. (I stuck mine right after Area, which is where I lifted the base code from, I'll admit.)

First Gotcha

Here's a bit that must have slipped past someone, though- See that t2dVector.setPolar() function I'm using? Load up t2dVector.h and go to its definition. A couple misplaced parenthesis made it not really work as expected- Replace it with
inline void setPolar(const F32 angle,F32 length)                    { mX = mSin(mDegToRad(angle))*length; mY = -mCos(mDegToRad(angle))*length; };

Enabling the Case

So that has the function working properly. Of course, CIRCLE isn't quite a valid enumerated type yet. Back into t2dParticleEmitter.cc, find
static EnumTable::Enums emitterTypeLookup[]
up near the top, and add in
{ t2dParticleEmitter::CIRCLE,     "CIRCLE" },
right after the entry for Area. Then hop over to t2dParticleEmitter.h and change the tEmitterType enum to
enum tEmitterType { POINT = 0, LINEX, LINEY, AREA, CIRCLE };

Second Gotcha: A little digging

This is the part that makes me love Notepad++'s 'Find in Files' feature for life. As far as the source is concerned, CIRCLE should be a perfectly valid type now. However, the editor doesn't know it exists yet, and the files that need to be tweaked to allow for it are buried pretty deep.

Running from the default install, head to "Torque Game Builder 1.7.5 Pro/tgb/tools/levelEditor/scripts/forms/quickEditClasses/particleFields" and open up particleEmitterStack.ed.cs, and ParticleEditorEmitterFunctions.ed.cs.

Inside particleEmitterStack, there'll be a line
%emitterStack.createListBox("emitterType", false, "Type", "POINT\tLINEX\tLINEY\tAREA");
. Change that to
%emitterStack.createListBox("emitterType", false, "Type", "POINT\tLINEX\tLINEY\tAREA\tCIRCLE");
Then in ParticleEditorEmitterFunctions.ed.cs, you should find
function LevelBuilderParticleEditor::initEmitterEdit(%this)
right near the top. Below that are lines of
ParticleEditorEmitterComType.add(
, so at the end, add
ParticleEditorEmitterComType.add("CIRCLE", 4);

Finale

That should take care of everything for getting it in. Now, I'll admit, it adds a few more calls to every particle being drawn in this style, and I haven't really tried to optimize it (if it even can be at this level), but hopefully it shouldn't be too bad.

About the author

Recent Blogs


#1
05/11/2010 (11:12 am)
Thanks, that sounds interesting. I'll try it when I get back to my TGB project.
#2
06/02/2010 (7:53 am)
I fixed the formatting of the code, for the \t to work it needs to be a double backslash, and each time you edit, it removes one. Keep that in mind, cos posting paths, usually / is a safe bet.

Looks like an interesting resource. I managed to do a circular burst of particles using a POINT type, and then size at the beginning of its life is zero. Halfway along, or whatever timing i had, i added size to be sudden , mixed with alpha and it looked pretty much what i was expecting.

Good work!