Turret Problems Resolved?
by Demolishun · in Torque Game Engine · 10/14/2005 (11:26 am) · 6 replies
Here is the reference thread:
www.garagegames.com/mg/forums/result.thread.php?qt=35524
I think I may have found the solution to my problem here, but I don't have a clue why.
If I go into shapeImage.cc and make the following changes:
I think the issue may be something in getMuzzleTransform failing for the turret classes and not the player classes:
So if it is failing the true false check for image.dataBlock what is my scripting/code not providing that the player.cc/player.cs files are providing?
WIth the above changes the turret is dead nuts accurate and does not break the player aiming either, but I do not know what other problems I may be introducing are.
Note:
Okay, it breaks one thing for player so far. There is no "eye" correction for aiming.
Also, this is using Torque 1.3 with minor modifications.
Thanks,
Frank
www.garagegames.com/mg/forums/result.thread.php?qt=35524
I think I may have found the solution to my problem here, but I don't have a clue why.
If I go into shapeImage.cc and make the following changes:
void ShapeBase::getMuzzleVector(U32 imageSlot,VectorF* vec)
{
MatrixF mat;
//getMuzzleTransform(imageSlot,&mat); // took this out
getMountTransform(imageSlot,&mat); // added this
MountedImage& image = mMountedImageList[imageSlot];
if (image.dataBlock->correctMuzzleVector)
if (GameConnection * gc = getControllingClient())
if (gc->isFirstPerson() && !gc->isAIControlled())
if (getCorrectedAim(mat, vec))
return;
mat.getColumn(1,vec);
}
void ShapeBase::getMuzzlePoint(U32 imageSlot,Point3F* pos)
{
MatrixF mat;
//getMuzzleTransform(imageSlot,&mat); // took this out
getMountTransform(imageSlot,&mat); // added this
mat.getColumn(3,pos);
}I think the issue may be something in getMuzzleTransform failing for the turret classes and not the player classes:
void ShapeBase::getMuzzleTransform(U32 imageSlot,MatrixF* mat)
{
// Muzzle transform in world space
MountedImage& image = mMountedImageList[imageSlot];
if (image.dataBlock) // I think it may be false here for some reason?
getImageTransform(imageSlot,image.dataBlock->muzzleNode,mat);
else
*mat = mObjToWorld;
}So if it is failing the true false check for image.dataBlock what is my scripting/code not providing that the player.cc/player.cs files are providing?
WIth the above changes the turret is dead nuts accurate and does not break the player aiming either, but I do not know what other problems I may be introducing are.
Note:
Okay, it breaks one thing for player so far. There is no "eye" correction for aiming.
Also, this is using Torque 1.3 with minor modifications.
Thanks,
Frank
About the author
I love programming, I love programming things that go click, whirr, boom. For organized T3D Links visit: http://demolishun.com/?page_id=67
#2
It has to do with the ShapeBase::getImageTransform() always using the eye transform on the server so in:
the (data.useEyeOffset && isFirstPerson()) condition is always true. So it aims according to the turret's eye vector rather than it's mounted gun. Nice. :/
I could not find where useEyeOffset is set to true, and it probably isn't what I want to mess with anyway since it's a datablock property. My first instinct was to override the isFirstPerson() to always return false. This didn't work as the default ShapeBase version of the code always ran (anyone know why? Please enlighten me!)
Anyway, what I ended up doing was instead reimplementing getImageTransform() in my Turret class:
That worked. The only thing I don't like about that is if a future torque build changes ShapeBase's getImageTransform(), that could create problems for me. However, getting rid of the eye offset check should make the code run ever so slightly faster and getImageTransform() is called quite frequently.
And that definitely makes me wonder: Why have an eye offset check at all in a base class like ShapeBase? Shouldn't that be placed in subclasses like Player instead? Or am I just getting way too picky?
Anyway, may the above fix lead to world peace... or at least stop some poor soul from having to figure it out again. :)
05/30/2007 (11:25 pm)
I ran into this exact same issue recently. It is a confusing problem and took me quite some time to unravel, but I think I've figured it out.It has to do with the ShapeBase::getImageTransform() always using the eye transform on the server so in:
void ShapeBase::getImageTransform(U32 imageSlot,MatrixF* mat)
{
// Image transform in world space
MountedImage& image = mMountedImageList[imageSlot];
if (image.dataBlock) {
ShapeBaseImageData& data = *image.dataBlock;
MatrixF nmat;
if (data.useEyeOffset && isFirstPerson()) {
getEyeTransform(&nmat);
mat->mul(nmat,data.eyeOffset);
}
else {
getMountTransform(image.dataBlock->mountPoint,&nmat);
mat->mul(nmat,data.mountTransform);
}
}
else
*mat = mObjToWorld;
}the (data.useEyeOffset && isFirstPerson()) condition is always true. So it aims according to the turret's eye vector rather than it's mounted gun. Nice. :/
I could not find where useEyeOffset is set to true, and it probably isn't what I want to mess with anyway since it's a datablock property. My first instinct was to override the isFirstPerson() to always return false. This didn't work as the default ShapeBase version of the code always ran (anyone know why? Please enlighten me!)
Anyway, what I ended up doing was instead reimplementing getImageTransform() in my Turret class:
void Turret::getImageTransform(U32 imageSlot,MatrixF* mat)
{
// Image transform in world space
MountedImage& image = mMountedImageList[imageSlot];
if (image.dataBlock)
{
ShapeBaseImageData& data = *image.dataBlock;
MatrixF nmat;
getMountTransform(image.dataBlock->mountPoint,&nmat);
mat->mul(nmat,data.mountTransform);
}
else
*mat = mObjToWorld;
}That worked. The only thing I don't like about that is if a future torque build changes ShapeBase's getImageTransform(), that could create problems for me. However, getting rid of the eye offset check should make the code run ever so slightly faster and getImageTransform() is called quite frequently.
And that definitely makes me wonder: Why have an eye offset check at all in a base class like ShapeBase? Shouldn't that be placed in subclasses like Player instead? Or am I just getting way too picky?
Anyway, may the above fix lead to world peace... or at least stop some poor soul from having to figure it out again. :)
#3
Also remember that useEyeOffset is declared in the Datablock (in your relavent .cs file).
05/31/2007 (6:22 am)
Quote:My first instinct was to override the isFirstPerson() to always return falseThere is alot of places (LOS, Lights, fxSunlight Flares, etc) where the isFirstPerson method is used. Changing it to always return false is probably not a good idea.
Quote:This didn't work as the default ShapeBase version of the code always ran (anyone know why? Please enlighten me!)Have a look in GameConnection.h. I think this might be bug (not 100% sure), but change
bool isFirstPerson() { return mCameraPos == 0; }tobool isFirstPerson() { return mFirstPerson; }Also remember that useEyeOffset is declared in the Datablock (in your relavent .cs file).
#4
Yes, I should clarify I wanted to override it only for my turret class. Changing it in general would indeed have nasty side effects, I'm sure.
Similarly, the getImageTransform() method is also very frequently called, but I've only overridden it for my turret class (which is derived from ShapeBase). So only derivatives of my turret class are affected by the change.
05/31/2007 (10:14 pm)
Quote:There is alot of places (LOS, Lights, fxSunlight Flares, etc) where the isFirstPerson method is used. Changing it to always return false is probably not a good idea.
Yes, I should clarify I wanted to override it only for my turret class. Changing it in general would indeed have nasty side effects, I'm sure.
Similarly, the getImageTransform() method is also very frequently called, but I've only overridden it for my turret class (which is derived from ShapeBase). So only derivatives of my turret class are affected by the change.
#5
05/31/2007 (11:39 pm)
Aaah.... I see ;)
#6
Anyway, getImageTransform() is a virtual method so you can freely reimplement it in subclasses.
06/02/2007 (12:42 am)
It turns out I could not override isFirstPerson() because it's not declared as a virtual method. Ooops. I thought I had checked that...Anyway, getImageTransform() is a virtual method so you can freely reimplement it in subclasses.
Torque Owner Demolishun
DemolishunConsulting Rocks!
void ShapeBase::getMuzzleTransform(U32 imageSlot,MatrixF* mat) { // Muzzle transform in world space MountedImage& image = mMountedImageList[imageSlot]; if (image.dataBlock) { //getImageTransform(imageSlot,image.dataBlock->muzzleNode,mat); getMountTransform(imageSlot, mat); // this seems to fix a lot of problems and because I changed it here the "eye" corrections work for the player. //Con::printf("getMuzzleTransform: found muzzle datablock"); } else { *mat = mObjToWorld; //Con::printf("getMuzzleTransform: setting to object global transform as no datablock can be found"); } }Also, do not change getMuzzlePoint or getMuzzleVector from default like I showed above. Leave those functions alone.
I still do not understand why there are so many function calls in this chain. I just cannot understand it.
Also, I cannot be the only person implementing turrest using the 1.2 turret resource am I?
How come nobody else is seeing this issue?