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 >
Wrap
C/C++ Source or Header
|
2000-08-14
|
8KB
|
399 lines
#include "api3ds.h"
#include "tunel.h"
TUNEL::~TUNEL()
{
delete data;
}
TUNEL::TUNEL()
{
}
TUNEL::TUNEL(int n,float sc)
{
reset(n,sc);
}
void TUNEL::reset(int n,float sc)
{
data=new OBRUCE;
for (int i=0;i<MAXEN1*TRLEN;i++)
{
(data->vx[i]).x=0.0;
(data->vx[i]).y=0.0;
(data->vx[i]).z=0.0;
(data->vx[i]).w=1.0;
(data->vx[i]).R=1.0;
(data->vx[i]).G=1.0;
(data->vx[i]).B=1.0;
(data->vx[i]).A=1.0;
(data->vx[i]).i=1.0;
(data->vx[i]).j=0.0;
(data->vx[i]).k=0.0;
(data->vx[i]).s=0.0;
(data->vx[i]).t=0.0;
(data->vx[i]).r=0.0;
(data->vx[i]).q=1.0;
}
float si,co,s,c;
r=g=b=1.0;
int j;
//t.Rotate(0,-PI/2,0);
if (n>MAXEN) n=MAXEN;
for (int i=0;i<TRLEN;i++)
{
data->en[i]=0;
data->sc[i]=0;
}
tex_x=0.0;
data->to_use=0;
en=n;
scale=sc;
step=sc;
inverse=0;
tr_pos=0;
data->en[0]=en;
data->sc[0]=scale;
data->polomerx[0]=1.0;
data->polomery[0]=1.0;
data->u [0]=t.U;
data->v [0]=t.V;
data->n [0]=t.N;
data->pos[0]=t.POS;
j=0;
for (int i=0;i<=en;i++)
{
s=sin(i*2*PI/en);
c=cos(i*2*PI/en);
si=scale*s;
co=scale*c;
(data->vx[j]).x= (t.POS).x + co*(t.N).x + si*(t.V).x;
(data->vx[j]).y= (t.POS).y + co*(t.N).y + si*(t.V).y;
(data->vx[j]).z= (t.POS).z + co*(t.N).z + si*(t.V).z;
if (inverse==0)
{
(data->vx[j]).i= -c*(t.N).x - s*(t.V).x;
(data->vx[j]).j= -c*(t.N).y - s*(t.V).y;
(data->vx[j]).k= -c*(t.N).z - s*(t.V).z;
}
else
{
(data->vx[j]).i= c*(t.N).x + s*(t.V).x;
(data->vx[j]).j= c*(t.N).y + s*(t.V).y;
(data->vx[j]).k= c*(t.N).z + s*(t.V).z;
}
(data->vx[j]).R=0.0;
(data->vx[j]).G=0.0;
(data->vx[j]).B=0.0;
(data->vx[j]).A=1.0;
(data->vx[j]).s=tex_x;
(data->vx[j]).t=i/float(en);
j++;
}
data->to_use=1;
tex_x+=0.1;
track[tr_pos].pos=t.POS;
track[tr_pos].u=t.U;
track[tr_pos].v=t.V;
track[tr_pos].n=t.N;
tr_pos=1;
}
void TUNEL::posun_t(float how_much)
{
t.Move(step*how_much);
}
void TUNEL::pridaj_obruc()
{
float si,co,s,c;
if (scale<0) scale=0;
int j=data->to_use*MAXEN1;
data->en[data->to_use]=en;
data->sc[data->to_use]=scale;
data->polomerx[data->to_use]=1.0;
data->polomery[data->to_use]=1.0;
data->u [data->to_use]=t.U;
data->v [data->to_use]=t.V;
data->n [data->to_use]=t.N;
data->pos[data->to_use]=t.POS;
for (int i=0;i<=en;i++)
{
s=sin(i*2*PI/en);
c=cos(i*2*PI/en);
si=scale*s;
co=scale*c;
(data->vx[j]).x= (t.POS).x + co*(t.N).x + si*(t.V).x;
(data->vx[j]).y= (t.POS).y + co*(t.N).y + si*(t.V).y;
(data->vx[j]).z= (t.POS).z + co*(t.N).z + si*(t.V).z;
if (inverse==0)
{
(data->vx[j]).i= -c*(t.N).x - s*(t.V).x;
(data->vx[j]).j= -c*(t.N).y - s*(t.V).y;
(data->vx[j]).k= -c*(t.N).z - s*(t.V).z;
}
else
{
(data->vx[j]).i= c*(t.N).x + s*(t.V).x;
(data->vx[j]).j= c*(t.N).y + s*(t.V).y;
(data->vx[j]).k= c*(t.N).z + s*(t.V).z;
}
(data->vx[j]).R=r;
(data->vx[j]).G=g;
(data->vx[j]).B=b;
(data->vx[j]).A=1.0;
(data->vx[j]).s= tex_x;
(data->vx[j]).t= i/float(en);
j++;
}
int a,b,q,ada,adb;
a=data->to_use;
b=a-1;
if (a==0) b=TRLEN-1;
q=a*MAXEN*4;
ada=a*MAXEN1;
adb=b*MAXEN1;
int ena=data->en[a];
int enb=data->en[b];
int enab=(ena<enb?ena:enb);
switch (inverse)
{
case 0:
if (ena>enb)
for (int i=0;i<enab;i++)
{
data->quads[q]=ada+i; q++;
data->quads[q]=adb+i; q++;
data->quads[q]=adb+(i+1); q++;
data->quads[q]=ada+(i+1); q++;
}
if (ena<=enb)
for (int i=0;i<enab;i++)
{
data->quads[q]=ada+(i+1); q++;
data->quads[q]=ada+i; q++;
data->quads[q]=adb+i; q++;
data->quads[q]=adb+(i+1); q++;
}
if (ena>enb)
{
data->triangle[a*3 ]=ada+enab;
data->triangle[a*3+1]=adb+enab;
data->triangle[a*3+2]=ada+(enab+1);
}
if (ena<enb)
{
data->triangle[a*3 ]=ada+enab;
data->triangle[a*3+1]=adb+enab;
data->triangle[a*3+2]=adb+(enab+1);
}
break;
case 1:
if (ena>enb)
for (int i=0;i<enab;i++)
{
data->quads[q]=ada+i; q++;
data->quads[q]=ada+(i+1); q++;
data->quads[q]=adb+(i+1); q++;
data->quads[q]=adb+i; q++;
}
if (ena<=enb)
for (int i=0;i<enab;i++)
{
data->quads[q]=adb+i; q++;
data->quads[q]=ada+i; q++;
data->quads[q]=ada+(i+1); q++;
data->quads[q]=adb+(i+1); q++;
}
if (ena>enb)
{
data->triangle[a*3 ]=ada+enab;
data->triangle[a*3+1]=ada+(enab+1);
data->triangle[a*3+2]=adb+enab;
}
if (ena<enb)
{
data->triangle[a*3 ]=ada+enab;
data->triangle[a*3+1]=adb+(enab+1);
data->triangle[a*3+2]=adb+enab;
}
break;
}
data->to_use++;
data->to_use%=TRLEN;
tex_x+=0.1;
track[tr_pos].pos=t.POS;
track[tr_pos].u=t.U;
track[tr_pos].v=t.V;
track[tr_pos].n=t.N;
tr_pos++;
tr_pos%=TRLEN;
}
void TUNEL::konvert_quads() //skonvertuje quads a triangle do q_array a t_array
{
int q=0;
int t=0;
int p,r;
int a,b,ena,enb,enab;
for (int i=0;i<TRLEN;i++)
{
a=i;
b=a-1;
if (a==0) b=TRLEN-1;
int ena=data->en[a];
int enb=data->en[b];
int enab=(ena<enb?ena:enb);
if ((ena>0)&(a!=data->to_use)&( (data->sc[a]>0)|(data->sc[b]>0) ))
{
p=a*MAXEN*4;
for (int j=0;j<enab;j++)
{
data->q_array[q]=data->quads[p]; q++;p++;
data->q_array[q]=data->quads[p]; q++;p++;
data->q_array[q]=data->quads[p]; q++;p++;
data->q_array[q]=data->quads[p]; q++;p++;
}
if (ena!=enb)
{
r=a*3;
data->t_array[t]=data->triangle[r]; t++;r++;
data->t_array[t]=data->triangle[r]; t++;r++;
data->t_array[t]=data->triangle[r]; t++;r++;
}
}
}
data->q_a=q;
data->t_a=t;
}
void TUNEL::rebuild()
{
float si,co;
float g_en,g_scalex,g_scaley;
INFO3D g_t;
for (int g=0;g<TRLEN;g++)
{
int j=g*MAXEN1;
g_en = data->en[g];
g_scalex= data->sc[g]*data->polomerx[g];
g_scaley= data->sc[g]*data->polomery[g];
g_t.u = data->u[g];
g_t.v = data->v[g];
g_t.n = data->n[g];
g_t.pos = data->pos[g];
for (int i=0;i<=g_en;i++)
{
si=g_scalex*sin(i*2*PI/g_en);
co=g_scaley*cos(i*2*PI/g_en);
(data->vx[j]).x= (g_t.pos).x + co*(g_t.n).x + si*(g_t.v).x;
(data->vx[j]).y= (g_t.pos).y + co*(g_t.n).y + si*(g_t.v).y;
(data->vx[j]).z= (g_t.pos).z + co*(g_t.n).z + si*(g_t.v).z;
j++;
}
}
}
void TUNEL::pridaj_obruc(float how_much)
{
posun_t(how_much);
pridaj_obruc();
}
void TUNEL::render()
{
konvert_quads();
//glInterleavedArrays(GL_T2F_N3F_V3F, 0, data->vx);
//glInterleavedArrays(GL_T2F_C4F_N3F_V3F, 0, data->vx);
glInterleavedArrays(GL_T4F_C4F_N3F_V4F, 0, data->vx);
glDrawElements(GL_QUADS, data->q_a, GL_UNSIGNED_INT, data->q_array);
if (data->t_a>0)
glDrawElements(GL_TRIANGLES, data->t_a, GL_UNSIGNED_INT, data->t_array);
}
INFO3D TUNEL::getinfo(float p)
{
Vector3f np,nn,nv,nu,prc;
INFO3D ret;
int cc=(int)p;
float dc=p-cc;
cc%=TRLEN;
int nc=(cc+1)%TRLEN;
INFO3D *ic=track+cc;
INFO3D *in=track+nc;
np=ic->pos;
nn=ic->n;
nv=ic->v;
nu=ic->u;
float a=30.0;
Vector3f pos0=ic->pos;
Vector3f pos1=ic->pos+a*(ic->u);
Vector3f pos2=in->pos-a*(in->u);
Vector3f pos3=in->pos;
if (p!=cc)
{
Vector3f int1=pos0+dc*(pos1-pos0);
Vector3f int2=pos2+dc*(pos3-pos2);
np=int1 + dc*(int2-int1);
// np+=dc*(in->pos-np);
nn+=dc*(in->n-nn);
nu+=dc*(in->u-nu);
nv+=dc*(in->v-nv);
}
ret.pos=np;
ret.u=nu;
ret.v=nv;
ret.n=nn;
return ret;
}