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. :)
(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):
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