Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7024183
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 27, 20262026-05-27T23:48:27+00:00 2026-05-27T23:48:27+00:00

Given a quaternion camera, how can I calculate its rotation when the player can

  • 0

Given a quaternion camera, how can I calculate its rotation when the player can walk on different surface normals (walls).

I’m working on a game which allows the player to walk on ceilings and walls in 3D space. I’ve opted to use a quaternion camera system to avoid Gimbal Lock. Given a set of up(0,1,0), right(1,0,0), and forward(0,0,1) vectors, I construct a quaternion. The player rotates around the up vector for heading and around the right vector for pitch.

Without changing gravity vectors, the camera works fine and allows the player to move about the environment as if it were a standard FPS game.

For simplicity, let’s say the player can press a key which grabs the normal from the nearest collision surface that differs from their current normal, and assigns that as the new gravity vector.

Unfortunately, I’ve run into a brainblock, and cannot figure out how to properly get the new up, right, and forward vectors from this new gravity vector and apply them to the current rotation quaternion, or even if that is the correct way to tackle the problem. If it helps, the movement and rotation code for my camera is below.

Field forwardVector:TVector = TVector.Create(0,0,1)
Field rightVector:TVector = TVector.Create(1,0,0)
Field upVector:TVector = TVector.Create(0,1,0)

Field pos:TVector = New TVector
Field headingQuaternion:TQuaternion = TQuaternion.Create()
Field pitchQuaternion:TQuaternion = TQuaternion.Create()
Field combinedRotation:TQuaternion = TQuaternion.Create()
Field gravityVector:TVector = TVector.Create(0,1,0)

'---------
'ChangeGravityVector
'---------
Method ChangeGravityVector( newGravityVector:TVector )

    gravityVector = newGravityVector

End Method

'---------
'MoveForward
'---------
Method MoveForward( moveAmount:Float, noGravity:Byte = False )

    Local vecRot:TVector

    If( noGravity = True )

        headingQuaternion.MultiplyByVector( forwardVector )
        vecRot = combinedRotation.MultiplyByVector( forwardVector )

    Else

        vecRot = headingQuaternion.MultiplyByVector( forwardVector )

    EndIf

    vecRot.ScaleVector( moveAmount )
    pos.AddVector( vecRot )

End Method

'---------
'MoveUp
'---------
Method MoveUp( moveAmount:Float, noGravity:Byte = False  )

    Local vecRot:TVector

    If( noGravity = True )

        headingQuaternion.MultiplyByVector( gravityVector )
        vecRot = combinedRotation.MultiplyByVector( gravityVector )

    Else

        vecRot = headingQuaternion.MultiplyByVector( gravityVector )

    EndIf

    vecRot.ScaleVector( moveAmount )
    pos.AddVector( vecRot )

End Method

'---------
'MoveRight
'---------
Method MoveRight( moveAmount:Float, noGravity:Byte = False  )

    Local vecRot:TVector

    If( noGravity = True )

        headingQuaternion.MultiplyByVector( rightVector )
        vecRot = combinedRotation.MultiplyByVector( rightVector )

    Else

        vecRot = headingQuaternion.MultiplyByVector( rightVector )

    EndIf

    vecRot.ScaleVector( moveAmount )
    pos.AddVector( vecRot )

End Method

'---------
'RotateX
'---------
Method RotateX( rotateAmount:Float )

    Local xRotQuat:TQuaternion = TQuaternion.Create()
    xRotQuat.ConvertFromAxisAngle( rightVector, rotateAmount )
    pitchQuaternion = pitchQuaternion.MultiplyByQuaternion( xRotQuat )

End Method

'---------
'RotateY
'---------
Method RotateY( rotateAmount:Float )

    Local yRotQuat:TQuaternion = TQuaternion.Create()
    yRotQuat.ConvertFromAxisAngle( gravityVector, rotateAmount )
    headingQuaternion = yRotQuat.MultiplyByQuaternion( headingQuaternion )

End Method

'---------
'GetCameraMatrix
'---------
Method GetCameraMatrix:TMatrix4x4()

    combinedRotation = headingQuaternion.MultiplyByQuaternion( pitchQuaternion )
    Return combinedRotation.GetMatrix()

End Method
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-27T23:48:28+00:00Added an answer on May 27, 2026 at 11:48 pm

    Ok, so I found a solution that works well, and it turns out, I was thinking about it wrong. The only vector that needs to change is the up vector, the others two vectors, forward and right, should stay the same. The following code will align the current quaternion with a new up vector. The trick was that you use the square of the dot product between the current up vector and new up vector and the cross vector between those two to create a new quaternion. You then multiply that by your current heading and slerp between the two. Remember to set your new up vector afterwards. You can use any value you want in the slerp to make it smoother, 1.0 makes the transition instantly.

            Local newQuat:TQuaternion = New TQuaternion
            Local cross:TVector = upVector.GetCrossProduct( newGravityVector )
            Local dot:Float = upVector.GetDotProduct( newGravityVector )
            Local dotSquare:Float = Sqr( ( 1.0 + dot ) * 2.0 )
            Local scale:Float = 1.0/dotSquare
            newQuat.x = cross.x*scale
            newQuat.y = cross.y*scale
            newQuat.z = cross.z*scale
            newQuat.w = dotSquare*0.5
    
            newQuat = newQuat.MultiplyByQuaternion( headingQuaternion )
    
            headingQuaternion = headingQuaternion.Slerp( headingQuaternion, newQuat, 1.0 )
    
            gravityVector = newGravityVector
            upVector = newGravityVector
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Given a quaternion value, I would like to find its nearest neighbour in a
Given a DateTime representing a person's birthday, how do I calculate their age in
Given the URL (single line): http://test.example.com/dir/subdir/file.html How can I extract the following parts using
Given the following string: s = 'abcdefg*' How can I match it or any
Basically, given a quaterion (qx, qy, qz, qw)... How can i convert that to
Given a file path (e.g. /src/com/mot ), how can I check whether mot exists,
Given the follow: <table id=myTable> <tr> </tr> <tr> </tr> ... </table> I can clear
Given that a ThreadLocal variable holds different values for different threads, is it possible
In my game I have a camera and I want to have an FPS
I am using quaternions in my game to calculate some basic angles. Now I

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.