Quake3World.com Forums
     Programming Discussion
        Creating 6DoF player movement


Post new topicReply to topic
Login | Profile | | FAQ | Search | IRC




Print view Previous topic | Next topic 
Topic Starter Topic: Creating 6DoF player movement

Veteran
Veteran
Joined: 17 May 2011
Posts: 159
PostPosted: 12-23-2012 03:26 AM           Profile Send private message  E-mail  Edit post Reply with quote


Hello !

I have created maps for Quake 3 in the past (look for MJDM2, DmeatSP01 and DmeatSP02 on Lvl) and now, after finishing my studies in graphic design / video game art, I'm really interrested in making my own games.

I allready did some programming in the past, in Flash and PHP, and I've studied some C++ by myself this summer. I'd like to use the Quake 3 engine in my projects, because it's quite solid technology, it's open source, it's free, and if someday I want to sell something I've done with it, I guess I can !

So yesterday, I've set up a "workspace", using the tutorial on the ioQuake3 wiki (I plan on using ioQ3). Good news, it compiled without any errors ! I even did a few first modifications, the basic rocket speed modification and deleting the rotation and bobbing of the portal camera.

My final objective in this self challenge to learn how to make different stuff with the engine is to make a Luftrauser clone with 3D gameplay. For that, I made a list of the first big challenges :
- 6 DoF player movement
- Looping environment
- Enemy planes !

I'll focus on the first point for the moment. I'll update the title later if needed :).

Here is a snapshot of the behaviour I'd like to achieve : https://www.youtube.com/watch?v=vWb9_5N91OE

Basicly, the trick is to have the X, Y and Z rotations for the player view, not only Y and Z. Moving the mouse up and down would make the player camera loog up and down FROM THE CURRENT ORIENTATION, and same with the left / right movement.

So, I have located some interresting functions in cl_input.c :
- CL_AdjustAngles // This functions seems to actually modify the values of the view angles with the input commands (&in_left, &in_right, &in_lookup, &in_lookdown)
- CL_MouseEvent // Seems to store the input coming from the mouse
- CL_MouseMove // At the end of the function, the YAW and the PITCH get modified
- CL_CreateCmd // Lines 594 to 599 at first looked like the PITCH limitations, but after thinking, I think it's just a security to prevent the rotation axis to overlay ... ?

Concerning the Client - Server relation, I think that data should be used server side, to manage, in the future, the orentation of the collision boxes.

But I'm afraid this won't be the only things to modify, and I might have to create new ones from scratch.

Has anyone worked on that subject ? Am I looking at the right things ? Will I have to re-write the definition of a player game entity ?

I have dozens of other questions in my mind about the rest of my "little" project, but I'll add them as I make some progress :)

Thanks for reading !



_________________
My blog - My portfolio
---------------------
MJDM2 - DmeatSP01 - DmeatSP02


Top
                 

Veteran
Veteran
Joined: 17 May 2011
Posts: 159
PostPosted: 12-25-2012 02:40 PM           Profile Send private message  E-mail  Edit post Reply with quote


Hey ! Sorry for double posting, but this is kind of a update on my progress :)

So, I found out that th function in which I was interrested is CL_MouseMove. After testing a few things, I understood that I could access the YAW, PICH and ROLL of the Camera. Yay !

All the beginning if the function modulates the input we get from the mouse (smoothing, acceleration, sensitivity), and the 6 last lines are the ones that I'm interrested in, or more simply :
Code:
cl.viewangles[YAW] -= m_yaw->value * mx;
cl.viewangles[PITCH] += m_pitch->value * my;


Now, the next challenge more math-related. In my project, the mouse movement still modifies the YAW and PICH, but strictly from the camera point of view (like in the old Descent games or Forsaken, see the video in the previous post).

I looked at the Quaternion business, but for the moment, I still don't understand how to apply it to my problem :)



_________________
My blog - My portfolio
---------------------
MJDM2 - DmeatSP01 - DmeatSP02


Top
                 

Señor Shambler
Señor Shambler
Joined: 07 Mar 2006
Posts: 849
PostPosted: 12-27-2012 06:29 AM           Profile Send private message  E-mail  Edit post Reply with quote


