Code de l’objet en 3D filaire

7 sujets de 1 à 7 (sur un total de 7)

  • Anonyme

      #9099

      Voici le PRG 3D filaire. Penchez-vous un peux dessus, si comprenez bien le principe, vous saurez affiché n’importe quel objet en 3D filaire, attention, car le PRG 3D avec polygon est très compliqué (c’est de la bidouille), c’est pour sa que je cherche un objet 3D, ou plutôt un fichier que je peut lire avec Wordpad, comme sa avec la commande Read_ je pourrais aller chercher les coordonnées de l’objet, imaginer un viewer d’objet 3D fais avec hollywood ;-) .

      En tous cas, vous remarquerez que l’on peut bouger l’objet avec les touches du clavier, en gros, on peux remplacer le cube par autre chose, un vaisseau par exemple ;-) .

      La je suis sur comment créer un monde en 3D filaire, puis si j’y arrive car c’est pas gagner tellement c’est hard, et que j’ai jamais fait de 3D de ma vie sauf avec Autocad (quand j’ai passé le diplôme d’automaticien) je bidouillerai le moteur pour qu’il fonctionne avec des polygons… Par contre pour avoir des objets texturé, hum… j’ai mes limites et je pense pas y arriver de sitôt.

      Bref, voici le code et bonne amusement, si vous arrivez à faire autre chose qu’un cube, faites le nous voir ;-) et si vous arrivez à faire partir le Bug, se serai sympa de me donnée la formule. Pour le PB, je sais que c’est la valeur calculeren sin et cos, à mon avis 360, c’est pas bon.

      Je suis parti de sa :

      BeginDoubleBuffer

      OX=320

      OY=200

      SetFormStyle(#ANTIALIAS)

      Repeat

      For c=0 To 6.26 Step 0.01

      x=Cos(c)*100

      Y=Sin(c)*100

      X1=Cos(c-1.56)*100

      Y1=Sin(c-1.56)*100

      Line(OX+x,OY+Y,OX+X1,OY+Y1,#WHITE)

      Line(OX-x,OY-Y,OX+X1,OY+Y1,#WHITE)

      Line(OX-x,OY-Y,OX-X1,OY-Y1,#WHITE)

      Line(OX+x,OY+Y,OX-X1,OY-Y1,#WHITE)

      Line(OX+x+50,OY+Y+50,OX+X1+50,OY+Y1+50,#WHITE)

      Line(OX-x+50,OY-Y+50,OX+X1+50,OY+Y1+50,#WHITE)

      Line(OX-x+50,OY-Y+50,OX-X1+50,OY-Y1+50,#WHITE)

      Line(OX+x+50,OY+Y+50,OX-X1+50,OY-Y1+50,#WHITE)

      Line(OX+x,OY+Y,OX+X+50,OY+Y+50,#WHITE)

      Line(OX-x,OY-Y,OX-x+50,OY-Y+50,#WHITE)

      Line(OX+x1,OY+Y1,OX+X1+50,OY+Y1+50,#WHITE)

      Line(OX-x1,OY-Y1,OX-x1+50,OY-Y1+50,#WHITE)

      Flip

      Cls

      Next

      Forever

      Pour arriver à sa:

      BeginDoubleBuffer

      EscapeQuit(True)

      OX=320

      OY=200

      SetFormStyle(#ANTIALIAS)

      Repeat

      For c=0 To 6.26 Step 0.01

      x=Cos(c)*100

      Y=Sin(c)*100

      X1=Cos(c-1.56)*100

      Y1=Sin(c-1.56)*100

      t={}

      t[0] = x ;X1

      t[1] = Y ;Y1

      t[2] = X+50 ;X2

      t[3] = Y+50 ;Y2

      t[4] = x1+50 ;X3

      t[5] = y1+50 ;Y3

      t[6] = X1 ;X4

      t[7] = Y1 ;Y4

      t[8] = x ;X5

      t[9] = Y ;Y5

      u={}

      u[0] = x ;X1

      u[1] = Y ;Y1

      u[2] = X+50 ;X2

      u[3] = Y+50 ;Y2

      u[4] = -x1+50;X3

      u[5] = -y1+50;Y3

      u[6] = -X1 ;X4

      u[7] = -Y1 ;Y4

      u[8] = x ;X5

      u[9] = Y ;Y5

      v = {}

      v[0] = x ;X1

      v[1] = Y ;Y1

      v[2] = X1 ;X2

      v[3] = Y1 ;Y2

      v[4] = -x ;X3

      v[5] = -Y ;Y3

      v[6] = -X1 ;X4

      v[7] = -Y1 ;Y4

      v[8] = x ;X5

      v[9] = Y ;Y5

      SetFillStyle(#FILLCOLOR)

      Polygon(OX+50, OY+50, v,5,$555555)

      Polygon(OX,OY,u,5,$999999)

      For i=0 To 9

      u=u*(-1)

      Next

      Polygon(OX+50,OY+50,u,5,$999999)

      Polygon(Ox,OY,t,5,$999999)

      For i=0 To 9

      t=t*(-1)

      Next

      Polygon(Ox+50,OY+50,t,5,$999999)

      Polygon(OX, OY, v, 5, #WHITE)

      Flip

      Cls

      Next

      Forever

      Et voila le bon code pour le filaire

      @SCREEN {Mode = « ask », Width = 640, Height = 400}

      SetFormStyle(#ANTIALIAS) ; Antialiasing sur le cube

      FC=200

      CX=160

      CY=100

      CZ=200

      Function Controle()

      If IsKeyDown(« Left »)=True Then Gauche() ; Vers la gauche

      If IsKeyDown(« Right »)=True Then Droite() ; Vers la droite

      If IsKeyDown(« Up »)=True Then Haut() ; Vers le Haut

      If IsKeyDown(« Down »)=True Then Bas() ; Vers le bas

      If IsKeyDown(« RSHIFT »)=True Then Zoomin() ; Zoom in

      If IsKeyDown(« RCONTROL »)=True Then Zoomout() ; Zoom Out

      EndFunction

      Function Gauche()

      AY=AY+1

      If AY>359 Then AY=0

      EndFunction

      Function Droite()

      AY=AY-1

      If AY<0 Then AY=359

      EndFunction

      Function Haut()

      AX=AX+1

      If AX>359 Then AX=0

      EndFunction

      Function Bas()

      AX=AX-1

      If AX<0 Then AX=359

      EndFunction

      Function Zoomin()

      CZ=CZ+10

      If CZ>500 Then CZ=500

      EndFunction

      Function Zoomout()

      CZ=CZ-10

      If CZ<80 Then CZ=80

      EndFunction

      Function PRG()

      Controle() ; Exécution de la fonction Controle

      ; Réservation mémoire et création des tableaux

      Dim CO[360] ; 360 cases réservé car une rotation c’est 360° pour le Cosinus

      Dim SI[360] ; 360 cases réservé car une rotation c’est 360° pour le Sinus

      Dim X[8] ; Un cube, c’est 8 points en X

      Dim Y[8] ; Un cube, c’est 8 points en Y

      Dim Z[8] ; Un cube, c’est 8 points en Z

      Dim XE[8] ; Point final du cube a dessiner en X

      Dim YE[8] ; Point final du cube a dessiner en Y

      Dim ZZ[8] ; Point final du cube a dessiner en Z

      Dim P1[12] ; Un cube, c’est 12 lignes (point de départ de la ligne)

      Dim P2[12] ; Un cube, c’est 12 lignes (point final de la ligne)

      Flip ; Flip d’écran pour le double buffer

      Cls ; Effacement de l’écran sinon on verrait des cube partout lol

      For I=0 To 359

      CO=Cos(I*0.1)*256 ; Mise en mémoire de 360 calcule du Cosinus des angles sur 360°

      SI=Sin(I*0.1)*256 ; Mise en mémoire de 360 calcule du Sinus des angles sur 360°

      Next

      For I=0 To 7

      X = {-50,50,50,-50,-50,50,50,-50} ; Coordonnées des points dans l’espace en X

      Y = {-50,-50,50,50,-50,-50,50,50} ; Coordonnées des points dans l’espace en Y

      Z = {-50,-50,-50,-50,50,50,50,50} ; Coordonnées des points dans l’espace en Z

      P1 = {0,1,2,3,4,5,6,7,0,1,2,3} ; Point de départ pour tracer la ligne

      P2 = {1,2,3,0,5,6,7,4,4,5,6,7} ; Point d’arrivée pour tracer la ligne

      ;Calcule 3D grâce au magazine Dream N°27 de Mars 1996

      Y1=(Y*CO[AX]+Z*SI[AX])/256

      Z1=(-Y*SI[AX]+Z*CO[AX])/256

      X1=(X*CO[AY]+Z1*SI[AY])/256

      ZZ=(-X*SI[AY]+Z1*CO[AY])/256

      X=(X1*CO[AZ]+Y1*SI[AZ])/256

      Y=(-X1*SI[AZ]+Y1*CO[AZ])/256

      D=FC/(Sqrt(X^2+Y^2+(CZ+ZZ)^2))

      XE=320+X*D

      YE=200+Y*D

      Next

      ; Calcule final

      For I=0 To 11

      GP1=P1

      GP2=P2

      X=XE[GP1]

      Y=YE[GP1]

      X1=XE[GP2]

      Y1=YE[GP2]

      Line (X,Y,X1,Y1,#WHITE) ; Traçage des lignes

      Next

      EndFunction

      BeginDoubleBuffer

      SetInterval(1,PRG,1000/50)

      Repeat

      WaitEvent

      Forever

      Amusez vous bien :-D

      thellier

        #139635

        Bonjour

        >je cherche un objet 3D, ou plutôt un fichier que je peut lire avec Wordpad

        Il y a un objet (starship.h) dans mon package

        http://aminet.net/package/dev/src/StarShip

        Par ailleurs voici qques routines generiques de projection/transformation ( http://aminet.net/package/dev/src/Cow3D )

        exemple d’utilisation

        float ViewMatrix[16];

        memcpy(P2,P,Pnb*sizeof(struct point3D)); /* copy the object’s points to P2*/

        SetMry(ViewMatrix,RotY); /* do a y rotation matrix */

        TransformP(ViewMatrix,P2,Pnb); /* fully transform the object’s points in P2*/

        ProjectP(P2,Pnb); /* project points to screen */

        /*==================================================================*/

        struct point3D{

        float x,y,z,u,v,w;

        UBYTE RGBA[4];

        };

        /*==================================================================*/

        /*=================================================================*/

        void SetMrot(float *M,float R ,UBYTE a,UBYTE b,UBYTE c,UBYTE d)

        { /* define a rotation matrix */

        float Pi =3.1416;

        WORD n;

        if(M==NULL) return;

        M[0]=M[5]=M[10]=M[15]= 1.0; M[1]=M[2]=M[3]=M[4]=M[6]=M[7]=M[8]=M[9]=M[11]=M[12]=M[13]=M[14]=0.0;

        if(R==0.0) return;

        if(R>=360.0)

        {n=R/360.0; R=R-n*360.0;}

        if(R<0.0)

        {n=1+R/360.0;R=R-n*360.0;}

        R= R / 180.0 * Pi;

        M[a] = (float)cos(R);

        M = M[a];

        M[c] = (float)sin(R);

        M[d] = -M[c];

        }

        /*=================================================================*/

        void SetMrx(float *M,float x) /* define X rotation matrix */

        { SetMrot(M,x,5,10,6,9); }

        /*=================================================================*/

        void SetMry(float *M,float y) /* define Y rotation matrix */

        { SetMrot(M,y,10,0,8,2); }

        /*=================================================================*/

        void SetMrz(float *M,float z) /* define Z rotation matrix */

        { SetMrot(M,z,0,5,1,4); }

        /*=================================================================*/

        void TransformP(register float *M,struct point3D *P,LONG Pnb)

        { /* transform points with a given matrix */

        register float x;

        register float y;

        register float z;

        register LONG n;

        NLOOP(Pnb)

        {

        x=P->x;y=P->y;z=P->z;

        P->x= M[0]*x + M[4]*y+ M[8] *z+ M[12];

        P->y= M[1]*x + M[5]*y+ M[9] *z+ M[13];

        P->z= M[2]*x + M[6]*y+ M[10]*z+ M[14];

        P++;

        }

        }

        /*=================================================================*/

        void YrotateP(register float *M,struct point3D *P,LONG Pnb)

        { /* y rotate points with a given matrix : optimized TransformP() */

        register float x;

        register float z;

        register float m0 =M[0];

        register float m8 =M[8];

        register float m2 =M[2];

        register float m10=M[10];

        register LONG n;

        NLOOP(Pnb)

        {

        x=P->x;z=P->z;

        P->x= m0*x + m8 *z;

        P->z= m2*x + m10*z;

        P++;

        }

        }

        /*=================================================================*/

        void ProjectP(struct point3D *P,LONG Pnb)

        { /* project points to screen-coordinates */

        register float x;

        register float y;

        register float z;

        register float sizex=LARGE/2.0;

        register float sizey=HIGH /2.0;

        register float sizez=0.8 /2.0;

        register LONG n;

        NLOOP(Pnb)

        {

        x=P->x;y=P->y;z=P->z;

        P->x= x*sizex+sizex;

        P->y= y*sizey+sizey;

        P->z= z*sizez+sizez;

        P->w= 1.0/P->z;

        P++;

        }

        }

        Anonyme

          #139636

          Merci pour l’objet, je regarde sa se soir.

          Pour le code, qu’elle est la commande pour afficher les points/polygon?

          Parceque sous hollywood, les comandes 3D n’existe pas (et c’est bien dommage :-( )

          Le code est bien plus compliqué que sous hollywood ;-)

          Par contre pour traduire sa… oulala, mais la formules peux beaucoup m’aider, je te remercie pour la source, et je tiens au courant pour poster un « meilleur » moteur.

          A+

          thellier

            #139637

            En fait l’idée c’est on a les points d’origine dans un tableau P

            (ce tableau est rempli une fois pour toute avec les données de « points » de starship.h)

            on les copie dans un tableau P2 qu’on transforme (rotation,projection)

            ensuite on affiche les triangles grace au tableau indices (définissant les triangles) et aux points de P2 (=coordonnées écran)

            (ainsi un même point est utilisé dans des triangles adjacents)

            >Pour le code, qu’elle est la commande pour afficher les points/polygon?

            Je te le fais avec un horrible pseudocode :-)

            faut faire une boucle n pour tout les triangles (=trianglesCount)

            {

            récupérer les 3 points du triangle parmi les points transformés (donc dans le tableau P2)

            point1 P2[indices[n*3+0]]

            point2 P2[indices[n*3+1]]

            point3 P2[indices[n*3+2]]

            tracer le triangle cad

            ligne(point1.x,point1.y,point2.x,point2.y)

            ligne(point2.x,point2.y,point3.x,point3.y)

            ligne(point3.x,point3.y,point1.x,point1.y)

            }

            Au fait que faudrait il pour que hollywood fasse de la 3D ? (un wrapper ? un datatype ? une library ?)

            Par ailleurs mon code est plus compliqué mais plus générique on peut faire des rotations en x ou y ou z et projeter sur n’importe quel écran de taille LARGE HIGH

            Aussi c’est un example didactique: un hacker ferait 3 fois plus court mais inbittable :-P

            Alain

            Anonyme

              #139638

              Merci,

              Pour hollywood la majorité du langage est codé avec LUA (je connais pas du tout se langage), je pense qu’il faut que tu rentre en contact avec Andreas Falkenhahn de airsoft software (qui lui est un coder 2D dans l’âme), il serait peut être intéressé pour une sorte de partenariat sur le développement de commandes pour de la création et gestion 3D. Sinon, il est possible d’écrire des applets pour hollywood, mais tu sera obligé de passé par les commandes de se langage pas du tous spécialisé dans la 3D.

              En tous cas, chapeau bas pour ton moteur 3D… j’aimerai vraiment arrivé à faire le genre de chose que tu fais, avec des objets 3D, du mapping, effet de lumière etc… généré un monde en 3D!! sa doit être très difficile surtout quand on part de zéro. J’ai plein d’idée, mais ma technique se limite surtout à la 2D.

              Hollywood est (pour résumé) une sorte d’Amos multiplateforme, la preuve, le programme du cube est à la base un programme amos que j’ai du transformé. En tous cas je suis content que la version compilé Morphos soit aussi rapide que la version AOS pour une même config, au moins, mes projet et essai seront identique sur ces 2 OS (sans compter pour warpos et 6800×0).

              Si j’arrive à lire ton fichier objet et à l’afficher, je mettrai les sources sur le sites afin que les autres puissent en profiter, plus on échangera nos travaux, et plus nos projets avanceront et s’amélioreront…

              Par contre, je trouve qu’il n’y a pas beaucoup de programmeur hollywood :-(. C’est dommage.

              Par contre, peut être qu’un datatype sa marcherai, mais il faut une version pour AOS, Morphos, Win x86, Mac, Warpos et 6800×0, sa fait du boulot pour toi.

              C’est quoi un wrapper? malgrès la définition du Net, je la comprend pas…

              Edit: Tu passe par des triangles pour construire des objets? C’est peut être pour sa que j’y arrive pas, j’essai avec des carré, je pensé que c’était comme sa que faisait les programmeurs 3D

              Re EDIT: Pourquoi U et V pour les coordonnées des points? il y a 3 axes dans l’espace… je ne comprend pas.. Bon j’essai avec les coordonnées X,Y et Z pour voir se que sa donne

              Merci

              thellier

                #139639

                >En tous cas, chapeau bas pour ton moteur 3D…

                MZERCI :-)


                un wrapper c’est quand tu convertis une première api en une autre deuxième api

                cad que l’utilisateur continue d’utiliser les commandes de l’api 1 (du langage 1) et que le wrapper convertit les paramétres et appelle en fait l’api 2 (du langage 2) de manière transparente

                Un exemple:

                Un wrapper Warp3D -> OpenGL pour mettre la couleur courante (cad le « pen »)

                Warp3D utilise la fonction W3D_SetCurrentColor

                OpenGL utilise la fonction glColor4fv

                ULONG W3D_SetCurrentColor(W3D_Context *context, W3D_Color *color)

                {

                float v[4]; /* format de couleur attendu par OpenGL */

                v[0]=color->r; /* conversion du paramétre couleur */

                v[1]=color->g;

                v[2]=color->b;

                v[3]=color->a;

                glColor4fv(v); /* appel de la fonction similaire d’opengl de manière transparente */

                WRETURN(W3D_SUCCESS); /* renvoi du bon paramétre warp3D

                }


                > des triangles .. je pensé que c’était comme sa que faisait les programmeurs 3D

                Avec OpenGL on peut faire les deux (rectangles(=quad) ou triangles (tris))

                Par contre Warp3D fait que des triangles mais peut en tracer des centaines avec une seule commande W3d_Drawarray()


                > Pourquoi U et V pour les coordonnées des points?

                C’est les coordonnées sur la texture. C’est comme des X Y mais sur l’image de la texture (u=0,v=0) est un coin de la texture (u=1.0,v=1.0) est l’autre coin de la texture

                (u=0.5,v=0.5) est le centre de la texture

                Y a aussi une coordonnée W qui est en rapport avec la perspective (en fait à quel point le Z est influencé par la perspective) et qui change donc le texturage

                U V W pour ton prog filaire ça sert à rien :-)

                Alain*/

                Anonyme

                  #139640

                  Stop stop… n’en jette plus…lol… mon petit cerveau explose ;-)

                  Super intéressant se que tu écrit, tu utilise 3 axes différent des points d’un triangle pour la texture, c’est pour sa que j’y arriver pas. Merci beaucoup pour toutes ses infos.

                  Je pense te filer starship en exécutable d’ici lundi (j’espère) avec le code soure (je le mettrai sur le forum)

                  Respect ;-)

                7 sujets de 1 à 7 (sur un total de 7)

                • Vous devez être connecté pour répondre à ce sujet.

                Forums AmigaOS, MorphOS et AROS Développement Code de l’objet en 3D filaire

                Amiga Impact