home *** CD-ROM | disk | FTP | other *** search
- #ifndef _vlacik2_H
- #define _vlacik2_H
-
- #define unit_length 100.0
- #define straight_line_max (unit_length/5.0)
- #define rail_spacing 10.0
- #define rail_size 1.4
- #define tube_sides 9
- #define tube_radius (rail_spacing/2.0+12.0)
- #define rail_tube_spacing 6.0
-
- // Sorts of tracks
-
- #define STRAIGHT 1
- #define HALFTURN_RIGHT 2
- #define QUARTERTURN_RIGHT 3
- #define UTURN_RIGHT 4
- #define HALFTURN_LEFT 5
- #define QUARTERTURN_LEFT 6
- #define UTURN_LEFT 7
- #define HALFTURN_UP 8
- #define QUARTERTURN_UP 9
- #define UTURN_UP 10
- #define HALFTURN_DOWN 11
- #define QUARTERTURN_DOWN 12
- #define UTURN_DOWN 13
- #define ASCEND 14
- #define DESCEND 15
- #define ASCEND_LOW 16
- #define DESCEND_LOW 17
- #define ASCEND_HIGH 18
- #define DESCEND_HIGH 19
- #define FULLWHIRL 20
- #define FULLWHIRL_CLOCKWISE 21
- #define HALFWHIRL 22
- #define HALFWHIRL_CLOCKWISE 23
- #define DOUBLEWHIRL 24
- #define DOUBLEWHIRL_CLOCKWISE 25
- #define LOOPING 26
-
- // Construction style flags
-
- #define HAS_TUBE 1
-
-
- struct track_base
- {
- static Material3DS* rail_material;
- static Material3DS* tube_material;
- unsigned long flag;
-
- GLmatrix_double cs;
- quaternion<double> qcs;
-
- track_base() {
- cs.Identity();
- qcs = quaternion<double> (1.0, 0.0, 0.0, 0.0);
- flag = 0;
- }
- void CS(const GLmatrix_double& m) {
- cs=m;
- };
- void QCS(const quaternion<double>& q) {
- qcs = q;
- };
-
- virtual double length() = 0;
- virtual Vector3d position(double t) = 0;
- virtual Vector3d direction(double t) = 0;
- virtual Vector3d udirection(double t) = 0;
- virtual double roll(double t) = 0;
- virtual quaternion<double> local_orientation(double t) = 0;
- virtual RenderableEntityA* rails() = 0;
-
- void normalize(Vector3d &u) {
- double l = 1.0/sqrt(u.x*u.x + u.y*u.y + u.z+u.z);
- u.x*=l; u.y*=l; u.z*=l;
- }
- GLmatrix_double answer_cs(const Vector3d &p, const Vector3d &d, const Vector3d &ud, double r) {
- Vector3d n, u, v, a,b;
- n=d;
- u=ud;
- v.x=-(u.y*n.z-u.z*n.y);
- v.y=-(u.z*n.x-u.x*n.z);
- v.z=-(u.x*n.y-u.y*n.x);
- double s = sin(r);
- double c = cos(r);
- a = c*u + s*v;
- b = -s*u + c*v;
- GLmatrix_double m;
- m[0]=a.x; m[4]=b.x; m[8]= n.x; m[12]=p.x;
- m[1]=a.y; m[5]=b.y; m[9]= n.y; m[13]=p.y;
- m[2]=a.z; m[6]=b.z; m[10]=n.z; m[14]=p.z;
- m[3]=0.0; m[7]=0.0; m[11]=0.0; m[15]=1.0;
- return m;
- }
- virtual GLmatrix_double coordinate_system(double t) {
- return cs*answer_cs(position(t), direction(t), udirection(t), roll(t));
- }
- virtual quaternion<double> orientation(double t) {
- return qcs*local_orientation(t);
- }
-
- virtual RenderableEntityA* tube() {
- if(!(flag&HAS_TUBE))
- return 0;
- GLmatrix_double m;
- double d = rail_spacing/2.0;
- int parts = (int)(length()/straight_line_max)+1;
- Vector3d P, X, Y, V, H, N;
- Vertex3DS* v = new Vertex3DS[tube_sides*(parts+1)];
-
- GLuint i = 0;
-
- for(int q=0; q<=parts; q++) {
- m = coordinate_system((double)q/(double)parts);
- P.x = m[12]; P.y = m[13]; P.z = m[14];
- X.x = m[0]; X.y = m[1]; X.z = m[2];
- Y.x = m[4]; Y.y = m[5]; Y.z = m[6];
- H = Y*sqrt(tube_radius*tube_radius - (d+rail_tube_spacing)*(d+rail_tube_spacing));
-
- for(int k=0; k<tube_sides; k++) {
- double a = ((2*PI)/(double)tube_sides)*k;
- N = X*cos(a) + Y*sin(a);
- V = P + H + tube_radius*N;
- v[i].x = V.x; v[i].y = V.y; v[i].z = V.z; v[i].w = 1.0F;
- v[i].i = N.x; v[i].j = N.y; v[i].k = N.z;
- v[i].R = v[i].G = v[i].B = v[i].A = 1.0F;
- v[i].s = v[i].t = v[i].r = 0.0F; v[i].q = 1.0F;
- i++;
- }
- }
-
- RenderableEntityA* obj = new RenderableEntityA;
- obj->SetMaterial(tube_material);
- obj->Vertices(tube_sides*(parts+1), v);
-
- int isize = (parts+1)<<1;
- GLuint* ind[tube_sides];
- for(int k=0; k<tube_sides; k++)
- ind[k] = new GLuint[isize];
-
- i = 0; int j = 0;
- for(int q=0; q<=parts; q++, i+=tube_sides, j+=2) {
- for(int k=0; k<tube_sides; k++) {
- *(ind[k]+j) = i+k;
- *(ind[k]+j+1) = i+((k+1)%tube_sides);
- }
- }
-
- for(int k=0; k<tube_sides; k++)
- obj->AddElement(GL_TRIANGLE_STRIP, isize, ind[k]);
-
- return obj;
- }
- };
-
- // initialization of static data
-
- Material3DS* track_base::rail_material = 0;
- Material3DS* track_base::tube_material = 0;
-
- // STRAIGHT
-
- struct straight_track : public track_base
- {
- double len;
- void Length(double f) { len=f; }
- virtual double length() { return len; }
-
- virtual Vector3d position(double t) {
- return Vector3d(0.0, 0.0, t*len);
- }
- virtual Vector3d direction(double t) {
- return Vector3d(0.0, 0.0, 1.0);
- }
- virtual Vector3d udirection(double t) {
- return Vector3d(1.0, 0.0, 0.0);
- }
- virtual double roll(double t) {
- return 0;
- }
- virtual quaternion<double> local_orientation(double t) {
- return quaternion<double> (1.0, 0.0, 0.0, 0.0);
- }
- virtual RenderableEntityA* rails() {
- GLmatrix_double m;
- double d = rail_spacing/2.0;
- int parts = 1;
- Vector3d P, X, Y, V;
- Vertex3DS* v = new Vertex3DS[6*(parts+1)];
-
- GLuint i = 0;
-
- for(int q=0; q<=parts; q++) {
- m = coordinate_system((double)q/(double)parts);
- P.x = m[12]; P.y = m[13]; P.z = m[14];
- X.x = m[0]; X.y = m[1]; X.z = m[2];
- Y.x = m[4]; Y.y = m[5]; Y.z = m[6];
-
- V = P - X*(d + rail_size*0.5);
- v[i].x = V.x; v[i].y = V.y; v[i].z = V.z; v[i].w = 1.0F;
- v[i].i = -X.x; v[i].j = -X.y; v[i].k = -X.z;
- v[i].R = v[i].G = v[i].B = v[i].A = 1.0F;
- v[i].s = v[i].t = v[i].r = 0.0F; v[i].q = 1.0F;
- i++;
- V = P - X*(d - rail_size*0.5);
- v[i].x = V.x; v[i].y = V.y; v[i].z = V.z; v[i].w = 1.0F;
- v[i].i = X.x; v[i].j = X.y; v[i].k = X.z;
- v[i].R = v[i].G = v[i].B = v[i].A = 1.0F;
- v[i].s = v[i].t = v[i].r = 0.0F; v[i].q = 1.0F;
- i++;
- V = P - X*d + Y*rail_size;
- v[i].x = V.x; v[i].y = V.y; v[i].z = V.z; v[i].w = 1.0F;
- v[i].i = Y.x; v[i].j = Y.y; v[i].k = Y.z;
- v[i].R = v[i].G = v[i].B = v[i].A = 1.0F;
- v[i].s = v[i].t = v[i].r = 0.0F; v[i].q = 1.0F;
- i++;
-
- V = P + X*(d - rail_size*0.5);
- v[i].x = V.x; v[i].y = V.y; v[i].z = V.z; v[i].w = 1.0F;
- v[i].i = -X.x; v[i].j = -X.y; v[i].k = -X.z;
- v[i].R = v[i].G = v[i].B = v[i].A = 1.0F;
- v[i].s = v[i].t = v[i].r = 0.0F; v[i].q = 1.0F;
- i++;
- V = P + X*(d + rail_size*0.5);
- v[i].x = V.x; v[i].y = V.y; v[i].z = V.z; v[i].w = 1.0F;
- v[i].i = X.x; v[i].j = X.y; v[i].k = X.z;
- v[i].R = v[i].G = v[i].B = v[i].A = 1.0F;
- v[i].s = v[i].t = v[i].r = 0.0F; v[i].q = 1.0F;
- i++;
- V = P + X*d + Y*rail_size;
- v[i].x = V.x; v[i].y = V.y; v[i].z = V.z; v[i].w = 1.0F;
- v[i].i = Y.x; v[i].j = Y.y; v[i].k = Y.z;
- v[i].R = v[i].G = v[i].B = v[i].A = 1.0F;
- v[i].s = v[i].t = v[i].r = 0.0F; v[i].q = 1.0F;
- i++;
- }
-
- RenderableEntityA* obj = new RenderableEntityA;
- obj->SetMaterial(rail_material);
- obj->Vertices(6*(parts+1), v);
- int isize = (parts+1)<<1;
- GLuint* ind1 = new GLuint[isize];
- GLuint* ind2 = new GLuint[isize];
- GLuint* ind3 = new GLuint[isize];
- GLuint* ind4 = new GLuint[isize];
- GLuint* ind5 = new GLuint[isize];
- GLuint* ind6 = new GLuint[isize];
-
- i = 0; int j = 0;
- for(int q=0; q<=parts; q++, i+=6, j+=2) {
- ind1[j] = i;
- ind1[j+1] = i+1;
-
- ind2[j] = i+1;
- ind2[j+1] = i+2;
-
- ind3[j] = i+2;
- ind3[j+1] = i;
-
- ind4[j] = i+3;
- ind4[j+1] = i+4;
-
- ind5[j] = i+4;
- ind5[j+1] = i+5;
-
- ind6[j] = i+5;
- ind6[j+1] = i+3;
- }
-
- obj->AddElement(GL_TRIANGLE_STRIP, isize, ind1);
- obj->AddElement(GL_TRIANGLE_STRIP, isize, ind2);
- obj->AddElement(GL_TRIANGLE_STRIP, isize, ind3);
- obj->AddElement(GL_TRIANGLE_STRIP, isize, ind4);
- obj->AddElement(GL_TRIANGLE_STRIP, isize, ind5);
- obj->AddElement(GL_TRIANGLE_STRIP, isize, ind6);
-
- return obj;
- }
-
- };
-
- // curved base
-
- struct track_base_curved : public track_base
- {
- virtual RenderableEntityA* rails() {
- GLmatrix_double m;
- double d = rail_spacing/2.0;
- int parts = (int)(length()/straight_line_max)+1;
- Vector3d P, X, Y, V;
- Vertex3DS* v = new Vertex3DS[6*(parts+1)];
-
- GLuint i = 0;
-
- for(int q=0; q<=parts; q++) {
- m = coordinate_system((double)q/(double)parts);
- P.x = m[12]; P.y = m[13]; P.z = m[14];
- X.x = m[0]; X.y = m[1]; X.z = m[2];
- Y.x = m[4]; Y.y = m[5]; Y.z = m[6];
-
- V = P - X*(d + rail_size*0.5);
- v[i].x = V.x; v[i].y = V.y; v[i].z = V.z; v[i].w = 1.0F;
- v[i].i = -X.x; v[i].j = -X.y; v[i].k = -X.z;
- v[i].R = v[i].G = v[i].B = v[i].A = 1.0F;
- v[i].s = v[i].t = v[i].r = 0.0F; v[i].q = 1.0F;
- i++;
- V = P - X*(d - rail_size*0.5);
- v[i].x = V.x; v[i].y = V.y; v[i].z = V.z; v[i].w = 1.0F;
- v[i].i = X.x; v[i].j = X.y; v[i].k = X.z;
- v[i].R = v[i].G = v[i].B = v[i].A = 1.0F;
- v[i].s = v[i].t = v[i].r = 0.0F; v[i].q = 1.0F;
- i++;
- V = P - X*d + Y*rail_size;
- v[i].x = V.x; v[i].y = V.y; v[i].z = V.z; v[i].w = 1.0F;
- v[i].i = Y.x; v[i].j = Y.y; v[i].k = Y.z;
- v[i].R = v[i].G = v[i].B = v[i].A = 1.0F;
- v[i].s = v[i].t = v[i].r = 0.0F; v[i].q = 1.0F;
- i++;
-
- V = P + X*(d - rail_size*0.5);
- v[i].x = V.x; v[i].y = V.y; v[i].z = V.z; v[i].w = 1.0F;
- v[i].i = -X.x; v[i].j = -X.y; v[i].k = -X.z;
- v[i].R = v[i].G = v[i].B = v[i].A = 1.0F;
- v[i].s = v[i].t = v[i].r = 0.0F; v[i].q = 1.0F;
- i++;
- V = P + X*(d + rail_size*0.5);
- v[i].x = V.x; v[i].y = V.y; v[i].z = V.z; v[i].w = 1.0F;
- v[i].i = X.x; v[i].j = X.y; v[i].k = X.z;
- v[i].R = v[i].G = v[i].B = v[i].A = 1.0F;
- v[i].s = v[i].t = v[i].r = 0.0F; v[i].q = 1.0F;
- i++;
- V = P + X*d + Y*rail_size;
- v[i].x = V.x; v[i].y = V.y; v[i].z = V.z; v[i].w = 1.0F;
- v[i].i = Y.x; v[i].j = Y.y; v[i].k = Y.z;
- v[i].R = v[i].G = v[i].B = v[i].A = 1.0F;
- v[i].s = v[i].t = v[i].r = 0.0F; v[i].q = 1.0F;
- i++;
- }
-
- RenderableEntityA* obj = new RenderableEntityA;
- obj->SetMaterial(rail_material);
- obj->Vertices(6*(parts+1), v);
- int isize = (parts+1)<<1;
- GLuint* ind1 = new GLuint[isize];
- GLuint* ind2 = new GLuint[isize];
- GLuint* ind3 = new GLuint[isize];
- GLuint* ind4 = new GLuint[isize];
- GLuint* ind5 = new GLuint[isize];
- GLuint* ind6 = new GLuint[isize];
-
- i = 0; int j = 0;
- for(int q=0; q<=parts; q++, i+=6, j+=2) {
- ind1[j] = i;
- ind1[j+1] = i+1;
-
- ind2[j] = i+1;
- ind2[j+1] = i+2;
-
- ind3[j] = i+2;
- ind3[j+1] = i;
-
- ind4[j] = i+3;
- ind4[j+1] = i+4;
-
- ind5[j] = i+4;
- ind5[j+1] = i+5;
-
- ind6[j] = i+5;
- ind6[j+1] = i+3;
- }
-
- obj->AddElement(GL_TRIANGLE_STRIP, isize, ind1);
- obj->AddElement(GL_TRIANGLE_STRIP, isize, ind2);
- obj->AddElement(GL_TRIANGLE_STRIP, isize, ind3);
- obj->AddElement(GL_TRIANGLE_STRIP, isize, ind4);
- obj->AddElement(GL_TRIANGLE_STRIP, isize, ind5);
- obj->AddElement(GL_TRIANGLE_STRIP, isize, ind6);
-
- return obj;
- }
- };
-
- // circular base
-
- struct circular_track : public track_base_curved
- {
- double a, b;
- double radius;
- double clk;
- circular_track() : a(0), b(0), radius(0), clk(1) {}
- void A(double f) { a=f; }
- void B(double f) { b=f; }
- void Radius(double f) { radius=f; }
- void Clk(double f) { clk=f; }
- virtual double length() { return radius*fabs(a-b); }
- };
-
- // HORIZONTAL
-
- struct turn_track_horizontal : public circular_track
- {
- virtual Vector3d position(double t) {
- double tt = a + t*(b-a);
- return Vector3d(radius*(cos(tt)-cos(a)),
- 0.0,
- radius*(sin(tt)-sin(a)));
- }
- virtual Vector3d direction(double t) {
- double tt = a + t*(b-a);
- return Vector3d(-sin(tt)*clk, 0.0, cos(tt)*clk);
- }
- virtual Vector3d udirection(double t) {
- double tt = a + t*(b-a);
- return Vector3d(cos(tt)*clk, 0.0, sin(tt)*clk);
- }
- virtual quaternion<double> local_orientation(double t) {
- return AngleAxis2Quaternion(-t*(b-a), 0.0, 1.0, 0.0);
- }
- virtual double roll(double t) {
- return 0;
- }
- };
-
- struct halfturn_left : public turn_track_horizontal {
- halfturn_left() { a=PI; b=PI/2.0; clk=-1.0; }
- };
- struct quarterturn_left : public turn_track_horizontal {
- quarterturn_left() { a=PI; b=(3*PI)/4.0; clk=-1.0; }
- };
- struct uturn_left : public turn_track_horizontal {
- uturn_left() { a=PI; b=0.0; clk=-1.0; }
- };
-
- struct halfturn_right : public turn_track_horizontal {
- halfturn_right() { a=0.0; b=PI/2.0; clk=1.0; }
- };
- struct quarterturn_right : public turn_track_horizontal {
- quarterturn_right() { a=0.0; b=PI/4.0; clk=1.0; }
- };
- struct uturn_right : public turn_track_horizontal {
- uturn_right() { a=0.0; b=PI; clk=1.0; }
- };
-
- // VERTICAL
-
- struct turn_track_vertical : public circular_track
- {
- virtual Vector3d position(double t) {
- double tt = a + t*(b-a);
- return Vector3d(0.0,
- radius*(sin(tt)-sin(a)),
- radius*(cos(tt)-cos(a)));
- }
- virtual Vector3d direction(double t) {
- double tt = a + t*(b-a);
- return Vector3d(0.0, cos(tt)*clk, -sin(tt)*clk);
- }
- virtual Vector3d udirection(double t) {
- double tt = a + t*(b-a);
- return Vector3d(1.0, 0.0, 0.0);
- }
- virtual double roll(double t) {
- return 0;
- }
- virtual quaternion<double> local_orientation(double t) {
- return AngleAxis2Quaternion(-t*(b-a), 1.0, 0.0, 0.0);
- }
- };
-
- struct ascend : public turn_track_vertical {
- ascend() { a=(3*PI)/2.0; b=(7*PI)/4.0; clk=1.0; }
- };
- struct descend : public turn_track_vertical {
- descend() { a=PI/2.0; b=PI/4.0; clk=-1.0; }
- };
- struct ascend_low : public turn_track_vertical {
- ascend_low() { a=(3*PI)/2.0; b=(5*PI)/3.0; clk=1.0; }
- };
- struct descend_low : public turn_track_vertical {
- descend_low() { a=PI/2.0; b=PI/3.0; clk=-1.0; }
- };
- struct ascend_high : public turn_track_vertical {
- ascend_high() { a=(3*PI)/2.0; b=(11*PI)/6.0; clk=1.0; }
- };
- struct descend_high : public turn_track_vertical {
- descend_high() { a=PI/2.0; b=PI/6.0; clk=-1.0; }
- };
-
- struct halfturn_down : public turn_track_vertical {
- halfturn_down() { a=PI/2.0; b=0.0; clk=-1.0; }
- };
- struct quarterturn_down : public turn_track_vertical {
- quarterturn_down() { a=PI/2.0; b=PI/4.0; clk=-1.0; }
- };
- struct uturn_down : public turn_track_vertical {
- uturn_down() { a=PI/2.0; b=-PI/2.0; clk=-1.0; }
- };
-
- struct halfturn_up : public turn_track_vertical {
- halfturn_up() { a=(3*PI)/2.0; b=2*PI; clk=1.0; }
- };
- struct quarterturn_up : public turn_track_vertical {
- quarterturn_up() { a=(3*PI)/2.0; b=(7*PI)/4.0; clk=1.0; }
- };
- struct uturn_up : public turn_track_vertical {
- uturn_up() { a=(3*PI)/2.0; b=(5*PI)/2; clk=1.0; }
- };
-
- // LOOPINGS
-
- struct loopings : public circular_track
- {
- virtual Vector3d position(double t) {
- Vector3d v;
- double tt = a + t*(b-a);
- v.x = (rail_spacing)*sin(t*PI/2.0)*sin(t*PI/2.0);
- v.y = radius*(sin(tt)-sin(a));
- v.z = radius*(cos(tt)-cos(a));
- return v;
- }
- virtual Vector3d direction(double t) {
- double tt = a + t*(b-a);
- return Vector3d(0.0, cos(tt)*clk, -sin(tt)*clk);
- }
- virtual Vector3d udirection(double t) {
- return Vector3d(1.0, 0.0, 0.0);
- }
- virtual double roll(double t) {
- return 0;
- }
- virtual quaternion<double> local_orientation(double t) {
- return AngleAxis2Quaternion(-t*(b-a), 1.0, 0.0, 0.0);
- }
- };
-
- struct looping : public loopings {
- looping() { a=(3*PI)/2.0; b=(7*PI)/2.0; clk=1.0; }
- };
-
-
- // WHIRL
-
- struct whirl_track : public track_base_curved
- {
- double len;
- double a;
- double clk;
- whirl_track() : a(0), len(0), clk(1) {}
- void Degree(double f) { a=f; }
- void Length(double f) { len=f; }
- void Clk(double f) { clk=f; }
- virtual double length() { return len; }
- virtual Vector3d position(double t) {
- return Vector3d(0.0, 0.0, t*len);
- }
- virtual Vector3d direction(double t) {
- return Vector3d(0.0, 0.0, 1.0);
- }
- virtual Vector3d udirection(double t) {
- return Vector3d(1.0, 0.0, 0.0);
- }
- virtual double roll(double t) {
- return clk*sin(t*PI/2.0)*sin(t*PI/2.0)*a;
- }
- virtual quaternion<double> local_orientation(double t) {
- return AngleAxis2Quaternion(roll(t), 0.0, 0.0, 1.0);
- }
-
- };
-
- struct fullwhirl : public whirl_track {
- fullwhirl() { a=2*PI; clk=1.0; }
- };
- struct fullwhirl_clockwise : public whirl_track {
- fullwhirl_clockwise() { a=2*PI; clk=-1.0; }
- };
- struct halfwhirl : public whirl_track {
- halfwhirl() { a=PI; clk=1.0; }
- };
- struct halfwhirl_clockwise : public whirl_track {
- halfwhirl_clockwise() { a=PI; clk=-1.0; }
- };
- struct doublewhirl : public whirl_track {
- doublewhirl() { a=4*PI; clk=1.0; }
- };
- struct doublewhirl_clockwise : public whirl_track {
- doublewhirl_clockwise() { a=4*PI; clk=-1.0; }
- };
-
- struct train_track_desc
- {
- int type;
- double arg1;
- double arg2;
- unsigned long f;
- };
-
- class train_track
- {
- List<track_base *> parts;
- RenderableEntities *construction;
-
- struct track_info
- {
- double length;
- double before;
- track_base *track;
- };
-
- int n_tracks;
- int tid;
- double track_length;
- track_info *info;
-
- void join_tracks() {
- track_base *ptrack;
- GLmatrix_double m;
- m.Identity();
- quaternion<double> q(1.0, 0.0, 0.0, 0.0);
- parts.rewind();
- for(int i=parts.size(); i; i--) {
- ptrack = *parts;
- ptrack->CS(m);
- ptrack->QCS(q);
- m = ptrack->coordinate_system(1.0);
- q = ptrack->orientation(1.0);
- ++parts;
- }
- }
- public:
- train_track() : construction(0) {}
-
- double length() { return track_length; }
-
- void AddTrack(track_base *p) {
- if(p) parts.push_back(p);
- }
- void operator +=(track_base *p) {
- if(p) parts.push_back(p);
- }
-
- void AddTrack(int type, double arg1, double arg2, unsigned long flag) {
- track_base *p = 0;
- switch(type) {
- case STRAIGHT:
- p = new straight_track;
- (*(straight_track *)p).Length(arg1);
- break;
- case HALFTURN_RIGHT:
- p = new halfturn_right;
- (*(halfturn_right *)p).Radius(arg1);
- break;
- case QUARTERTURN_RIGHT:
- p = new quarterturn_right;
- (*(quarterturn_right *)p).Radius(arg1);
- break;
- case UTURN_RIGHT:
- p = new uturn_right;
- (*(uturn_right *)p).Radius(arg1);
- break;
- case HALFTURN_LEFT:
- p = new halfturn_left;
- (*(halfturn_left *)p).Radius(arg1);
- break;
- case QUARTERTURN_LEFT:
- p = new quarterturn_left;
- (*(quarterturn_left *)p).Radius(arg1);
- break;
- case UTURN_LEFT:
- p = new uturn_left;
- (*(uturn_left *)p).Radius(arg1);
- break;
- case HALFTURN_UP:
- p = new halfturn_up;
- (*(halfturn_up *)p).Radius(arg1);
- break;
- case QUARTERTURN_UP:
- p = new quarterturn_up;
- (*(quarterturn_up *)p).Radius(arg1);
- break;
- case UTURN_UP:
- p = new uturn_up;
- (*(uturn_up *)p).Radius(arg1);
- break;
- case HALFTURN_DOWN:
- p = new halfturn_down;
- (*(halfturn_down *)p).Radius(arg1);
- break;
- case QUARTERTURN_DOWN:
- p = new quarterturn_down;
- (*(quarterturn_down *)p).Radius(arg1);
- break;
- case UTURN_DOWN:
- p = new uturn_down;
- (*(uturn_down *)p).Radius(arg1);
- break;
- case ASCEND:
- p = new ascend;
- (*(ascend *)p).Radius(arg1);
- break;
- case DESCEND:
- p = new descend;
- (*(descend *)p).Radius(arg1);
- break;
- case ASCEND_HIGH:
- p = new ascend_high;
- (*(ascend_high *)p).Radius(arg1);
- break;
- case DESCEND_HIGH:
- p = new descend_high;
- (*(descend_high *)p).Radius(arg1);
- break;
- case ASCEND_LOW:
- p = new ascend_low;
- (*(ascend_low *)p).Radius(arg1);
- break;
- case DESCEND_LOW:
- p = new descend_low;
- (*(descend_low *)p).Radius(arg1);
- break;
- case FULLWHIRL:
- p = new fullwhirl;
- (*(fullwhirl *)p).Length(arg1);
- break;
- case FULLWHIRL_CLOCKWISE:
- p = new fullwhirl_clockwise;
- (*(fullwhirl_clockwise *)p).Length(arg1);
- break;
- case HALFWHIRL:
- p = new halfwhirl;
- (*(halfwhirl *)p).Length(arg1);
- break;
- case HALFWHIRL_CLOCKWISE:
- p = new halfwhirl_clockwise;
- (*(halfwhirl_clockwise *)p).Length(arg1);
- break;
- case DOUBLEWHIRL:
- p = new doublewhirl;
- (*(doublewhirl *)p).Length(arg1);
- break;
- case DOUBLEWHIRL_CLOCKWISE:
- p = new doublewhirl_clockwise;
- (*(doublewhirl_clockwise *)p).Length(arg1);
- break;
- case LOOPING:
- p = new looping;
- (*(looping *)p).Radius(arg1);
- break;
- default:
- return;
- }
- p->flag = flag;
- AddTrack(p);
- }
-
- RenderableEntities* Construct() {
- if(construction)
- return construction;
- construction = new RenderableEntities;
- if(parts.size()==0)
- return construction;
-
- RenderableEntities tubes;
- join_tracks();
- info = new track_info[parts.size()];
- n_tracks = parts.size();
- tid = 0;
- track_length = 0;
- track_base *ptrack;
- double l = 0;
- parts.rewind();
- for(int i=0; i<parts.size(); i++) {
- ptrack = *parts;
- construction->Add(ptrack->rails());
- tubes.Add(ptrack->tube());
- info[i].track = ptrack;
- info[i].length = ptrack->length();
- info[i].before = track_length;
- track_length+=ptrack->length();
- ++parts;
- }
- construction->Add(tubes);
- return construction;
- }
-
- RenderableEntities* Construct(int n, train_track_desc *desc) {
- for(int i=n; i; i--, desc++)
- AddTrack(desc->type, desc->arg1, desc->arg2, desc->f);
- return Construct();
- }
-
- GLmatrix coordinate_system(double len) {
- double l = len - floor(len/track_length)*track_length;
- while(l<info[tid].before||l>(info[tid].before+info[tid].length))
- if(l<info[tid].before) tid--;
- else tid++;
- l = (l-info[tid].before)/info[tid].length; // scale to <0,1>
- GLmatrix_double q = (info[tid].track)->coordinate_system(l);
- GLmatrix m;
- for(int i=0; i<16; i++)
- m[i] = (GLfloat)q[i];
- return m;
- }
- quaternion<float> orientation(double len) {
- double l = len - floor(len/track_length)*track_length;
- while(l<info[tid].before||l>(info[tid].before+info[tid].length))
- if(l<info[tid].before) tid--;
- else tid++;
- l = (l-info[tid].before)/info[tid].length; // scale to <0,1>
- quaternion<double> q = (info[tid].track)->orientation(l);
- return quaternion<float> ((float)re(q), (float)im1(q), (float)im2(q), (float)im3(q));
- }
-
- void Render() {
- if(construction)
- construction->Render();
- }
-
- };
-
-
- #endif