Game Development Community

Torque Flashlight & Laser Sighting

by Robert Brower · 08/04/2003 (12:50 pm) · 34 comments

Download Code File

Instructions and files are included in the zip file.
Page «Previous 1 2
#1
08/04/2003 (2:30 pm)
Awesome job, works great!
#2
08/04/2003 (2:40 pm)
Can't this be combined with the volumetric lights thing earlier?
#3
08/04/2003 (7:43 pm)
I don't know how that other resource works. I bet it would look pretty sweet.
#4
08/05/2003 (11:19 pm)
Way cool!! I made a laser pointer and a spot light... roxx! :)
#5
08/07/2003 (10:35 pm)
One problem I noticed with this was that the collision check for the lighting doesn't ignore the shapebase that the image is mounted on. Though this may be intentional, it proved to make helmets, shoulder-mounted lights, and short-barrelled weapon lights problematic.

"Fixing" this is fairly simple, so... Just find the relevant bits of code and add the bits in bold.

In ShapeBase.h, modify the line:

void registerWeaponImageLights(LightManager * lightManager, bool lightingScene, Container* container, const Point3F &muzzlePoint, const VectorF &muzzleVector, U32 startTime[b], ShapeBase *obj = NULL[/b]);


In shapeImage.cc, modify the line:

imageData->registerWeaponImageLights(lightManager, lightingScene, getContainer(), pos, vec, mLightTime[b], this[/b]);


Then modify:

void ShapeBaseImageData::registerWeaponImageLights(LightManager * lightManager, bool lightingScene, Container* container, const Point3F &muzzlePoint, const VectorF &muzzleVector, U32 startTime[b], ShapeBase *obj[/b])


Then scroll down a little and in that same function and add the following:

if (maxLightLength > 0)
{
[b]    // Disable collision with the shapebase the image is mounted on.
    if (obj != NULL)
    {
        obj->disableCollision();
    }[/b]

    VectorF scale = mLight.mDirection * maxLightLength;
    VectorF endPoint = mLight.mPos + scale;


... scroll down a little further in the same function and add ...

mLight.mPos = endPoint;
    }

[b]    if (obj != NULL)
    {
        obj->enableCollision();
    }[/b]
}
#6
08/08/2003 (8:00 pm)
Heh cool Beffy :)
#7
08/09/2003 (11:23 am)
Very nice resource.
#8
08/10/2003 (7:19 am)
Dan Eden,

Thanks for contributing to the resource! Good eye! Your addition makes complete sense and was an oversight on my part.

Robert
#9
08/10/2003 (10:47 am)
I've been messing around with the shapeimagebase-based lighting stuff over the last few days, posted earlier about a possible bug (which I have yet to have had verified, but have "fixed" the code for -- assuming that it's broken in the first place), and so on, and added a few features and the like to the base code.

I haven't really got the time or the inclination to keep running with the resource, however (since my codebase is significantly divergent from HEAD and, at the moment, I'd just rather be working on getting my own game up and running properly), but... I will add a few minor changes that I can remember, however...

If you're using this very cool little resource, you may have noticed some lighting direction inaccuracy and/ or flickering with the flashlight effect (I'm not talking about the pop caused when you stop shining your light at an object -- I'm talking about a slight flicker caused if you're moving at a relatively brisk pace or if both objects are continually changing direction. This is because the initial code was using object positions and not rendering positions.

You can fix this by looking in ShapeImage.cc and finding the function ShapeBase::registerLights. Once you've got it, modify it to:

// RFB ->
if (imageData->muzzleNode >= 0)
{
    VectorF vec;
    Point3F pos;
[b]    getRenderMuzzleVector(i, &vec);
    getRenderMuzzlePoint(i, &pos);[/b]
    imageData->registerWeaponImageLights(lightManager, lightingScene, getContainer(), pos, vec, mLightTime[b], this[/b]);
}


You should also be able to remove any network requirements for this resource, by opening up Shapebase.cc and changing a few things. First, find ShapeBase::setLightDirection and change it to the following:

void ShapeBase::setLightDirection(VectorF direction)
{
    // Set the new direction for the shape.
    mLightDir = direction;
}


Then remove what's below from ShapeBase::packUpdate:

// RFB ->
    mathWrite(*stream, mLightDir);
    // <- RFB


... and also the following from ShapeBase::unpackUpdate:

// RFB ->
    mathRead(*stream, &mLightDir);
    // <- RFB


