home *** CD-ROM | disk | FTP | other *** search
/ The Best of Mecomp Multimedia 2 / MECOMP-CD-II.iso / amiga / tools / libs / graphics3d / src / library / graphics3df_t.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-13  |  11.8 KB  |  402 lines

  1. /*
  2. **      $VER: graphics3Df_t.c 10.01 (01.11.97)
  3. **
  4. **      External functions for graphics3D.library
  5. **
  6. **      (C) Copyright 97 Patrizio Biancalani
  7. **      All Rights Reserved.
  8. **
  9. **    Note: this code is traslate from the blitzbasic 3d graphics engine 
  10. **          V 0.9 of Maciej R. Gorny.
  11. */
  12.  
  13. #include <exec/types.h>
  14. #include <exec/memory.h>
  15. #include <proto/exec.h>
  16. #include <proto/intuition.h>
  17. #include <intuition/intuition.h>
  18. #include <intuition/screens.h>
  19.  
  20. #include <graphics/rastport.h>
  21. #include <graphics/clip.h>
  22. #include <graphics/regions.h>
  23. #include <graphics/gfx.h>
  24. #include <graphics/gfxmacros.h>
  25. #include <graphics/layers.h>
  26.  
  27. #include "graphics3Dc.h"
  28. #include "graphics3D.h"
  29. #include "graphics3Df_proto.h"
  30. #include "graphics3D2d_proto.h"
  31.  
  32.  /* Please note, that &PovedtBase always resides in register __a6 as well,
  33.     but if we don't need it, we need not reference it here.
  34.  
  35.     Also note, that registers a0, a1, d0, d1 always are scratch registers,
  36.     so you usually should only *pass* parameters there, but make a copy
  37.     directly after entering the function. To avoid problems of kind
  38.     "implementation defined behaviour", you should make a copy of A6 too,
  39.     when it is actually used.
  40.  
  41.     In this example case, scratch register saving would not have been 
  42.     necessary (since there are no other function calls inbetween), but we 
  43.     did it nevertheless.
  44.   */
  45.  
  46. extern void createworldtocamera(struct ambient3d *in);
  47. extern void recalcobj(struct ambient3d *in);
  48. extern long int t_removeobject(struct ambient3d *in);
  49. extern void localtoworld(struct ambient3d *in);
  50. extern void worldtocamera(struct ambient3d *in);
  51. extern void removebackfacesandshade(struct ambient3d *in);
  52. extern void clipobject3d(struct ambient3d *in);
  53. extern void generatepolylist(struct ambient3d *in);
  54. extern struct objectnode *resetobj(struct ambient3d *in);
  55. extern struct objectnode *nextobj(struct ambient3d *in);
  56. extern struct objectnode *pobj(struct ambient3d *in);
  57. extern void aggobj(struct ambient3d *in);
  58. extern void matidentity4x4(struct matrix4x4 *imatrix); 
  59. extern void matzero4x4(struct matrix4x4 imatrix);
  60. extern void matcopy4x4(struct matrix4x4 *s_m,struct matrix4x4 *d_m);
  61. extern void matmult4x4(struct matrix4x4 *a,struct matrix4x4 *b,
  62.         struct matrix4x4 *r);
  63. extern void matmult4x4s(struct matrix4x4 *a,struct matrix4x4 *b,
  64.         struct matrix4x4 *r);
  65. extern void matmult1x4s(struct matrix1x4 *a,struct matrix4x4 *b,
  66.         struct matrix1x4 *r);
  67. extern void makevector3d(struct vertex *a,struct vertex *b,
  68.          struct vector *result);
  69. extern long int vectormag3d(struct vector *a);
  70. extern void normalpol(struct vertex *v0,struct vertex *v1,
  71.      struct vertex *v2,struct vector *normal);
  72. extern long int dotproduct(struct vector *u,struct vector *v);
  73. extern long int sqri(long int v);
  74. extern long int abs(long int val);
  75. extern void qsort(long int lo0,long int hi0,long int *pol,long int *count);
  76. extern void cls_b(struct grafica *graf,long int x0,long int y0,
  77.     long int x1,long int y1i);
  78. extern long int clipbox(struct grafica *graf,long int minx,long int miny,
  79.     long int dx,long int dy);
  80. extern void paintpol(struct grafica *graf,long int *iwp,
  81.     long int total_polys,long int colb); 
  82. extern long int quicksort(long int len,long int *pol);
  83.  
  84. /**********************************************************/
  85.  
  86. /****************************************************
  87.  ** Routin per la gestione della grafica, in stile **
  88.  ** 2.0                                            ** 
  89.  ** (c) 1994 BIANCA HARD&SOFT Vers:1.00            **
  90.  ****************************************************/
  91.  
  92. /************ FUNZIONI 3D (trasformazioni oggetti) **********************/
  93.  
  94. /************************************************
  95.  ** sposta origine oggetto attuale.           **
  96.  ************************************************
  97.  *** INPUT :                        * 
  98.  * in -> valore > 0 restituito da display3d.    *
  99.  * dx -> valore spostamento su asse x           *
  100.  *       (valore in FIXPOINT).            *
  101.  * dy -> valore spostamento su asse y           *
  102.  *       (valore in FIXPOINT).            *
  103.  * dz -> valore spostamento su asse z           *
  104.  *       (valore in FIXPOINT).            *
  105.  *** OUTPUT:                    *
  106.  * nessuno.                    *
  107.  ************************************************/
  108. void GD_translateobject(in,dx,dy,dz)
  109. REG(a0)struct ambient3d *in;
  110. REG(d0)long int dx;
  111. REG(d1)long int dy;
  112. REG(d2)long int dz;
  113. {
  114. struct objectnode *obj;
  115.  
  116. obj=pobj(in);
  117.  
  118. obj->worldposx+=dx;
  119. obj->worldposy+=dy;
  120. obj->worldposz+=dz;
  121.  
  122. obj->trasf |= 0x02;
  123.  
  124. }
  125.  
  126. /************************************************
  127.  ** posiziona oggetto attuale in modo assoluto.**
  128.  ************************************************
  129.  *** INPUT :                        * 
  130.  * in -> valore > 0 restituito da display3d.    *
  131.  * dx -> valore posizione su asse x             *
  132.  *       (valore in FIXPOINT).            *
  133.  * dy -> valore posizione su asse y             *
  134.  *       (valore in FIXPOINT).            *
  135.  * dz -> valore posizione su asse z             *
  136.  *       (valore in FIXPOINT).            *
  137.  *** OUTPUT:                    *
  138.  * nessuno.                    *
  139.  ************************************************/
  140. void GD_positionobject(in,x,y,z)
  141. REG(a0)struct ambient3d *in;
  142. REG(d0)long int x;
  143. REG(d1)long int y;
  144. REG(d2)long int z;
  145. {
  146. struct objectnode *obj;
  147.  
  148. obj=pobj(in);
  149.  
  150. obj->worldposx=x;
  151. obj->worldposy=y;
  152. obj->worldposz=z;
  153.  
  154. obj->trasf |= 0x02;
  155.  
  156. }
  157.  
  158. /************************************************
  159.  ** riscala oggetto attuale sui tre assi.      **
  160.  ** Lavora SEMPRE sulle coordinate iniziali,   **
  161.  ** quindi occorre cumulare le eventuali varia-**
  162.  ** zioni di scala all'esterno di questa routin**
  163.  ************************************************
  164.  *** INPUT :                        * 
  165.  * in -> valore > 0 restituito da display3d.    *
  166.  * xscale_fact -> valore riscalatura su asse x  *
  167.  *          (valore in FIXPOINT).        *
  168.  * yscale_fact -> valore riscalatura su asse y  *
  169.  *          (valore in FIXPOINT).        *
  170.  * zscale_fact -> valore riscalatura su asse z  *
  171.  *          (valore in FIXPOINT).        *
  172.  *** OUTPUT:                    *
  173.  * nessuno.                    *
  174.  ************************************************/
  175. void GD_scaleobject(in,xscale_fact,yscale_fact,zscale_fact)
  176. REG(a0)struct ambient3d *in;
  177. REG(d0)long int xscale_fact;
  178. REG(d1)long int yscale_fact;
  179. REG(d2)long int zscale_fact;
  180. {
  181. struct objectnode *obj;
  182. struct vertex *vl,*vo;
  183. long int curr_vertex;
  184.  
  185. obj=pobj(in);
  186. vo=obj->vlocal;
  187. vl=obj->vorig;
  188.  
  189. if (xscale_fact==FIXV AND yscale_fact==FIXV AND zscale_fact==FIXV) return(0);
  190. if (obj->trasf&0x01!=NULL) vl=obj->vlocal;
  191.  
  192. for(curr_vertex=0 ; curr_vertex<obj->numverts ; curr_vertex++)
  193.     {
  194.     vo[curr_vertex].x=(vl[curr_vertex].x*xscale_fact) >> SFIXV;
  195.     vo[curr_vertex].y=(vl[curr_vertex].y*yscale_fact) >> SFIXV;
  196.     vo[curr_vertex].z=(vl[curr_vertex].z*zscale_fact) >> SFIXV;
  197.     }
  198.  
  199. obj->trasf |= 0x01;
  200.  
  201. }
  202.  
  203. /************************************************
  204.  ** ruota oggetto attuale sui tre assi .       **
  205.  ** Lavora SEMPRE sulle coordinate iniziali,   **
  206.  ** quindi occorre cumulare le eventuali varia-**
  207.  ** zioni di rot. all'esterno di questa routin **
  208.  ************************************************
  209.  *** INPUT :                        * 
  210.  * in -> valore > 0 restituito da display3d.    *
  211.  * angle_x -> valore rotazione su asse x.       *
  212.  *           (in gradi INTERO)            *
  213.  * angle_y -> valore rotazione su asse y.       *
  214.  *           (in gradi INTERO)            *
  215.  * angle_z -> valore rotazione su asse z.       *
  216.  *           (in gradi INTERO)            *
  217.  *** OUTPUT:                    *
  218.  * nessuno.                    *
  219.  ************************************************/
  220. void GD_rotateobject(in,angle_x,angle_y,angle_z)
  221. REG(a0)struct ambient3d *in;
  222. REG(d0)long int angle_x;
  223. REG(d1)long int angle_y;
  224. REG(d2)long int angle_z;
  225. {
  226. struct objectnode *obj;
  227. struct vertex *vo,*vl;
  228. long int *sin,*cos;
  229. long int i,product;
  230. struct matrix4x4 rotate_x;
  231. struct matrix4x4 rotate_y;
  232. struct matrix4x4 rotate_z;
  233. struct matrix4x4 rot;
  234. struct matrix4x4 temp;
  235.  
  236. obj=pobj(in);
  237. vo=obj->vlocal;
  238. vl=obj->vorig;
  239. if (obj->trasf&0x01 != NULL) vl=obj->vlocal;
  240. sin=in->sintable;
  241. cos=in->costable;
  242.  
  243. product=0;
  244.  
  245. matidentity4x4(&rot);
  246.  
  247. if (angle_x<0 OR angle_x>360)
  248.     {
  249.     angle_x-=(angle_x/360)*360;
  250.     if (angle_x<0) angle_x+=360;
  251.     }
  252.  
  253. if (angle_y<0 OR angle_y>360)
  254.     {
  255.     angle_y-=(angle_y/360)*360;
  256.     if (angle_y<0) angle_y+=360;
  257.     }
  258.  
  259. if (angle_z<0 OR angle_z>360)
  260.     {
  261.     angle_z-=(angle_z/360)*360;
  262.     if (angle_z<0) angle_z+=360;
  263.     }
  264.  
  265. if (angle_x!=0 AND angle_x!=360) product+=4;
  266. if (angle_y!=0 AND angle_y!=360) product+=2;
  267. if (angle_z!=0 AND angle_z!=360) product+=1;
  268.  
  269. switch (product)
  270.     {
  271.     case(1):
  272.         rot.r0c0=cos[angle_z];
  273.         rot.r0c1=sin[angle_z];
  274.         rot.r1c0=-sin[angle_z];
  275.         rot.r1c1=cos[angle_z];
  276.         for(i=0 ; i<obj->numverts ; i++)
  277.             {
  278.             vo[i].x=(vl[i].x*rot.r0c0+vl[i].y*rot.r1c0) >> SFIXV;
  279.             vo[i].y=(vl[i].x*rot.r0c1+vl[i].y*rot.r1c1) >> SFIXV;
  280.             vo[i].z=vl[i].z;
  281.             }
  282.         obj->trasf|=0x01;
  283.         break;
  284.     case(2):
  285.         rot.r0c0=cos[angle_y];
  286.         rot.r0c2=-sin[angle_y];
  287.         rot.r2c0=sin[angle_y];
  288.         rot.r2c2=cos[angle_y];
  289.         for(i=0 ; i<obj->numverts ; i++)
  290.             {
  291.             vo[i].x=(vl[i].x*rot.r0c0+vl[i].z*rot.r2c0) >> SFIXV;
  292.             vo[i].z=(vl[i].x*rot.r0c2+vl[i].z*rot.r2c2) >> SFIXV;
  293.             vo[i].y=vl[i].y;
  294.             }
  295.         obj->trasf|=0x01;
  296.         break;
  297.     case(3):
  298.         rot.r0c0=(cos[angle_y]*cos[angle_z]) >> SFIXV;
  299.         rot.r0c1=(cos[angle_y]*sin[angle_z]) >> SFIXV;
  300.         rot.r0c2=-sin[angle_y];
  301.         rot.r1c0=-sin[angle_z];
  302.         rot.r1c1=cos[angle_z];
  303.         rot.r2c0=(sin[angle_y]*cos[angle_z]) >> SFIXV;
  304.         rot.r2c1=(sin[angle_y]*sin[angle_z]) >> SFIXV;
  305.         rot.r2c2=cos[angle_y];
  306.         for(i=0 ; i<obj->numverts ; i++)
  307.             {
  308.             vo[i].x=(vl[i].x*rot.r0c0 + vl[i].y*rot.r1c0 +
  309.                 vl[i].z*rot.r2c0) >> SFIXV;
  310.             vo[i].y=(vl[i].x*rot.r0c1 + vl[i].y*rot.r1c1 +
  311.                 vl[i].z*rot.r2c1) >> SFIXV;
  312.             vo[i].z=(vl[i].x*rot.r0c2+vl[i].z*rot.r2c2) >> SFIXV;
  313.             }
  314.         obj->trasf|=0x01;
  315.         break;
  316.     case(4):
  317.         rot.r1c1=cos[angle_x];
  318.         rot.r1c2=sin[angle_x];
  319.         rot.r2c1=-sin[angle_x];
  320.         rot.r2c2=cos[angle_x];
  321.         for(i=0 ; i<obj->numverts ; i++)
  322.             {
  323.             vo[i].y=(vl[i].y*rot.r1c1+vl[i].z*rot.r2c1) >> SFIXV;
  324.             vo[i].z=(vl[i].y*rot.r1c2+vl[i].z*rot.r2c2) >> SFIXV;
  325.             vo[i].x=vl[i].x;
  326.             }
  327.         obj->trasf|=0x01;
  328.         break;
  329.     case(5):
  330.         rot.r0c0=cos[angle_z];
  331.         rot.r0c1=sin[angle_z];
  332.         rot.r1c0=(-cos[angle_x]*sin[angle_z]) >> SFIXV;
  333.         rot.r1c1=(cos[angle_x]*cos[angle_z]) >> SFIXV;
  334.         rot.r1c2=sin[angle_x];
  335.         rot.r2c0=(sin[angle_x]*sin[angle_z]) >> SFIXV;
  336.         rot.r2c1=(-sin[angle_x]*cos[angle_z]) >> SFIXV;
  337.         rot.r2c2=cos[angle_x];
  338.         for(i=0 ; i<obj->numverts ; i++)
  339.             {
  340.             vo[i].x=(vl[i].x*rot.r0c0 + vl[i].y*rot.r1c0 +
  341.                 vl[i].z*rot.r2c0) >> SFIXV;
  342.             vo[i].y=(vl[i].x*rot.r0c1 + vl[i].y*rot.r1c1 +
  343.                 vl[i].z*rot.r2c1) >> SFIXV;
  344.             vo[i].z=(vl[i].y*rot.r1c2+vl[i].z*rot.r2c2) >> SFIXV;
  345.             }
  346.         obj->trasf|=0x01;
  347.         break;
  348.     case(6):
  349.         rot.r0c0=cos[angle_y];
  350.         rot.r0c2=-sin[angle_y];
  351.         rot.r1c0=(sin[angle_x]*sin[angle_y]) >> SFIXV;
  352.         rot.r1c1=cos[angle_x];
  353.         rot.r1c2=(sin[angle_x]*cos[angle_y]) >> SFIXV;
  354.         rot.r2c0=(cos[angle_x]*sin[angle_y]) >> SFIXV;
  355.         rot.r2c1=-sin[angle_x];
  356.         rot.r2c2=(cos[angle_x]*cos[angle_y]) >> SFIXV;
  357.         for(i=0 ; i<obj->numverts ; i++)
  358.             {
  359.             vo[i].x=(vl[i].x*rot.r0c0 + vl[i].y*rot.r1c0+
  360.                 vl[i].z*rot.r2c0) >> SFIXV;
  361.             vo[i].y=(vl[i].y*rot.r1c1+vl[i].z*rot.r2c1) >> SFIXV;
  362.             vo[i].z=(vl[i].x*rot.r0c2 + vl[i].y*rot.r1c2 +
  363.                 vl[i].z*rot.r2c2) >> SFIXV;
  364.             }
  365.         obj->trasf|=0x01;
  366.         break;
  367.     case(7):
  368.         matidentity4x4(&rotate_x);
  369.         rotate_x.r1c1=cos[angle_x];
  370.         rotate_x.r1c2=sin[angle_x];
  371.         rotate_x.r2c1=-sin[angle_x];
  372.         rotate_x.r2c2=cos[angle_x];
  373.         matidentity4x4(&rotate_y);
  374.         rotate_y.r0c0=cos[angle_y];
  375.         rotate_y.r0c2=-sin[angle_y];
  376.         rotate_y.r2c0=sin[angle_y];
  377.         rotate_y.r2c2=cos[angle_y];
  378.         matidentity4x4(&rotate_z);
  379.         rotate_z.r0c0=cos[angle_z];
  380.         rotate_z.r0c1=sin[angle_z];
  381.         rotate_z.r1c0=-sin[angle_z];
  382.         rotate_z.r1c1=cos[angle_z];
  383.         matmult4x4s(&rotate_x,&rotate_y,&temp);
  384.         matmult4x4s(&temp,&rotate_z,&rot);
  385.         for(i=0 ; i<obj->numverts ; i++)
  386.             {
  387.             vo[i].x=(vl[i].x*rot.r0c0 + vl[i].y*rot.r1c0 +
  388.                 vl[i].z*rot.r2c0) >> SFIXV;
  389.             vo[i].y=(vl[i].x*rot.r0c1 + vl[i].y*rot.r1c1 +
  390.                 vl[i].z*rot.r2c1) >> SFIXV;
  391.             vo[i].z=(vl[i].x*rot.r0c2+vl[i].y*rot.r1c2+
  392.                 vl[i].z*rot.r2c2) >> SFIXV;
  393.             }
  394.         obj->trasf|=0x01;
  395.         break;
  396.     }
  397.  
  398. }
  399.  
  400.  
  401. /********************* fine *************************/
  402.