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.