The reason we should be able to remove this data send (which would, incidentally be spammed across the network almost constantly as you moved your flashlight or the object you were lighting moved or whatever) is twofold:

First, the shadow direction is only really important (and accurate) on the client (since the light manager only registers lights for the client scene graph anyway); and second, because the engine is already sending the position of both the object being lit and the object (that has an image) doing the lighting across the network and determining where it's going to be rendered on your screen (or off your screen for that matter).

Oh, and I had a look at spotlights and some of the other unworking lighting, but it's over my head on initial inspection and I haven't the time to spend working on it. It'd be nice if someone out there was to dedicate themselves solely to improving lighting in the engine (hint hint). =)

Rob: Not a problem. Great idea with the flashlight effect in the first place and kudos to someone who finds the time to put up a resource that helps everyone in the community. Just don't call me Dan, eh? =)
#10
08/22/2003 (1:40 pm)
I have a problem with it, it dosnt work in network for me. I have everything done right, i think. Thanks for any help.
#11
02/03/2004 (1:57 pm)
Hi there,
I was trying to run this resource but after following all the steps the flashlight effect does not seem to work.
For step 22: when I added the following function i got errors
void ShapeBaseImageData::registerWeaponImageLights(LightManager * lightManager, bool lightingScene, Container* container, const Point3F &muzzlePoint, const VectorF &muzzleVector, U32 startTime )
{
....
}

So I changed it as follows....
void ShapeBase::MountedImage::registerWeaponImageLights(LightManager * lightManager, bool lightingScene, Container* container, const Point3F &muzzlePoint, const VectorF &muzzleVector, U32 startTime )
{
....
}

I was getting a lot of compilation errors when I tried to build it.
The errors said,
lightType is undeclared
mLightOn is undeclared
mPrevObject is undeclared
maxLightLength is undeclared
LightRadius is undeclared
MinLightRadius is undeclared

In order to rectify the error I converted them all to
dataBlock -> lightType
dataBlock -> mLightOn
dataBlock -> mPrevObject
dataBlock -> maxLightLength
dataBlock -> LightRadius
dataBlock -> MinLightRadius

Then it compiled without errors. But when I tried running the program there was no flashlight effect shown.

For step 24: I had to change to call also to -
if (imageData->muzzleNode >= 0)
{
VectorF vec;
Point3F pos;
getMuzzleVector(i, &vec);
getMuzzlePoint(i, &pos);
mMountedImageList[i].registerWeaponImageLights(lightManager, lightingScene, getContainer(), pos, vec, mLightTime);
}
else
{
mMountedImageList[i].registerImageLights(lightManager, lightingScene, getRenderPosition(), mLightTime);
}


......................................

Kindly help.

Thanking you,
Aditya Varma
#12
02/13/2004 (8:32 am)
Hi!

I
#13
09/18/2004 (9:45 am)
Please be warned that I found a bug in this resource last night. The problem occurs when a ShapeBase object that the light is shining on is deleted. The problem manifests itself as memory corruption and will probably crash your game. To fix it, change all the places where mPrevObject is used. Although the following code is not exactly the same as what's in the resource, it's very similar, and shows how to add mPrevObectId and how to correct the problem. ***Note... you can remove the mPrevObject member completely from the source and just use mPrevObectId as shown here. Sorry about the bug. I'm glad i found this!


