Results 1 to 18 of 18
  1. #1
    MSgt. Shooter Person
    Join Date
    Aug 2011
    Posts
    63

    Default Quaternion fail logic :(

    I'm trying to simulate a ship flying around. I can make it work with euler angles but there is gimbal lock when looking straight down and up. Been working on a quaternion solution the whole night and can't seem to get it to work. Here's the code:

    Inside my PlayerController class:

    Code:
    myRotation = Rotation;
    
    if(MousePosition.Y > (LastHUDSizeY * 0.5) + (LastHUDSizeY * 0.1))
    	{
    		myRotation.Pitch += abs(MousePosition.Y - LastHUDSizeY * 0.5)/LastHUDSizeY * TestMoveScale * DeltaTime;
    	}
    	else if(MousePosition.Y < (LastHUDSizeY * 0.5) - (LastHUDSizeY * 0.1))
    	{
    		myRotation.Pitch -= abs(MousePosition.Y - LastHUDSizeY * 0.5)/LastHUDSizeY * TestMoveScale * DeltaTime;
    	}
    
    	//convert myRotation to Quat
    	myQuatRotation = QuatFromRotator( Rotation );
    	QuatRotation = QuatFindBetween(Normal(Vector(Rotation)), Normal(Vector(myRotation)));
    	QuatRotation = QuatProduct(myQuatRotation, QuatRotation);
    	myRotation = QuatToRotator(QuatRotation);
    When I do this just modifying the yaw, it works fine. When modifying the pitch as seen here, the ship also rolls and changes in pitch too. When just modifying the roll, nothing happens. Any solutions? Thanks.

  2. #2

    Default

    I was messing around with something similar and ended up abandoning quaternions for GetAxes, cross/dot products and OrthoRotation. I found vectors easier to manipulate. Maybe that could work for you?

  3. #3

    Default

    Try converting to a quat first, then applying the offset. If you visualize it, you'll see that the reason roll doesn't work is because the quat is facing "into" the roll, so it's just rolling around itself. Pitch and yaw have problems for similar reasons.
    Try my game Never End, now on the App Store! For more info, see the release thread.

    My Blog: WillyG Productions - Your Premiere UDK Resource
    My YouTube Channel: WillyG Productions
    My Facebook Page: WillyG Productions

  4. #4
    MSgt. Shooter Person
    Join Date
    Aug 2011
    Posts
    63

    Default

    Awesome, got it working. However, I still have an issue with looking straight up or down, it does a super fast 360. Any ideas on how to get rid of that? This is the working code btw:

    In the PlayerController:

    Code:
    myRotation = Rotation;
    	QuatRotation = QuatFromRotator( Rotation );
    	myQuatRotation = QuatFromRotator( myRotation );
    
    	if(MousePosition.X > (LastHUDSizeX * 0.5) + (LastHUDSizeX * 0.1))
    	{
    		//myRotation.Yaw += abs(MousePosition.X - LastHUDSizeX * 0.5)/LastHUDSizeX * TestMoveScale * DeltaTime;
    		myQuatRotation = QuatFromAxisAndAngle( vect(0,0,1), DeltaTime * abs(MousePosition.X - LastHUDSizeX * 0.5)/LastHUDSizeX * TestMoveScale );
    		QuatRotation = QuatProduct(QuatRotation, myQuatRotation);
    	}
    	else if(MousePosition.X < (LastHUDSizeX * 0.5) - (LastHUDSizeX * 0.1))
    	{
    		//myRotation.Yaw -= abs(MousePosition.X - LastHUDSizeX * 0.5)/LastHUDSizeX * TestMoveScale * DeltaTime;
    		myQuatRotation = QuatFromAxisAndAngle( vect(0,0,1), DeltaTime * abs(MousePosition.X - LastHUDSizeX * 0.5)/LastHUDSizeX * -TestMoveScale );
    		QuatRotation = QuatProduct(QuatRotation, myQuatRotation);
    	}
    
    	if(MousePosition.X > (LastHUDSizeX * 0.5) + (LastHUDSizeX * 0.1))
    	{
    		//myRotation.Roll -= abs(MousePosition.Y - LastHUDSizeY * 0.5)/LastHUDSizeY  * TestMoveScale * DeltaTime;
    		myQuatRotation = QuatFromAxisAndAngle( vect(1,0,0), DeltaTime * abs(MousePosition.X - LastHUDSizeX * 0.5)/LastHUDSizeX * -TestMoveScale );
    		QuatRotation = QuatProduct(QuatRotation, myQuatRotation);
    	}
    	else if(MousePosition.X < (LastHUDSizeX * 0.5) - (LastHUDSizeX * 0.1))
    	{
    		//myRotation.Roll += abs(MousePosition.Y - LastHUDSizeY * 0.5)/LastHUDSizeY  * TestMoveScale * DeltaTime;
    		myQuatRotation = QuatFromAxisAndAngle( vect(1,0,0), DeltaTime * abs(MousePosition.X - LastHUDSizeX * 0.5)/LastHUDSizeX * TestMoveScale);
    		QuatRotation = QuatProduct(QuatRotation, myQuatRotation);
    	}
    	
    
    	if(MousePosition.Y > (LastHUDSizeY * 0.5) + (LastHUDSizeY * 0.1))
    	{
    		//myRotation.Pitch += abs(MousePosition.Y - LastHUDSizeY * 0.5)/LastHUDSizeY * TestMoveScale * DeltaTime;
    		myQuatRotation = QuatFromAxisAndAngle( vect(0,1,0), DeltaTime * abs(MousePosition.Y - LastHUDSizeY * 0.5)/LastHUDSizeY * TestMoveScale );
    		QuatRotation = QuatProduct(QuatRotation, myQuatRotation);
    	}
    	else if(MousePosition.Y < (LastHUDSizeY * 0.5) - (LastHUDSizeY * 0.1))
    	{
    		//myRotation.Pitch -= abs(MousePosition.Y - LastHUDSizeY * 0.5)/LastHUDSizeY * TestMoveScale * DeltaTime;
    		myQuatRotation = QuatFromAxisAndAngle( vect(0,1,0), DeltaTime * abs(MousePosition.Y - LastHUDSizeY * 0.5)/LastHUDSizeY * -TestMoveScale );
    		QuatRotation = QuatProduct(QuatRotation, myQuatRotation);
    	}
    
            //auto rotate function
    	//mouse inside the dead zone
    	if(MousePosition.X < (LastHUDSizeX * 0.5) + (LastHUDSizeX * 0.1) && MousePosition.X > (LastHUDSizeX * 0.5) - (LastHUDSizeX * 0.1)
    		&& MousePosition.Y < (LastHUDSizeY * 0.5) + (LastHUDSizeY * 0.1) && MousePosition.Y > (LastHUDSizeY * 0.5) - (LastHUDSizeY * 0.1) )
    	{
    		//100 for a buffer so it doesnt alternate super fast
    		if(myRotation.Roll > 100)
    		{
    			myQuatRotation = QuatFromAxisAndAngle( vect(1,0,0), DeltaTime * TestMoveScale);
    			QuatRotation = QuatProduct(QuatRotation, myQuatRotation);
    		}
    		else if(myRotation.Roll < -100)
    		{
    			myQuatRotation = QuatFromAxisAndAngle( vect(1,0,0), DeltaTime * -TestMoveScale);
    			QuatRotation = QuatProduct(QuatRotation, myQuatRotation);
    		}
    		
    	}
    
    	myRotation = QuatToRotator(QuatRotation);

  5. #5
    MSgt. Shooter Person
    Join Date
    Aug 2011
    Posts
    63

    Default

    In regards to the super fast 360, I think this is what is happening. As my plane's pitch approaches the point of looking straight up, my value for roll is still 0. However, once it reaches that point and beyond, my roll is now upside down, resulting in a value of about 32000 or (65536/2). The script then interpolates the mesh's rotation so that it rolls from 0 to 32000. If we try looking straight down, the roll goes from 0 to about -32000. Any solutions?

    EDIT: It appears that if I attempt a loop while having a slight roll, I can complete the loop. However, at some point soon afterwards, the plane will spin, I believe so that it can correct it's axis or something. I need to fix this behavior, any ideas as to where to look?
    Last edited by tho121; 04-27-2012 at 04:35 PM.

  6. #6

    Default

    Hmm well one question...is this an interpolating function? if it is you could try use RInterpTo() from the old rot to the new rot, this finds the "quickest" way to get from one rotator to the other so it should eliminate the 360 spin.
    Try my game Never End, now on the App Store! For more info, see the release thread.

    My Blog: WillyG Productions - Your Premiere UDK Resource
    My YouTube Channel: WillyG Productions
    My Facebook Page: WillyG Productions

  7. #7
    MSgt. Shooter Person
    Join Date
    Aug 2011
    Posts
    63

    Default

    Quote Originally Posted by willyg302 View Post
    Hmm well one question...is this an interpolating function? if it is you could try use RInterpTo() from the old rot to the new rot, this finds the "quickest" way to get from one rotator to the other so it should eliminate the 360 spin.
    It's in the PlayerTick function. Would that make it interpolating since DeltaTime is one of it's arguments? Thanks for the reply.

    Also I just made a video to demonstrate my issue.

    http://www.youtube.com/watch?v=gkHBW...ature=youtu.be

  8. #8
    MSgt. Shooter Person
    Join Date
    Aug 2011
    Posts
    63

    Default

    Okay, I kind of worked around this issue using MT_Pawn(Pawn).FaceRotation(RInterpTo(Pawn.Rotation , NewRotation, DeltaTime, 2), deltatime). Seems pretty hacky as it limits how fast I can rotate and the twitch is still there but not as bad. It seems SetRotation() doesn't like to treat pitch the same way as it does yaw. I mean if I looked all the way behind me and kept rotating, I wouldn't spin the other direction until I was looking behind myself again and continue from where I left off.

  9. #9

    Default

    Sorry for the late reply. Yes, anything in PlayerTick is technically an interpolating function. Not sure what you mean by the SetRotation() thing, but for the RInterpTo() I'm wondering why you're calling an interp on an interp? As in, you have the RInterpTo inside the FaceRotation()...you can simply use the output of RInterpTo as the new rotation value if i'm not mistaken.
    Try my game Never End, now on the App Store! For more info, see the release thread.

    My Blog: WillyG Productions - Your Premiere UDK Resource
    My YouTube Channel: WillyG Productions
    My Facebook Page: WillyG Productions

  10. #10
    MSgt. Shooter Person
    Join Date
    Aug 2011
    Posts
    63

    Default

    Thanks for the reply. I applied the QuatSlerp instead of RInterpTo, moved the SetRotation function calls to my PlayerTick() and stubbed out UpdateRotation(). I guess I didn't really understand where the interpolating was happening. In a way, I think what I'm aiming for is no interpolating because the ship's roll goes from 0 to 32767 in a frame due to the ship going from right side up to upside down. The interpolating is causing the twitch is my guess. That considered, I tried commenting out QuatSlerp and it still twitches.

    Another video of what is happening (last one wasn't quite right):

    http://www.youtube.com/watch?v=SsWKd...ature=youtu.be

    Here is what I have so far in my PlayerController.

    Code:
    function PlayerTick(float DeltaTime)
    {
    	local MT_MouseInterfacePlayerInput MouseInterfacePlayerInput;
    	local IntPoint MousePosition;
    	local Quat QuatRotation, myQuatRotation;
    
    	// Cast to get the MouseInterfacePlayerInput
    	MouseInterfacePlayerInput = MT_MouseInterfacePlayerInput(PlayerInput); 
    
    	PlayerCamera.ViewTarget.POV.Location += PlayerViewOffset;
    
    	if (MouseInterfacePlayerInput != None)
    	{
    		// To retrieve/use the mouse X position
    		MousePosition.X = MouseInterfacePlayerInput.MousePosition.X;
    		// To retrieve/use the mouse Y position
    		MousePosition.Y = MouseInterfacePlayerInput.MousePosition.Y;
    
    	}
    
    	myRotation = Rotation;
    	QuatRotation = QuatFromRotator( Rotation );
    	myQuatRotation = QuatFromRotator( myRotation );
    
            //Roll
    	if(PlayerInput.aStrafe > 0)//MousePosition.X > (LastHUDSizeX * 0.5) + (LastHUDSizeX * 0.1))
    	{
    		myQuatRotation = QuatFromAxisAndAngle( vect(1,0,0), DeltaTime * PlayerInput.aStrafe * -1);
    		QuatRotation = QuatProduct(QuatRotation, myQuatRotation);
    	}
    	else if(PlayerInput.aStrafe < 0)//MousePosition.X < (LastHUDSizeX * 0.5) - (LastHUDSizeX * 0.1))
    	{
    		myQuatRotation = QuatFromAxisAndAngle( vect(1,0,0), DeltaTime * PlayerInput.aStrafe * -1);
    		QuatRotation = QuatProduct(QuatRotation, myQuatRotation);
    	}
    
    	//auto rotate function
    	//if mouse inside the dead zone
    	if(MousePosition.X < (LastHUDSizeX * 0.5) + (LastHUDSizeX * 0.1) && MousePosition.X > (LastHUDSizeX * 0.5) - (LastHUDSizeX * 0.1)
    		&& MousePosition.Y < (LastHUDSizeY * 0.5) + (LastHUDSizeY * 0.1) && MousePosition.Y > (LastHUDSizeY * 0.5) - (LastHUDSizeY * 0.1) )
    	{
    		//100 for a buffer so it doesnt alternate super fast
    		if((myRotation.Roll > 100 && myRotation.Roll < 16200) || (myRotation.Roll > -32667 && myRotation.Roll < -16200))
    		{
    			myQuatRotation = QuatFromAxisAndAngle( vect(1,0,0), DeltaTime * TestMoveScale);
    			QuatRotation = QuatProduct(QuatRotation, myQuatRotation);
    		}
    		else if(myRotation.Roll < -100 && myRotation.Roll > -16200 || (myRotation.Roll < 32667 && myRotation.Roll > 16200))
    		{
    			myQuatRotation = QuatFromAxisAndAngle( vect(1,0,0), DeltaTime * -TestMoveScale);
    			QuatRotation = QuatProduct(QuatRotation, myQuatRotation);
    		}
    		
    	}
    
    	
            //Yaw
    	if(MousePosition.X > (LastHUDSizeX * 0.5) + (LastHUDSizeX * 0.1))
    	{
    		myQuatRotation = QuatFromAxisAndAngle( vect(0,0,1), DeltaTime * abs(MousePosition.X - LastHUDSizeX * 0.5)/LastHUDSizeX * TestMoveScale );
    		QuatRotation = QuatProduct(QuatRotation, myQuatRotation);
    	}
    	else if(MousePosition.X < (LastHUDSizeX * 0.5) - (LastHUDSizeX * 0.1))
    	{
    		myQuatRotation = QuatFromAxisAndAngle( vect(0,0,1), DeltaTime * abs(MousePosition.X - LastHUDSizeX * 0.5)/LastHUDSizeX * -TestMoveScale );
    		QuatRotation = QuatProduct(QuatRotation, myQuatRotation);
    	}
    
            //Pitch
    	if(MousePosition.Y > (LastHUDSizeY * 0.5) + (LastHUDSizeY * 0.1))
    	{
    		//myRotation.Pitch += abs(MousePosition.Y - LastHUDSizeY * 0.5)/LastHUDSizeY * TestMoveScale * DeltaTime;
    		myQuatRotation = QuatFromAxisAndAngle( vect(0,1,0), DeltaTime * abs(MousePosition.Y - LastHUDSizeY * 0.5)/LastHUDSizeY * TestMoveScale ); //vect(0,1,0)
    		QuatRotation = QuatProduct(QuatRotation, myQuatRotation);
    	}
    	else if(MousePosition.Y < (LastHUDSizeY * 0.5) - (LastHUDSizeY * 0.1))
    	{
    		//myRotation.Pitch -= abs(MousePosition.Y - LastHUDSizeY * 0.5)/LastHUDSizeY * TestMoveScale * DeltaTime;
    		myQuatRotation = QuatFromAxisAndAngle( vect(0,1,0), DeltaTime * abs(MousePosition.Y - LastHUDSizeY * 0.5)/LastHUDSizeY * -TestMoveScale );//vect(0,1,0)
    		QuatRotation = QuatProduct(QuatRotation, myQuatRotation);
    	}
    
    
    	QuatRotation = QuatSlerp(QuatFromRotator( Rotation ), QuatRotation, 1, true);
    	myRotation = QuatToRotator(QuatRotation);
    
    	SetRotation(myRotation);
    	Pawn.SetRotation(myRotation);
    
    	super.PlayerTick(DeltaTime);
    }
    Last edited by tho121; 04-30-2012 at 03:06 PM.

  11. #11
    MSgt. Shooter Person
    Join Date
    Aug 2011
    Posts
    155

    Default

    I chose a way not involing quats at all.

    Is your pawn class a vehicle or just a pawn? If it is a vehicle you can let PhysX take care of it. It is way simpler. It just involves simple vector math.
    I know it would be frustating to start again at square one though.

  12. #12
    MSgt. Shooter Person
    Join Date
    Aug 2011
    Posts
    63

    Default

    It's just a pawn. I'm still trying to get AddTorque to work on the mesh. I might not be applying it right, I think it takes the vector which represents the desired direction you want to face and rotate the mesh there. I'll also look at the vehicle code too and see how much of that I can throw into my pawn class.

  13. #13
    Banned
    Join Date
    Feb 2011
    Location
    BXL/Paris
    Posts
    2,169

    Default

    Why you not extending from Vehicle class?

  14. #14
    MSgt. Shooter Person
    Join Date
    Aug 2011
    Posts
    63

    Default

    I wasn't familiar with the Vehicle class and figured I could just swap out the Pawn mesh and apply my rotations. Works for everything except when the plane goes vertical. I'm reading through the vehicle code now and am trying a physics based approach to the rotation, setting the Physics to PHYS_Rigidbody. Can't figure out how to rotate it with it being set to a Rigidbody though... If all fails, I guess I'll just remake it, extend from the vehicle class or the cicada and redo the code.

  15. #15
    Banned
    Join Date
    Feb 2011
    Location
    BXL/Paris
    Posts
    2,169

    Default

    I'm not saying you can't do this, but extending from UTVehicle (if not UTAirVehicle...) will save you a lot of work and time. Minimum necessary is UDKVehicle, which is native and that's mean that most of stuff is running natively.

    Anyways, this problem could be related with the camera it self - hard to say...

    Edit: Yep, i saw your two videos and this is camera issue, plane rotation is OK all the time (even in first video...) - have you bStayUpright=true..?
    Last edited by VendorX; 05-02-2012 at 03:20 AM.

  16. #16
    MSgt. Shooter Person
    Join Date
    Aug 2011
    Posts
    63

    Default

    Quote Originally Posted by VendorX View Post
    I'm not saying you can't do this, but extending from UTVehicle (if not UTAirVehicle...) will save you a lot of work and time. Minimum necessary is UDKVehicle, which is native and that's mean that most of stuff is running natively.

    Anyways, this problem could be related with the camera it self - hard to say...

    Edit: Yep, i saw your two videos and this is camera issue, plane rotation is OK all the time (even in first video...) - have you bStayUpright=true..?
    No, bStayUpright is not declared at all since I'm currently still extending from Pawn. Hmm, I didn't consider it to be a camera issue...If so, I'm guessing it might have to do with the camera rotation. I'll take a look. Thanks for the reply.

    EDIT: Hmm, now that I'm thinking about it, I doubt it is the camera since in my logs, I can see the ship's roll interpolate from 0 to ~32000. Also, the camera's position and rotation depends on the pawn.

    What my rotation looks like in multiplayer:

    http://www.youtube.com/watch?v=A1_IF...ature=youtu.be

    Seems like there's a fundamental error in way I'm rotating it...
    Last edited by tho121; 05-02-2012 at 05:16 AM.

  17. #17
    MSgt. Shooter Person
    Join Date
    Aug 2011
    Posts
    155

    Default

    I heavily recommend to start over and extending from UTAirVehicle, that is the easiest way.

    Don't waste your time on the camera code of a normal Pawn. The camera is handled differently for a vehicle.
    In this thread I have turned Syphon's bugged plane code into a working simple spaceship. We both extend from UTAirVehicle:
    http://forums.epicgames.com/threads/...7#post27347357

  18. #18
    MSgt. Shooter Person
    Join Date
    Aug 2011
    Posts
    63

    Default

    Finally solved it! After trying again using a vehicle, I was still getting the same error. However, someone mentioned the camera could be a source of error, so I looked at that too. Turns out the camera was the culprit. I made my own camera extending off of the camera class and used that instead and it works! No more twitches! Seems to be something in the GamePlayerCamera code that does the twitching when rotation is at the max yaw. I'll look at it some other time, just happy to finally have this working! Thanks to everyone that replied to this post!

    EDIT: found the problem. In my Pawn's CalcCamera function, I set my Camera Rotation with:

    out_CamRot = rotator((out_CamLoc - CamStart) * -1);

    Thinking that I would get the direction vector from the camera to the Pawn's Location. This rotation also happens to be the same as the rotation of the pawn... I changed it to this:

    out_CamRot = Rotation;

    And now I realize 1 line of code = hours and hours and hours of...*cries* I don't even know anymore...
    Last edited by tho121; 05-10-2012 at 01:32 AM.


 

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Copyright ©2009-2011 Epic Games, Inc. All Rights Reserved.
Digital Point modules: Sphinx-based search vBulletin skin by CompletevB.com.