[tankpack] turret camera
by Pat AfterMoon · in Torque Game Engine · 01/19/2005 (3:23 pm) · 49 replies
This thread related to the BraveTree TankPack is intended to continue the discussion started here, but in private forum like Joe Maruschak from BraveTree has suggested.
So, I have commented BraveTree camera code and script, and reintroduced the eye/cam classic view like Michael Cozzolino has described. It works, but I have a little bug, similar to one already existing in Paul Dana Turret resource :
My eye node's parent is the codeWeapon node, so in 1st person view, It look where barrel aim. If I use the eye2 position the bug never occur. If I use the eye1 position the bug occur. I have modified tank datablock for allow horizontal 360 degree turn range and vertical 90 degree, for testing. The bug seem to occur when I look to the left or right (90 degree) or when I move the barrel up, first it work well, when I reach 45 degree the barrel and complete tank disappear, then if I move up a little bit it reappear.
I have enlarged the bound object with 3dsmax in case of, but no changement, any idea ?
So, I have commented BraveTree camera code and script, and reintroduced the eye/cam classic view like Michael Cozzolino has described. It works, but I have a little bug, similar to one already existing in Paul Dana Turret resource :
Quote:in first person view the turret's barrel disappears for certain pitch angles. I am not sure what causes this. The turret still functions...you just can't see the barrel at those angles in first person view.Look at the 3dsmax screenshot :
My eye node's parent is the codeWeapon node, so in 1st person view, It look where barrel aim. If I use the eye2 position the bug never occur. If I use the eye1 position the bug occur. I have modified tank datablock for allow horizontal 360 degree turn range and vertical 90 degree, for testing. The bug seem to occur when I look to the left or right (90 degree) or when I move the barrel up, first it work well, when I reach 45 degree the barrel and complete tank disappear, then if I move up a little bit it reappear.I have enlarged the bound object with 3dsmax in case of, but no changement, any idea ?
#22
05/03/2005 (8:48 am)
By the way... hope it's okay to post that code... just let me know if it's not!
#23
A bigger problem for me with 1st person has been a shaky/jerky camera view using this fix or the previously larger fix of commenting out all of the Tank camera code. I notice that this 4 line fix completely bypasses some camera smoothing code. Has anyone gotten a smooth camera in 1st person with the tank pack? I'm gonna try and see if I can use the camera smoothing logic that is there for 1st person but I'm hoping someone has already done it(in a better way than I would). thanks
01/02/2006 (6:32 am)
The four line 1st person fix works well except that you can see sometimes see the inside of the tank. It's especially pronounced in the Sherman. Maybe adding another node in a better spot and using that inside of the muzzle node might help. A bigger problem for me with 1st person has been a shaky/jerky camera view using this fix or the previously larger fix of commenting out all of the Tank camera code. I notice that this 4 line fix completely bypasses some camera smoothing code. Has anyone gotten a smooth camera in 1st person with the tank pack? I'm gonna try and see if I can use the camera smoothing logic that is there for 1st person but I'm hoping someone has already done it(in a better way than I would). thanks
#24
code deleted and added below
01/02/2006 (12:45 pm)
Ok, I made some progress in solving this myself. I reverted back to the original tankpack all the tankshape camera stuff. Then instead of the 4 line change I added this which reuses the smoothing code already present. I had to reverse the detection of first person view because for some reason it starts off thinking it's in first person and that the alternative view is not but I need the opposite. Also commented out some of the positioning datablock parameters, probably will create another set for first person view. Anyone think this would be useful as a resource?code deleted and added below
#25
C:\Torque\SDK\engine\game\tankShape.cc(2911) : error C2065: 'getMuzzleTransformForRender' : undeclared identifier
01/04/2006 (2:59 pm)
I get this error when implementing your code Joseph:C:\Torque\SDK\engine\game\tankShape.cc(2911) : error C2065: 'getMuzzleTransformForRender' : undeclared identifier
#26
Add two new fields to the TankCameraData to position the camera in 1st person view
In TankCameraData::TankCameraData() add
In TankCameraData::initPersistFields() add
In TankCameraData::packData(BitStream* stream) add
In TankCameraData::unpackData(BitStream* stream) add
Add this function after the defination of TankShape::setRenderPosition
Then change TankShape::getCameraTransform() to
In tankshape.h
After
After
Then in TankFx.cs you can adjust how far above and in front of the muzzle you want the camera
E.g.
// For the 1st person view, all relative to the muzzle
camFirstPersonHorizontal = 1.25; // dist. in front of muzzle to place camera
camFirstPersonVertical = 0.20; // dist. above the muzzle to float cam
I position the camera a bit in front of turret because I don't want to see the gun at all. I need to play with the model and where to position the camera because I don't want the gun to show in 1st person mode but I also don't want to see through walls which is what happens if the camera winds up outside the collision box.
I think thats all of it. Let us know how it works out for you.
01/04/2006 (3:50 pm)
Ok I fleshed out my change and tested it, works pretty good.Add two new fields to the TankCameraData to position the camera in 1st person view
In TankCameraData::TankCameraData() add
camFirstPersonHorizontal = 0.80; camFirstPersonVertical = 0.09;
In TankCameraData::initPersistFields() add
addField("camFirstPersonHorizontal", TypeF32, Offset(camFirstPersonHorizontal,TankCameraData));
addField("camFirstPersonVertical", TypeF32, Offset(camFirstPersonVertical,TankCameraData));In TankCameraData::packData(BitStream* stream) add
stream->write(camFirstPersonHorizontal); stream->write(camFirstPersonVertical);
In TankCameraData::unpackData(BitStream* stream) add
stream->read(&camFirstPersonHorizontal); stream->read(&camFirstPersonVertical);Make sure you pack and unpack in the same order relative to the other fields.
Add this function after the defination of TankShape::setRenderPosition
//-----------------------------------------------------------
// Function name: TankShape::getMuzzleTransformForRender
// Summary:
// Called in OnRender
// Used to return the muzzle transform without calling animation
//-----------------------------------------------------------
void TankShape::getMuzzleTransformForRender(MatrixF * mat)
{
*mat = getRenderTransform();
// make sure tank is animated...
// ...then grab muzzle transform
// updateAnimation(true);
mat->mul(mShapeInstance->mNodeTransforms[getDataBlock()->muzzleNode]);
}Then change TankShape::getCameraTransform() to
void TankShape::getCameraTransform(F32* pos,MatrixF* mat)
{
// track last mode -- see code for details...a little kooky
static bool altMode = false;
static F32 altMultiplier = 1.0f;
if (pos && *pos>0.5f && !altMode)
altMultiplier *= -1.0f;
// reijo01 - 3rd/1st person cameras
// FIXME - we start off in 1st person but it's really the opposite, how does the engine
// thinks it's in 1st person?
// First reverse the check for first person
altMode = pos && *pos<=0.5f;
MatrixF startHere;
if (altMode)
{
// 1st person - use the muzzle as the reference point
// MatrixF muzzle;
getMuzzleTransformForRender(&startHere);
}
else
{
startHere = getRenderTransform();
}
// matrix not always properly initialized at this point
// set to identity in order to get rid of junk in unused
// part of matrix
mat->identity();
// if time step too big, warp camera position
// otherwise, perform smoothing operation on camera...
U32 deltaTime = Platform::getVirtualMilliseconds()-mPrevCameraTime;
F64 k = (F64)(deltaTime)/sCameraSmoothTime;
bool doWarp = deltaTime>sCameraWarpTime;
// back up camera -- use x & z to get y
// smooth on x,z, and p
Point3F p,x,y,z;
startHere.getColumn(0,&x);
startHere.getColumn(2,&z);
startHere.getColumn(3,&p);
if (doWarp)
{
// just grab y from matrix
startHere.getColumn(1,&y);
}
else
{
// smooth out x & z, then generate y
// do quick and dirty vector averages...
F32 smoothX = exp(k*log((F64)mClampF(getDataBlock()->camera->camSmoothTurn,0.1f,1.0f)));
x = smoothX * mPrevCameraX + (1.0f-mClampF(smoothX,0.0f,1.0f)) * x;
if (mDot(x,x)>0.0001f)
x.normalize();
else
// oops, recover gracefully...
startHere.getColumn(0,&x);
F32 smoothZ = exp(k*log((F64)mClampF(getDataBlock()->camera->camSmoothUp,0.1f,1.0f)));
z = smoothZ * mPrevCameraZ + (1.0f-mClampF(smoothZ,0.0f,1.0f)) * z;
if (mDot(z,z)>0.01f)
z.normalize();
else
// oops, recover gracefully...
startHere.getColumn(2,&z);
mCross(z,x,&y);
if (mDot(y,y)>0.01f)
y.normalize();
else
// oops, recover gracefully...
startHere.getColumn(1,&y);
}
mPrevCameraX = x;
mPrevCameraZ = z;
Point3F lookat = p;
lookat += y * getDataBlock()->camera->camFocusDist; // focus this many meters out
lookat.z += getDataBlock()->camera->camFocusUpDist; // focus this many meters up
Point3F cam = p;
if (altMode)
{
// How far in front of startHere should the camera float?
cam += getDataBlock()->camera->camFirstPersonHorizontal * y;
}
else
{
cam -= getDataBlock()->camera->camBackupDist * y;
}
/*
// try a different camera view -- side view
if (altMode)
{
cam = p;
cam += altMultiplier * getDataBlock()->camera->camBackupDist * mPrevCameraX;
lookat = p;
}
*/
// adjust z so that it doesn't go under ground
// and floats a certain distance above tank's
// orientation plane...
F32 saveZ = cam.z;
goTowardGround(cam,sCameraCollisionMask);
cam.z = getMax(cam.z,saveZ);
if (altMode)
{
cam.z += getDataBlock()->camera->camFirstPersonVertical; // hang out this many meters above the ground behind the tank
}
else
{
cam.z += getDataBlock()->camera->camFloatHeight; // hang out this many meters above the ground behind the tank
}
// if (altMode)
// over-ride this from side view and hard-code new value
// cam.z -= getDataBlock()->camera->camFloatHeight - 3.0f;
// above we "warped" if too much time had passed...warp also if position step too big...
// otherwise, perform smoothing operation on camera...
Point3F deltaPos = cam-mPrevCameraPos;
doWarp |= mDot(deltaPos,deltaPos)>sCameraWarpDistance*sCameraWarpDistance;
if (!doWarp)
{
// Apply camera smoothing...but in frame-rate independent manner
// (this function called once per frame, so must pay attention
// to deltaTime). The smooth factor from the datablock is normalized
// to occur over a duration determined by sCameraSmoothTime.
F32 smoothFactor = exp(k*log((F64)mClampF(getDataBlock()->camera->camSmooth,0.1f,1.0f)));
// Perform the smooth using exponential average (weighted sum of old and new).
cam = smoothFactor * mPrevCameraPos + (1.0f-mClampF(smoothFactor,0.0f,1.0f)) * cam;
}
mPrevCameraPos = cam;
mPrevCameraTime = Platform::getVirtualMilliseconds();
Point3F look = lookat-cam;
look.normalize(); // take our chances with an exception here...
Point3F up,left;
mCross(look,Point3F(0,0,1),&left);
left.normalize(); // take our chances with an exception here...
mCross(left,look,&up);
// now set materix
mat->setColumn(0,left);
mat->setColumn(1,look);
mat->setColumn(2,up);
mat->setColumn(3,cam);
}In tankshape.h
After
void getMuzzleTransform(MatrixF * mat);add
void getMuzzleTransformForRender(MatrixF * mat);
After
F32 camBackupDist; // distance behind tank to place camera F32 camFloatHeight; // distance above the ground to float cameraadd
F32 camFirstPersonHorizontal; // dist. in front of muzzle to place camera F32 camFirstPersonVertical; // dist. above the muzzle to float cam
Then in TankFx.cs you can adjust how far above and in front of the muzzle you want the camera
E.g.
// For the 1st person view, all relative to the muzzle
camFirstPersonHorizontal = 1.25; // dist. in front of muzzle to place camera
camFirstPersonVertical = 0.20; // dist. above the muzzle to float cam
I position the camera a bit in front of turret because I don't want to see the gun at all. I need to play with the model and where to position the camera because I don't want the gun to show in 1st person mode but I also don't want to see through walls which is what happens if the camera winds up outside the collision box.
I think thats all of it. Let us know how it works out for you.
#27
A few changes I made myself to get it to work as I wanted.
I wanted to see the tank and have a crosshair to aim with.
My changes to Joseph's code:
changed:
if (altMode)
to
if (!altMode)
This so the default mode is firstperson (so i can enable the crosshair).
then changed:
bool doWarp = deltaTime>sCameraWarpTime;
to
bool doWarp = true;
This is because i want the camera always to be positioned behind the muzzle so the crosshair always lines up with the muzzle (you can try without it, and it will be very hard to aim).
Then i did some script changes.
In tank.cs and TankShapeData::onAdd() I commented out hideCrossHair();
This so i have something to aim after.
in tankFx.cs i added this to datablock TankCameraData(DefaultTankCamera):
camFirstPersonHorizontal = -5; // dist. in front of muzzle to place camera
camFirstPersonVertical = 1; // dist. above the muzzle to float cam
This will position the camera right above the abraham's turret. I have not tested this with the WW2 tank, so you might need some other values for that one.
Again a big thank you to Joseph!
Some screenshots:
www.deep-north.net/screenshots/screenshot_001-00001.png
www.deep-north.net/screenshots/screenshot_001-00002.png
www.deep-north.net/screenshots/screenshot_001-00003.png
01/04/2006 (4:37 pm)
This works like a charm! Thank you for sharing this with us.A few changes I made myself to get it to work as I wanted.
I wanted to see the tank and have a crosshair to aim with.
My changes to Joseph's code:
changed:
if (altMode)
to
if (!altMode)
This so the default mode is firstperson (so i can enable the crosshair).
then changed:
bool doWarp = deltaTime>sCameraWarpTime;
to
bool doWarp = true;
This is because i want the camera always to be positioned behind the muzzle so the crosshair always lines up with the muzzle (you can try without it, and it will be very hard to aim).
Then i did some script changes.
In tank.cs and TankShapeData::onAdd() I commented out hideCrossHair();
This so i have something to aim after.
in tankFx.cs i added this to datablock TankCameraData(DefaultTankCamera):
camFirstPersonHorizontal = -5; // dist. in front of muzzle to place camera
camFirstPersonVertical = 1; // dist. above the muzzle to float cam
This will position the camera right above the abraham's turret. I have not tested this with the WW2 tank, so you might need some other values for that one.
Again a big thank you to Joseph!
Some screenshots:
www.deep-north.net/screenshots/screenshot_001-00001.png
www.deep-north.net/screenshots/screenshot_001-00002.png
www.deep-north.net/screenshots/screenshot_001-00003.png
#28
01/05/2006 (4:14 pm)
I'm glad to hear that it helped you. I triedbool doWarp = true;but I lose the smoothing effect that I wanted to begin with. There seems to be a slight discrepency when firing and stopping at the same time but I hadn't noticed it until you pointed it out. I don't think it should be a problem for the gameplay I'm planning.
#29
Your code works very nicely, just wanted to post how to have a fixed camera above the tank with a crosshair.
01/05/2006 (4:17 pm)
Yes, that was the idea to skip the smoothing because then the crosshair would not line up with the muzzle. So the point you are actually aiming at, does not match with the crosshair.Your code works very nicely, just wanted to post how to have a fixed camera above the tank with a crosshair.
#30
First of all thanks to all of you helping me better understand TGE
Second... I've just apply the modification for 1st person camera and it's running until I press TAB for change view... someone know why?
Third... I would like to slow down turret movement... it's possible? how?
Thanks in advance for your reply
ps. sorry for my bad bad english
01/06/2006 (7:48 am)
Hi all tank's friend... :)First of all thanks to all of you helping me better understand TGE
Second... I've just apply the modification for 1st person camera and it's running until I press TAB for change view... someone know why?
Third... I would like to slow down turret movement... it's possible? how?
Thanks in advance for your reply
ps. sorry for my bad bad english
#31
First of all thanks to all of you helping me better understand TGE
Second... I've just apply the modification for 1st person camera and it's running until I press TAB for change view... someone know why?
Third... I would like to slow down turret movement... it's possible? how?
Thanks in advance for your reply
ps. sorry for my bad bad english
01/06/2006 (9:01 am)
Hi all tank's friend... :)First of all thanks to all of you helping me better understand TGE
Second... I've just apply the modification for 1st person camera and it's running until I press TAB for change view... someone know why?
Third... I would like to slow down turret movement... it's possible? how?
Thanks in advance for your reply
ps. sorry for my bad bad english
#32
I added two new datablock variables (turretHorRate and turretVerRate) and added them into the updateTurret function like so:
If you're unsure why or how I added the datablock variables, post back and I'll try to explain.
01/06/2006 (9:33 am)
@ Dasca:I added two new datablock variables (turretHorRate and turretVerRate) and added them into the updateTurret function like so:
F32 tHorRate, tVerRate = 0; tHorRate = getDataBlock()->turretHorRate; tVerRate = getDataBlock()->turretVerRate; tHor += (move->yaw / (tHorRate * M_PI)); tVer += (move->pitch / (tVerRate * M_PI));
If you're unsure why or how I added the datablock variables, post back and I'll try to explain.
#33
Thanks for your prompt reply.... Yes, I really need some more info about apply your modification, I've bought TGE 2 days ago :) and I'm still figure out how to work with it.
I'm very interested in learning as much as possible about TGE.
Have you made some other modification to tank packs? if yes I would like to study it and learn how to make my own.
I'll try to make a BF2 game but with armor only.... do you think it's possible with TGE?
Ok... no more question for today! :)
01/06/2006 (9:47 am)
@JerryThanks for your prompt reply.... Yes, I really need some more info about apply your modification, I've bought TGE 2 days ago :) and I'm still figure out how to work with it.
I'm very interested in learning as much as possible about TGE.
Have you made some other modification to tank packs? if yes I would like to study it and learn how to make my own.
I'll try to make a BF2 game but with armor only.... do you think it's possible with TGE?
Ok... no more question for today! :)
#34
Almost anything is possible with TGE. I've seen some amazing games done with TGE (ex: Illumina, Minions of Mirth, plus others)
Let me know if you have any more questions.
01/06/2006 (12:14 pm)
Take a look at the resource I posted last year where I added tread marks and emitters to the tankAlmost anything is possible with TGE. I've seen some amazing games done with TGE (ex: Illumina, Minions of Mirth, plus others)
Let me know if you have any more questions.
#35
thx
01/06/2006 (5:03 pm)
Well.... yes I've asked you how to implement the 5 lines of code for slowing down the turret velocity... I've try but without success... could you please explain in a very easy way how to do it...thx
#36
thx
01/06/2006 (5:32 pm)
Well.... yes I've asked you how to implement the 5 lines of code for slowing down the turret velocity... I've try but without success... could you please explain in a very easy way how to do it...thx
#37
ok jerry I figured out how to add the lines you suggest me
It's work pretty well now
Thanks
01/07/2006 (8:18 am)
@Jerryok jerry I figured out how to add the lines you suggest me
It's work pretty well now
Thanks
#38
I've try your code for changing camera but I have a problem when change the camera from 1st to external view.... when I press TAB, Torque simply crash...
I check your modification and I add the lines how you told.... I didnt understand where could be the problem
Help!!!
01/07/2006 (8:23 am)
@JosephI've try your code for changing camera but I have a problem when change the camera from 1st to external view.... when I press TAB, Torque simply crash...
I check your modification and I add the lines how you told.... I didnt understand where could be the problem
Help!!!
#39
I've try your code for changing camera but I have a problem when change the camera from 1st to external view.... when I press TAB, Torque simply crash...
I check your modification and I add the lines how you told.... I didnt understand where could be the problem
Help!!!
01/07/2006 (8:30 am)
@JosephI've try your code for changing camera but I have a problem when change the camera from 1st to external view.... when I press TAB, Torque simply crash...
I check your modification and I add the lines how you told.... I didnt understand where could be the problem
Help!!!
#40
01/07/2006 (8:34 am)
Where does it crash? can you send me your tankshape.cc and tankshape.h files so I can compare to mine?
Torque Owner decryptoid
You will have to forgive me if the code is hard to read.... just thought I should share since everyone is so helpful on garagegames!
void TankShape::updateTurret(const Move * move, const QuatF & oldRot, const QuatF & newRot) { //AssertFatal(move,"doh!"); // get old position F32 tHor = deltaHelper.getTurretHorTarget(); F32 tVer = deltaHelper.getTurretVerTarget(); F32 tVerDelta = 0; F32 tHorDelta = 0; F32 turretSoundVal = 0; // auto adjust to stay level if (getDataBlock()->turretAutoLevel>0.01f) { MatrixF oldMat, newMat; MatrixF turretMat(EulerF(0,0,tHor * mDegToRad(getDataBlock()->turretHorRange))); turretMat.mul(MatrixF(EulerF(tVer * mDegToRad(getDataBlock()->turretVerRange) + mDegToRad(getDataBlock()->turretVerCenter),0,0))); oldRot.setMatrix(&oldMat); oldMat.mul(turretMat); newRot.setMatrix(&newMat); newMat.mul(turretMat); Point3F y0,y1,x0, x1, z0, z1; oldMat.getColumn(0,&x0); oldMat.getColumn(1,&y0); oldMat.getColumn(2,&z0); newMat.getColumn(0,&x1); newMat.getColumn(1,&y1); newMat.getColumn(2,&z1); // up and down code F32 muzzleDelta = 0.0f; y0 -= mDot(y0,x1) * x1; if (mDot(y0,y0)>0.0f) { y0.normalize(); if (mDot(y0,y1)<1.0f) muzzleDelta = mAcos(mDot(y0,y1)); if (y0.z<y1.z) muzzleDelta *= -1.0f; } //tVer -= getDataBlock()->turretAutoLevel * muzzleDelta/mDegToRad(getDataBlock()->turretVerRange); tVerDelta -= muzzleDelta/mDegToRad(getDataBlock()->turretVerRange); // left and right code muzzleDelta = 0.0f; x0 -= mDot(x0,z1) * z1; if (mDot(x0,x0)>0.0f) { x0.normalize(); if (mDot(x0,x1)<1.0f) muzzleDelta = mAcos(mDot(x0,x1)); if (x0.x<x1.x) muzzleDelta *= -1.0f; if (x0.y>0) muzzleDelta *= -1.0f; } tHorDelta -= muzzleDelta/mDegToRad(getDataBlock()->turretHorRange); } //add mouse movement to barrell tHorDelta += ((move->yaw/4) / M_PI); tVerDelta += (move->pitch / M_PI); //adjust the values tHor += tHorDelta; tVer += tVerDelta; //turret sound Point3F CalcTurrSpeed; CalcTurrSpeed.x = abs(tHorDelta); CalcTurrSpeed.y = abs(tVerDelta); CalcTurrSpeed.z = 0; turretSoundVal = CalcTurrSpeed.len() * 10; if (turretSoundVal > 0.01f) { turretSoundVal = mClampF(turretSoundVal,0.6f,0.9f); if (getDataBlock()->fx->tankturrSound) { if (mTurretSound == NULL_AUDIOHANDLE) mTurretSound = alxPlay(getDataBlock()->fx->tankturrSound,&getTransform()); if (alxIsValidHandle(mTurretSound)) { alxSourceMatrixF(mTurretSound, &getTransform()); alxSourcef(mTurretSound,AL_PITCH,turretSoundVal); alxSourcef(mTurretSound,AL_GAIN_LINEAR,0.2); } } }else{ if (mTurretSound != NULL_AUDIOHANDLE) { //mTurretSound alxStop(mTurretSound); mTurretSound = NULL_AUDIOHANDLE; } } //clamp vertical to range limit tVer = mClampF(tVer,-1.0f,1.0f); deltaHelper.setTurret(tHor,tVer); setMaskBits(TurretMask); }