Jittering quakestyle movement when circle strafing.

Started by
18 comments, last by Erik Labree 23 years, 9 months ago
Hi there, I've got a problem with quake/unreal-like movement in my engine. Although the engine is running at 60+ FPS. camera movement when 'circle strafing' jitters too much to my liking. Forward, backward and left/right strafing is smooth. In Quake/Unreal or most other 3d games it is much smoother even at lower framerates. How do they do it. Do they use somekind of filtering or interpolation between frames??? Here is the code that updates the camera object (its not optimized so don't bother about that). The messages it receives come from a DirectInput (i use immidiate mode. i.o.w i get state data from DirectInput not buffered data) wrapper. The variable sys_frameTime holds the time elapsed since the last frame. switch(event->eventType) { case INP_EV_DRAG: if (event->key == STRAFE_LEFT_KEY) { pcamera->worldposition.SetX(pcamera->worldposition.X() + (float)sin((pcamera->heading - 90) * deg2rad) * (STRAFE_VELOCITY * sys_frameTime)); pcamera->worldposition.SetZ(pcamera->worldposition.Z() + (float)cos((pcamera->heading - 90) * deg2rad) * (STRAFE_VELOCITY * sys_frameTime)); } else if (event->key == STRAFE_RIGHT_KEY) { pcamera->worldposition.SetX(pcamera->worldposition.X() + (float)sin((pcamera->heading + 90) * deg2rad) * (STRAFE_VELOCITY * sys_frameTime)); pcamera->worldposition.SetZ(pcamera->worldposition.Z() + (float)cos((pcamera->heading + 90) * deg2rad) * (STRAFE_VELOCITY * sys_frameTime)); } else if (event->key == MOVE_BACKWARD_KEY) { pcamera->worldposition.SetX(pcamera->worldposition.X() + (float)sin(pcamera->heading * deg2rad) * (BACKWARD_VELOCITY * sys_frameTime)); pcamera->worldposition.SetZ(pcamera->worldposition.Z() + (float)cos(pcamera->heading * deg2rad) * (BACKWARD_VELOCITY * sys_frameTime)); } else if (event->key == MOVE_FORWARD_KEY) { pcamera->worldposition.SetX(pcamera->worldposition.X() - (float)sin(pcamera->heading * deg2rad) * (FORWARD_VELOCITY * sys_frameTime)); pcamera->worldposition.SetZ(pcamera->worldposition.Z() - (float)cos(pcamera->heading * deg2rad) * (FORWARD_VELOCITY * sys_frameTime)); } break; case INP_EV_MOUSEMOVE: { pcamera->leftright = pcamera->heading - (event->mouseDeltaX / MOUSE_COMPENSATION); pcamera->updown = pcamera->updown + (event->mouseDeltaY / MOUSE_COMPENSATION); } break; } the main frame function looks like this. void SYS_Frame() { // Update time data updateFrameTimes(); // Take input from user(s). INP_Frame(); // Determine visibilty of objects pworld->determineVisibility(sys_frameId); // Draw the scene. REN_drawFrame(pworld, pcamera, sys_frameId); // Update frame id sys_frameId++; } any suggestion are appreciated. Thanks Erik Labree, the Netherlands Edited by - Erik Labree on 6/25/00 8:16:32 AM
Advertisement
Make heading more precise.
Don''t use degrees. Divide the circle to 1000, or more
"degrees". Then heading will be in range [0,999] and
sin( heading * PI / 500 ) will give you requested sine.




Interesting. I''ll look over it in the weekend.

Cheers Erik.
Erik, if pcamera->heading is a FLOAT, then multiplying it by some constant like 1000 won''t increase precision.

You mentioned interpolating/filtering the mouse input, which Half-life optionally does (it averages mouse input over the last 2 frames). I was wondering about why they did that, and here''s what I''m guessing: At high frame-rates, the mouse delta is going to be really small, so small that maybe it starts pushing the limit of its mechanical precision (...Remember that high-rez ''gaming'' mouse released recently?). So I would try averaging the mouse input over the last coupla'' frames.
The jittering only happens when you''re sidestepping and turning at the same time? Maybe it comes from recalculating the view once for the strafe, and then calculating a new angle for the rotation and calculating the view, which could make the display look like step-turn-step-turn-step-turn really fast, instead of step&turn,step&turn,step&turn. Does each frame take into account both the movement and the rotation since the last frame?

Hmm. From looking at the code, it does... What triggers a new frame? Does it just draw as fast as it can?

Yo, try taking the else''s off your if''s and tell me what happeneds(just a thought).
Thanks everyone for the replies.

Anonymous, Tried it but it didn''t work out.

Eric, I had already tried that and it didn''t solve the problems. I even tried to interpolate over the last 10 frames wich of course gave very bad respons for mousemovments.

Chiroptera, Yes right that''s what you call circle strafing. You take a step to the left or right and turn you body at the same time and that''s where the problem is.
Each frame does take into account both the movement and the rotation since the last frame accoording to the time elapsed since the previous frame.
When a frame is finished the program starts with the next one. (See SYS_Frame())

Esap1, The elses are there to make sure when an if evaluates to TRUE it won''t keep on evaluating the remaining if''s wich of course would be redundant.

...another thing, my framerate was limited to 60 because of the refreshrate of my hardware. So the program was performing better then what the hardware could display, always hitting 60 FPS. So i increased the resolution of the screen and now the program runs at around 35 FPS. This does seem work a bit better but still not as smooth as Q3, HL or UT. It''s more fluent but sometimes it jitters. It''s just looks like the amount of rotation and movement must be within a certain ratio for a couple of frames to make it smooth.

Gonna play some UT deathmatch with a piece of paper and a pencil and do some drawing. Maybe i''ll see the light...

Frag''em

Erik Labree




quote: Original post by Esap1

Yo, try taking the else's off your if's and tell me what happeneds(just a thought).


I believe this is the problem - I've made this mistake too...
If you're circle strifing you gotta do two of those each frame, otherwise it'll jerk between the two



Edited by - Magmai Kai Holmlor on June 25, 2000 4:50:12 PM
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
Magmai Kai Holmlor,

I did try it and it didn''t solve the problem.
Every possible input event goes trough this piece of code each frame. For instance, when a player is circle strafing, pressing the ''a'' key and moving the mouse along the X axis these input events will get handled by each frame(with or without elses). All key and mouse events are passed trough this code and when something evaluates to TRUE it gets handled.
It''s based on an input system from an article by Chris Hargrove from his excellent Code on the Cob column.

http://www.loonygames.com/content/1.5/cotc/

Thanks Erik.
Hello there,

Check out the thread named ''point of ''else if'' ?''

Greetz Erik

This topic is closed to new replies.

Advertisement