[REGLE] Sprite3D & Rotation

Programmation avancée de jeux en PureBasic
Anonyme

Message par Anonyme »

tiens j'ai virer le pivot quine fonctionnais pas , je sais pas pourquoi j'avais fait ca :oops:

Code : Tout sélectionner

Procedure RotateSprite3DEX(*SpriteIDEX.PB_Sprite3DEX,Angle.f)
Protected *VertexSprite.PB_Sprite3D = IsSprite3D(*SpriteIDEX\No)
Protected SizeW2.l,SizeH2.l


SizeW2 = *VertexSprite\Width/2
SizeH2 = *VertexSprite\Height/2


      *VertexSprite\Vertice[0]\sx = SizeW2 - *SpriteIDEX\DA  * Cos((Angle+*SpriteIDEX\AA)*#PI/180)
      *VertexSprite\Vertice[0]\sy = SizeH2 - *SpriteIDEX\DA  * Sin((Angle+*SpriteIDEX\AA)*#PI/180)
                                                               
      *VertexSprite\Vertice[1]\sx = SizeW2- *SpriteIDEX\DB  * Cos((Angle+*SpriteIDEX\AB)*#PI/180)
      *VertexSprite\Vertice[1]\sy = SizeH2- *SpriteIDEX\DB  * Sin((Angle+*SpriteIDEX\AB)*#PI/180)
                                                                  
      *VertexSprite\Vertice[3]\sx = SizeW2 - *SpriteIDEX\DD  * Cos((Angle+*SpriteIDEX\AD)*#PI/180)
      *VertexSprite\Vertice[3]\sy = SizeH2 - *SpriteIDEX\DD  * Sin((Angle+*SpriteIDEX\AD)*#PI/180)
                                                                    
      *VertexSprite\Vertice[2]\sx = SizeW2 - *SpriteIDEX\DC  * Cos((Angle+*SpriteIDEX\AC)*#PI/180)     
      *VertexSprite\Vertice[2]\sy = SizeH2 - *SpriteIDEX\DC  * Sin((Angle+*SpriteIDEX\AC)*#PI/180)  
                                     
EndProcedure
Avatar de l’utilisateur
Progi1984
Messages : 2659
Inscription : mar. 14/déc./2004 13:56
Localisation : France > Rennes
Contact :

Message par Progi1984 »

En fait, c'est pour faire des angles de 90, 180, 270 & 360 ° principalement ! Donc je vais essayer de voir et comprendre ton code :)

[edit] A quoi correspond le rectangle rouge ?

[edit2] Si je mets : RotateSprite3DEX(A,0) au lieu de RotateSprite3DEX(A,r), il n'est pas orienté d'un angle 0...
Anonyme

Message par Anonyme »

@Edit 1
c'etait juste pour voir si cela coincidait avec mes modifs sur les vertex

@Edit 2
ca dépend combien vaut R dans la boucle principale.

edit: j'ai compris ce que tu voulais dire, c'est normale sans trop l'etre



Bonus :

tu peut choisir la couleur d'un vertex ainsi que l'alpha ^^

Code : Tout sélectionner

ProcedureDLL RGBA(Red,Green,Blue,Alpha) 
  ProcedureReturn RGB(Blue,Green,Red) + Alpha << 24
EndProcedure

Procedure SetSprite3DVertexColor(Sprite3D,Vertex.l,Color.l)
Protected *VertexSprite.PB_Sprite3D = IsSprite3D(SpriteID)
*VertexSprite\Vertice[Vertex]\Color = Color
*VertexSprite\Vertice[Vertex]\Color = Color 
EndProcedure
Avatar de l’utilisateur
Progi1984
Messages : 2659
Inscription : mar. 14/déc./2004 13:56
Localisation : France > Rennes
Contact :

Message par Progi1984 »

@ Edit 1 : oki

@ Edit 2 : r vaut 0 ! c ca le pire ! Tente ! tu veras !

@Bonus : merci mais je ne vais pas en avoir l'utilité à l'heure actuelle !
Anonyme

Message par Anonyme »

l'angle retourner par la fonction etait juste précis a 5 pixels près, ce qui donne se décalage meme à zero :?

c'est corrigé aussi :D

Code : Tout sélectionner

Procedure ReturnAngle(x1,y1,x2,y2)
Protected Distance.l,Xa.l,Ya.l

Distance = Distance(x1,y1,x2,y2)

For A = 0 To 360

Xa = x1 + Distance * Cos(A*#Deg)
Ya = y1 + Distance * Sin(A*#Deg)

If Xa > x2 -1 And Xa < x2 + 1
 If Ya > y2 -1 And Ya < y2 + 1
  ProcedureReturn A
 EndIf
EndIf

Next A


EndProcedure
Avatar de l’utilisateur
Progi1984
Messages : 2659
Inscription : mar. 14/déc./2004 13:56
Localisation : France > Rennes
Contact :

Message par Progi1984 »

Merci beaucoup, j'essaie de le mettre en application dés ce soir et je te tiens au courant !
Avatar de l’utilisateur
Progi1984
Messages : 2659
Inscription : mar. 14/déc./2004 13:56
Localisation : France > Rennes
Contact :

Message par Progi1984 »

Ca marche mais il faut que je configure

Code : Tout sélectionner

SizeW2 = *VertexSprite\Width/2
SizeH2 = *VertexSprite\Height/2 
dans el cas d'un angle à 90° ou 270°

pour que l'angle gauche haut soit placé en haut à droite du cube rouge et c'est le bordel !

Peux tu m'aider Cpl Bator ?
Anonyme

Message par Anonyme »

tu as du code, parce que là, j'ai rien compris avec ton histoire de cube. :?
Avatar de l’utilisateur
Progi1984
Messages : 2659
Inscription : mar. 14/déc./2004 13:56
Localisation : France > Rennes
Contact :

Message par Progi1984 »

Pas cube ! Zut ! mais rectangle rouge '@Edit 1
c'etait juste pour voir si cela coincidait avec mes modifs sur les vertex)
Anonyme

Message par Anonyme »

je comprend toujours pas.

quel rapport avec ca :

Code : Tout sélectionner

SizeW2 = *VertexSprite\Width/2
SizeH2 = *VertexSprite\Height/2
et les angles ?

ce code permet juste d'obtenir la taille du sprite.

ensuite, j'ai reperer 2 erreur dans mes procedures au niveau des paramètres. Sprite3D doit être SpriteID , ou l'inverse

Code : Tout sélectionner

SetSprite3DVertexColor(Sprite3D,Vertex.l,Color.l)
Protected *VertexSprite.PB_Sprite3D = IsSprite3D(SpriteID) ; erreur ici SpriteID doit etre Sprite3D
...
ensuite si rotatespriteEX() n'est pas très précis, c'est à cause de la fonction de mer... qui retourne l'angle, elle est codé à la barbare!
Avatar de l’utilisateur
Progi1984
Messages : 2659
Inscription : mar. 14/déc./2004 13:56
Localisation : France > Rennes
Contact :

Message par Progi1984 »

En fait, il faudrait que pour n'importe quel angle (0, 90, 180, 270), l'angle en haut à gauche du sprite3D soit toujours positionné à la même position !

Et moi qui croyait que c'était avec :
SizeW2 = *VertexSprite\Width/2
SizeH2 = *VertexSprite\Height/2

lol
Anonyme

Message par Anonyme »

Tu veut en fait , que ce coin, devienne le pivot ?
Avatar de l’utilisateur
Progi1984
Messages : 2659
Inscription : mar. 14/déc./2004 13:56
Localisation : France > Rennes
Contact :

Message par Progi1984 »

Si, je comprends par pivot, qu'un angle à 90° fait un mirror horizontal alors non !

En fait voilà ce que je veux réussir à faire :
Image

Le rectangle est formé par le carré rouge et jaune.
Pour l'instant pas de pb pour 0° et 180 !

Mais ca bugge pour 90° et 270°...
Anonyme

Message par Anonyme »

ca bug pour tout les angles en fait, je regarde ce que je peut faire :?
Anonyme

Message par Anonyme »

j'ai testé, ca à l'air de fonctionner

Code : Tout sélectionner

Structure vertex
    sx.f
    sy.f
    sz.f
    rhw.f
    Color.l
    specular.l
    tu.f
    tv.f
EndStructure

Structure PB_Sprite3D
     Texture.l         
     Vertice.vertex[4]
     Width.w
     Height.w
EndStructure

Structure PB_Sprite3DEX
      No.l
      AA.f:AB.f:AC.f:AD.f
      DA.f:DB.f:DC.f:dd.f
      Pivot_x.f
      Pivot_y.f
EndStructure





Procedure Distance(x1,y1,x2,y2)
Protected Result.f
Result = Sqr(  Pow(x1-x2,2) + Pow(y1-y2,2) + Pow(z1-z2,2) )
ProcedureReturn Result
EndProcedure


Procedure.f ReturnAngle(x1.f,y1.f,x2.f,y2.f)
  A.f = x1-x2
  b.f = y1-y2
  c.f = -Sqr(A*A+b*b)
  angle.f = ACos(A/c)*180/#PI
  If y1 < y2 : angle=360-angle : EndIf
  ProcedureReturn Abs(angle - 360)
EndProcedure


Procedure Sprite3DModifyPivot(*SpriteID.PB_Sprite3DEX,X.f,Y.f)
Protected *VertexSprite.PB_Sprite3D = IsSprite3D(*SpriteID\No)

*SpriteID\AA = ReturnAngle(*VertexSprite\Vertice[0]\sx,*VertexSprite\Vertice[0]\sy,X,Y)
*SpriteID\AB = ReturnAngle(*VertexSprite\Vertice[1]\sx,*VertexSprite\Vertice[1]\sy,X,Y)
*SpriteID\AC = ReturnAngle(*VertexSprite\Vertice[2]\sx,*VertexSprite\Vertice[2]\sy,X,Y)
*SpriteID\AD = ReturnAngle(*VertexSprite\Vertice[3]\sx,*VertexSprite\Vertice[3]\sy,X,Y)

*SpriteID\DA = Distance(*VertexSprite\Vertice[0]\sx,*VertexSprite\Vertice[0]\sy,X,Y)
*SpriteID\DB = Distance(*VertexSprite\Vertice[1]\sx,*VertexSprite\Vertice[1]\sy,X,Y)
*SpriteID\DC = Distance(*VertexSprite\Vertice[2]\sx,*VertexSprite\Vertice[2]\sy,X,Y)
*SpriteID\dd = Distance(*VertexSprite\Vertice[3]\sx,*VertexSprite\Vertice[3]\sy,X,Y)

*SpriteID\Pivot_x=X
*SpriteID\Pivot_y=Y
EndProcedure

Procedure CreateSprite3DEX(Sprite3D)
Protected *VertexSprite.PB_Sprite3D = IsSprite3D(Sprite3D)
Protected *VertexSpriteEX.PB_Sprite3DEX = AllocateMemory(SizeOf(PB_Sprite3DEX))

*VertexSpriteEX\No = Sprite3D 



SizeW.f = *VertexSprite\Width/2
SizeH.f = *VertexSprite\Height/2

               
*VertexSpriteEX\AA = ReturnAngle(*VertexSprite\Vertice[0]\sx,*VertexSprite\Vertice[0]\sy,SizeW,SizeH)
*VertexSpriteEX\AB = ReturnAngle(*VertexSprite\Vertice[1]\sx,*VertexSprite\Vertice[1]\sy,SizeW,SizeH)
*VertexSpriteEX\AC = ReturnAngle(*VertexSprite\Vertice[2]\sx,*VertexSprite\Vertice[2]\sy,SizeW,SizeH)
*VertexSpriteEX\AD = ReturnAngle(*VertexSprite\Vertice[3]\sx,*VertexSprite\Vertice[3]\sy,SizeW,SizeH)

*VertexSpriteEX\DA = Distance(*VertexSprite\Vertice[0]\sx,*VertexSprite\Vertice[0]\sy,SizeW,SizeH)
*VertexSpriteEX\DB = Distance(*VertexSprite\Vertice[1]\sx,*VertexSprite\Vertice[1]\sy,SizeW,SizeH)
*VertexSpriteEX\DC = Distance(*VertexSprite\Vertice[2]\sx,*VertexSprite\Vertice[2]\sy,SizeW,SizeH)
*VertexSpriteEX\dd = Distance(*VertexSprite\Vertice[3]\sx,*VertexSprite\Vertice[3]\sy,SizeW,SizeH)

ProcedureReturn *VertexSpriteEX 
EndProcedure


Procedure RotateSprite3DEX(*SpriteID.PB_Sprite3DEX,angle.f)
Protected *VertexSprite.PB_Sprite3D = IsSprite3D(*SpriteID\No)
Protected SizeW2.l,SizeH2.l
        
     *VertexSprite\Vertice[0]\sx = *SpriteID\Pivot_x  - *SpriteID\DA  * Cos((angle+*SpriteID\AA)*#PI/180)
     *VertexSprite\Vertice[0]\sy = *SpriteID\Pivot_y  - *SpriteID\DA  * Sin((angle+*SpriteID\AA)*#PI/180)
                                                                        
     *VertexSprite\Vertice[1]\sx = *SpriteID\Pivot_x  - *SpriteID\DB  * Cos((angle+*SpriteID\AB)*#PI/180)
     *VertexSprite\Vertice[1]\sy = *SpriteID\Pivot_y  - *SpriteID\DB  * Sin((angle+*SpriteID\AB)*#PI/180)
                           ; ;                                          
     *VertexSprite\Vertice[3]\sx = *SpriteID\Pivot_x  - *SpriteID\dd  * Cos((angle+*SpriteID\AD)*#PI/180)
     *VertexSprite\Vertice[3]\sy = *SpriteID\Pivot_y  - *SpriteID\dd  * Sin((angle+*SpriteID\AD)*#PI/180)
                                                                        
     *VertexSprite\Vertice[2]\sx = *SpriteID\Pivot_x  - *SpriteID\DC  * Cos((angle+*SpriteID\AC)*#PI/180)     
     *VertexSprite\Vertice[2]\sy = *SpriteID\Pivot_y  - *SpriteID\DC  * Sin((angle+*SpriteID\AC)*#PI/180) 
                                                                     
EndProcedure



InitSprite() : InitSprite3D() : InitKeyboard()
OpenScreen(800,600,32,"")


CreateSprite(0,128,64,#PB_Sprite_Texture)
 StartDrawing(SpriteOutput(0))
  Box(0,0,64,64,RGB(255,0,0))
  Box(64,0,64,64,RGB(255,255,0))
   StopDrawing()
CreateSprite3D(0,0)

A = CreateSprite3DEX(0)
b = CreateSprite3DEX(0)
c = CreateSprite3DEX(0)
d = CreateSprite3DEX(0)
e = CreateSprite3DEX(0)
f = CreateSprite3DEX(0)



Sprite3DModifyPivot(e,0,32)
Sprite3DModifyPivot(f,64,0)


Repeat
 r.f = 90 + 45 * Cos(ElapsedMilliseconds()/500)



 ExamineKeyboard()
 ClearScreen(0)
 Start3D()
 
RotateSprite3DEX(A,0)
DisplaySprite3D(0,100,100)

RotateSprite3DEX(b,90)
DisplaySprite3D(0,300,100)

RotateSprite3DEX(c,180)
DisplaySprite3D(0,100,300)

RotateSprite3DEX(d,270)
DisplaySprite3D(0,300,300)

RotateSprite3DEX(e,r)
DisplaySprite3D(0,500,200)


RotateSprite3DEX(f,-r)
DisplaySprite3D(0,500,400)


Stop3D()
 
 
 StartDrawing(ScreenOutput())
 DrawText(100,100,"0 DEG")
 DrawText(300,100,"90 DEG")
 DrawText(100,300,"180 DEG")
 DrawText(300,300,"270 DEG")
 Circle(500,232,4,RGB(0,0,255))
 Circle(564,400,4,RGB(0,0,255))
 
 StopDrawing()
 
 FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape)


@++
Répondre