void UnderWaterVehicle::registerLights(LightManager * lightManager, bool lightingScene)
{
if(lightingScene)
return;

Point3F defaultDir(0.57f,0.57f,-0.57f);

if (mDataBlock->lightNode != -1)
{
// if the light was pointing at shapebase object and is turned off
// then reset the light direction on the object if it still exists
if (mLightOn == false)
{
ShapeBase* ptr;
if (mPrevObjectId != -1 && Sim::findObject(mPrevObjectId, ptr))
{
ptr->setLightDirection(defaultDir);
mPrevObjectId = -1;
}
return;
}

MatrixF mat;
mat.mul(getRenderTransform(),
mShapeInstance->mNodeTransforms[mDataBlock->lightNode]);
mat.getColumn(3,&mLight.mPos);
mat.getColumn(1,&mLight.mDirection);

// if lightDistance > 0 then we're casting a ray from the light node
// in the model to some point in space in front of the car. The angle
// at which the ray is cast is determined by the node transform. If
// we hit something, then we will adjust the distance at which we
// will register the light.
if (mDataBlock->lightDistance > 0)
{
VectorF scale = mLight.mDirection * mDataBlock->lightDistance;
VectorF endPoint = mLight.mPos + scale;
RayInfo rInfo;
if (getContainer()->castRay(mLight.mPos, endPoint,
sClientCollisionMask,&rInfo) == true)
{
ShapeBase* obj = dynamic_cast(rInfo.object);
S32 objId = rInfo.object->getId();
if (obj)
{
if (objId != mPrevObjectId)
{
ShapeBase* ptr;
if (mPrevObjectId != -1 && Sim::findObject(mPrevObjectId, ptr))
ptr->setLightDirection(defaultDir);
obj->setLightDirection(mLight.mDirection);
mPrevObjectId = objId;
}
else
obj->setLightDirection(mLight.mDirection);
}
else
{
ShapeBase* ptr;
if (mPrevObjectId != -1 && Sim::findObject(mPrevObjectId, ptr)) {
ptr->setLightDirection(defaultDir);
mPrevObjectId = -1;
}
}
mLight.mPos = rInfo.point;
}
else
{
ShapeBase* ptr;
if (mPrevObjectId != -1 && Sim::findObject(mPrevObjectId, ptr)) {
ptr->setLightDirection(defaultDir);
mPrevObjectId = -1;
}
mLight.mPos = endPoint;
}
}
//
mLight.mType = LightInfo::Point;
mLight.mRadius = mDataBlock->lightRadius;
mLight.mColor = mDataBlock->lightColor * mFadeVal;
lightManager->addLight(&mLight);
}
}
#14
11/28/2004 (6:19 pm)
It seem to not work at TGE 1.3
#15
11/29/2004 (2:11 am)
Written in torque 1.2. I use it in 1.3 and I don't think there is anything special I am doing.
#16
02/01/2005 (2:54 pm)
UPDATE: I have temporarily pulled my comments/update as I've found something peculiar that needs furher debugging. I'll re-post when I get this worked out. Meanwhile, this is a KA resource and you should use it. Thanks Robert!
#17
02/01/2005 (4:14 pm)
I don't have the lighting pack. How does the flashlight effect look with it? I had to fiddle with, turn down the brightness of the light to make it so things that were lit up weren't so bled out. Does it look good? Can you show me a pic?

BTW Thanks for the pending contribution to the community.

Robert
#18
03/25/2005 (6:08 pm)
Additional 1.3 Changes

Had to move bool mLightOn to Public.

(ShapeBase.h)


struct ShapeBaseImageData: public GameBaseData {
private:
typedef GameBaseData Parent;

public:

// RFB ->
bool mLightOn;
// <- RFB

enum Constants {
MaxStates = 31, ///< We get one less than state bits because of
/// the way data is packed.
NumStateBits = 5,
};



I desperately need this for weapons aiming.
None of the third person reticles work the way I want, and after testing in the Quake engine, the laser pointer is the way to go.
I'm hoping to use mutli-colors so that squads can stay on their common targets.
Aditya Varma, I'm right there with ya.
I came to the same changes and 0 errors, 0 warnings.
Unfortunately, everytime I equip my newly lit weapon, big crash.
It's in the engine because as soon as the weapon scripts calls it, crash.
I am using TGE 1.3.
I have the scripted inventory system with the object view window in.
Maybe it has something to do with the crash, or else it will look very cool soon.
I'm going back to double check my work.
If I solve this I'll post my changes for 1.3 well.

Ari Rule
#19
04/01/2005 (5:29 pm)
That would be nice, I'm having trouble integrating this into Torque 1.3 as well.

I can get the flashlight to show up, but it does not cast any shadows or light up static objects. I also do not know how to write the ShapeBase::registerLights function. The only way I can ever get the light to show up is by commenting out the check
//if(imageData->muzzleNode >= 0)

If anyone has gotten this to work well with the 1.3 version, could you please list what has to be done?, any help would be great! Thanks.


EDIT:
I am also not able to get the flashlight to work over a multiplayer game. The person that creates the server is the only one who can see the flashlights.
The only way I can get it to work over a multiplayer game is to start everyone out immediately with flashlights, then it seems to work okay except that everyon'es flashlight is double powered on the servers side. Plus I'd rather have the flashlight be an optional item that you must find first so I really don't want to start everyone with their flashlight on. Does anyone have any ideas on what might be causing this? Thanks.
#20
04/19/2005 (6:32 am)
I was able to get this resource to work in version 1.3 and it works over multiplayer. The shadows don't seem quite right though.

Anyway, shoot me an e-mail if anyone has problems and I'll try and help.
Page «Previous 1 2