It looks to me like what is going on in the Forsaken video is the same movement as the spectator in Q3, only with a slight rotation when you start to strafe. I would search through the code to see how the spectator's view is being handled. As you note, you can access YAW PITCH and ROLL so you should be looking at just adding a value to a variable and not monkeying around with any difficult math. Another thing to look into is to see how portal views are handled, since their roll angles (I'm pretty sure it's roll) oscillate at a certain rate by default (for example, load up q3dm0 and look into the teleporter). Hope that helps!




Top
                 

Cool #9
Cool #9
Joined: 01 Dec 2000
Posts: 44138
PostPosted: 12-27-2012 10:25 AM           Profile   Send private message  E-mail  Edit post Reply with quote


Spectator's view angles are locked in the same way as normal players. What OP wants to achieve is to remove these locks and make it possible for the player to fly up-side-down as well.




Top
                 

I'm the dude!
I'm the dude!
Joined: 04 Feb 2002
Posts: 12498
PostPosted: 12-27-2012 10:58 AM           Profile Send private message  E-mail  Edit post Reply with quote


Can't wait for finally being able to do a backflip. :owned:



_________________
GtkRadiant | Q3Map2 | Shader Manual


Top
                 

Veteran
Veteran
Joined: 17 May 2011
Posts: 159
PostPosted: 12-27-2012 04:01 PM           Profile Send private message  E-mail  Edit post Reply with quote


Thanks a lot for your replies !

Yes, the main result of 6 degrees of freedom movement is the ability to get yourself upside down.
I forced some test values to the ROLL of the viewAngles, and it is definitely possible to see upside down in the quuake 3 engine.

