Many a 3D application does not provide a plausible orbit camera motion.
there is however several ways to achieve such good one.
I like this one: a combination of two rotation axis that act like a "miller wheel",
As shown below:
Here's a sample code to show it:
Global ExplorerBaseX#
Global ExplorerBaseY#
Global ExplorerBaseZ#
Global ExplorerBaseYaw#
Global ExplorerBasePitch#
Global ExplorerBaseRoll#
Global ExplorerCurrentX#
Global ExplorerCurrentY#
Global ExplorerCurrentZ#
Global ExplorerCurrentYaw#
Global ExplorerCurrentPitch#
Global ExplorerCurrentRoll#
Global ExplorerTrackBallCenterX#
Global ExplorerTrackBallCenterY#
Global ExplorerTrackBallCenterZ#
Global PrefsTrackballRotHSpeed#
Global PrefsTrackballRotVSpeed#
Sync On: Sync Rate 0
Set Display Mode 800, 600, 32
PrefsTrackballRotHSpeed# = -0.5: Rem Speed in unit/pixel of mouse move
PrefsTrackballRotVSpeed# = 0.5: Rem Reverse axis by changing sign
Autocam Off
CreateScene()
SelectedObject = 1
SelectObject(SelectedObject, 5)
Explorer_SetTrackBallCenter(Object Position X(SelectedObject), Object Position Y(SelectedObject), Object Position Z(SelectedObject))
Set Camera Range 0, 0.125, 32.0
Explorer_SetCameraPosition(0.0, 2.0, -6.0)
Explorer_SetCameraRotation(0.0, 15.0, 0.0)
Explorer_UpdateCamera(0)
Sync
Do
AscKey = Asc(Inkey$())
If (AscKey = 9) And KeyReleased
Inc SelectedObject: If SelectedObject > 4 Then SelectedObject = 1
SelectObject(SelectedObject, 5)
Explorer_SetTrackBallCenter(Object Position X(SelectedObject), Object Position Y(SelectedObject), Object Position Z(SelectedObject))
KeyReleased = 0
EndIf
If AscKey = 0 Then KeyReleased = 1
If MouseClick() = 1
PrevMX = MouseX(): PrevMY = MouseY(): Hide Mouse
Explore_TrackBall()
Show Mouse
Position Mouse PrevMX, PrevMY
EndIf
Text 0, 0, "TAB key to change object"
Sync
Loop
End
`_____________________________________________________________________________________________________
Function Explore_Trackball()
MouseDeltaX = MouseMoveX(): MouseDeltaY = MouseMoveY()
MouseDeltaX = MouseMoveX(): MouseDeltaY = MouseMoveY()
While MouseClick()
MouseDeltaX = MouseDeltaX + MouseMoveX(): MouseDeltaY = MouseDeltaY + MouseMoveY()
DeltaYaw# = MouseDeltaX * PrefsTrackballRotHSpeed#
DeltaPitch# = MouseDeltaY * PrefsTrackballRotVSpeed#
Explorer_TrackBall(DeltaYaw#, DeltaPitch#)
Explorer_UpdateCamera(0)
Sync
EndWhile
Explorer_SetBase()
EndFunction
`_____________________________________________________________________________________________________
Function Explorer_SetTrackBallCenter(X#, Y#, Z#)
ExplorerTrackBallCenterX# = X#
ExplorerTrackBallCenterY# = Y#
ExplorerTrackBallCenterZ# = Z#
EndFunction
`_____________________________________________________________________________________________________
Function Explorer_SetCameraPosition(X#, Y#, Z#)
ExplorerBaseX# = X#: ExplorerBaseY# = Y#: ExplorerBaseZ# = Z#
ExplorerCurrentX# = X#: ExplorerCurrentY# = Y#: ExplorerCurrentZ# = Z#
EndFunction
`_____________________________________________________________________________________________________
Function Explorer_SetCameraRotation(Yaw#, Pitch#, Roll#)
ExplorerBaseYaw# = Yaw#: ExplorerBasePitch# = Pitch#: ExplorerBaseRoll# = Roll#
ExplorerCurrentYaw# = Yaw#: ExplorerCurrentPitch# = Pitch#: ExplorerCurrentRoll# = Roll#
EndFunction
`_____________________________________________________________________________________________________
Function Explorer_UpdateCamera(Camera)
Position Camera Camera, ExplorerCurrentX#, ExplorerCurrentY#, ExplorerCurrentZ#
Rotate Camera Camera, ExplorerCurrentPitch#, ExplorerCurrentYaw#, 0.0
Roll Camera Left Camera, ExplorerCurrentRoll#
EndFunction
`_____________________________________________________________________________________________________
Function Explorer_SetBase()
ExplorerBaseX# = ExplorerCurrentX#: ExplorerBaseYaw# = WrapValue(ExplorerCurrentYaw#)
ExplorerBaseY# = ExplorerCurrentY#: ExplorerBasePitch# = WrapValue(ExplorerCurrentPitch#)
ExplorerBaseZ# = ExplorerCurrentZ#: ExplorerBaseRoll# = WrapValue(ExplorerCurrentRoll#)
EndFunction
`_____________________________________________________________________________________________________
Function Explorer_TrackBall(DeltaYaw#, DeltaPitch#)
Local SinAngle#, CosAngle#
X# = ExplorerBaseX# - ExplorerTrackBallCenterX#
Y# = ExplorerBaseY# - ExplorerTrackBallCenterY#
Z# = ExplorerBaseZ# - ExplorerTrackBallCenterZ#
SinAngle# = Sin(ExplorerBaseYaw#): CosAngle# = Cos(ExplorerBaseYaw#)
X2# = X#*CosAngle# - Z#*SinAngle#
Y2# = Y#
Z2# = X#*SinAngle# + Z#*CosAngle#
SinAngle# = Sin(DeltaPitch#): CosAngle# = Cos(DeltaPitch#)
X# = X2#
Y# = Y2#*CosAngle# - Z2#*SinAngle#
Z# = Y2#*SinAngle# + Z2#*CosAngle#
SinAngle# = Sin(DeltaYaw#-ExplorerBaseYaw#): CosAngle# = Cos(DeltaYaw#-ExplorerBaseYaw#)
ExplorerCurrentX# = ExplorerTrackBallCenterX# + X#*CosAngle# - Z#*SinAngle#
ExplorerCurrentY# = ExplorerTrackBallCenterY# + Y#
ExplorerCurrentZ# = ExplorerTrackBallCenterZ# + X#*SinAngle# + Z#*CosAngle#
ExplorerCurrentYaw# = ExplorerBaseYaw# - DeltaYaw#
ExplorerCurrentPitch# = ExplorerBasePitch# + DeltaPitch#
EndFunction
`_____________________________________________________________________________________________________
Function SelectObject(Object, OutlineObject)
If Object Exist(OutlineObject) Then Delete Object OutlineObject
Clone Object OutlineObject, Object
Set Object WireFrame OutlineObject, 1
Set Object Light OutlineObject, 1
Set Object Emissive OutlineObject, 0xff0000
Set Object Diffuse OutlineObject, 0
Enable Object ZBias OutlineObject, -1.0, 0.0
EndFunction
`_____________________________________________________________________________________________________
Function CreateScene()
Make Matrix 1, 4.0, 4.0, 4, 4
Position Matrix 1, -2.0, 0.0, -2.0
Make Object Cube 1, 1.0
Position Object 1, 0.0, 0.5, 1.5
Make Object Sphere 2, 1.0
Position Object 2, 1.5, 0.5, 0.0
Make Object Cylinder 3, 1.0
Position Object 3, 0.0, 0.5, -1.5
Make Object Cone 4, 1.0
Position Object 4, -1.5, 0.5, 0.0
EndFunction
This snippet is a part of my
Simple 3D Sandbox