Vol libre dans un champ d'étoiles

Généralités sur la programmation 3D
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Vol libre dans un champ d'étoiles

Message par Ollivier »

Bonjour à vous,

Je copie ce code ici afin qu'il puisse subir d'éventuelles mises à jour.
C'est donc un champ d'étoiles (présenté il y a un an en section Débutant).

Je me suis lancé là-dedans par besoin de représenter l'espace alors que je ne disposais plus de la librairie Ogre (elle plante sur ma configuration). De plus, quand cette librairie fonctionnait, ce type de rotation de caméra était impossible. Les choses évoluant (N3xt-D disposait de ce type de rotation), sûrement que ce type de rotation sera pris en compte un jour prochain.

(+) En attendant, les avantages de ce code c'est d'être simple dans la mise en oeuvre: copier-coller-exécuter.
(-) La perspective est suffisante mais arbitraire
(-) Les objets se répètent irrégulièrement quand on avance

Les touches d'utilisation sont les suivantes:
[Enter] = Accélérer
[BackSpace] = Décélérer

[Tab] = Rotation gauche
[A] = Rotation droite

[Flèche gauche] = Roulis vers la gauche
[Flèche droite] = Roulis vers la droite

[Flèche haut] = Plongeon en avant
[Flèche bas] = Plongeon en arrière

Code : Tout sélectionner

DisableDebugger
N = 3999
Global.F Dim X(N), Dim Y(N), Dim Z(N), Dim S(N), H, R, A
Macro Ro(CoA, CoB, CoC) ; Macro d'une procédure de rotation
Procedure R#CoA(i, Angle.F)
    Protected.F X, Y, Z
    X = X(i)
    Y = Y(i)
    Z = Z(i)
    H = CoA
    R = Sqr((CoB * CoB) + (CoC * CoC) )
    A = ACos(CoC / R): If CoB < 0.0: A = 0.0 - A: EndIf
    CoA#(i) = H
    CoB#(i) = Sin(A + Angle) * R
    CoC#(i) = Cos(A + Angle) * R