So, for the past days I looked at some Quaternion math, and I think that science is definitely useful to get this problem solved - and as I was looking at some source codes from Forsaken (a 1998 Descent-like game, now free, check http://fly.thruhere.net/), it seems that their camera movement is driven by Quaternion.

Basicly, a quaternion is an array of 4 floats. It is possible to convert it from and to EULER angles (Roll, Pitch and Yaw values, that Quake 3 wants to set up the camera angles).
I even have a vague idea of what I have to accomplish :
1. get the current view angles into a quaternion
2. generate a quaternion from the mouse input (I think it will be possible without converting from Euler angles)
3. ???? (apply quaternion from 2. to 1. ... and I have no idea how to do that for the moment !)
4. Convert the quaternion to Euler angles and apply to cl.viewAngles.

If you are interrested, check these two pages :
http://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation - (I try to understand from the french page, so I don't know if the english one is easy or not)
http://www.euclideanspace.com/maths/geometry/rotations/conversions/eulerToQuaternion/index.htm - At the bottom of the page, there is a little tool that takes angles in degrees and puts it into a quaternion, this is currently helps me get it more clearly :)

Thanks for reading, and when I'll have something interresting to show, I'll post it here !



_________________
My blog - My portfolio
---------------------
MJDM2 - DmeatSP01 - DmeatSP02


Top
                 

Veteran
Veteran
Joined: 17 May 2011
Posts: 159
PostPosted: 01-13-2013 10:52 AM           Profile Send private message  E-mail  Edit post Reply with quote


http://youtu.be/WpHCQyQQ9jI

here's my first attempt. As you can see, it's quite buggy =D

I added some quaternion related functions in q_math.c, the main "routine" is to get the curent cl.viewangles, make a quaternion (vec_4t) out of them, do the same with a vec3_t containing the mouse input for X and Y, Then Multiply the two quaternions and put the result into Euler angles (Yaw Pitch Roll) and put that into cl.viewangles.

But as you can notice, it's very glitchy for the moment, and the mouse movement doesn't produce the wanted result. I'll continue thinking about it, but as usual, if anybody has an idea about how to do, I'll thank him a lot !

I'd like to say thank you to the source code of ProjectX WebGL (https://github.com/chino/pxwgl-net, related to the Forsaken game, http://fly.thruhere.net/) and This page, that has all the math. I actually took the multiply function from the javascript.



_________________
My blog - My portfolio
---------------------
MJDM2 - DmeatSP01 - DmeatSP02


Top
                 

Veteran
Veteran
Joined: 17 May 2011
Posts: 159
PostPosted: 01-19-2013 08:17 AM           Profile Send private message  E-mail  Edit post Reply with quote


http://youtu.be/9YaobvumM_o

Here's a second attempt, using only buit in Quake 3 math function (RotatePointAroundAxis stuff). In theory, it should work well, but as you can see this is just not it.

I created this video 4 days ago, and since then, I haven't made any progress. I tried back the quaternions and tried having something made out the my problematic QuatMultiply function, but no answer.

What I would try to do now is to make it work with the built in functions using axis rotations.

Since we have a "AngleVectors" function that gives us 3 vectors for Forward, Up and Right, I just have to rotate first tne Forward and Right vectors of "MouseX" degrees around the Up vector using the "RotatePointAroundVector" function to have the yaw modification, and then do the same with forward and Up using the right vector. That routine actually describes quite well the 6 degrees of freedom movement I'm trying to achieve.

But I've encountered a problem : I need for this to have my 3 vectors set up at the moment where the player spawns (at the beginning of the game, or going out of teleporter or respawning), which I plan to do in the TeleportPlayer function (g_misc.c) with an AngleVectors function, that takes the viewangles variable from the playerState. Then, the 3 axis are modified in the MouseMove function.

And that's when I understood that the viewangles existed not only on the client side (as defined in client.h, in the structure "clientActive_t"), but in the PlayerState structure as well.

And so my question is, if anybody knows about that science, where is the link between cl.viewangles and ps.viewangles ? how does it work ? If I want to add a new variable in this structure, can I add it just after the viewangles or at the end ?

On the other hand, I've commented two checks for the Yaw Limitation, one in cl_input.c in CreateCmd, the other one in bg_pmove.c, PM_UpdateViewAngles function. so now, on normal player movement, a big movement of the mouse to the down "teleports" the view to the top, and vice versa.



_________________
My blog - My portfolio
---------------------
MJDM2 - DmeatSP01 - DmeatSP02


Top
                 

Veteran
Veteran
Joined: 17 May 2011
Posts: 159
PostPosted: 01-28-2013 07:11 AM           Profile Send private message  E-mail  Edit post Reply with quote


Hey guys !

So, I finally made something where I'm able to "backflip" : http://www.youtube.com/watch?v=s_GXkdakbss

This actually helps me a lot thinking about the logic of my 6 degree of freedom movement. But some glitches / bugs keep making my mind sad. Respawning in spectator mode seems to screw up my 360° Pitch rotations, and before that, when I pass from looking in front to backwards, by looking up or down, there is a small gap. For the first problem, i'm quite sure it comes from the difference between the playerstate viewangles and the client's viewangles. For the second, I think there's an offset between the center of the camera and the center of rotation.

If some people still read my messages, does anyone have an idea about someone I could ask about my project ? I'm not trying to find a coder, but more a professor that could answer my questions about idTech 3 :)



_________________
My blog - My portfolio
---------------------
MJDM2 - DmeatSP01 - DmeatSP02


Top
                 

Cool #9
Cool #9
Joined: 01 Dec 2000
Posts: 44138
PostPosted: 01-28-2013 08:06 AM           Profile   Send private message  E-mail  Edit post Reply with quote


For what it's worth, I do keep following your posts with interests. I'm just afraid I'm not of much help to you.




Top
                 

i like to program
i like to program
Joined: 16 Dec 1999
Posts: 6899
PostPosted: 01-29-2013 10:28 PM           Profile Send private message  E-mail  Edit post Reply with quote


Welcome to gimbal lock :) http://en.wikipedia.org/wiki/Gimbal_lock

Unfortunately, you're going to have to solve this with quaternions to get the effect you want.

As for the link between cl.viewangles and ps.viewangles - you'll want to be modifying cl.viewangles. cl.viewangles are turned into a user command, the user command is turned into ps.viewangles in the cgame prediction code, and then ps.viewangles are turned into cg.refdefViewAngles which are what's passed to the renderer.




