pitch/yaw/roll

Blitz3D Forums/Blitz3D Bug Reports/pitch/yaw/roll

The forum is locked. These are the original blitzbasic.com forums, kept so they can still be read. No new topics, replies or edits can be made here. To join in, head over to the Blitz3D+ forums.

Aha, so this is the infamous Gimbal lock. Thanks a lot, I used fredborgs solution and it works now.
I also tried getting the pitch/yaw/roll directly from the GetMatElement() matrix, with the help of a routine from leadwerks. For completion, I added both functions:
Thanks again, after hunting me all night, I hope this Gimbal demon is exorcised for good now. :)
Graphics3D 800, 600, 0, 2 
SetBuffer BackBuffer() 

pivot = CreatePivot() 
RotateEntity pivot, 90, 90, 0 

Print "standard:"
Print EntityPitch(pivot) 
Print EntityYaw(pivot) 
Print EntityRoll(pivot) 

Print "fredborgs:"
Print GlobalEntityPitch(pivot)
Print GlobalEntityYaw(pivot)
Print GlobalEntityRoll(pivot)

Print "matrix:"
Print mEntityPitch(pivot)
Print mEntityYaw(pivot)
Print mEntityRoll(pivot)


;fredborg
;post = www.blitzbasic.com/Community/posts.php?topic=31781 <http://www.blitzbasic.com/Community/posts.php?topic=31781> 

Const GIMBAL_LIMIT# = 89.98

Function GlobalEntityPitch#(entity)

	pit# = Int(EntityPitch(entity,True)*1000)/1000.0
	
	Return pit

End Function

Function GlobalEntityYaw#(entity)
	
	pit# = Int(EntityPitch(entity,True)*1000)/1000.0
	yaw# = Int(EntityYaw(entity,True)*1000)/1000.0
	
	If Abs(pit)>GIMBAL_LIMIT
		temp = CreatePivot(entity)
		TurnEntity temp,Sgn(pit)*-90.0,0,0
		yaw# = Int(EntityYaw(temp,True)*1000)/1000.0
		FreeEntity temp
	EndIf

	Return yaw
	
End Function

Function GlobalEntityRoll#(entity)

	pit# = Int(EntityPitch(entity,True)*1000)/1000.0
	rol# = Int(EntityRoll(entity,True)*1000)/1000.0

	If Abs(pit)>GIMBAL_LIMIT
		temp = CreatePivot(entity)
		TurnEntity temp,Sgn(pit)*-90.0,0,0
		rol# = Int(EntityRoll(temp,True)*1000)/1000.0
		FreeEntity temp
	EndIf

	Return rol

End Function

;leadwerks
;post = <a href="http://www.blitzbasic.co.nz/Community/posts.php?topic=21362" target="_blank">http://www.blitzbasic.co.nz/Community/posts.php?topic=21362</a>
Function mEntityPitch#(Entity) 
	Return -ASin(GetMatElement(Entity,2,1)) 
End Function 

Function mEntityYaw#(Entity) 
	Return -ATan2(GetMatElement(Entity,2,0),GetMatElement(Entity,2,2)) 
End Function 

Function mEntityRoll#(Entity) 
	Return ATan2(GetMatElement(Entity,0,1),GetMatElement(Entity,1,1)) ;-ATan2(m(1,0),m(1,1)) 
End Function 


(edit)
Because I needed the local angles too, I modified the FredBorg functions. As fas as I can tell they work, but I don't understand exactly how they work I just made them local (to the parent):
Const GIMBAL_LIMIT# = 89.98

Function GlobalEntityPitch#(entity)

	pit# = Int(EntityPitch(entity)*1000)/1000.0
	
	Return pit

End Function

Function GlobalEntityYaw#(entity)
	
	pit# = Int(EntityPitch(entity)*1000)/1000.0
	yaw# = Int(EntityYaw(entity)*1000)/1000.0
	
	If Abs(pit)>GIMBAL_LIMIT
		temp = CreatePivot(entity)
		EntityParent temp, GetParent(entity)
		TurnEntity temp,Sgn(pit)*-90.0,0,0
		yaw# = Int(EntityYaw(temp)*1000)/1000.0
		FreeEntity temp
	EndIf

	Return yaw
	
End Function

Function GlobalEntityRoll#(entity)

	pit# = Int(EntityPitch(entity)*1000)/1000.0
	rol# = Int(EntityRoll(entity)*1000)/1000.0

	If Abs(pit)>GIMBAL_LIMIT
		temp = CreatePivot(entity)
		EntityParent temp, GetParent(entity)
		TurnEntity temp,Sgn(pit)*-90.0,0,0
		rol# = Int(EntityRoll(temp)*1000)/1000.0
		FreeEntity temp
	EndIf

	Return rol

End Function