EndProcedure
EndMacro
Ro(x,y,z):Ro(y,z,x):Ro(z,x,y) ;3 procs pour les 3 rotations X, Y et Z
    InitSprite()
    InitSprite3D()
    InitKeyboard()
    InitMouse()
    ExamineDesktops()
    Dw = DesktopWidth(0)
    Dh = DesktopHeight(0)
    Dd = DesktopDepth(0)
    Dhw = Dw / 2: Dhh = Dh / 2
    OpenScreen(Dw, Dh, Dd, "")
    KeyboardMode(#PB_Keyboard_International)
    For I = 0 To N
        S(I) = 0  
        X(I) = Random(1000000) / 10.0 - 50000.0
        Y(I) = Random(1000000) / 10.0 - 50000.0
        Z(I) = Random(1000000) / 10.0 - 50000.0
    Next I
    Zoom.F = 1.0
    Size = 512
    CreateImage(0, Size, Size, 32)
    StartDrawing(ImageOutput(0) )
        For I = 0 To (Size / 2)
            G = I * 511 / Size
            Circle(Size / 2, Size / 2, (Size - (I * 2) ) / 2, RGBA(G, G, G, 255) )
        Next I
    StopDrawing()
    CreateSprite(0, Size, Size, #PB_Sprite_Texture | #PB_Sprite_AlphaBlending)
    StartDrawing(SpriteOutput(0) )
        DrawAlphaImage(ImageID(0), 0, 0)
        DrawingMode(#PB_2DDrawing_AlphaChannel)
        DrawAlphaImage(ImageID(0), 0, 0)
    StopDrawing()
    CreateSprite3D(0, 0)
    PitchCamera.F = 0.0: PitchCameraAccel.F = 0.001
    TurnCamera.F = 0.0: TurnCameraAccel.F = 0.001
    RollCamera.F = 0.0: RollCameraAccel.F = 0.001
    CameraSpeed.F = 0.0: Size2 = Size / 2
    Repeat
        Delay(1)
        ExamineKeyboard()
        ExamineMouse()
        ClearScreen(RGBA(0, 0, 0, 0) )
        Start3D()
        Sprite3DBlendingMode(5, 7)
        If KeyboardPushed(#PB_Key_Left): RollCamera - RollCameraAccel: EndIf
        If KeyboardPushed(#PB_Key_Right): RollCamera + RollCameraAccel: EndIf
        If KeyboardPushed(#PB_Key_Down): PitchCamera + PitchCameraAccel: EndIf
        If KeyboardPushed(#PB_Key_Up): PitchCamera - PitchCameraAccel: EndIf
        If KeyboardPushed(#PB_Key_Tab): TurnCamera + TurnCameraAccel: EndIf
        If KeyboardPushed(#PB_Key_A): TurnCamera - TurnCameraAccel: EndIf
        If KeyboardPushed(#PB_Key_Back): CameraSpeed / 1.1: EndIf
        If KeyboardPushed(#PB_Key_Return): CameraSpeed + 10.0: EndIf
        For I = 0 To N
            Z(I) - CameraSpeed: If Z(I) < - 50000.0: Z(I) + 100000.0: EndIf
            Rx(I, PitchCamera)
            Ry(I, TurnCamera)
            Rz(I, RollCamera)
            Coef.F = 400.0 / Z(i) * Zoom
            If Z(i) > 0.0
                DisplaySprite3D(S(i), 0, 0)
                sx1 = Dhw + (X(i) - Size2) * Coef
                sy1 = Dhh + (Y(i) - Size2) * Coef
                sx2 = Dhw + (X(i) + Size2) * Coef
                sy2 = Dhh + (Y(i) - Size2) * Coef
                sx3 = Dhw + (X(i) + Size2) * Coef
                sy3 = Dhh + (Y(i) + Size2) * Coef
                sx4 = Dhw + (X(i) - Size2) * Coef
                sy4 = Dhh + (Y(i) + Size2) * Coef
                sz.F = Coef * 100
                TransformSprite3D(S(I), sx1, sy1, sz, sx2, sy2, sz, sx3, sy3, sz, sx4, sy4, sz)
            EndIf
        Next I
        PitchCamera * 0.99
        TurnCamera * 0.99
        RollCamera * 0.99
        CameraSpeed * 0.999
        Stop3D()
        FlipBuffers()
    Until KeyboardPushed(#PB_Key_Escape)
    CloseScreen()
    End
Avatar de l’utilisateur
flaith
Messages : 1487
Inscription : jeu. 07/avr./2005 1:06
Localisation : Rennes
Contact :

Re: Vol libre dans un champ d'étoiles

Message par flaith »

C'est dingue ce qu'on peut faire en si peu de lignes, pas mal du tout Ollivier et merci :D Image
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Vol libre dans un champ d'étoiles

Message par djes »

Très beau code, comme d'habitude ! Il semble y avoir un espace vide à un moment, je n'ai pas compris d'où ça pouvait venir. Visuellement, le transformsprite() semble vraiment apporter un petit plus, comparé au simple zoom. :)
Sinon, une petite amélioration consisterait à jouer sur l'alpha, afin de faire apparaître progressivement les étoiles.

PS : la section rotation est vraiment magnifique !
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Re: Vol libre dans un champ d'étoiles

Message par comtois »

Sympa ce code. J'aime bien.

Si je le fais tourner avec la version x86 sur mon système 64 bits, ça tourne nickel avec ou sans débogueur, par contre avec la version x64 ça plante si je lance le programme sans le débogueur ?
Avec le débogueur ça tourne bien. Je n'ai pas encore pris le temps d'isoler le problème, est-ce que ça le fait chez d'autres ?
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Warkering
Messages : 808
Inscription : ven. 08/janv./2010 1:14
Localisation : Québec, Canada

Re: Vol libre dans un champ d'étoiles

Message par Warkering »

Moi, il ne démarre tout simplement pas sans débogueur. Mais sinon, c'est assez absorbant au point d'en donner un mal de tête!
Bref, bravo! C'est trop "Su'a coche!" :lol:
Avatar de l’utilisateur
case
Messages : 1546
Inscription : lun. 10/sept./2007 11:13

Re: Vol libre dans un champ d'étoiles

Message par case »

en 32bits avec ou sans débogueur ca roule, en 64 bits ca foire si je ne met pas le debugger. bizarre tout ca :)
ImageImage
Avatar de l’utilisateur
venom
Messages : 3136
Inscription : jeu. 29/juil./2004 16:33
Localisation : Klyntar
Contact :

Re: Vol libre dans un champ d'étoiles

Message par venom »

Sous mon x64 débogueur actif sa roule parfaitement. (mon compilateur est en x86)
Sympa en effet 8)







@++
Windows 10 x64, PureBasic 5.73 x86 & x64
GPU : radeon HD6370M, CPU : p6200 2.13Ghz
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: Vol libre dans un champ d'étoiles

Message par Ollivier »

Bonjour à vous tous qui avez répondu,

Je vous remercie beaucoup. C'est très gentil.

@Comtois

Ton attention est bénéfique car je crois avoir repéré ce qui se trahit par d'étranges anomalies.

Je pense qu'il s'agit d'une division par zéro superflue plus ou moins gérée selon les OS. J'ai donc interverti les lignes 76 et 77.

Code : Tout sélectionner

            If Z(i) > 0.0
                Coef.F = 400.0 / Z(i) * Zoom
Ainsi, la division par Z(i) est «sécurisée».

@Djes
Djes a écrit :Il semble y avoir un espace vide à un moment, je n'ai pas compris d'où ça pouvait venir.
J'allais bêtement t'écrire «c'est ce que j'ai noté en inconvénient en haut!» (en effet, j'ai noté «(-) Les objets se répètent irrégulièrement quand on avance»). Et puis... «Poum!» (équivalent moderne du Eurêka grec!). En cette phrase tu m'offres involontairement un très joli cadeau! Je n'ai pas le temps en ce moment de m'accrocher à l'informatique.

En effet, derrière ce "bug" se cache l'ombre d'une liberté: celle de donner l'illusion d'une circulation dans un ensemble non limité.
  • Sur une ligne droite, on ne peut se déplacer que dans 1 direction. Quelque soit le sens (positif ou négatif, exclusivement), durant ce déplacement, se produisent deux sous-actions simultanées nécessaires à la gestion du déplacement:
    • (1) On quitte un endroit...
    • ...pour (2) gagner un autre endroit
    Conclusion: il y a "2 puissance 1" zones à gérer
  • Dans (ou "sur") un plan cathésien, on peut se déplacer dans 2 directions perpendiculaires.
    Conclusion: il y a donc "2 puissance 2" zones à gérer pour se déplacer sur un plan(d'où les 4 pages présentes dans le code de cet autre sujet pour se scroller dans le plan)
  • Dans un espace euclidien, on peut se déplacer dans 3 directions perpendiculaires.
    Conclusion: il y a donc "2 puissance 3" zones à gérer.
    Il me faudra construire 8 espaces contigüs pour réussir à éviter de manière tout à fait naturelle les "irrégularités" que tu aperçois! Je pense que ça sera l'un de mes prochains codes...
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Vol libre dans un champ d'étoiles

Message par djes »

Tiens, c'est pas bête, je n'y avais jamais pensé...
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Vol libre dans un champ d'étoiles

Message par Backup »

Ollivier a écrit : Il me faudra construire 8 espaces contigüs pour réussir à éviter de manière tout à fait naturelle les "irrégularités" que tu aperçois! Je pense que ça sera l'un de mes prochains codes...[/list]
8 espaces ?
t'es sur que c'est pas plus ?

si je me place au centre d'un Rubic cube ,qui je pense est la meilleur représentation
de ce que tu explique là...

chaque cube symbolisant un "espace" a venir dans le mouvement
ça devrai faire plus que 8 non ?

mais j'ai peut etre rien compris ... comme d'hab :lol:
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Re: Vol libre dans un champ d'étoiles

Message par comtois »

Je viens de passer un petit moment pour isoler le problème. Ce code suffit pour reproduire le phénomène !

Code : Tout sélectionner

N = 3999
Dim A(N)
Avec une constante ça passe.

Code : Tout sélectionner

#N = 3999
Dim A(#N)
Donc le problème n'apparait qu'avec la version x64, avec la version x86 c'est ok.
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: Vol libre dans un champ d'étoiles

Message par Ollivier »

Bonjour Comtois,

C'est quoi la nouvelle logique en fait avec Dim?

Ollivier
G-Rom
Messages : 3641
Inscription : dim. 10/janv./2010 5:29

Re: Vol libre dans un champ d'étoiles

Message par G-Rom »

Comme j'avais dis il y a quelque temps déjà , la perspective est foireuse , faire un jeu avec sa , c'est la gerbe assuré.
pour ceux que cela intéresse , voici comment les moteurs 3D fonctionnent au niveau des transformations géométrique ( projection à l'écran )

le code n'est pas si gros que ca , la plupart c'est des routines sur les vecteurs & matrice4x4.

Code : Tout sélectionner

; ----------------------------------------------------------------------------------------
;
; ----------------------------------------------------------------------------------------

#PI_OVER_180 	=	0.0174532925199432957
#PI_OVER_360 	=	0.0087266462599716478

; ----------------------------------------------------------------------------------------
;
; ----------------------------------------------------------------------------------------

Structure vector3
  x.f : y.f : z.f
EndStructure

; ----------------------------------------------------------------------------------------
;
; ----------------------------------------------------------------------------------------

Structure matrix4
  m.f[16]
EndStructure

; ----------------------------------------------------------------------------------------
;
; ----------------------------------------------------------------------------------------

ProcedureDLL vector3(x.f=0, y.f=0, z.f=0)
  *v.vector3 = AllocateMemory(SizeOf(vector3))
  *v\x = x
  *v\y = y
  *v\z = z
  ProcedureReturn *v
EndProcedure

; ----------------------------------------------------------------------------------------
;
; ----------------------------------------------------------------------------------------

ProcedureDLL free_vector3(*v.vector3)
  FreeMemory(*v)  
EndProcedure

; ----------------------------------------------------------------------------------------
;
; ----------------------------------------------------------------------------------------

ProcedureDLL vector3_add(*ReturnVector.vector3, *V1.vector3, *V2.vector3)
  *ReturnVector\x = *V1\x + *V2\x
  *ReturnVector\y = *V1\y + *V2\y
  *ReturnVector\z = *V1\z + *V2\z
EndProcedure

; ----------------------------------------------------------------------------------------
;
; ----------------------------------------------------------------------------------------

ProcedureDLL vector3_subtract(*ReturnVector.vector3, *V1.vector3, *V2.vector3)
  *ReturnVector\x = *V1\x - *V2\x
  *ReturnVector\y = *V1\y - *V2\y
  *ReturnVector\z = *V1\z - *V2\z
EndProcedure

; ----------------------------------------------------------------------------------------
;
; ----------------------------------------------------------------------------------------

ProcedureDLL vector3_multiply(*ReturnVector.vector3, *V1.vector3, *V2.vector3)
  *ReturnVector\x = *V1\x * *V2\x
  *ReturnVector\y = *V1\y * *V2\y
  *ReturnVector\z = *V1\z * *V2\z
EndProcedure

; ----------------------------------------------------------------------------------------
;
; ----------------------------------------------------------------------------------------

ProcedureDLL vector3_crossProduct(*ReturnVector.vector3, *V1.vector3, *V2.vector3)
  *ReturnVector\x = *V1\y * *V2\z - *V2\y * *V1\z
  *ReturnVector\y = *V1\z * *V2\x - *V2\z * *V1\x
  *ReturnVector\z = *V1\x * *V2\y - *V2\x * *V1\y
EndProcedure

; ----------------------------------------------------------------------------------------
;
; ----------------------------------------------------------------------------------------

ProcedureDLL.d vector3_dotProduct(*V1.vector3, *V2.vector3)
  ProcedureReturn (*V1\x * *V2\x) + (*V1\y * *V2\y) + (*V1\z * *V2\z)
EndProcedure

; ----------------------------------------------------------------------------------------
;
; ----------------------------------------------------------------------------------------

ProcedureDLL.f vector3_length(x.f, y.f, z.f)
  ProcedureReturn Sqr(x * x + y * y + z * z)
EndProcedure

; ----------------------------------------------------------------------------------------
;
; ----------------------------------------------------------------------------------------

ProcedureDLL vector3_normalize(*NormVector.vector3)
  length.f      = vector3_length(*NormVector\x, *NormVector\y, *NormVector\z)
  *NormVector\x = *NormVector\x / length
  *NormVector\y = *NormVector\y / length
  *NormVector\z = *NormVector\z / length
EndProcedure

; ----------------------------------------------------------------------------------------
;
; ----------------------------------------------------------------------------------------

ProcedureDLL vector3_scale(*Vector.vector3,Scale.f)
  *Vector\x * Scale
  *Vector\y * Scale
  *Vector\z * Scale
EndProcedure  

; ----------------------------------------------------------------------------------------
;
; ----------------------------------------------------------------------------------------

ProcedureDLL.i matrix4(*pointer=#Null)
  *m.matrix4 = AllocateMemory(SizeOf(matrix4))
  
  If *pointer<>#Null
    CopyMemory(*pointer,@*m\m,64)
  EndIf 
  
  ProcedureReturn *m  
EndProcedure

; ----------------------------------------------------------------------------------------
;
; ----------------------------------------------------------------------------------------

ProcedureDLL free_matrix4(*m.matrix4)
  FreeMemory(*m)
EndProcedure

; ----------------------------------------------------------------------------------------
;
; ----------------------------------------------------------------------------------------

ProcedureDLL matrix4_identity(*m.matrix4)
  With *m
    \m[0] = 1 : \m[4] = 0 : \m[8]  = 0  : \m[12] = 0
    \m[1] = 0 : \m[5] = 1 : \m[9]  = 0  : \m[13] = 0
    \m[2] = 0 : \m[6] = 0 : \m[10] = 1  : \m[14] = 0
    \m[3] = 0 : \m[7] = 0 : \m[11] = 0  : \m[15] = 1
  EndWith
EndProcedure

; ----------------------------------------------------------------------------------------
;
; ----------------------------------------------------------------------------------------

ProcedureDLL matrix4_multiply(*mB.matrix4, *mA.matrix4)
  Protected temp.matrix4
  For i = 0 To 3
    temp\m[i*4+0] = *mA\m[i*4] * *mB\m[0] + *mA\m[i*4+1] * *mB\m[4] + *mA\m[i*4+2] * *mB\m[8]  + *mA\m[i*4+3] * *mB\m[12]
    temp\m[i*4+1] = *mA\m[i*4] * *mB\m[1] + *mA\m[i*4+1] * *mB\m[5] + *mA\m[i*4+2] * *mB\m[9]  + *mA\m[i*4+3] * *mB\m[13]
    temp\m[i*4+2] = *mA\m[i*4] * *mB\m[2] + *mA\m[i*4+1] * *mB\m[6] + *mA\m[i*4+2] * *mB\m[10] + *mA\m[i*4+3] * *mB\m[14]
    temp\m[i*4+3] = *mA\m[i*4] * *mB\m[3] + *mA\m[i*4+1] * *mB\m[7] + *mA\m[i*4+2] * *mB\m[11] + *mA\m[i*4+3] * *mB\m[15]
  Next 
  CopyStructure(@temp,*mB,matrix4)
EndProcedure

; ----------------------------------------------------------------------------------------
;
; ----------------------------------------------------------------------------------------

ProcedureDLL matrix4_perspective(*m.matrix4, fov.f, aspect.f, zNear.f, zFar.f)
  Protected temp.matrix4
  Protected fov2.f = fov * #PI_OVER_180
  Protected t.f    = zNear * Tan(fov/2)
  Protected r.f    = t * aspect
  
  temp\m[0] = zNear / r
  temp\m[1] = 0
  temp\m[2] = 0
  temp\m[3] = 0
  
  temp\m[4] = 0
  temp\m[5] = zNear / t
  temp\m[6] = 0
  temp\m[7] = 0
  
  temp\m[8]  = 0
  temp\m[9]  = 0
  temp\m[10] = -1*(zFar+zNear)/(zFar-zNear)
  temp\m[11] = (-2*zFar*zNear)/(zFar-zNear)
  
  temp\m[12] = 0
  temp\m[13] = 0
  temp\m[14] = -1
  temp\m[15] = 1


  matrix4_multiply(*m,@temp)
EndProcedure

; ----------------------------------------------------------------------------------------
;
; ----------------------------------------------------------------------------------------

Procedure matrix4_translate(*m.matrix4, x.f, y.f, z.f)
  Protected temp.matrix4
  
  temp\m[0] = 1 : temp\m[4] = 0 : temp\m[8]  = 0 : temp\m[12] = x
  temp\m[1] = 0 : temp\m[5] = 1 : temp\m[9]  = 0 : temp\m[13] = y
  temp\m[2] = 0 : temp\m[6] = 0 : temp\m[10] = 1 : temp\m[14] = z
  temp\m[3] = 0 : temp\m[7] = 0 : temp\m[11] = 0 : temp\m[15] = 1
  
  matrix4_multiply(*m,@temp)
EndProcedure

; ----------------------------------------------------------------------------------------
;
; ----------------------------------------------------------------------------------------

Procedure matrix4_scale(*m.matrix4, x.f, y.f, z.f)
  Protected temp.matrix4
  
  temp\m[0] = x : temp\m[4] = 0 : temp\m[8]  = 0 : temp\m[12] = 0
  temp\m[1] = 0 : temp\m[5] = y : temp\m[9]  = 0 : temp\m[13] = 0
  temp\m[2] = 0 : temp\m[6] = 0 : temp\m[10] = z : temp\m[14] = 0
  temp\m[3] = 0 : temp\m[7] = 0 : temp\m[11] = 0 : temp\m[15] = 1
  
  matrix4_multiply(*m,@temp)
EndProcedure

; ----------------------------------------------------------------------------------------
;
; ----------------------------------------------------------------------------------------

ProcedureDLL matrix4_rotate(*m.matrix4, a.f, x.f, y.f, z.f)
  Protected angle.f     = a * #PI_OVER_180
  Protected temp.matrix4
  
  temp\m[0] = 1+(1-Cos(angle))*(x*x-1)
  temp\m[1] = -z*Sin(angle)+(1-Cos(angle))*x*y
  temp\m[2] = y*Sin(angle)+(1-Cos(angle))*x*z
  temp\m[3] = 0
  
  temp\m[4] = z*Sin(angle)+(1-Cos(angle))*x*y
  temp\m[5] = 1+(1-Cos(angle))*(y*y-1)
  temp\m[6] = -x*Sin(angle)+(1-Cos(angle))*y*z
  temp\m[7] = 0
  
  temp\m[8]  = -y*Sin(angle)+(1-Cos(angle))*x*z
  temp\m[9]  = x*Sin(angle)+(1-Cos(angle))*y*z
  temp\m[10] = 1+(1-Cos(angle))*(z*z-1)
  temp\m[11] = 0
  
  temp\m[12] = 0
  temp\m[13] = 0
  temp\m[14] = 0
  temp\m[15] = 1

  matrix4_multiply(*m,@temp)
EndProcedure

; ----------------------------------------------------------------------------------------
;
; ----------------------------------------------------------------------------------------

ProcedureDLL matrix4_ortho(*m.matrix4, left.f, right.f, bottom.f, top.f, zNear.f, zFar.f)
  Protected temp.matrix4
  
  temp\m[0] = 2 / (right - left)
  temp\m[1] = 0
  temp\m[2] = 0
  temp\m[3] = -(( right + left ) / (right - left))
  
  temp\m[4] = 0
  temp\m[5] = 2 / (top - bottom)
  temp\m[6] = 0
  temp\m[7] = -(( top + bottom) / (top - bottom))
  
  temp\m[8]  = 0
  temp\m[9]  = 0
  temp\m[10] = 2 / ( zFar - zNear)
  temp\m[11] = -((zFar + zNear) / (zFar - zNear))
  
  temp\m[12] = 0
  temp\m[13] = 0
  temp\m[14] = 0
  temp\m[15] = 1

  matrix4_multiply(*m,@temp)
EndProcedure

; ----------------------------------------------------------------------------------------
;
; ----------------------------------------------------------------------------------------

ProcedureDLL.i matrix4_coordinate(*m.matrix4,*v.vector3)
  *temp.vector3 = AllocateMemory(SizeOf(vector3))
   *temp\x = *v\x * *m\m[0] + *v\y * *m\m[4] + *v\z * *m\m[8]  + *m\m[12]
   *temp\y = *v\x * *m\m[1] + *v\y * *m\m[5] + *v\z * *m\m[9]  + *m\m[13]
   *temp\z = *v\x * *m\m[2] + *v\y * *m\m[6] + *v\z * *m\m[10] + *m\m[14]
  ProcedureReturn *temp
EndProcedure

; ----------------------------------------------------------------------------------------
;
; ----------------------------------------------------------------------------------------

#NB_STAR = 5000

Structure Stars
  position.vector3
  rotation.vector3
  mat_view.matrix4
EndStructure

Structure StarsRendering
  ScreenCoordinate.vector3  
EndStructure


Global NewList StarsRendering.StarsRendering()

Dim Star.Stars(#NB_STAR-1)

For i = 0 To #NB_STAR-1
  Star(i)\position\x = -Random(50000) + Random(50000)
  Star(i)\position\y = -Random(50000) + Random(50000)
  Star(i)\position\z = -Random(50000) + Random(50000)
Next 


; ----------------------------------------------------------------------------------------
;-OpenScreen()
; ----------------------------------------------------------------------------------------
Global ScreenW = 1024
Global ScreenH = 768
InitSprite() : InitKeyboard() 
Global Window  = OpenWindow(#PB_Any,0,0,ScreenW,ScreenH, "FlyInTheSky")
Global wHwd    = WindowID(Window)
OpenWindowedScreen(wHwd,0,0,ScreenW,ScreenH,1,0,0)
; ----------------------------------------------------------------------------------------
;-Setup 3D
; ----------------------------------------------------------------------------------------

; Matrice de perspective
Global *MATRICE_PROJECTION = matrix4()
matrix4_identity(*MATRICE_PROJECTION)
matrix4_perspective(*MATRICE_PROJECTION,45,ScreenW/ScreenH,1,1000)

;Matrice modelview (camera)
Global *MATRIX_MODELVIEW = matrix4()



KeyboardMode(#PB_Keyboard_International)
Repeat
  ClearScreen(0)  
  ExamineKeyboard()

  
  
  If KeyboardPushed(#PB_Key_Up)
    CamZ + 100
  EndIf 
  
  If KeyboardPushed(#PB_Key_Down)
    CamZ - 100
  EndIf 
  
  
  If KeyboardPushed(#PB_Key_PageDown)
    CamPitch.f + 1
  EndIf 
 
  If KeyboardPushed(#PB_Key_PageUp)
    CamPitch.f - 1
  EndIf 
  
    If KeyboardPushed(#PB_Key_Right)
    CamYaw.f + 1
  EndIf 
 
  If KeyboardPushed(#PB_Key_Left)
    CamYaw.f - 1
  EndIf 
  
  
  ClearList(StarsRendering())
  
  matrix4_identity(*MATRIX_MODELVIEW)
  matrix4_rotate(*MATRIX_MODELVIEW,CamPitch,1,0,0)
  matrix4_rotate(*MATRIX_MODELVIEW,CamYaw  ,0,1,0)
  matrix4_rotate(*MATRIX_MODELVIEW,CamRoll ,0,0,1)
  matrix4_translate(*MATRIX_MODELVIEW,CamX,CamY,CamZ)  
  
  *MATRICE_PROJVIEW.matrix4 = matrix4(*MATRICE_PROJECTION)
   
  matrix4_multiply(*MATRICE_PROJVIEW,*MATRIX_MODELVIEW)
  
  For i = 0 To #NB_STAR-1 
    matrix4_identity(@Star(i)\mat_view)
    matrix4_translate(@Star(i)\mat_view,Star(i)\position\x,Star(i)\position\y,Star(i)\position\z)
    
    *MATRIX_MODELPROJ.matrix4 = matrix4(@Star(i)\mat_view)
    
    matrix4_multiply(*MATRICE_PROJVIEW,*MATRIX_MODELPROJ)
    ;On projette :
    *ScreenCoordinate.vector3 = matrix4_coordinate(*MATRICE_PROJVIEW,@Star(i)\position)
    *ScreenCoordinate\x * 0.5 / *ScreenCoordinate\z + 0.5
    *ScreenCoordinate\y * 0.5 / *ScreenCoordinate\z + 0.5
    *ScreenCoordinate\x * ScreenW
    *ScreenCoordinate\y * ScreenH
    
    If *ScreenCoordinate\z>1 
      If *ScreenCoordinate\x>0 And *ScreenCoordinate\x<ScreenW-1 And *ScreenCoordinate\y>0 And *ScreenCoordinate\y<ScreenH-1
        AddElement(StarsRendering())
        StarsRendering()\ScreenCoordinate\x = *ScreenCoordinate\x
        StarsRendering()\ScreenCoordinate\y = *ScreenCoordinate\y
        StarsRendering()\ScreenCoordinate\z = *ScreenCoordinate\z
       EndIf                               
    EndIf 
    
    free_vector3(*ScreenCoordinate)
  Next 
  
  
  free_matrix4(*MATRICE_PROJVIEW)
  
  StartDrawing(ScreenOutput())
    ForEach StarsRendering()
      Plot(StarsRendering()\ScreenCoordinate\x,StarsRendering()\ScreenCoordinate\y,$FFFFFF)        
    Next 
    
    
    DrawText(10,10,"Move with Up/Down key")
    DrawText(10,30,"Rotate yaw with Right/Left key")
    DrawText(10,50,"Rotate pitch with pageup/down key")
    
    
    
  StopDrawing()
  
  
  
  FlipBuffers()
Until WindowEvent() = #PB_Event_CloseWindow
Avec sa , vous allez pouvoir dresser la carte du ciel en 3D ^^
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Vol libre dans un champ d'étoiles

Message par Backup »

G-Rom
je suis une bille en 3D , mais lorsque je vois ton code
StartDrawing(ScreenOutput())
ForEach StarsRendering()
Plot(StarsRendering()\ScreenCoordinate\x,StarsRendering()\ScreenCoordinate\y,$FFFFFF)
Next


DrawText(10,10,"Move with Up/Down key")
DrawText(10,30,"Rotate yaw with Right/Left key")
DrawText(10,50,"Rotate pitch with pageup/down key")



StopDrawing()

FlipBuffers()
Until WindowEvent() = #PB_Event_CloseWindow
notamment la partie en rouge , je ne m'étonne pas que sur mon NC10
(qui n'as pas de carte graph 3D) , ça rame !!

il n'y aurai pas moyen de pré-calculer (prédessiner...),la position des etoiles
au lieu de redessiner l'immensité des étoiles de la galaxie a chaque boucle Repeat ??

je dis ça, car chez moi ton code Rame, grave de chez grave ! ;)

PS: [Reedit]
faut dire que , si j'ai bien compris le truc, tu semble déplacer l'ensemble de la galaxie
par rapport a l'observateur .. 8O
puisque tu redefinis l'emplacement des etoiles a chaque boucle...

serai pas possible de deplacer l'observateur seulement, et pas toucher aux étoiles ?

enfin, j'y connais rien... mais ça me semble tres lourds non ?


[/Reedit]
Avatar de l’utilisateur
SPH
Messages : 4944
Inscription : mer. 09/nov./2005 9:53

Re: Vol libre dans un champ d'étoiles

Message par SPH »

Moi comme d'hab, j'ai un invalid memory access ici :

Code : Tout sélectionner

 CopyStructure(@temp,*mB,matrix4)

!i!i!i!i!i!i!i!i!i!
!i!i!i!i!i!i!
!i!i!i!
//// Informations ////
Intel Core i7 4770 64 bits - GTX 650 Ti
Version de PB : 6.12LTS- 64 bits
Répondre