Top
                 

Veteran
Veteran
Joined: 17 May 2011
Posts: 159
PostPosted: 01-31-2013 02:14 AM           Profile Send private message  E-mail  Edit post Reply with quote


Yay ! Thanks for replying !

Thanks for ewplaining me the way the viewangles data go, I see more clearly now :) but I have a question : when a player respawns or spawns out of a teleport, do the client's viewangles (cl.viewangles) gets reset to the new angles ? For the moment, I think they're not, or that there is something fishy about that.

I've considered the guimbal lock problem since the beginning, and my first attempt also used quaternions. But I'm having trouble with the math, especially the quaternion multiply function, that turns my movement into a very glitchy soup, even if the same math seems to work in my c++ test program.



_________________
My blog - My portfolio
---------------------
MJDM2 - DmeatSP01 - DmeatSP02


Top
                 

Cool #9
Cool #9
Joined: 01 Dec 2000
Posts: 44138
PostPosted: 01-31-2013 03:15 AM           Profile   Send private message  E-mail  Edit post Reply with quote


Not sure if relevant, but about your teleporter question: a trigger_teleport entity targets a position entity to where the teleporter will teleport the player (could be a target_position, but a misc_teleporter_dest is more commonly used).

If you look at the TeleportPlayer function in g_misc.c, you'll see that an origin and angles are passed to it, which are then applied to the player. The origin and angles are defined by the misc_teleporter_dest entity.

In-game, if you exit a teleporter, your Z-axis rotation (yaw) is always matching the angle that the misc_teleporter_dest has defined. I guess the same is true for pitch and roll, but those will probably default to 0 to center your view (which is the common in-game behavior observed when moving through a teleporter)

So to me it sounds like your observation of players moving to a teleporter not having their viewangles reset is incorrect.

I guess the same is true for spawning at a spawnpoint because spawnpoints allow you to define an angle as well, which determines in which direction the player will look. Again, the pitch and roll values default to 0.




Top
                 

Mentor
Mentor
Joined: 12 Mar 2005
Posts: 3958
PostPosted: 02-03-2013 03:17 PM           Profile Send private message  E-mail  Edit post Reply with quote


Quote:
But I'm having trouble with the math, especially the quaternion multiply function, that turns my movement into a very glitchy soup, even if the same math seems to work in my c++ test program.


Is it possible that what you're seeing is the result of accumulated rounding errors? Common practice is to round or truncate every n floating point operations to maintain consistency (if not accuracy).

The value of n is something you'll have to establish empirically but it should be small.




Top
                 

Veteran
Veteran
Joined: 17 May 2011
Posts: 159
PostPosted: 02-04-2013 01:23 PM           Profile Send private message  E-mail  Edit post Reply with quote


Thanks for your replies / feedback !

First, a video of the actual effect (don't deactivate the comments to understand the circumstances of the test) : http://www.youtube.com/watch?v=XKcSK5xH0zA
The funny thing is, only the MouseY input is taken into account ! The result would be interresting if this was a drunken man simulator I guess. for reference here is a bretty bad quality video I captured from Forsaken showing a similar rotation (based on looking 45° in yaw and having 45° roll, and doing a complete 360 with MouseY) : http://www.youtube.com/watch?v=kG8ZqGDMhiM.

First, to answer to Eraser, here is the comment I found before the cl.viewangles declaration in client.h :

Code:
   // the client maintains its own idea of view angles, which are
   // sent to the server each frame.  It is cleared to 0 upon entering each level.
   // the server sends a delta each frame which is added to the locally
   // tracked view angles to account for standing on rotating objects,
   // and teleport direction changes


If you want, I can code a little feedback line that shows the difference between the client side angles and the playerstate (server) angles, and I'll take screenshots.
But that question of updating the angles of the client will go back for the moment, since I can't even locally have my 6dof motion ...

Concerning the precision of the float type, I don't think it's really the problem for the moment, even if some days I'm really lost and I don't know where to look to make it work.

Today, two hypothesises :
- The problem comes from the conversion phases, since I found a different algorithm for Euler to Quaternion function that uses a very different logic compared to what I've allready done
- The problem comes from the rotation phase, where i'm not using the right axis or something. Or the built in function AngleVectors doesn't spit out the right vectors, which would be very scary.

Both have the same question on their head : What is the Euler rotation order in Quake 3 ? The angles variable are made like this :
(supposing X is right, Y is up and Z is forward, for camera-space coordinates))
angle[0] = angle[PITCH] = Rotation among X axis / looking up / down
angle[1] = angle[YAW] = Rotation among Y axis / looking left / right
angle[2] = angle[ROLL] = Rotation among Z axis / Rolling around
And that seems to tell that the order is Pitch>Yaw>Roll. Where can I get confirmation of this ? The order of rotation is important when converting from and to quaternions.

