home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 February / Chip_2001-02_cd1.bin / bonus / demos / CS / exp / SOURCES / DEMO / tunel.cpp < prev    next >
C/C++ Source or Header  |  2000-08-14  |  8KB  |  399 lines

  1. #include "api3ds.h"
  2. #include "tunel.h"
  3.  
  4. TUNEL::~TUNEL()
  5. {
  6. delete data;
  7. }
  8.  
  9. TUNEL::TUNEL()
  10. {
  11. }
  12.  
  13. TUNEL::TUNEL(int n,float sc)
  14. {
  15. reset(n,sc);
  16. }
  17.  
  18. void TUNEL::reset(int n,float sc)
  19. {
  20. data=new OBRUCE;
  21.  
  22. for (int i=0;i<MAXEN1*TRLEN;i++)
  23.   {
  24.   (data->vx[i]).x=0.0;
  25.   (data->vx[i]).y=0.0;
  26.   (data->vx[i]).z=0.0;
  27.   (data->vx[i]).w=1.0;
  28.  
  29.   (data->vx[i]).R=1.0;
  30.   (data->vx[i]).G=1.0;
  31.   (data->vx[i]).B=1.0;
  32.   (data->vx[i]).A=1.0;
  33.  
  34.   (data->vx[i]).i=1.0;
  35.   (data->vx[i]).j=0.0;
  36.   (data->vx[i]).k=0.0;
  37.  
  38.   (data->vx[i]).s=0.0;
  39.   (data->vx[i]).t=0.0;
  40.   (data->vx[i]).r=0.0;
  41.   (data->vx[i]).q=1.0;
  42.   }
  43.  
  44.  
  45. float si,co,s,c;
  46. r=g=b=1.0;
  47. int j;
  48.  
  49. //t.Rotate(0,-PI/2,0);
  50. if (n>MAXEN) n=MAXEN;
  51. for (int i=0;i<TRLEN;i++) 
  52.   {
  53.   data->en[i]=0;
  54.   data->sc[i]=0;
  55.   }
  56. tex_x=0.0;
  57. data->to_use=0;
  58. en=n;
  59. scale=sc;
  60. step=sc;
  61. inverse=0;
  62. tr_pos=0;
  63.  
  64. data->en[0]=en;
  65. data->sc[0]=scale;
  66. data->polomerx[0]=1.0;
  67. data->polomery[0]=1.0;
  68. data->u  [0]=t.U;
  69. data->v  [0]=t.V;
  70. data->n  [0]=t.N;
  71. data->pos[0]=t.POS;
  72. j=0;
  73.  
  74. for (int i=0;i<=en;i++)
  75.   { 
  76.   s=sin(i*2*PI/en);
  77.   c=cos(i*2*PI/en);
  78.   si=scale*s;
  79.   co=scale*c;
  80.  
  81.   (data->vx[j]).x= (t.POS).x + co*(t.N).x + si*(t.V).x;
  82.   (data->vx[j]).y= (t.POS).y + co*(t.N).y + si*(t.V).y;
  83.   (data->vx[j]).z= (t.POS).z + co*(t.N).z + si*(t.V).z;
  84.  
  85.   if (inverse==0)
  86.     {
  87.     (data->vx[j]).i= -c*(t.N).x - s*(t.V).x;
  88.     (data->vx[j]).j= -c*(t.N).y - s*(t.V).y;
  89.     (data->vx[j]).k= -c*(t.N).z - s*(t.V).z;
  90.     }
  91.    else
  92.     {
  93.     (data->vx[j]).i= c*(t.N).x + s*(t.V).x;
  94.     (data->vx[j]).j= c*(t.N).y + s*(t.V).y;
  95.     (data->vx[j]).k= c*(t.N).z + s*(t.V).z;
  96.     }
  97.  
  98.  
  99.   (data->vx[j]).R=0.0;
  100.   (data->vx[j]).G=0.0;
  101.   (data->vx[j]).B=0.0;
  102.   (data->vx[j]).A=1.0;
  103.  
  104.   (data->vx[j]).s=tex_x;
  105.   (data->vx[j]).t=i/float(en);
  106.   j++;
  107.   }
  108. data->to_use=1;
  109. tex_x+=0.1;
  110. track[tr_pos].pos=t.POS;
  111. track[tr_pos].u=t.U;
  112. track[tr_pos].v=t.V;
  113. track[tr_pos].n=t.N;
  114. tr_pos=1;
  115. }
  116.  
  117.  
  118.  
  119. void TUNEL::posun_t(float how_much)
  120. {
  121. t.Move(step*how_much);
  122. }
  123.  
  124.  
  125.  
  126. void TUNEL::pridaj_obruc()
  127. {
  128. float si,co,s,c;
  129. if (scale<0) scale=0;
  130.  
  131. int j=data->to_use*MAXEN1;
  132. data->en[data->to_use]=en;
  133. data->sc[data->to_use]=scale;
  134. data->polomerx[data->to_use]=1.0;
  135. data->polomery[data->to_use]=1.0;
  136. data->u  [data->to_use]=t.U;
  137. data->v  [data->to_use]=t.V;
  138. data->n  [data->to_use]=t.N;
  139. data->pos[data->to_use]=t.POS;
  140. for (int i=0;i<=en;i++)
  141.   { 
  142.   s=sin(i*2*PI/en);
  143.   c=cos(i*2*PI/en);
  144.  
  145.   si=scale*s;
  146.   co=scale*c;
  147.  
  148.   (data->vx[j]).x= (t.POS).x + co*(t.N).x + si*(t.V).x;
  149.   (data->vx[j]).y= (t.POS).y + co*(t.N).y + si*(t.V).y;
  150.   (data->vx[j]).z= (t.POS).z + co*(t.N).z + si*(t.V).z;
  151.  
  152.   if (inverse==0)
  153.     {
  154.     (data->vx[j]).i= -c*(t.N).x - s*(t.V).x;
  155.     (data->vx[j]).j= -c*(t.N).y - s*(t.V).y;
  156.     (data->vx[j]).k= -c*(t.N).z - s*(t.V).z;
  157.     }
  158.    else
  159.     {
  160.     (data->vx[j]).i= c*(t.N).x + s*(t.V).x;
  161.     (data->vx[j]).j= c*(t.N).y + s*(t.V).y;
  162.     (data->vx[j]).k= c*(t.N).z + s*(t.V).z;
  163.     }
  164.   (data->vx[j]).R=r;
  165.   (data->vx[j]).G=g;
  166.   (data->vx[j]).B=b;
  167.   (data->vx[j]).A=1.0;
  168.         
  169.   (data->vx[j]).s= tex_x;
  170.   (data->vx[j]).t= i/float(en);
  171.   j++;
  172.   }
  173.  
  174. int a,b,q,ada,adb;
  175.  
  176. a=data->to_use;
  177. b=a-1;
  178. if (a==0) b=TRLEN-1;
  179. q=a*MAXEN*4;
  180. ada=a*MAXEN1;
  181. adb=b*MAXEN1;
  182.  
  183. int ena=data->en[a];
  184. int enb=data->en[b];
  185. int enab=(ena<enb?ena:enb);
  186.  
  187. switch (inverse)
  188.   {
  189.   case 0:
  190.       if (ena>enb)
  191.       for (int i=0;i<enab;i++)
  192.         {
  193.         data->quads[q]=ada+i;     q++;
  194.         data->quads[q]=adb+i;     q++;
  195.         data->quads[q]=adb+(i+1); q++;
  196.         data->quads[q]=ada+(i+1); q++;
  197.         }
  198.       if (ena<=enb)
  199.       for (int i=0;i<enab;i++)
  200.         {
  201.         data->quads[q]=ada+(i+1); q++;
  202.         data->quads[q]=ada+i;     q++;
  203.         data->quads[q]=adb+i;     q++;
  204.         data->quads[q]=adb+(i+1); q++;
  205.         }
  206.  
  207.       if (ena>enb)
  208.        {
  209.        data->triangle[a*3  ]=ada+enab;
  210.        data->triangle[a*3+1]=adb+enab;
  211.        data->triangle[a*3+2]=ada+(enab+1);
  212.        }
  213.       if (ena<enb)
  214.        {
  215.        data->triangle[a*3  ]=ada+enab;
  216.        data->triangle[a*3+1]=adb+enab;
  217.        data->triangle[a*3+2]=adb+(enab+1);
  218.        }
  219.  
  220.     break;
  221.   case 1:
  222.       if (ena>enb)
  223.       for (int i=0;i<enab;i++)
  224.         {
  225.         data->quads[q]=ada+i;     q++;
  226.         data->quads[q]=ada+(i+1); q++;
  227.         data->quads[q]=adb+(i+1); q++;
  228.         data->quads[q]=adb+i;     q++;
  229.         }
  230.       if (ena<=enb)
  231.       for (int i=0;i<enab;i++)
  232.         {
  233.         data->quads[q]=adb+i;     q++;
  234.         data->quads[q]=ada+i;     q++;
  235.         data->quads[q]=ada+(i+1); q++;
  236.         data->quads[q]=adb+(i+1); q++;
  237.         }
  238.       if (ena>enb)
  239.        {
  240.        data->triangle[a*3  ]=ada+enab;
  241.        data->triangle[a*3+1]=ada+(enab+1);
  242.        data->triangle[a*3+2]=adb+enab;
  243.        }
  244.       if (ena<enb)
  245.        {
  246.        data->triangle[a*3  ]=ada+enab;
  247.        data->triangle[a*3+1]=adb+(enab+1);
  248.        data->triangle[a*3+2]=adb+enab;
  249.        }
  250.     break;
  251.   }
  252.  
  253. data->to_use++;
  254. data->to_use%=TRLEN;
  255. tex_x+=0.1;
  256. track[tr_pos].pos=t.POS;
  257. track[tr_pos].u=t.U;
  258. track[tr_pos].v=t.V;
  259. track[tr_pos].n=t.N;
  260. tr_pos++;
  261. tr_pos%=TRLEN;
  262. }
  263.  
  264. void TUNEL::konvert_quads() //skonvertuje quads a triangle do q_array a t_array
  265. {
  266. int q=0;
  267. int t=0;
  268. int p,r;
  269. int a,b,ena,enb,enab;
  270.  
  271. for (int i=0;i<TRLEN;i++) 
  272.   {
  273.   a=i;
  274.   b=a-1;
  275.   if (a==0) b=TRLEN-1;
  276.   int ena=data->en[a];
  277.   int enb=data->en[b];
  278.   int enab=(ena<enb?ena:enb);
  279.   
  280.  
  281.   if ((ena>0)&(a!=data->to_use)&( (data->sc[a]>0)|(data->sc[b]>0) ))
  282.     {
  283.     p=a*MAXEN*4;
  284.     for (int j=0;j<enab;j++)
  285.       {
  286.       data->q_array[q]=data->quads[p]; q++;p++;
  287.       data->q_array[q]=data->quads[p]; q++;p++;
  288.       data->q_array[q]=data->quads[p]; q++;p++;
  289.       data->q_array[q]=data->quads[p]; q++;p++;
  290.       }
  291.     if (ena!=enb) 
  292.       {
  293.       r=a*3;
  294.       data->t_array[t]=data->triangle[r]; t++;r++;
  295.       data->t_array[t]=data->triangle[r]; t++;r++;
  296.       data->t_array[t]=data->triangle[r]; t++;r++;
  297.       }
  298.     }
  299.   }
  300. data->q_a=q;
  301. data->t_a=t;
  302. }
  303.  
  304. void TUNEL::rebuild()
  305. {
  306. float si,co;
  307. float g_en,g_scalex,g_scaley;
  308. INFO3D g_t;
  309.  
  310. for (int g=0;g<TRLEN;g++)
  311.   {
  312.   int j=g*MAXEN1;
  313.  
  314.   g_en    = data->en[g];
  315.   g_scalex= data->sc[g]*data->polomerx[g];
  316.   g_scaley= data->sc[g]*data->polomery[g];
  317.   g_t.u   = data->u[g];
  318.   g_t.v   = data->v[g];
  319.   g_t.n   = data->n[g];
  320.   g_t.pos = data->pos[g];
  321.  
  322.   for (int i=0;i<=g_en;i++)
  323.     { 
  324.     si=g_scalex*sin(i*2*PI/g_en);
  325.     co=g_scaley*cos(i*2*PI/g_en);
  326.   
  327.     (data->vx[j]).x= (g_t.pos).x + co*(g_t.n).x + si*(g_t.v).x;
  328.     (data->vx[j]).y= (g_t.pos).y + co*(g_t.n).y + si*(g_t.v).y;
  329.     (data->vx[j]).z= (g_t.pos).z + co*(g_t.n).z + si*(g_t.v).z;         
  330.     j++;
  331.     }
  332.   }
  333. }
  334.  
  335. void TUNEL::pridaj_obruc(float how_much)
  336. {
  337. posun_t(how_much);
  338. pridaj_obruc();
  339. }
  340.  
  341.  
  342. void TUNEL::render()
  343. {
  344. konvert_quads();
  345. //glInterleavedArrays(GL_T2F_N3F_V3F, 0, data->vx);
  346.  
  347. //glInterleavedArrays(GL_T2F_C4F_N3F_V3F, 0, data->vx);
  348. glInterleavedArrays(GL_T4F_C4F_N3F_V4F, 0, data->vx);
  349.  
  350.  
  351.  
  352. glDrawElements(GL_QUADS, data->q_a, GL_UNSIGNED_INT, data->q_array);
  353. if (data->t_a>0) 
  354.   glDrawElements(GL_TRIANGLES, data->t_a, GL_UNSIGNED_INT, data->t_array);
  355. }
  356.  
  357. INFO3D TUNEL::getinfo(float p)
  358. {
  359. Vector3f np,nn,nv,nu,prc;
  360. INFO3D ret;
  361.  
  362. int cc=(int)p;
  363. float dc=p-cc;
  364. cc%=TRLEN;
  365. int nc=(cc+1)%TRLEN;
  366.  
  367. INFO3D *ic=track+cc;
  368. INFO3D *in=track+nc;
  369.  
  370. np=ic->pos;
  371. nn=ic->n;
  372. nv=ic->v;
  373. nu=ic->u;
  374.  
  375. float a=30.0;
  376. Vector3f pos0=ic->pos;
  377. Vector3f pos1=ic->pos+a*(ic->u);
  378. Vector3f pos2=in->pos-a*(in->u);
  379. Vector3f pos3=in->pos;
  380.  
  381. if (p!=cc)
  382.   {
  383.   Vector3f int1=pos0+dc*(pos1-pos0);
  384.   Vector3f int2=pos2+dc*(pos3-pos2);
  385.   np=int1 + dc*(int2-int1);
  386.  
  387. //  np+=dc*(in->pos-np);
  388.   nn+=dc*(in->n-nn);
  389.   nu+=dc*(in->u-nu);
  390.   nv+=dc*(in->v-nv);
  391.   }
  392. ret.pos=np;
  393. ret.u=nu;
  394. ret.v=nv;
  395. ret.n=nn;
  396. return ret;
  397. }
  398.  
  399.