Jeu de FPS en multijoueur. Voir la description sur planete casio
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

face.c 5.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. #include "face.h"
  2. #include "texture.h"
  3. #include "zbuffer.h"
  4. #include <stdbool.h>
  5. #include <gint/display.h>
  6. #define min(x,y) (x<y?x:y)
  7. #define max(x,y) (x>y?x:y)
  8. #define abs(x) (x>0?x:-x)
  9. static bool sens_horaire(FE_face const * face)
  10. {
  11. int area = 0;
  12. area+=face->s1->translated.x*face->s2->translated.y;
  13. area-=face->s2->translated.x*face->s1->translated.y;
  14. area+=face->s2->translated.x*face->s3->translated.y;
  15. area-=face->s3->translated.x*face->s2->translated.y;
  16. area+=face->s3->translated.x*face->s1->translated.y;
  17. area-=face->s1->translated.x*face->s3->translated.y;
  18. return (area < 0);
  19. }
  20. // gestion des lignes
  21. typedef struct line line;
  22. struct line
  23. {
  24. int x,y,z;
  25. int dx,dy,dz;
  26. bool no_line; // si les deux points sont confondus
  27. };
  28. static void set_line(line* segment,FE_point const * s1, FE_point const * s2)
  29. {
  30. segment->x=s1->translated.x;
  31. segment->y=s1->translated.y;
  32. segment->z=s1->translated.z;
  33. segment->dx=s2->translated.x-s1->translated.x;
  34. segment->dy=s2->translated.y-s1->translated.y;
  35. segment->dz=s2->translated.z-s1->translated.z;
  36. segment->no_line=(segment->dx==0&&segment->dy==0);
  37. }
  38. static bool get_x(int y, line const * segment, int * x)
  39. {
  40. y-=segment->y;
  41. if (y<0 && segment->dy>0)
  42. return false;
  43. if (y>0 && segment->dy<0)
  44. return false;
  45. if (abs(y)>abs(segment->dy))
  46. return false;
  47. if (segment->dy!=0)
  48. *x=segment->x+(y*segment->dx)/segment->dy;
  49. else if (y==0)
  50. *x=segment->x+segment->dx;
  51. else
  52. return false;
  53. return true;
  54. }
  55. void FE_draw_face(FE_face const * face)
  56. {
  57. if (sens_horaire(face)!=face->visible)
  58. return;
  59. if (face->s1->translated.x<0 && face->s2->translated.x<0 && face->s3->translated.x<0)
  60. return;
  61. if (face->s1->translated.x>127 && face->s2->translated.x>127 && face->s3->translated.x>127)
  62. return;
  63. if (face->s1->translated.y<0 && face->s2->translated.y<0 && face->s3->translated.y<0)
  64. return;
  65. if (face->s1->translated.y>63 && face->s2->translated.y>63 && face->s3->translated.y>63)
  66. return;
  67. if (face->s1->translated.z<=0 && face->s2->translated.z<=0 && face->s3->translated.z<=0)
  68. return;
  69. line cotes[3];
  70. set_line(&cotes[0],face->s1,face->s2);
  71. set_line(&cotes[1],face->s1,face->s3);
  72. set_line(&cotes[2],face->s2,face->s3);
  73. if (cotes[0].no_line||cotes[1].no_line||cotes[2].no_line)
  74. return;
  75. const int ymin=max(min(face->s1->translated.y,min(face->s2->translated.y,face->s3->translated.y)),0);
  76. const int ymax=min(max(face->s1->translated.y,max(face->s2->translated.y,face->s3->translated.y)),63);
  77. const int xAB=face->s2->translated.x-face->s1->translated.x, yAB=face->s2->translated.y-face->s1->translated.y, zAB=face->s2->translated.z-face->s1->translated.z;
  78. const int xAC=face->s3->translated.x-face->s1->translated.x, yAC=face->s3->translated.y-face->s1->translated.y, zAC=face->s3->translated.z-face->s1->translated.z;
  79. const int diviseur_commun=(xAB*yAC-yAB*xAC); //(multiplier par 10000)
  80. const int fact_1=(10000*yAC)/diviseur_commun, fact_2=(10000*xAC)/diviseur_commun;
  81. const int fact_3=(10000*xAB)/diviseur_commun, fact_4=(10000*yAB)/diviseur_commun;
  82. const int r_xAB=face->s2->rotated.x-face->s1->rotated.x, r_yAB=face->s2->rotated.y-face->s1->rotated.y;
  83. const int r_xAC=face->s3->rotated.x-face->s1->rotated.x, r_yAC=face->s3->rotated.y-face->s1->rotated.y;
  84. const int r_diviseur_commun=(r_xAB*r_yAC-r_yAB*r_xAC);
  85. const int r_fact_1=(10000*r_yAC)/r_diviseur_commun, r_fact_2=(10000*r_xAC)/r_diviseur_commun;
  86. const int r_fact_3=(10000*r_xAB)/r_diviseur_commun, r_fact_4=(10000*r_yAB)/r_diviseur_commun;
  87. for (int y=ymin; y<=ymax; y++)
  88. {
  89. // détermination du xmin et du xmax de la ligne
  90. int tx1,tx2;
  91. for (int t=0;t<3;t++)
  92. {if (get_x(y,&cotes[t],&tx1)) break;}
  93. for (int t=0;t<3;t++)
  94. {if (get_x(y,&cotes[t],&tx2)&&tx1!=tx2) break;}
  95. const int txmin=max(min(tx1,tx2),0), txmax=min(max(tx1,tx2),127);
  96. for (int x=txmin; x<=txmax; x++)
  97. {
  98. int xcalc,ycalc,vx,vy,vz,z,rx,ry;
  99. // initialisation des variables temporaires au calcul de vx, vy
  100. xcalc=x-face->s1->translated.x;
  101. ycalc=y-face->s1->translated.y;
  102. // calcul de vx,vy, et vz sans la déformation
  103. vx=(xcalc*fact_1-ycalc*fact_2); // 0 <vx< 10_000
  104. vy=(ycalc*fact_3-xcalc*fact_4); // idem
  105. vz=face->s1->translated.z + (vx*zAB+vy*zAC)/10000;
  106. // transformation
  107. rx=x-63; // on determine le centre de l'écran comme le point X(63,31)
  108. ry=y-31;
  109. rx*=vz; // on annule la perspective
  110. ry*=vz;
  111. // deuxieme processus de calcul (avec déformation)
  112. xcalc=rx-face->s1->rotated.x;
  113. ycalc=ry-face->s1->rotated.y;
  114. vx=(xcalc*r_fact_1-ycalc*r_fact_2);
  115. vy=(ycalc*r_fact_3-xcalc*r_fact_4);
  116. z=face->s1->translated.z + (vx*zAB+vy*zAC)/10000;
  117. // Affichage du point
  118. if (FE_zbuffer_set_dist(x,y,z))
  119. dpixel(x, y, 3*FE_get_pixel(face->texturenum,vx/1250,vy/1250)); // 3* means cast to black and white, and vx,and vy casted between 0 and 7
  120. }
  121. }
  122. // x=Det(AM,AC)/det(AB,AC)
  123. // y=det(AM,AB)/det(AC,AB)
  124. // x=(xAM*yAC-yAM*xAC)/(xAB*yAC-yAB*xAC)
  125. // y=(xAM*yAB-yAM*xAB)/(xAC*yAB-yAC*xAB)
  126. // soit diviseur_commun = (xAB*yAC-yAB*xAC)
  127. // x=xAM*yAC/diviseur_commun-yAM*xAC/diviseur_commun
  128. // y=yAM*xAB/diviseur_commun-xAM*yAB/diciseur_commun
  129. }