Thanks a lot for your support !



_________________
My blog - My portfolio
---------------------
MJDM2 - DmeatSP01 - DmeatSP02


Top
                 

Commander
Commander
Joined: 22 Jul 2011
Posts: 139
PostPosted: 02-11-2013 03:31 PM           Profile Send private message  E-mail  Edit post Reply with quote


The camera rotates around the right vector when the pitch angle changes, but when the yaw angle changes it rotates around the vertical axis of the world (Y?) instead of the up vector. I think if you change the way anglevectors gets the vectors you could do it, I mean doing a rotation around up and right vectors instead of Y axis and right vector.




Top
                 

Veteran
Veteran
Joined: 17 May 2011
Posts: 159
PostPosted: 03-01-2013 02:54 PM           Profile Send private message  E-mail  Edit post Reply with quote


Hello Quake3world ! I'm back !

nearly one month after the latest post, I come back with good news : I managed to succeed ! Please check the video : http://youtu.be/pwdo9AVaaCI

to answer to user Uglyfoot : Thanks for your reply, and yes, the AngleVectors is a very important function in my process. I had nailed the logic of 6 dof quite early, I just couldn't understand the behaviour that was happening.

What is actually very important is somehow how often you use AngleVectors : I was blocked all this week with a system that could work if you updated only rotation around one axis at a time, and with the view oriented by default (for example, if you are looking straight forward on spawn / map load, 360° rotations around the forward, up or right were possible and running smoothly !), but as soon as the view was oriented other than that, the cursor stars making strange and random loops on mouse move.

I checked my calculations to create quaternions from axis+angle to quaternion, and the results were the same as what Blender gave me when creating the same examples.

This afternoon, after some testing, I tried something : I update the axis not on every mouse move function call, but only once every 25 times.

Somehow, it works. Don't ask me why, I have no idea why that function gave some strange behaviour if summoned on every mouseMove call.

Right now the feeling is not very smooth, but this could be manageable with some quaternion interpolation (and thus give a feeling more close to Forsaken and Descent, where there is a little inertia going on).

I'm currently writing an article that goes into detail about what was difficult in programming that feature. I'll post it here when done ! Maybe I'll also prepare another article about what you have to do to understand and implement it in Quake 3.

Thanks for your support ! In the upcoming weeks, it might be really difficult to me to start programming my next planned feature, since I have a trip to japan planned, an after that maybe I'll directly move on to my first job (that's not about programming hehehe). I still hope to make progress and manage one day to make a complete little game with idTech 3 !



_________________
My blog - My portfolio
---------------------
MJDM2 - DmeatSP01 - DmeatSP02


Top
                 

Cool #9
Cool #9
Joined: 01 Dec 2000
Posts: 44138
PostPosted: 03-02-2013 10:22 AM           Profile   Send private message  E-mail  Edit post Reply with quote


Awesome. Good job. The video looks very cool, even if it's just flying through q3tourney3. It has some feeling of freedom that you don't have in normal Q3. Are you planning on making a Descent type of game out of it?




Top
                 

Theftbot
Theftbot
Joined: 07 Oct 2009
Posts: 483
PostPosted: 03-02-2013 03:08 PM           Profile Send private message  E-mail  Edit post Reply with quote


