Sebastian hat geschrieben:Bei dem Beispiel fällt mir auf: Die recht Fläche scheint ein wenig um den Mittelpunkt zu "eiern". Woran liegt es und kann man es umgehen?
Jo da hast du recht, liegt daran, dass ich in dem Beispiel "nur" ein Beispiel für z geben wollte.
Ich habe dort jedoch die Radiusverkleinerung hinten unterschlagen.
Hier eine Version bei der die Achse stabil ist:
Code: Alles auswählen
InitSprite()
InitSprite3D()
OpenWindow(0, 0, 0, 800, 600, "Screen", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(0), 0, 0, WindowWidth(0), WindowHeight(0), 0, 0, 0)
CreateSprite(1, 64, 64, #PB_Sprite_Texture)
StartDrawing(SpriteOutput(1))
Box(0, 0, 64, 64, $808080)
For x = 0 To 7
For y = 0 To 7
If (x+y)%2 : Box(x*8, y*8, 8, 8, $FFFFFF) : EndIf
Next
Next
StopDrawing()
CreateSprite3D(1, 1)
Repeat
ClearScreen(0)
#HalfSize = 150
#Distance = 500
Start3D()
a.f = ElapsedMilliseconds()/1000
z1.f = #Distance-Sin(a)*#HalfSize : z4.f=z1
z2.f = #Distance+Sin(a)*#HalfSize : z3.f=z2
x1.f = -Cos(a)*#HalfSize*#Distance/z1 : x4.f=x1
x2.f = Cos(a)*#HalfSize*#Distance/z2 : x3.f=x2
j.f = #HalfSize*#HalfSize
y1.f = -#HalfSize-Sin(a)*j/z1 : y2.f=-#HalfSize+Sin(a)*j/z2
y3.f = #HalfSize-Sin(a)*j/z3 : y4.f= #HalfSize+Sin(a)*j/z4
TransformSprite3D(1, x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4)
DisplaySprite3D(1, 400, 300)
TransformSprite3D(1, x2,y2,z2, x1,y1,z1, x4,y4,z4, x3,y3,z3)
DisplaySprite3D(1, 400, 300)
Stop3D()
FlipBuffers()
Until WindowEvent() = #PB_Event_CloseWindow
Aber wie gesagt, das ist eine recht unflexible variante ...
Man kann natürlich auch eine mit der echten RotationsMatrix rechnen, ähnlich wie hier:
http://www.purebasic.fr/german/viewtopi ... =3&t=23247
Dort dann mittels Prozedure ein Sprite mit 3 Koordinaten und 3 Rotationen anzuzeigen
Das sehe dann so aus:
Code: Alles auswählen
Structure Vector3D
x.f : y.f : z.f
EndStructure
Structure Rotation3D
CosX.f : SinX.f : CosY.f : SinY.f : CosZ.f : SinZ.f
EndStructure
Procedure Drawing3D_UpdateRotation3D(*Rotation3D.Rotation3D, Rx.f, Ry.f, Rz.f)
With *Rotation3D
\CosX = Cos(Rx) : \SinX = Sin(Rx)
\CosY = Cos(Ry) : \SinY = Sin(Ry)
\CosZ = Cos(Rz) : \SinZ = Sin(Rz)
EndWith
EndProcedure
Procedure Drawing3D_MatrixTimesVector(*Result.Vector3D, *Rotation3D.Rotation3D, *Vector.Vector3D)
With *Rotation3D
*Result\x = *Vector\x * (\CosY*\CosZ) + *Vector\y * (\CosY*\SinZ) + *Vector\z * (-\SinY)
*Result\y = *Vector\x * (\CosZ*\SinX*\SinY-\CosX*\SinZ) + *Vector\y * (\CosX*\CosZ+\SinX*\SinY*\SinZ) + *Vector\z * (\CosY*\SinX)
*Result\z = *Vector\x * (\CosX*\CosZ*\SinY+\SinX*\SinZ) + *Vector\y * (-\CosZ*\SinX+\CosX*\SinY*\SinZ) + *Vector\z * (\CosX*\CosY)
EndWith
EndProcedure
#Distance = 800
Procedure DisplayField3D(Sprite3D, Width.f, Height.f, Px.f, Py.f, Pz.f, Rx.f, Ry.f, Rz.f)
Protected Dim Corner.Vector3D(3), Dim NewCorner.Vector3D(3)
Protected Dim V.Vector3D(3), Rotation3D.Rotation3D
Corner(0)\x = -Width*0.5 : Corner(0)\y = -Height*0.5
Corner(1)\x = Width*0.5 : Corner(1)\y = -Height*0.5
Corner(2)\x = Width*0.5 : Corner(2)\y = Height*0.5
Corner(3)\x = -Width*0.5 : Corner(3)\y = Height*0.5
Drawing3D_UpdateRotation3D(Rotation3D, Rx, Ry, Rz)
For n = 0 To 3
Drawing3D_MatrixTimesVector(NewCorner(n), Rotation3D, Corner(n))
NewCorner(n)\z + Pz
V(n)\x = NewCorner(n)\x * #Distance / (NewCorner(n)\z+#Distance) + Px
V(n)\y = NewCorner(n)\y * #Distance / (NewCorner(n)\z+#Distance) + Py
V(n)\z = NewCorner(n)\z + #Distance
Next
TransformSprite3D(Sprite3D, V(0)\x,V(0)\y,V(0)\z, V(1)\x,V(1)\y,V(1)\z, V(2)\x,V(2)\y,V(2)\z, V(3)\x,V(3)\y,V(3)\z)
DisplaySprite3D(Sprite3D, 0, 0)
EndProcedure
InitSprite()
InitSprite3D()
OpenWindow(0, 0, 0, 800, 600, "Screen", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(0), 0, 0, WindowWidth(0), WindowHeight(0), 0, 0, 0)
Sprite3DQuality(1)
Font = FontID(LoadFont(#PB_Any, "Arial", 48))
CreateSprite(1, 64, 64, #PB_Sprite_Texture)
StartDrawing(SpriteOutput(1))
For x = 0 To 7
For y = 0 To 7
Box(x*8, y*8, 8, 8, $808080+$404040*(x+y)%2)
Next
Next
DrawingFont(Font) : DrawingMode(1)
DrawText(16,0,"F", $FF0000, 0)
StopDrawing()
CreateSprite3D(1, 1)
Define pd3d.IDirect3DDevice9
Repeat
ClearScreen(0)
#HalfSize = 150
Start3D()
; Zum Rändern der "anderen" Seite
EnableASM
!extrn _PB_Screen_Direct3DDevice
!MOV dword EAX, [_PB_Screen_Direct3DDevice]
!MOV dword [v_pd3d],EAX
DisableASM
pd3d\SetRenderState(22,1)
a.f = ElapsedMilliseconds()/1000
DisplayField3D(1,200,200, 150,300,0, a,0,0)
DisplayField3D(1,200,200, 400,300,0, 0,a,0)
DisplayField3D(1,200,200, 650,300,0, a,0,a/3)
FlipBuffers()
Until WindowEvent() = #PB_Event_CloseWindow
Hier kannst du nun wirklich, eine beliebige Rotation durchführen ...
@super_castle: finde deins viel umständlicher, zumal ich n externe DLL brauche, und in der 3D-Engine "gefangen" bin.