Bullet Tracers
by Blake LaPierre · 07/26/2004 (10:01 am) · 15 comments
In game/Projectile.h in the public section of the ProjectileData class definition(around line 63) add:
In the Projectile class definition(around line 178) add:
Now we will be modifying game/Projectile.cc:
In the ProjectileData constructor we will put the default values for the tracer attributes, add (around line 91):
Down a little bit in ProjectileData::initPersistFields() add (around line 147):
A little further down at the very end of ProjectileData::packData() add (around line 304):
Then in ProjectileData::unpackData() add (around line 372):
Scroll down a ways to Projectile::unpackData() at about line 1062 and find:
and right before
And finally the part that makes it all work, scroll down to Projectile::renderObject() and right before:
add (about line 1266):
To turn the tracers on you will need to goto your script file containing your ProjectileData datablocks for the Projectiles you would like to add tracers to and place:
somewhere within them. You may need to tweak the tracerLength and tracerColor values to get the effect you want.
Hopefully that should work! :)
F32 tracerLength; // Length of the tracer, also distance from source object that tracer will start being visible ColorF tracerColor; // Color of tracers
In the Projectile class definition(around line 178) add:
Point3F mInitialPosition; // Initial position of projectile when created
Now we will be modifying game/Projectile.cc:
In the ProjectileData constructor we will put the default values for the tracer attributes, add (around line 91):
tracerLength = 0; tracerColor.set(1.0, 1.0, 0.55);
Down a little bit in ProjectileData::initPersistFields() add (around line 147):
addNamedField(tracerLength, TypeF32, ProjectileData); addNamedField(tracerColor, TypeColorF, ProjectileData);
A little further down at the very end of ProjectileData::packData() add (around line 304):
stream->write(tracerLength); stream->writeFloat(tracerColor.red, 7); stream->writeFloat(tracerColor.green, 7); stream->writeFloat(tracerColor.blue, 7);
Then in ProjectileData::unpackData() add (around line 372):
stream->read(&tracerLength); tracerColor.red = stream->readFloat(7); tracerColor.green = stream->readFloat(7); tracerColor.blue = stream->readFloat(7);
Scroll down a ways to Projectile::unpackData() at about line 1062 and find:
mCurrDeltaBase = pos;
mCurrBackDelta = mCurrPosition - pos;
mCurrPosition = pos;
setPosition(mCurrPosition);and right before
mCurrDeltaBase = pos;add:
mInitialPosition = pos;
And finally the part that makes it all work, scroll down to Projectile::renderObject() and right before:
dglSetCanonicalState();
add (about line 1266):
if (mDataBlock->tracerLength > 0) {
Point3F end = mCurrVelocity;
end.normalize(mClampF((mCurrPosition - mInitialPosition).len(), 1.0, mDataBlock->tracerLength));
glLineWidth(0.5);
glBegin(GL_LINES);
glColor3fv(mDataBlock->tracerColor);
glVertex3f(mCurrPosition.x, mCurrPosition.y, mCurrPosition.z);
end = mCurrPosition - end;
glVertex3f(end.x, end.y, end.z);
glEnd();
glLineWidth(.1f);
}To turn the tracers on you will need to goto your script file containing your ProjectileData datablocks for the Projectiles you would like to add tracers to and place:
tracerLength = 50; tracerColor = "1.0 1.0 0.55";
somewhere within them. You may need to tweak the tracerLength and tracerColor values to get the effect you want.
Hopefully that should work! :)
#3
Thanks for sharing.
r/Alex
07/27/2004 (12:43 am)
Dont worry about the formatting. I normally just do a select all and format script in Visual Studio. :)Thanks for sharing.
r/Alex
#4
I'm probably busting something else horribly by doing this, but I was tinkering and added a few things. First I added a second color (just duplicated the relevent color definition lines everywhere) and used the new color as the second vertex's color. The line is drawn as a gradient between the first and second colors.
Then I bumped it up to glColor4fv and enabled GL_BLEND in this if block so the tracer line has an alpha value (appropriately adding a fourth value to all the color definitions and stream read/write functions.) It'll interpolate alpha values between the two vertexes too, so the tracer can fade as it gets further back from the projectile.
Finally I made the line thickness a datablock variable so the tracer width was settable per-projectile.
07/27/2004 (10:49 am)
Neat effect! Thanks for sharing it.I'm probably busting something else horribly by doing this, but I was tinkering and added a few things. First I added a second color (just duplicated the relevent color definition lines everywhere) and used the new color as the second vertex's color. The line is drawn as a gradient between the first and second colors.
Then I bumped it up to glColor4fv and enabled GL_BLEND in this if block so the tracer line has an alpha value (appropriately adding a fourth value to all the color definitions and stream read/write functions.) It'll interpolate alpha values between the two vertexes too, so the tracer can fade as it gets further back from the projectile.
Finally I made the line thickness a datablock variable so the tracer width was settable per-projectile.
#5
07/28/2004 (4:14 am)
Simple, yet neat and nicely done. Thanks!
#6
07/29/2004 (7:12 pm)
We should take the additions to projectiles like this and create new classes of projectiles. A TracerProjectile class would be a plug and play thing ya know.
#7
08/07/2004 (6:16 pm)
@Sam: It is plug and play... if you don't want tracers, dont include the requisite fields in the datablock definition and they don't appear.
#8
09/27/2004 (2:34 pm)
Very nice resource.
#9
12/21/2004 (3:42 pm)
How is this different from putting a particle emitter on your projectile? Particle initial velocities set to 0, no gravity, long particle lifetime...
#10
@Eric: I know my reply comes late, but the advantage of this resource is that drawing a line directly is much, much faster than drawing one or many textured triangles *and* having to go all the way through the particle system.
Especially since long particle lifetime equals many particles. It would bring your system to it's knees fast.
If all you need is a tracer projectile for sniper weapons or machine guns, then this is more than adequate. Heck, you can still do fancy effects by using textured triangles instead of the GL_LINE.
The only thing I wonder, is whether it is really necessary to transmit information like color and width via pack/unpackData. Isn't that a bit redundant? Wouldn't it be enough to know what kind of datablock we're talking about and use the defaults, or am I dead wrong here?
02/20/2007 (3:39 am)
This is an excellent resource for it is simple and effective.@Eric: I know my reply comes late, but the advantage of this resource is that drawing a line directly is much, much faster than drawing one or many textured triangles *and* having to go all the way through the particle system.
Especially since long particle lifetime equals many particles. It would bring your system to it's knees fast.
If all you need is a tracer projectile for sniper weapons or machine guns, then this is more than adequate. Heck, you can still do fancy effects by using textured triangles instead of the GL_LINE.
The only thing I wonder, is whether it is really necessary to transmit information like color and width via pack/unpackData. Isn't that a bit redundant? Wouldn't it be enough to know what kind of datablock we're talking about and use the defaults, or am I dead wrong here?
#11
06/02/2007 (6:56 pm)
I know this resource is dated (still very useful) but, I would love to add alpha to this effect. I'm not a coder...anybody able to give me a hint on how to do this?
#12
Eric: I'm gonna try to get alpha working like Luke D mentioned. But all the experience I've had with graphics programming is implementing this resource, so it'll be kinda hit or miss ;)
EDIT: Just tested it, and it seems my lines are showing up flat black. Strange - I'm absolutely convinsed that it actually did work at one point. But now everything's black :P...
Whoah! It works if I move the camera a long way away. Now that's strange...
EDIT:
Colour blending works (but still that strange problem with having to be far away...).
To use this code, you'll have to change your datablock tracerColor to tracerStartColor, and add a second field, tracerEndColor. In the pack/unpackUpdate methods, make sure you include the alpha values. I also added another datablock field, tracerWidth. Note that this is a value in pixels - so unless you enable anti-aliasing, decimal values get rounded.
Then replace the render code with this:
03/31/2008 (7:41 am)
Nice resource - easy to add, and a nice effect.Eric: I'm gonna try to get alpha working like Luke D mentioned. But all the experience I've had with graphics programming is implementing this resource, so it'll be kinda hit or miss ;)
EDIT: Just tested it, and it seems my lines are showing up flat black. Strange - I'm absolutely convinsed that it actually did work at one point. But now everything's black :P...
Whoah! It works if I move the camera a long way away. Now that's strange...
EDIT:
Colour blending works (but still that strange problem with having to be far away...).
To use this code, you'll have to change your datablock tracerColor to tracerStartColor, and add a second field, tracerEndColor. In the pack/unpackUpdate methods, make sure you include the alpha values. I also added another datablock field, tracerWidth. Note that this is a value in pixels - so unless you enable anti-aliasing, decimal values get rounded.
Then replace the render code with this:
if (mDataBlock->tracerLength > 0)
{
Point3F end = mCurrVelocity;
end.normalize(mClampF((mCurrPosition - mInitialPosition).len(), 1.0, mDataBlock->tracerLength));
if(mDataBlock->tracerWidth > 0)
glLineWidth(mDataBlock->tracerWidth);
else
glLineWidth(0.5);
glBegin(GL_LINES);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glColor4fv(mDataBlock->tracerStartColor);
glVertex3f(mCurrPosition.x, mCurrPosition.y, mCurrPosition.z);
end = mCurrPosition - end;
glColor4fv(mDataBlock->tracerEndColor);
glVertex3f(end.x, end.y, end.z);
glDisable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ZERO);
glEnd();
glLineWidth(.1f);
}I'm not getting alpha blending, but like I said, the colour blends.
#13
07/22/2008 (1:53 pm)
Me like.
#14
all things checked twice, but found no problem, any ideas???
even after adding Daniel's alpha addon :(
08/13/2008 (5:45 am)
hi, used this resource - all things ok, but tracers color is BLACKall things checked twice, but found no problem, any ideas???
even after adding Daniel's alpha addon :(
#15
12/23/2008 (12:40 am)
Try getting farther away from the tracers - fire some slow bullets, then switch to the free camera and get some distance. I found that for some reason, if I was far away, the tracer colour would show up, but if I was too close, it would be black. 
Torque Owner Blake LaPierre