Very much win-Descent awesome




Top
                 

Commander
Commander
Joined: 22 Jul 2011
Posts: 139
PostPosted: 03-03-2013 02:49 PM           Profile Send private message  E-mail  Edit post Reply with quote


Congrats man. I've been these days trying to do this with quaternions but I gave up so I tried another way which works well, though it might have other problems. The idea is to save the viewaxis and do a rotation with them when viewangles changes. Obviously the angles of rotation are the viewangles variation. The problem is that the server and client must share viewaxis and I don't know what is the best way to do it, any ideas?




Top
                 

Veteran
Veteran
Joined: 17 May 2011
Posts: 159
PostPosted: 03-04-2013 01:10 AM           Profile Send private message  E-mail  Edit post Reply with quote


Thanks for your replies !

Eraser wrote:
Are you planning on making a Descent type of game out of it?

I'm not planning on that right away, my current goal is to make a sort of arcade plane shooter. But now that I have the code, if I want to make a Descent style game, I guess it will be more easy :)

UglyFoot wrote:
The problem is that the server and client must share viewaxis and I don't know what is the best way to do it, any ideas?

I tried to do like this at one point, and it worked well until I tried to get euler angles from my view axis :) I also looked up on how I could get some new information shared between client and server, but this looked way too complicated for me ... so I managed to have everything client-side, and only the view angles are sent over the network, like in normal qualke 3 :)

So I wrote an article on my blog about what was dificult and what was the process, if you have time to read it (I find it quite long), check it out :) http://dmeat.free.fr/blog/index.php?post/2013/03/02/ioQuake3-modding-6dof-0.5-Achieved-!

My new goal is to have a "repeating" map : on a square map, if you hit one side, you het teleported on the other, keeping velocity, angles, position ; and the most difficult part, having some "portals" that make that repetition seamless. A lot of "heightmap" terrain based games do like this, but in quake 3, this will require some graphical tweaks ... but as for what the engine is capable of, check this Portal mod : http://www.youtube.com/watch?v=Ych-gZieoVk. I find it really neat, and I'll try to contact it's author to have some tips on the subject :)



_________________
My blog - My portfolio
---------------------
MJDM2 - DmeatSP01 - DmeatSP02


Top
                 

Cool #9
Cool #9
Joined: 01 Dec 2000
Posts: 44138
PostPosted: 03-04-2013 01:54 AM           Profile   Send private message  E-mail  Edit post Reply with quote


Cool, having portals with Q3's physics opens up a whole new array of possible trickjumps. I think Portal's physics are too sluggish for it.
You do see that the time resolution (or whatever it's called) of the physics engine is too low when moving at really high speeds. In the video he's falling through an endless tunnel portal setup and you just see the view stutter between two different positions, rather than a smooth fall.




Top
                 

Cool #9
Cool #9
Joined: 01 Dec 2000
Posts: 44138
PostPosted: 03-04-2013 02:02 AM           Profile   Send private message  E-mail  Edit post Reply with quote


Quote:
So go have a poop, it frees up space in your body and your mind !


This is so true :olo:
You don't want to know how many programming epiphanies I've had while wiping my butt :olo:




Top
                 

Messatsu Ko Jy-ouu
Messatsu Ko Jy-ouu
Joined: 24 Nov 2000
Posts: 44139
PostPosted: 03-04-2013 02:32 AM           Profile   Send private message  E-mail  Edit post Reply with quote


prolly why your code is so shit :idea:




Top
                 

Cool #9
Cool #9
Joined: 01 Dec 2000
Posts: 44138
PostPosted: 03-04-2013 02:35 AM           Profile   Send private message  E-mail  Edit post Reply with quote


Zing!




Top
                 
Quake3World.com | Forum Index | Programming Discussion


Post new topic Reply to topic


cron
Quake3World.com
© ZeniMax. Zenimax, QUAKE III ARENA, Id Software and associated trademarks are trademarks of the ZeniMax group of companies. All rights reserved.
This is an unofficial fan website without any affiliation with or endorsement by ZeniMax.
All views and opinions expressed are those of the author.