I've always just worked around it by using turn entity instead of rotateentity, but as I am approaching a more serious stage in my projects evolution, I am wondering 'what am I missing'?
I found the following code on
http://www.dscho.co.uk/blitz/tutorials/quaternions.shtml
I have changed it to use both rotateentity and turnentity.
As far as I can see, using turnentity makes the 'Gimbal Lock' problem go away... Propably because B3D uses Quaternians internally.
What am I missing? Why should I use quaternions when turnentity does the same...
; Set up the scene quickly
Graphics3D 800,600
SetBuffer BackBuffer()
cube = CreateExampleCube()
cam = CreateCamera()
TranslateEntity cam, -5, -5, -5
PointEntity cam, cube
CameraViewport cam, 0, 0, GraphicsWidth (), GraphicsHeight ()
; the start rotation
Global pitch = 0
Global yaw = 0
Global roll = 0
Global test = 0
Global a$=""
Repeat
; update the rotation
pitch = pitch + KeyHit(200) * 10 ; up
pitch = pitch - KeyHit(208) * 10 ; down
yaw = yaw + KeyHit(203) * 10 ; left
yaw = yaw - KeyHit(205) * 10 ; right
roll = roll + KeyHit(30) * 10 ; a
roll = roll - KeyHit(44) * 10 ; z
If KeyHit(68) Then test=Abs(test-1)
; rotate the cube
If test=0 Then
; Rotate using RotateEntity
RotateEntity cube, pitch, yaw, roll, 1
a$="RotateEntity"
EndIf
If test=1 Then
; Rotate using TurnEntity
RotateEntity cube, 0.0, 0.0, 0.0, 1
TurnEntity cube,pitch,0.0,0.0, 1
TurnEntity cube,0.0,yaw,0.0, 1
TurnEntity cube,0.0,0.0,roll, 1
a$="TurnEntity"
EndIf
; draw the scene
UpdateWorld
RenderWorld
Text 10, 10, "Pitch:" + Int(EntityPitch (cube))
Text 10, 20, "Yaw: " + Int(EntityYaw (cube))
Text 10, 30, "Roll: " + Int(EntityRoll (cube))
Text 10, 50, "Use cursor keys, a, z, F10 and escape to exit"
Text 10, 60, a$
Flip 1
Until KeyHit(1) ; escape
End
Function CreateExampleCube()
; This will create & return a white cube with 3 coloured spikes going through it
; to emphasise the rotations, and also a light
Local cube = CreateCube()
Local xspike = CreateCone(16, True, cube)
Local yspike = CreateCone(16, True, cube)
Local zspike = CreateCone(16, True, cube)
Local tempBrush = CreateBrush(255, 255, 255)
PaintEntity cube, tempBrush
BrushColor tempbrush, 255, 0, 0
PaintEntity xspike, tempBrush
BrushColor tempbrush, 0, 255, 0
PaintEntity yspike, tempBrush
BrushColor tempbrush, 0, 0, 255
PaintEntity zspike, tempBrush
ScaleEntity xspike, 0.5, 4, 0.5
ScaleEntity yspike, 0.5, 4, 0.5
ScaleEntity zspike, 0.5, 4, 0.5
RotateEntity xspike, 0, 0, 0, 1
RotateEntity yspike, 90, 0, 0, 1
RotateEntity zspike, 0, 0, 90, 1
FreeBrush tempBrush
Local light = CreateLight(1)
PositionEntity light, -5, -5, -4
Return cube
End Function
Andy
I found the following code on
http://www.dscho.co.uk/blitz/tutorials/quaternions.shtml
I have changed it to use both rotateentity and turnentity.
As far as I can see, using turnentity makes the 'Gimbal Lock' problem go away... Propably because B3D uses Quaternians internally.
What am I missing? Why should I use quaternions when turnentity does the same...
; Set up the scene quickly
Graphics3D 800,600
SetBuffer BackBuffer()
cube = CreateExampleCube()
cam = CreateCamera()
TranslateEntity cam, -5, -5, -5
PointEntity cam, cube
CameraViewport cam, 0, 0, GraphicsWidth (), GraphicsHeight ()
; the start rotation
Global pitch = 0
Global yaw = 0
Global roll = 0
Global test = 0
Global a$=""
Repeat
; update the rotation
pitch = pitch + KeyHit(200) * 10 ; up
pitch = pitch - KeyHit(208) * 10 ; down
yaw = yaw + KeyHit(203) * 10 ; left
yaw = yaw - KeyHit(205) * 10 ; right
roll = roll + KeyHit(30) * 10 ; a
roll = roll - KeyHit(44) * 10 ; z
If KeyHit(68) Then test=Abs(test-1)
; rotate the cube
If test=0 Then
; Rotate using RotateEntity
RotateEntity cube, pitch, yaw, roll, 1
a$="RotateEntity"
EndIf
If test=1 Then
; Rotate using TurnEntity
RotateEntity cube, 0.0, 0.0, 0.0, 1
TurnEntity cube,pitch,0.0,0.0, 1
TurnEntity cube,0.0,yaw,0.0, 1
TurnEntity cube,0.0,0.0,roll, 1
a$="TurnEntity"
EndIf
; draw the scene
UpdateWorld
RenderWorld
Text 10, 10, "Pitch:" + Int(EntityPitch (cube))
Text 10, 20, "Yaw: " + Int(EntityYaw (cube))
Text 10, 30, "Roll: " + Int(EntityRoll (cube))
Text 10, 50, "Use cursor keys, a, z, F10 and escape to exit"
Text 10, 60, a$
Flip 1
Until KeyHit(1) ; escape
End
Function CreateExampleCube()
; This will create & return a white cube with 3 coloured spikes going through it
; to emphasise the rotations, and also a light
Local cube = CreateCube()
Local xspike = CreateCone(16, True, cube)
Local yspike = CreateCone(16, True, cube)
Local zspike = CreateCone(16, True, cube)
Local tempBrush = CreateBrush(255, 255, 255)
PaintEntity cube, tempBrush
BrushColor tempbrush, 255, 0, 0
PaintEntity xspike, tempBrush
BrushColor tempbrush, 0, 255, 0
PaintEntity yspike, tempBrush
BrushColor tempbrush, 0, 0, 255
PaintEntity zspike, tempBrush
ScaleEntity xspike, 0.5, 4, 0.5
ScaleEntity yspike, 0.5, 4, 0.5
ScaleEntity zspike, 0.5, 4, 0.5
RotateEntity xspike, 0, 0, 0, 1
RotateEntity yspike, 90, 0, 0, 1
RotateEntity zspike, 0, 0, 90, 1
FreeBrush tempBrush
Local light = CreateLight(1)
PositionEntity light, -5, -5, -4
Return cube
End Function
Andy