Possible Code For Weapon Bob
Originally written by Ishtvan on http://forums.thedarkmod.com/topic/3395
I posted this on D3World in response to someone's question, figured I'd record it here in case we ever decide to add random bob to our bow or other projectile weapons (e.g. pick up a guard's crossbow and fire it with a lot of wobble because you're not trained in crossbow). We had thought about random weapon bob earlier, but decided not to worry about it, but it might turn out to be pretty easy to code in the event that we change our mind. This code is supposed to make the projectile fire exactly where the weapon is pointing. So you could add random bobbing of the weapon viewmodel and get actual aiming errors from that, but it would be realistic "what you see is what you get" behavior instead of random conefire like in some games.
From D3World Post:
It seems possible, though maybe a bit difficult. The bullet gets launched from the barrel in: idWeapon::Event_LaunchProjectiles . You might want to look at that to see how they are calculating the place it's launched from and the direction.
It calls this to launch the projectile in the end:
proj->Launch( muzzle_pos, dir, pushVelocity, fuseOffset, launchPower, dmgPower );
I think the two things you want to worry about are muzzle_pos (position of muzzle) and dir (direction of launch). Don't worry about pushVelocity, that just applies the velocity the player is already moving at to the projectile. For bullets this doesn't have much effect.
It looks like there is already an option to launch from the barrel of the weapon viewmodel, a spawnarg "launchFromBarrel" in the weapon .def file. I think viewmodel means the 1st person weapon model, but not sure.
Set "launchFromBarrel" to "1" in the weapon .def. Now you have to address the direction it's fired. Right now it applies some random spread but bases it on the player view model. This is how it calculates the vector dir that it later feeds into the launch function:
float spreadRad = DEG2RAD( spread ); ang = idMath::Sin( spreadRad * gameLocal.random.RandomFloat() ); spin = (float)DEG2RAD( 360.0f ) * gameLocal.random.RandomFloat(); dir = playerViewAxis[ 0 ] + playerViewAxis[ 2 ] * ( ang * idMath::Sin( spin ) ) - playerViewAxis[ 1 ] * ( ang * idMath::Cos( spin ) ); dir.Normalize();
You want it to have a direction defined by how the muzzle is pointed at that moment in time though, so you'll have to change this.
Earlier in Event_LaunchProjectiles the code wrote the axis of the muzzle of the weapon and stored it:
GetGlobalJointTransform( true, barrelJointView, muzzleOrigin, muzzleAxis ); /* idWeapon::GetGlobalJointTransform This returns the offset and axis of a weapon bone in world space, suitable for attaching models or lights */
So the axis matrix of the weapon relative to world space is stored in muzzleAxis. I'm not sure, but making the projectile launch down the barrel might be as simple as replacing the earlier line to calculate dir with this:
dir = muzzleAxis[ 0 ]; dir.Normalize();
If that works, it accomplishes half of what you wanted: Making the projectile launch down the barrel of the weapon, not out of the center of the screen. Again, I think the method above should apply the bob of the viewmodel of the weapon to the firing direction, so you shouldn't have to worry about adding bob to the 3rd person model, but I'm not positive.
The second half of what you want is adding random bob to the weapon. That I don't know how to do offhand, but you can probably trace it in weapon.cpp from that "bob" key that you found. It looks like it's in idWeapon::PresentWeapon. If you want to make it realistic you probably want to increase the bob as you move faster, less weapon bob when in a crouch, stuff like that.