Working on weapon sway, need help with eye offset matrices
by Bryce · in Torque Game Engine · 03/08/2010 (7:35 pm) · 16 replies
Hello everyone!
I've come to the conclusion that the shape images in torque are too stiff, so I decided to work on getting weapon sway to work. Basically, I'm trying to get the weapon to swing in the direction the player is turning, as he turns.
To do this, I decided that I could hook up the $mvPitch and $mvYaw variables to the image rendering code. When the player turns quickly, these values are higher, and these could tune an offset that moves the weapon in the desired direction during the turn.
After digging around, I brought myself to ShapeBase::getImageTransform, in shapeImage.cc (I'm using TGE 1.4.2). Here's that function for you:
What I'm trying to do is add an offset to the part where it says "mat->mul(nmat,data.eyeOffset);" I'm a lot more familiar with the Torque script vector functions ( VectorAdd(%pos,%vec); etc.) that I am with matrices and C++ code.
So all in all, can somebody give me the equivalent of
but in C++ and matrix form? Hope I'm being clear to you all, help is very much appreciated!
Thanks,
Bryce
I've come to the conclusion that the shape images in torque are too stiff, so I decided to work on getting weapon sway to work. Basically, I'm trying to get the weapon to swing in the direction the player is turning, as he turns.
To do this, I decided that I could hook up the $mvPitch and $mvYaw variables to the image rendering code. When the player turns quickly, these values are higher, and these could tune an offset that moves the weapon in the desired direction during the turn.
After digging around, I brought myself to ShapeBase::getImageTransform, in shapeImage.cc (I'm using TGE 1.4.2). Here's that function for you:
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;
}What I'm trying to do is add an offset to the part where it says "mat->mul(nmat,data.eyeOffset);" I'm a lot more familiar with the Torque script vector functions ( VectorAdd(%pos,%vec); etc.) that I am with matrices and C++ code.
So all in all, can somebody give me the equivalent of
// ( torque script :] ) %offsetX = FormulaThatIHaveNotWrittenOutYet; %offsetZ = AnotherFormulaThatIHaveNotWrittenOutYet; %determinedOffset = %offsetX SPC "0" SPC %offsetZ; %eyeOffset = %data.eyeOffset; %newOffset = VectorAdd(%determinedOffset,%eyeOffset);
but in C++ and matrix form? Hope I'm being clear to you all, help is very much appreciated!
Thanks,
Bryce
#2
If you've included (most) of the "more realistic first person resource" than you'll already have a first-person gun using eyeoffset that moves somewhat with the player's animations.
If you can find the code that makes the player animate when they rotate (I remember someone made this aeons ago, so that when you turn on the spot the side animation played), then you'd have an fps weapon using eyeoffset that animated when you turn/rotate.
03/09/2010 (7:07 am)
Not entirely related but ...If you've included (most) of the "more realistic first person resource" than you'll already have a first-person gun using eyeoffset that moves somewhat with the player's animations.
If you can find the code that makes the player animate when they rotate (I remember someone made this aeons ago, so that when you turn on the spot the side animation played), then you'd have an fps weapon using eyeoffset that animated when you turn/rotate.
#3
Edit:
What Steve is refering to (an animation when turning on the spot) probably wouldn't work because the "sway" wouldn't happen if you were moving forward, back, etc, and turning. You'd have to utilize a change in the value of mRot to decide when to play the "weaponSway" animation. Ex:
03/09/2010 (1:28 pm)
Sway?! what exactly do you mean? Do you want the weapon to sway as if it were rubber (i assume not) or continue moving a bit after the player stops turning and lag behind when the player starts turning? If so, try making the "sway" action(s) of the weapon animation(s) and add sequence(s) to the shapeImage. These animations/sequences could be triggered whenever the player adjusts their yaw or pitch (like the fire animation is triggered. $mvTrigger0)and the only changes you'd need to make to the engine would be the addition of a trigger or two (though I don't think it would be needed as there's already $mvTrigger0 - $mvTrigger5 or 6. $mvTrigger2 is jump and $mvTrigger0 is probably you're fire but the rest aren't being used) and a check for whatever triggers you're using.Edit:
What Steve is refering to (an animation when turning on the spot) probably wouldn't work because the "sway" wouldn't happen if you were moving forward, back, etc, and turning. You'd have to utilize a change in the value of mRot to decide when to play the "weaponSway" animation. Ex:
//WARNING: EXTREME PSUEDO-CODE TO FOLLOW...
if(mRot.z != mRot_lastVal.z)
{
if(mRot.z > mRot_lastVal.z)
playLeftSwayAnim;
else
playRightSwayAnim;
}...or something like that
#4
For TGE 1.4.2:
In player.cc, after
add
In Player::Player(), under mContactTimer = 0;, add
In player.h, after S32 mImpactSound;, add
Voila!
03/09/2010 (2:33 pm)
Turns out that I was working in the wrong function. Player::renderMountedImage was where I needed to be, because that's where the muzzle is oriented forward. But I got it!For TGE 1.4.2:
In player.cc, after
// See if we are pushed into a wall...
Point3F start, end;
smat.getColumn(3, &start);
nmat.getColumn(3, &end);
Point3F displace = (start - end) * mWeaponBackFraction;
glTranslatef(displace.x, displace.y, displace.z);
}
dglMultMatrix(&mat);add
if (con->isFirstPerson() && !con->isAIControlled())
{
F32 Yaw;
F32 Pitch;
Yaw = Con::getFloatVariable("$mvYaw");
Pitch = Con::getFloatVariable("$mvPitch");
if (Yaw > 0 && Yaw != 0 && Yaw < 0.25)
mSwayX += 0.0015;
if (Yaw < 0 && Yaw != 0 && Yaw > 0.25)
mSwayX -= 0.0015;
// Yaw sway
if (Yaw == 0)
{
if (mSwayX < 0)
mSwayX += 0.00035;
if (mSwayX > 0)
mSwayX -= 0.00035;
}
// Now do pitch sway
if (Pitch > 0 && Pitch != 0 && Pitch < 0.25)
mSwayZ += 0.0010;
if (Pitch < 0 && Pitch != 0 && Pitch < 0.25)
mSwayZ -= 0.0010;
if (Pitch == 0)
{
if (mSwayZ < 0)
mSwayZ += 0.00035;
if (mSwayZ > 0)
mSwayZ -= 0.00035;
}
glTranslatef(mSwayX,0,mSwayZ);
}
else
{
mSwayX = 0;
mSwayZ = 0;
}In Player::Player(), under mContactTimer = 0;, add
mSwayX = 0; mSwayZ = 0;
In player.h, after S32 mImpactSound;, add
F32 mSwayX; F32 mSwayZ;
Voila!
#5
03/09/2010 (3:26 pm)
Problem with the above, however. The position updates frame-by-frame from what I can tell, so irregularities in framerate seem to be causing problems. I tried moving the sway code that determines the offset into processTick for a smoother effect, but it doesn't seem to be working. Suggestions?
#6
03/10/2010 (5:52 am)
try putting it in interpolateTick. This is called in between every tick i.e. processTick is called 30 times/sec interpolateTick is called 60 times/sec. If that doesn't work, try breaking the sway code out into a separate void and calling it multiple times from where ever you deem appropriate.
#7
For the record, I agree with Steve's suggestion - but that does mean developing a whole new animation model for Player, which is taking up a lot of my time :P.
03/10/2010 (12:51 pm)
Quote:This is called in between every tick i.e. processTick is called 30 times/sec interpolateTick is called 60 times/sec.From what I understand, interpolateTick may be called any number of times between two ticks, with different values passed into it representing the progress from one tick to another. I think the idea is for it to be called each frame, so that objects interpolate smoothly between ticks even when the framerate is very high.
Quote:I tried moving the sway code that determines the offset into processTick for a smoother effect, but it doesn't seem to be working. Suggestions?Debug! Are you putting the code in a serverside-only section of processTick? Step through renderMountedImage and see if the values are being used right.
For the record, I agree with Steve's suggestion - but that does mean developing a whole new animation model for Player, which is taking up a lot of my time :P.
#8
03/10/2010 (2:49 pm)
I didn't know there was a server side section to processTick, no wonder! That ended up being the best place to put it, interpolateTick produced choppy movement. The effect works and looks good, thank you all for your help!
#10
I made some changes here and there to make it work smoother. I might make this a resource eventually.
03/10/2010 (4:53 pm)
But of course!I made some changes here and there to make it work smoother. I might make this a resource eventually.
#11
03/11/2010 (4:25 am)
two crosshairs? have you considered making the sight on the weapon and the crosshair into one (make the weapons sight line up with the players eye LOS and eliminate the 2d crosshair) so the player doesn't have to see both? might mean a redesign of the player mesh but well worth it. Glad to see it worked out for you!
#12
03/11/2010 (5:14 am)
What do you mean? There's the regular crosshair with the four dots, which is for firing from the hip (up close, reflex shooting), and the whatever comes up when you aim down the sights of the gun (red dot, scope, etc). That's deliberate, because I have aiming down the sights directly tied to the bullet spread to discourage spraying bullets from the hip.
#13
03/12/2010 (4:30 am)
in third person, you have the 4 dot crosshair as well as the sight on the weapon (the circular part sticking up on the weapon mesh at the muzzle tip). are both needed while in third person or could you get away with one or the other? in FP the 4 dot crosshair isn't there. is there a way to do away with it in third person? may make for a cleaner play gui.
#14
Good work Bryce!
03/13/2010 (3:43 am)
Resourcing this would be very appreciated, this is some very cool stuff.Good work Bryce!
#15
04/05/2010 (11:38 am)
Quote:I might make this a resource eventually.Will this happen? I'm also tired of the statue like weapon holding.
Torque Owner Daniel Buckmaster
T3D Steering Committee
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); //Define an offset vector, in this case 1,1,1 Point3F offset(1,1,1); //Transform that into image space //NOTE: I'M NOT SURE ABOUT THIS LINE! //I could be using the wrong function, but give it a go :P mat->mulV(offset,&offset); //Add the offset to the render position mat->setPosition(mat->getPosition() + offset); } else { getMountTransform(image.dataBlock->mountPoint,&nmat); mat->mul(nmat,data.mountTransform); //Do a similar thing here } } else *mat = mObjToWorld; }That's completely untested and so on, but I think it's kind of what you're looking for.