CalcDrawOffset() Question

A refuge for those migrating from the fallen DXEditing.com and a place for general discussion relating to Deus Ex editing (coding, mapping, etc).
Post Reply
Cybernetic pig
Illuminati
Posts: 2284
Joined: Thu Mar 08, 2012 3:21 am

CalcDrawOffset() Question

Post by Cybernetic pig »

How to make weapon render for the player update smoothly over time? Currently the weapon render follows the player precisely/stiffly. Take a look at any modern first person game you'll notice weapon location interpolates to the desired over time when the player looks or moves.

To understand exactly what I'm talking about, view this video @ 2:53 - 2:55 and watch the weapon as the player looks around the room.
In old games the weapon render follows the player location and view rotation (+ offset) every frame precisely. In modern games the weapon location & rotation updates a few frames behind which makes the weapon handling and general movement feel more realistic.

The Location code (DeusExWeapon.uc) that would require modification:

Code: Select all

simulated function vector CalcDrawOffset()
{
	local vector		DrawOffset, WeaponBob;
	local ScriptedPawn	SPOwner;
	local Pawn			PawnOwner;
	local vector unX,unY,unZ;

	SPOwner = ScriptedPawn(Owner);
	if (SPOwner != None)
	{
		DrawOffset = ((0.9/SPOwner.FOVAngle * PlayerViewOffset) >> SPOwner.ViewRotation);
		DrawOffset += (SPOwner.BaseEyeHeight * vect(0,0,1));
	}
	else
	{
		// copied from Engine.Inventory to not be FOVAngle dependent
		PawnOwner = Pawn(Owner);
		DrawOffset = ((0.9/PawnOwner.Default.FOVAngle * PlayerViewOffset) >> PawnOwner.ViewRotation);
		DrawOffset += (PawnOwner.EyeHeight * vect(0,0,1));
		WeaponBob = BobDamping * PawnOwner.WalkBob;
		WeaponBob.Z = (0.45 + 0.55 * BobDamping) * PawnOwner.WalkBob.Z;
		DrawOffset += WeaponBob;
	}
And rotation update in RenderOverlays():

Code: Select all

NewRot = Pawn(Owner).ViewRotation;
It should be simple, but I can't figure out what would be needed.
Hanfling
MJ12
Posts: 406
Joined: Sun Oct 04, 2009 6:54 pm

Re: CalcDrawOffset() Question

Post by Hanfling »

I would basically start with saving the last time CalcDrawOffset() was called and the last WeaponRotation.

Code: Select all

var float LastWeaponRotationUpdateTime;
var Rotator LastWeaponRotation;

simulated function vector CalcDrawOffset()
{
  local float DeltaTime;
  local Rotator DeltaRot;
  local int MaxDeltaAngle;

  // Update time.
  DeltaTime = Level.TimeSeconds - LastWeaponRotationUpdateTime;
  LastWeaponRotationUpdateTime = Level.TimeSeconds;

  // Calculate (signed) minimum deltas between ViewRotation and LastWeaponRotation. Just a bit special cases and modula. Keep in mind UnrealScript has no mathematic
  // modulo, but that shitty programmer one instead.
  // DeltaRot = [...]

  Now calculate how much unreal degree change of the weapon is allowed.
  MaxDeltaAngle = DeltaTime * SOME_CONSTANT;

  // Clamp DeltaRot components to MaxDeltaAngle (keep the sign!)
  // [...]
  
  // Add the clamped DeltaRot components to LastWeaponRotation.
  // [...]

  // Render using LastWeaponRotation.
  // [..]
}
One could make a bit more complicated solution, not clamping the individual components but limiting the angle around the axis the change was performed, but this is a bit trickier to set up. But that approach should be sufficient anyway.

Wolfenstein was nice to play. Still need to find all stuff in this game.
I demand my DXE User ID back. Launcher for DeusEx, Rune, Nerf, Unreal & Botpack. HX on Mod DB. Revision on Steam.
Cybernetic pig
Illuminati
Posts: 2284
Joined: Thu Mar 08, 2012 3:21 am

Re: CalcDrawOffset() Question

Post by Cybernetic pig »

Thanks again.

Yeah Wolfenstein was the only decent singleplayer pure FPS of its generation in my opinion. It is upsetting that it doesn't have a pistol or a shotgun though.
Cybernetic pig
Illuminati
Posts: 2284
Joined: Thu Mar 08, 2012 3:21 am

Re: CalcDrawOffset() Question

Post by Cybernetic pig »

Another thing that could do with updating is the headbob. Deus Ex's is shit. A good one to emulate would be Thief: the Dark Projects, as it matches footsteps accurately and just feels better.

We can override headbob in dxplayer:

Code: Select all

/////////////////////////////////////////////////////////
//CheckBob() //Cybernetic pig: overrides code in playerPawn. Uncomment and modify headbob.
/////////////////////////////////////////////////////////
///

/*function CheckBob(float DeltaTime, float Speed2D, vector Y)
{
	local float OldBobTime;

    if (!bModdedHeadBob) //Cybernetic pig: If we want to make new headbob optional.
    {
    Super.CheckBob(DeltaTime, Speed2D, Y);
    return;
    } //Cybernetic pig: the below can be modified/re-done to achieve better head bobbing.
	OldBobTime = BobTime;
	if ( Speed2D < 10 )
		BobTime += 0.2 * DeltaTime;
	else
		BobTime += DeltaTime * (0.5 + 0.8 * Speed2D/GroundSpeed);   //0.5 + 0.8
	WalkBob = Y * 0.65 * Bob * Speed2D * sin(6 * BobTime);
	AppliedBob = AppliedBob * (1 - FMin(1, 2 * deltatime -70));
	if ( LandBob > 0.01 )
	{
		AppliedBob += FMin(1, 2 * deltatime) * LandBob;
		LandBob *= (1 - 8*Deltatime);
	}
	if ( Speed2D < 160 )
		WalkBob.Z = 0; // AppliedBob + Bob * 30 * sin(12 * BobTime);   // take out the "breathe" effect - DEUS_EX CNN
	else
		WalkBob.Z = AppliedBob/9 + Bob * (Speed2D/4) * cos(12 * BobTime);

} */

Post Reply