Calculating hidden surfaces for 3D objects
Posted: Sat Jan 29, 2022 9:56 am
Hi, tested a nice graphics library from Stargate and now I started to make something similar to show (convex) objects in 3D...
...hopefully some of you have soe experience in doing such stuff and maybe someone can give e a hint for calculating which surfaces needs to be drawn before others.
In the example below you can see what's going on - rotating the objects are done using the cursor keys (use shift to move the object), some object data will be displayed by using the keys 'D' and 'I'...
...hopefully some of you have soe experience in doing such stuff and maybe someone can give e a hint for calculating which surfaces needs to be drawn before others.
In the example below you can see what's going on - rotating the objects are done using the cursor keys (use shift to move the object), some object data will be displayed by using the keys 'D' and 'I'...
Code: Select all
; Define
EnableExplicit
#WX=1200
#WY=850
#ZoomScale=0.1
#ZweiPi=#PI+#PI
#PiHalbe=#PI/2
#PiTeil=#PI/18
#PiRadiant=#PI/180
#PiGrad=180/#PI
; ------------------------------------------------------------------------------------
Structure DotType
x.d; skaliert
y.d; skaliert
z.d; skaliert
_x.i; 2D-Transformation
_y.i; 2D-Transformation
;_rb.i; 3D-Punkt-Distanz (rot/blau)
_distance.q; Z-Distanz zum Betrachter
EndStructure
Structure ObjectType
Type.i; Punkt, Linie, Oberfläche (3 oder 4 Punkte)
Point.i[4]; Punktkoordinaten
Color.i; Flächenfarbe
Outline.i; Linienfarbe
Centre.i; Flächenmittelpunkt
Visible.i; sichtbares Segment
EndStructure
Structure SorterType
Object.i
Distance.q
EndStructure
Structure Mat
x.d[4]
y.d[4]
z.d[4]
t.d[4]
EndStructure
Structure SettingType
ShowOutline.i
ShowSurface.i
ShowPoints.i
ShowInformation.i
ModeCalculation.i
ModeRotation.i
ModeFill.i
ModeLine.i
Optimizer.i
ZoomFactor.i
ShowThreeD.i; 3D-Darstellung
ThreeD_Distance.i; Punktabstand für 3D-Effekt; - - -
ThreeD_Left.i; Farbfilter für das linke Auge (rot) - - -
ThreeD_Right.i; ...rechtes Auge (grün, blau) - - -
EndStructure
; ------------------------------------------------------------------------------------
Global MaxElements= 25000
Global.Mat Matrix, Calc, RotXMat, RotYMat, RotZMat, Camera, TempMat
Global Dim Dot.DotType(MaxElements)
Global Dim Object.ObjectType(MaxElements)
Global Dim Sorter.SorterType(MaxElements)
; Bildschirmgröße für Graphikfenster
Global ScreenX=GetSystemMetrics_(#SM_CXSCREEN)
Global ScreenY=GetSystemMetrics_(#SM_CYSCREEN)
Global Screen_X=ScreenX-1
Global Screen_Y=ScreenY-1
Global ScreenZ
Global OffsetX=ScreenX>>1
Global OffsetY=ScreenY>>1
; Skalierung für 3D-Transformation
Global.d ViewX, ViewY, ViewZ, Scale
Global.d AngleX, AngleY, AngleZ; Rotationswinkel (per Maus auswählbar)
Global.d XdivPi=#PI/OffsetX; Skalierung, um genau eine Drehung nach 'X' zu erlauben
Global.d YdivPi=#PI/OffsetY; Skalierung, um genau eine Drehung nach 'Y' zu erlauben
Global.d RealZoomFactor; skalierte Vergrößerung
Global CounterPoints, CounterObjects
Global OptCamera; =OptCameraZ
Global OptCameraX, OptCameraY
Global Setting.SettingType
; ------------------------------------------------------------------------------------
OptCamera= 500
With Setting
\ShowSurface= 1
\ShowOutline= 0
\ZoomFactor= 25
\ModeRotation= 1
\ModeFill= 1
\Optimizer= 1
EndWith
; ------------------------------------------------------------------------------------
Enumeration
#Win
#Canvas
;
#ShiftLeft
#ShiftRight
#ShiftUp
#ShiftDown
#RotateLeft
#RotateRight
#RotateUp
#RotateDown
#PerspectiveMinus
#PerspectivePlus
#ResetView
#ToggleRotation
#ToggleLine
#ToggleFill
#ToggleCalcMode
#ToggleOutline
#ToggleSurface
#TogglePoints
#ToggleInformation
EndEnumeration
; ------------------------------------------------------------------------------------
Macro StrM(value)
RSet(StrD(value,2),8)
EndMacro
Macro CreateLine(p1,p2,outline)
CreateObject(#ObjectTypeLine,p1,p2,#Null,#Null,#Null,outline)
EndMacro
Macro CreateRectangle(p1,p2,p3,p4,color,outline)
CreateObject(#ObjectTypeRectangle,p1,p2,p3,p4,color,outline)
EndMacro
; EndDefine
Procedure Distance(dot)
With Dot(dot)
ProcedureReturn Sqr(Pow(ViewX-OptCameraX+\x,2)+Pow(ViewY-OptCameraY+\y,2)+Pow(ViewZ-OptCamera+\z,2))
ProcedureReturn Sqr(Pow(ViewX-\x,2)+Pow(ViewY-\y,2)+Pow(ViewZ-\z,2))
ProcedureReturn Sqr(Pow(OptCameraX-\x,2)+Pow(OptCameraY-\y,2)+Pow(OptCamera-\z,2))
EndWith
EndProcedure
Procedure SetNorm(*m.mat)
*m\x[0]=1 : *m\y[0]=0 : *m\z[0]=0 : *m\t[0]=0
*m\x[1]=0 : *m\y[1]=1 : *m\z[1]=0 : *m\t[1]=0
*m\x[2]=0 : *m\y[2]=0 : *m\z[2]=1 : *m\t[2]=0
*m\x[3]=0 : *m\y[3]=0 : *m\z[3]=0 : *m\t[3]=1
EndProcedure
Procedure SetTransformation(*m.mat,x.d,y.d,z.d)
*m\x[0]=1 : *m\y[0]=0 : *m\z[0]=0 : *m\t[0]=0
*m\x[1]=0 : *m\y[1]=1 : *m\z[1]=0 : *m\t[1]=0
*m\x[2]=0 : *m\y[2]=0 : *m\z[2]=1 : *m\t[2]=0
*m\x[3]=x : *m\y[3]=y : *m\z[3]=z : *m\t[3]=1
EndProcedure
Procedure SetCamera(x,y,z.d)
OptCameraX=x
OptCameraY=y
OptCamera=z
Camera\x[0]=1 : Camera\y[0]=0 : Camera\z[0]=0 : Camera\t[0]=0
Camera\x[1]=0 : Camera\y[1]=1 : Camera\z[1]=0 : Camera\t[1]=0
Camera\x[2]=0 : Camera\y[2]=0 : Camera\z[2]=1 : Camera\t[2]=0
Camera\x[3]=x : Camera\y[3]=y : Camera\z[3]=z : Camera\t[3]=1
EndProcedure
Procedure SetScale(*m.mat,x.d,y.d,z.d)
*m\x[0]=x : *m\y[0]=0 : *m\z[0]=0 : *m\t[0]=0
*m\x[1]=0 : *m\y[1]=y : *m\z[1]=0 : *m\t[1]=0
*m\x[2]=0 : *m\y[2]=0 : *m\z[2]=z : *m\t[2]=0
*m\x[3]=0 : *m\y[3]=0 : *m\z[3]=0 : *m\t[3]=1
EndProcedure
Procedure SetRotX(*m.mat,angle.d)
Protected s.d=Sin(angle)
Protected c.d=Cos(angle)
*m\x[0]=1 : *m\y[0]=0 : *m\z[0]=0 : *m\t[0]=0
*m\x[1]=0 : *m\y[1]=c : *m\z[1]=s : *m\t[1]=0
*m\x[2]=0 : *m\y[2]=-s : *m\z[2]=c : *m\t[2]=0
*m\x[3]=0 : *m\y[3]=0 : *m\z[3]=0 : *m\t[3]=1
EndProcedure
Procedure SetRotY(*m.mat,angle.d)
Protected s.d=Sin(angle)
Protected c.d=Cos(angle)
*m\x[0]=c : *m\y[0]=0 : *m\z[0]=s : *m\t[0]=0
*m\x[1]=0 : *m\y[1]=1 : *m\z[1]=0 : *m\t[1]=0
*m\x[2]=-s : *m\y[2]=0 : *m\z[2]=c : *m\t[2]=0
*m\x[3]=0 : *m\y[3]=0 : *m\z[3]=0 : *m\t[3]=1
EndProcedure
Procedure SetRotZ(*m.mat,angle.d)
Protected s.d=Sin(angle)
Protected c.d=Cos(angle)
*m\x[0]=c : *m\y[0]=s : *m\z[0]=0 : *m\t[0]=0
*m\x[1]=-s : *m\y[1]=c : *m\z[1]=0 : *m\t[1]=0
*m\x[2]=0 : *m\y[2]=0 : *m\z[2]=1 : *m\t[2]=0
*m\x[3]=0 : *m\y[3]=0 : *m\z[3]=0 : *m\t[3]=1
EndProcedure
Procedure Multiply(*m.mat,*n.mat,*result.mat)
TempMat\x[0]=*m\x[0]**n\x[0] + *m\x[1]**n\y[0] + *m\x[2]**n\z[0] + *m\x[3]**n\t[0]
TempMat\y[0]=*m\y[0]**n\x[0] + *m\y[1]**n\y[0] + *m\y[2]**n\z[0] + *m\y[3]**n\t[0]
TempMat\z[0]=*m\z[0]**n\x[0] + *m\z[1]**n\y[0] + *m\z[2]**n\z[0] + *m\z[3]**n\t[0]
TempMat\t[0]=*m\t[0]**n\x[0] + *m\t[1]**n\y[0] + *m\t[2]**n\z[0] + *m\t[3]**n\t[0]
TempMat\x[1]=*m\x[0]**n\x[1] + *m\x[1]**n\y[1] + *m\x[2]**n\z[1] + *m\x[3]**n\t[1]
TempMat\y[1]=*m\y[0]**n\x[1] + *m\y[1]**n\y[1] + *m\y[2]**n\z[1] + *m\y[3]**n\t[1]
TempMat\z[1]=*m\z[0]**n\x[1] + *m\z[1]**n\y[1] + *m\z[2]**n\z[1] + *m\z[3]**n\t[1]
TempMat\t[1]=*m\t[0]**n\x[1] + *m\t[1]**n\y[1] + *m\t[2]**n\z[1] + *m\t[3]**n\t[1]
TempMat\x[2]=*m\x[0]**n\x[2] + *m\x[1]**n\y[2] + *m\x[2]**n\z[2] + *m\x[3]**n\t[2]
TempMat\y[2]=*m\y[0]**n\x[2] + *m\y[1]**n\y[2] + *m\y[2]**n\z[2] + *m\y[3]**n\t[2]
TempMat\z[2]=*m\z[0]**n\x[2] + *m\z[1]**n\y[2] + *m\z[2]**n\z[2] + *m\z[3]**n\t[2]
TempMat\t[2]=*m\t[0]**n\x[2] + *m\t[1]**n\y[2] + *m\t[2]**n\z[2] + *m\t[3]**n\t[2]
TempMat\x[3]=*m\x[0]**n\x[3] + *m\x[1]**n\y[3] + *m\x[2]**n\z[3] + *m\x[3]**n\t[3]
TempMat\y[3]=*m\y[0]**n\x[3] + *m\y[1]**n\y[3] + *m\y[2]**n\z[3] + *m\y[3]**n\t[3]
TempMat\z[3]=*m\z[0]**n\x[3] + *m\z[1]**n\y[3] + *m\z[2]**n\z[3] + *m\z[3]**n\t[3]
TempMat\t[3]=*m\t[0]**n\x[3] + *m\t[1]**n\y[3] + *m\t[2]**n\z[3] + *m\t[3]**n\t[3]
*result\x[0]=TempMat\x[0]
*result\x[1]=TempMat\x[1]
*result\x[2]=TempMat\x[2]
*result\x[3]=TempMat\x[3]
*result\y[0]=TempMat\y[0]
*result\y[1]=TempMat\y[1]
*result\y[2]=TempMat\y[2]
*result\y[3]=TempMat\y[3]
*result\z[0]=TempMat\z[0]
*result\z[1]=TempMat\z[1]
*result\z[2]=TempMat\z[2]
*result\z[3]=TempMat\z[3]
*result\t[0]=TempMat\t[0]
*result\t[1]=TempMat\t[1]
*result\t[2]=TempMat\t[2]
*result\t[3]=TempMat\t[3]
EndProcedure
Procedure ShowMat(*m.mat,title.s="")
Debug "- "+title+RSet(" ",38-Len(title),"-")
Debug "X"+StrM(*m\x[0])+" |"+StrM(*m\x[1])+" |"+StrM(*m\x[2])+" |"+StrM(*m\x[3])
Debug "Y"+StrM(*m\y[0])+" |"+StrM(*m\y[1])+" |"+StrM(*m\y[2])+" |"+StrM(*m\y[3])
Debug "Z"+StrM(*m\z[0])+" |"+StrM(*m\z[1])+" |"+StrM(*m\z[2])+" |"+StrM(*m\z[3])
Debug "T"+StrM(*m\t[0])+" |"+StrM(*m\t[1])+" |"+StrM(*m\t[2])+" |"+StrM(*m\t[3])
Macro DebugMat
ShowMat(@Camera,"Camera")
ShowMat(@Matrix,"Matrix")
ShowMat(@Calc,"Calc")
EndMacro
EndProcedure
Procedure CreatePoint(x.d,y.d,z.d)
Protected i
If Setting\Optimizer; Punkt in den gespeicherten Punkten suchen...
i=CounterPoints
While i
With Dot(i)
If \x=x And \y=y And \z=z
Break
EndIf
EndWith
i-1
Wend
EndIf
If i=0 And CounterPoints<MaxElements; neuer Punkt
CounterPoints+1
i=CounterPoints
EndIf
With Dot(i); Koordinaten setzen
\x=x
\y=y
\z=z
EndWith
ProcedureReturn i
EndProcedure
Procedure CreateObject(type,a,b,c,d,color,outline=#Null)
Enumeration
#ObjectTypeDot
#ObjectTypeLine
#ObjectTypeTriangle
#ObjectTypeRectangle
EndEnumeration
If CounterObjects<MaxElements
CounterObjects+1
With Object(CounterObjects)
\Type=type
\Point[0]=a
\Point[1]=b
\Point[2]=c
\Point[3]=d
\Color=color
\Outline=outline
Select type
Case #ObjectTypeLine
\Centre=CreatePoint((Dot(a)\x+Dot(b)\x)/2,(Dot(a)\y+Dot(b)\y)/2,(Dot(a)\z+Dot(b)\z)/2)
Case #ObjectTypeRectangle
\Centre=CreatePoint((Dot(a)\x+Dot(b)\x+Dot(c)\x+Dot(d)\x)/4,(Dot(a)\y+Dot(b)\y+Dot(c)\y+Dot(d)\y)/4,(Dot(a)\z+Dot(b)\z+Dot(c)\z+Dot(d)\z)/4)
EndSelect
EndWith
ProcedureReturn CounterObjects
EndIf
ProcedureReturn #Null
EndProcedure
Procedure CreateBox(ax.d,ay.d,az.d, bx.d,by.d,bz.d,color.i,outline.i=#Null)
Protected p1,p2,p3,p4,p5,p6,p7,p8
bx+ax
by+ay
bz+az
p1=CreatePoint(ax,ay,az)
p2=CreatePoint(bx,ay,az)
p3=CreatePoint(bx,by,az)
p4=CreatePoint(ax,by,az)
p5=CreatePoint(ax,ay,bz)
p6=CreatePoint(bx,ay,bz)
p7=CreatePoint(bx,by,bz)
p8=CreatePoint(ax,by,bz)
If outline
CreateLine(p1,p2,outline)
CreateLine(p2,p3,outline)
CreateLine(p3,p4,outline)
CreateLine(p4,p1,outline)
CreateLine(p5,p6,outline)
CreateLine(p6,p7,outline)
CreateLine(p7,p8,outline)
CreateLine(p8,p5,outline)
CreateLine(p1,p5,outline)
CreateLine(p2,p6,outline)
CreateLine(p3,p7,outline)
CreateLine(p4,p8,outline)
EndIf
CreateRectangle(p1,p2,p3,p4,color,outline)
CreateRectangle(p1,p2,p6,p5,color,outline)
CreateRectangle(p2,p3,p7,p6,color,outline)
CreateRectangle(p3,p4,p8,p7,color,outline)
CreateRectangle(p4,p1,p5,p8,color,outline)
CreateRectangle(p5,p6,p7,p8,color,outline)
EndProcedure
Procedure Redraw()
Protected.i i,n
Protected.d x,y,z
Protected.s s
Protected FillMode
Protected.d LineMode
StartVectorDrawing(CanvasVectorOutput(#Canvas))
VectorFont(FontID(0))
;VectorSourceColor($C0FFFFFF)
VectorSourceColor($FFFFFFFF)
FillVectorOutput()
FillMode=Setting\ModeFill*$FF000000
LineMode=Setting\ModeLine+0.8
If Setting\ShowInformation
VectorSourceColor($FF000080)
MovePathCursor(20,20)
DrawVectorText("Viewpoint: "+Str(ViewX)+" | "+Str(ViewY)+" | "+Str(ViewZ))
MovePathCursor(20,40)
DrawVectorText("Camera: "+Str(OptCameraX)+" | "+Str(OptCameraY)+" | "+Str(OptCamera))
EndIf
If Setting\ShowSurface
While i<CounterObjects
i+1
n=Sorter(i)\Object
With Object(n)
Select \type
Case #ObjectTypeRectangle
MovePathCursor(Dot(\Point[0])\_x,Dot(\Point[0])\_y)
AddPathLine(Dot(\Point[1])\_x,Dot(\Point[1])\_y)
AddPathLine(Dot(\Point[2])\_x,Dot(\Point[2])\_y)
AddPathLine(Dot(\Point[3])\_x,Dot(\Point[3])\_y)
ClosePath()
VectorSourceColor(\Color|FillMode)
FillPath(#PB_Path_Preserve)
VectorSourceColor(\Outline)
StrokePath(LineMode,#PB_Path_RoundCorner)
If Setting\ShowInformation
s=Str(i)+" (#"+Str(n)+") "+Str(Dot(\Centre)\_distance)
s=Str(Distance(\Centre))
Debug s
MovePathCursor(Dot(\Centre)\_x-VectorTextWidth(s)/2,Dot(\Centre)\_y-VectorTextHeight(s)/2)
VectorSourceColor($FF000000)
DrawVectorText(s)
EndIf
EndSelect
EndWith
Wend
EndIf
If Setting\ShowOutline
LineMode=Setting\ModeLine+1
n=0
While n<CounterObjects
n+1
With Object(n)
Select \type
Case #ObjectTypeLine
If \Outline
MovePathCursor(Dot(\Point[0])\_x,Dot(\Point[0])\_y)
AddPathLine(Dot(\Point[1])\_x,Dot(\Point[1])\_y)
VectorSourceColor(\Outline)
StrokePath(LineMode,#PB_Path_RoundEnd)
EndIf
EndSelect
EndWith
Wend
EndIf
If Setting\ShowPoints
x=120
y=20+Setting\ShowInformation*60
z=1
n=0
While n<CounterPoints
n+1
VectorSourceColor($FF000000+$A0<<(8*n%3))
With Object(n)
AddPathCircle(Dot(n)\_x,Dot(n)\_y,3)
FillPath()
MovePathCursor(Dot(n)\_x,Dot(n)\_y)
AddPathLine(x,y)
StrokePath(1)
s=StrF(Dot(n)\_distance,2)
MovePathCursor(x-z*VectorTextWidth(s),y-VectorTextHeight(s)/2)
DrawVectorText(s)
y+18
If y>#WY-30
x=#WX-100
y=20
z=0
EndIf
EndWith
Wend
EndIf
StopVectorDrawing()
EndProcedure
Procedure Recalc(mode)
Protected i
Protected maxdist.q
Multiply(@Camera,@Matrix,@Calc)
DebugMat
RealZoomFactor=Setting\ZoomFactor * #ZoomScale
For i=1 To CounterPoints
With Dot(i)
ViewX = \x*calc\x[0] + \y*calc\x[1] + \z*calc\x[2] + calc\x[3]
ViewY = \x*calc\y[0] + \y*calc\y[1] + \z*calc\y[2] + calc\y[3]
ViewZ = \x*calc\z[0] + \y*calc\z[1] + \z*calc\z[2] + calc\z[3]
Scale=OptCamera/ViewZ
\_x=ViewX*Scale*RealZoomFactor+OffsetX
\_y=ViewY*Scale*RealZoomFactor+OffsetY
\_distance=Scale*10000000
;\_distance=Int(Scale*10000000)*10000-(Abs(\_x-OffsetX)+Abs(\_y-OffsetY))/100
;\_rb=(Opt3DDistance+OptZoomFactor)/(ViewZ+32)
EndWith
Next i
For i=1 To CounterObjects
With Sorter(i)
\Object=i
If Setting\ModeCalculation
If 0
maxdist=#Null
If maxdist < Dot(Object(i)\Point[0])\_distance
maxdist=Dot(Object(i)\Point[0])\_distance
EndIf
If maxdist < Dot(Object(i)\Point[1])\_distance
maxdist=Dot(Object(i)\Point[1])\_distance
EndIf
If maxdist < Dot(Object(i)\Point[2])\_distance
maxdist=Dot(Object(i)\Point[2])\_distance
EndIf
If maxdist < Dot(Object(i)\Point[3])\_distance
maxdist=Dot(Object(i)\Point[3])\_distance
EndIf
\Distance=maxdist
Else
maxdist=Dot(Object(i)\Point[0])\_distance
If maxdist > Dot(Object(i)\Point[1])\_distance
maxdist=Dot(Object(i)\Point[1])\_distance
EndIf
If maxdist > Dot(Object(i)\Point[2])\_distance
maxdist=Dot(Object(i)\Point[2])\_distance
EndIf
If maxdist > Dot(Object(i)\Point[3])\_distance
maxdist=Dot(Object(i)\Point[3])\_distance
EndIf
\Distance=maxdist
EndIf
Else
\Distance=Dot(Object(i)\Centre)\_distance; Distanz Mittelpunkt
;\Distance=Distance(Object(i)\Centre)
EndIf
EndWith
Next i
SortStructuredArray(Sorter(),#PB_Sort_Ascending,OffsetOf(SorterType\Distance),TypeOf(SorterType\Distance),1,CounterObjects)
If mode
Redraw()
EndIf
EndProcedure
Procedure Rotation()
SetRotX(@RotXMat,AngleY)
SetRotZ(@RotYMat,AngleX)
SetRotY(@RotZMat,AngleZ)
Multiply(@RotXMat,@RotYMat,@Matrix)
Multiply(@Matrix,@RotZMat,@Matrix)
Recalc(#True)
EndProcedure
Procedure DoObjects(demo)
Select demo
Case 0
CreateBox(0,0,0, 100,100,100,$E0f0a060,$80000000)
CreateBox(200,0,0, 100,100,100,$E0f060a0,$80000000)
CreateBox(0,200,0, 100,100,100,$E0c0a0f0,$80000000)
CreateBox(0,0,200, 100,100,100,$E0c0f0a0,$80000000)
Case 1
CreateBox(0,0,0, 100,100,100,$E0f0a060,$80000000)
;CreateBox(120,0,0, 80,100,80,$E0f060a0,$80000000)
;CreateBox(0,0,120, 60,100,60,$E0c0a0f0,$80000000)
;CreateBox(120,0,120, 40,100,40,$E0c0f0a0,$80000000)
CreateBox(0,0,105, 10,100,10,$10a0f060,$80000000)
;CreateBox(105,0,105, 10,100,10,$10a0f060,$80000000)
EndSelect
EndProcedure
Procedure Main()
LoadFont(0,"Segoe UI",8)
OpenWindow(#Win,8,8,#WX,#WY,"Cursor-Keys, Zoom +/- Options: O=Outline S=Surfaces, L=Lines, D=Dots Modes: F=Fill, R=Rotation, C=Depth Other: P=Perspective, I=Debugging")
CanvasGadget(#Canvas,0,0,#WX,#WY)
AddKeyboardShortcut(#Win,#PB_Shortcut_Left|#PB_Shortcut_Shift,#ShiftLeft)
AddKeyboardShortcut(#Win,#PB_Shortcut_Right|#PB_Shortcut_Shift,#ShiftRight)
AddKeyboardShortcut(#Win,#PB_Shortcut_Up|#PB_Shortcut_Shift,#ShiftUp)
AddKeyboardShortcut(#Win,#PB_Shortcut_Down|#PB_Shortcut_Shift,#ShiftDown)
AddKeyboardShortcut(#Win,#PB_Shortcut_Left,#RotateLeft)
AddKeyboardShortcut(#Win,#PB_Shortcut_Right,#RotateRight)
AddKeyboardShortcut(#Win,#PB_Shortcut_Up,#RotateUp)
AddKeyboardShortcut(#Win,#PB_Shortcut_Down,#RotateDown)
AddKeyboardShortcut(#Win,#PB_Shortcut_Back,#ResetView)
AddKeyboardShortcut(#Win,#PB_Shortcut_C,#ToggleCalcMode)
AddKeyboardShortcut(#Win,#PB_Shortcut_D,#TogglePoints)
AddKeyboardShortcut(#Win,#PB_Shortcut_F,#ToggleFill)
AddKeyboardShortcut(#Win,#PB_Shortcut_I,#ToggleInformation)
AddKeyboardShortcut(#Win,#PB_Shortcut_L,#ToggleLine)
AddKeyboardShortcut(#Win,#PB_Shortcut_O,#ToggleOutline)
AddKeyboardShortcut(#Win,#PB_Shortcut_P,#PerspectivePlus)
AddKeyboardShortcut(#Win,#PB_Shortcut_P|#PB_Shortcut_Shift,#PerspectiveMinus)
AddKeyboardShortcut(#Win,#PB_Shortcut_R,#ToggleRotation)
AddKeyboardShortcut(#Win,#PB_Shortcut_S,#ToggleSurface)
; ------------------------------------------------------------------------------------
DoObjects(1)
; ------------------------------------------------------------------------------------
OptCameraX=-100
OptCameraY=50
OptCamera=1000
AngleX=Radian(0)
AngleY=Radian(-170)
AngleZ=Radian(20)
SetCamera(OptCameraX,OptCameraY,OptCamera)
SetNorm(@Matrix)
Rotation()
Repeat
Select WindowEvent()
Case #PB_Event_Gadget,#PB_Event_Menu
Select EventGadget()
Case #ShiftLeft
SetCamera(OptCameraX-30,OptCameraY,OptCamera)
Recalc(#True)
Case #ShiftRight
SetCamera(OptCameraX+30,OptCameraY,OptCamera)
Recalc(#True)
Case #ShiftUp
SetCamera(OptCameraX,OptCameraY-30,OptCamera)
Recalc(#True)
Case #ShiftDown
SetCamera(OptCameraX,OptCameraY+30,OptCamera)
Recalc(#True)
Case #RotateLeft
If Setting\ModeRotation
AngleZ-#PiTeil
If AngleZ<0 : AngleZ+#ZweiPi : EndIf
Else
AngleX-#PiTeil
If AngleX<0 : AngleX+#ZweiPi : EndIf
EndIf
Rotation()
Case #RotateRight
If Setting\ModeRotation
AngleZ+#PiTeil
If AngleZ>#ZweiPi : AngleZ-#ZweiPi : EndIf
Else
AngleX+#PiTeil
If AngleX>#ZweiPi : AngleX-#ZweiPi : EndIf
EndIf
Rotation()
Case #RotateUp
AngleY-#PiTeil
Rotation()
Case #RotateDown
AngleY+#PiTeil
Rotation()
Case #ToggleOutline
Setting\ShowOutline!1
Redraw()
Case #ToggleSurface
Setting\ShowSurface!1
Redraw()
Case #TogglePoints
Setting\ShowPoints!1
Redraw()
Case #ToggleCalcMode
Setting\ModeCalculation!1
Recalc(#True)
Case #ToggleInformation
Setting\ShowInformation!1
Redraw()
Case #ToggleFill
Setting\ModeFill!1
Redraw()
Case #ToggleLine
Setting\ModeLine!1
Redraw()
Case #ToggleRotation
Setting\ModeRotation!1
Case #PerspectivePlus
If OptCamera>300
SetCamera(OptCameraX,OptCameraY,OptCamera-50)
Recalc(#True)
EndIf
Case #PerspectiveMinus
If OptCamera<3000
SetCamera(OptCameraX,OptCameraY,OptCamera+50)
Recalc(#True)
EndIf
Case #ResetView
AngleX=0 : AngleY=0 : AngleZ=0
ViewX=0 : ViewY=0 : ViewZ=0
SetCamera(0,0,1000)
SetNorm(@Matrix)
Rotation()
Recalc(#True)
EndSelect
Case #PB_Event_CloseWindow
End
Case #WM_CHAR
Select EventwParam()
Case '+'
If OptCamera>300
Setting\ZoomFactor+1
Recalc(#True)
EndIf
Case '-'
If Setting\ZoomFactor>1 : Setting\ZoomFactor-1 : EndIf
Recalc(#True)
EndSelect
EndSelect
ForEver
EndProcedure
Main()
End