|
|
The C++ source code attached here generates animations sequences of
camera rides along maglev tracks, which in turn are generated according
to small ASCII scripts describing connected rail segments. These track
definition scripts (TDSs) are defined as follows:
<Type>,<length|bend angle>,<non-relevant|bend radius>, <CR>
"Type" can take on the values of either 0 (straight rail segment) or 1
(bent segment). If "Type" is 0, then the second value is interpreted as
length in POV units (1 POV unit equals 1 metre), otherwise it is
interpreted as the angle of the bend, given in degrees. Positive values
describe right turns, negative ones describe left turns.
If "Type" is 0, then the third value is not interpreted at all;
otherwise it is interpreted as radius in POV units.
Every line is followed by \n (carriage return), but after the last value
of the last line no comma follows.
Type is an integer, length/angle and radius are float variables.
A typical TDS:
0,8,0,
1,-80,10,
1,179,7,
1,31,7,
1,-30,8,
0,12,0
The third and fourth line show a special restriction: as bends are
constructed as CSG difference objects from full-circle lathes, any bend
greater than 180 degrees must be split up in two segments each shorter
than 180 degrees, otherwise the segment will be rendered interrupted by
gaps!
The C++ routine, called makemm ("make MyMaglev") is started from the
Linux or Windows console (I compiled it only for 64-bit Linux) with
seven parameters:
makemm <start_x> <start_y> <start_z> <direction> <speed> <frames per
second> <camera height above track>
Example:
makemm 0 0 0 80 5 25 0.2
will generate a track which first segment starts centered at <start_x,
start_y, start_z>, and is oriented into a direction of 80 degrees (0
being in positive direction along the z axis, 90 in positive direction
along the x axis and so on), the camera moves at 5 metres/second using
25 frames per second, at 0.2 POV units above the track.
You will be asked for the name of the TDS file and an output file, then
the camera animation sequence is written.
After that, you append this to the existing scene "header":
// cabinrailway.pov
// Maglev commuter train and Personal Rail Cabin system, 60-cm gauge
// (c) 2009 by J�rg 'Yadgar' Bleimann (yaz### [at] gmxde)
// Thanks to:
// Martin (don### [at] onocom) for fixing the segment connection routine
// VARIABLES
#declare ani=1; // animation flag
// TEXTURES
#declare T_Bright_Metal =
texture
{
pigment
{
color rgb 0.85
}
finish
{
ambient 0.15
diffuse 1
brilliance 0.3
phong 0.9
phong_size 110
}
}
#declare T_Simple_Green =
texture
{
pigment
{
color rgb <0, 0.7, 0>
}
finish
{
ambient 0.15
diffuse 1
brilliance 0.2
}
}
// OBJECTS
#macro StraightRail(le) // le: length in metres
#local StraightOuterRounding =
cylinder
{
<0.005, 0.495, 0>, <0.005, 0.495, 4>, 0.005
}
union
{
prism
{
linear_sweep
linear_spline
0, -le, 21
<0, 0>, <0, 0.495>, <0.005, 0.495>, <0.005, 0.5>,
<0.21, 0.5>, <0.225, 0.485>, <0.225, 0.315>, <0.21, 0.3>,
<0.1, 0.3>, <0.1, 0.15>, <0.5, 0.15>, <0.5, 0.3>, <0.39, 0.3>,
<0.375, 0.315>, <0.375, 0.485>, <0.39, 0.5>, <0.595, 0.5>,
<0.595, 0.495>, <0.6, 0.495>, <0.6, 0>, <0, 0>
rotate -x*90
}
object { StraightOuterRounding }
object { StraightOuterRounding translate x*0.59 }
texture { T_Bright_Metal }
translate <-0.3, -0.45, 0>
}
#end
#macro Straight_GroundCutout(le) // le: length in metres
box
{
<0, 0, -0.0001>, <0.6, 0.451, le+0.0001>
translate -x*0.3
}
#end
#macro BendRail(rd, ang) // rd: bend central radius; ang: circle section
angle (positive: right, negative: left);
#local FullCircle =
lathe
{
linear_spline
21
<rd-0.3, 0>, <rd-0.3, 0.495>, <rd-0.295, 0.495>, <rd-0.295, 0.5>,
<rd-0.09, 0.5>, <rd-0.075, 0.485>, <rd-0.075, 0.315>, <rd-0.09, 0.3>,
<rd-0.2, 0.3>, <rd-0.2, 0.15>, <rd+0.2, 0.15>, <rd+0.2, 0.3>,
<rd+0.09, 0.3>,
<rd+0.075, 0.315>, <rd+0.075, 0.485>, <rd+0.09, 0.5>, <rd+0.295, 0.5>,
<rd+0.295, 0.495>, <rd+0.3, 0.495>, <rd+0.3, 0>, <rd-0.3, 0>
}
#local Bend_Subtraction_Block =
box
{
<-(rd+0.31), -1, 0>, <rd+0.31, 1, rd+0.31>
}
#local BendOuterRounding =
torus
{
rd+0.295, 0.005
}
#local BendInnerRounding =
torus
{
rd-0.295, 0.005
}
#local BendOuterRounding =
difference
{
object { BendOuterRounding }
object
{
Bend_Subtraction_Block
rotate y*ang
}
object { Bend_Subtraction_Block rotate y*180 }
}
#local BendInnerRounding =
difference
{
object { BendInnerRounding }
object
{
Bend_Subtraction_Block
rotate y*ang
}
object { Bend_Subtraction_Block rotate y*180 }
}
union
{
difference
{
object { FullCircle }
object
{
Bend_Subtraction_Block
rotate y*ang
}
object { Bend_Subtraction_Block rotate y*180 }
}
object { BendOuterRounding translate y*0.495 }
object { BendInnerRounding translate y*0.495 }
texture { T_Bright_Metal }
#if (ang >= 0)
translate x*rd
#else
translate -x*rd
#end
translate -y*0.45
}
#end
#macro Bend_GroundCutout (rd, ang) // rd: bend central radius; ang:
circle section angle (positive: right, negative: left);
#local FullCircle =
difference
{
cylinder
{
0, <0, 0.451, 0>, rd+0.3
}
cylinder
{
<0, -0.001, 0>, <0, 0.452, 0>, rd-0.3
}
}
#local Bend_Subtraction_Block =
box
{
<-(rd+0.31), -1, 0>, <rd+0.31, 1, rd+0.31>
}
difference
{
object { FullCircle }
object
{
Bend_Subtraction_Block
rotate y*(ang+0.0001)
}
object { Bend_Subtraction_Block rotate y*180 }
#if (ang >= 0)
translate x*rd
#else
translate -x*rd
#end
}
#end
// ACTUAL SCENE
sky_sphere
{
pigment
{
gradient y
color_map
{
[0 rgb 1 ]
[0.3 rgb 0.5 ]
}
}
}
light_source
{
<0, 1000, -2000>
color rgb 1
}
// INSERTION GENERATED WITH MAKEMM
// INSERTION BEGIN
#declare RailElements = array[6][3];
#declare i=0;
#declare ty =0;
#declare s = 0;
#declare r = 0;
#fopen RailData "railtest4.txt" read
#while (defined(RailData))
#read (RailData,ty,s, r)
#declare RailElements[i][0] = ty;
#declare RailElements[i][1] = s;
#declare RailElements[i][2] = r;
#declare i=i+1;
#end
#fclose RailData
#declare trans_general = <0, 0, 0>;
#declare d_general = 0;
#declare i = 0; // loop counter
#declare trans = trans_general; // position of first rail segment
(center of front side)
#declare d = d_general; // orientation (degrees) of first rail segment
#while (i < 6)
#switch (RailElements[i][0])
#case (0)
object
{
StraightRail(RailElements[i][1])
rotate y*d
translate trans
#declare trans = trans+vrotate(<0, 0, RailElements[i][1]>,<0,
d, 0>);
}
#break
#case (1)
object
{
BendRail(RailElements[i][2], RailElements[i][1])
rotate y*d
translate trans
// begin of Martin's code
#declare dir= select(RailElements[i][1],1,-1,-1);
#declare pt= vrotate(x*(RailElements[i][2])*dir,
RailElements[i][1]*y)-x*RailElements[i][2]*dir;
#declare trans= trans+vrotate(pt,y*d);
// end of Martin's code
#declare d = d+RailElements[i][1];
}
#break
#end
#declare i=i+1;
#end
#declare i=0;
#declare trans=trans_general; // position of first ground cutout segment
(center of front side)
#declare d=d_general; // orientation (degrees) of first ground cutout
segment
#declare Ground_Cutout =
union
{
#while (i<6)
#switch (RailElements[i][0])
#case (0)
object
{
Straight_GroundCutout(RailElements[i][1])
rotate y*d
translate trans
#declare trans = trans+vrotate(<0, 0, RailElements[i][1]>,<0,
d, 0>);
}
#break
#case (1)
object
{
Bend_GroundCutout(RailElements[i][2], RailElements[i][1])
rotate y*d
translate trans
// begin of Martin's code
#declare dir= select(RailElements[i][1],1,-1,-1);
#declare pt= vrotate(x*(RailElements[i][2])*dir,
RailElements[i][1]*y)-x*RailElements[i][2]*dir;
#declare trans= trans+vrotate(pt,y*d);
// end of Martin's code
#declare d = d+RailElements[i][1];
}
#break
#end
#declare i=i+1;
#end
}
difference
{
plane
{
y, 0
texture { T_Simple_Green }
}
object { Ground_Cutout translate -y*0.45 }
}
#declare speed = 5; // metres/second
#declare fps = 25; // animation frames per second
#if (ani)
camera
{
#switch (clock)
#range(0, 40) // track segment #1: 8 metres straight; total
length = 8
#declare loc = < 0, 0.2, 0 > + < 0, 0, 0> + < 0* (clock-0), 0,
0.2 * (clock-0)>;
#declare ldir = vrotate(<0, 0, 1>, y*0);
location loc
look_at loc+ldir
#break
#range(41, 110) // track segment #2: 80 degrees left turn; total
length = 21.9626
#declare loc = < 0, 0.2, 8 > + < -10, 0, 1.94115e-06 > + 10 *
<sin(radians(0+90-0.214101-( 1.14592 * ( clock-41)))), 0,
cos(radians(0+90-0.214101-( 1.14592 * ( clock-41))))>;
#declare ldir = vrotate(<0, 0, 1>,
y*(0-0.214101-(1.14592*(clock - 41))));
location loc
look_at loc+ldir
#break
#range(111, 220) // track segment #3: 179 degrees right turn;
total length = 43.8316
#declare loc = < -8.26352, 0.2, 17.8481 > + < 1.21554, 0,
6.89365 > + 7 * <sin(radians(-80-90+1.07247+( 1.63702 * ( clock-111)))),
0, cos(radians(-80-90+1.07247+( 1.63702 * ( clock-111))))>;
#declare ldir = vrotate(<0, 0, 1>,
y*(-80+1.07247+(1.63702*(clock - 111))));
location loc
look_at loc+ldir
#break
#range(221, 239) // track segment #4: 31 degrees right turn;
total length = 47.619
#declare loc = < -5.95294, 0.2, 31.6556 > + < -1.09504, 0,
-6.91382 > + 7 * <sin(radians(99-90+0.103427+( 1.63702 * (
clock-221)))), 0, cos(radians(99-90+0.103427+( 1.63702 * ( clock-221))))>;
#declare ldir = vrotate(<0, 0, 1>,
y*(99+0.103427+(1.63702*(clock - 221))));
location loc
look_at loc+ldir
#break
#range(240, 260) // track segment #5: 30 degrees left turn; total
length = 51.8078
#declare loc = < -2.54847, 0.2, 30.104 > + < 5.1423, 0, 6.12836
> + 8 * <sin(radians(130+90-0.080288-( 1.43239 * ( clock-240)))), 0,
cos(radians(130+90-0.080288-( 1.43239 * ( clock-240))))>;
#declare ldir = vrotate(<0, 0, 1>,
y*(130-0.080288-(1.43239*(clock - 240))));
location loc
look_at loc+ldir
#break
#range(261, 321) // track segment #6: 12 metres straight; total
length = 63.8078
#declare loc = < 1.20465, 0.2, 28.3539 > + < 0, 0, -0> + <
0.196962* (clock-261), 0, -0.0347296 * (clock-261)>;
#declare ldir = vrotate(<0, 0, 1>, y*100);
location loc
look_at loc+ldir
#break
#end
angle 40
}
#end
// end of code
And here the C++ source code:
// makemm version 0.1
// A utility to generate PoV-Ray scripts for animating camera rides
along railroad tracks
// (C) 2009 by Jörg "Yadgar" Bleimann (yaz### [at] gmxde,
http://www.khyberspace.de)
// Thanks to 0xdeadbeef for the implementation of the "explode" function
#include <iostream>
#include <stdlib.h>
#include <cstdlib>
#include <fstream>
#include <string>
#include <vector>
#include <sstream>
#include <stdexcept>
#include <cmath>
using namespace std;
// begin code by 0xdeadbeef
template <typename to, typename from>
to convert(from const &src) {
stringstream converter;
to dest;
converter << src;
converter >> dest;
if(!converter) {
throw invalid_argument("Conversion failed");
}
return dest;
}
vector<string> explode (string const &line, char delim)
{
istringstream in(line);
vector<string> result;
string token;
while(getline(in, token, delim))
{
result.push_back(token);
}
return result;
}
// end code by 0xdeadbeef
int main(int argc, char* argv[])
{
double x, y, z, d, sp;
unsigned short fps; // animation frames per second
double loc_y; // camera height above track
x = atof(argv[1]);
y = atof(argv[2]);
z = atof(argv[3]);
d = atof(argv[4]);
sp = atof(argv[5]); // provisional version of makemm: constant speed
of camera ride, to be replaced later on by a speed script, see also line 149
fps = atoi(argv[6]);
loc_y = atof(argv[7]);
ifstream track;
string track_name;
cout << "Track script? ";
cin >> track_name;
track.open(track_name.c_str());
if (!track)
{
cerr << track_name << " cannot be opened!\n";
exit (-1);
}
ofstream anim;
string anim_name;
char ch;
vector<char> buffer;
unsigned short segments=0;
while (track.get(ch))
{
buffer.push_back(ch);
if (ch == '\n') segments++;
};
track.close();
cout << "Animation script? ";
cin >> anim_name;
anim.open(anim_name.c_str());
if (!anim)
{
cerr << anim_name << " cannot be opened!\n";
exit (-1);
}
anim << "// INSERTION GENERATED WITH MAKEMM" << endl;
anim << endl;
anim << "// INSERTION BEGIN" << endl;
anim << "#declare RailElements = array[" << segments << "][3];" << endl;
anim << "#declare i=0;" << endl;
anim << "#declare ty =0;" << endl;
anim << "#declare s = 0;" << endl;
anim << "#declare r = 0;" << endl;
anim << endl;
anim << "#fopen RailData \"" << track_name << "\" read" << endl;
anim << " #while (defined(RailData))" << endl;
anim << " #read (RailData,ty,s, r)" << endl;
anim << " #declare RailElements[i][0] = ty;" << endl;
anim << " #declare RailElements[i][1] = s;" << endl;
anim << " #declare RailElements[i][2] = r;" << endl;
anim << " #declare i=i+1;" << endl;
anim << " #end" << endl;
anim << "#fclose RailData" << endl;
anim << endl;
anim << "#declare trans_general = <" << argv[1] << ", " << argv[2] <<
", " << argv[3] << ">;" << endl;
anim << "#declare d_general = " << argv[4] << ";" << endl;
anim << endl;
anim << "#declare i = 0; // loop counter" << endl;
anim << "#declare trans = trans_general; // position of first rail
segment (center of front side)" << endl;
anim << "#declare d = d_general; // orientation (degrees) of first
rail segment" << endl;
anim << endl;
anim << "#while (i < " << segments << ")" << endl;
anim << " #switch (RailElements[i][0])" << endl;
anim << " #case (0)" << endl;
anim << " object" << endl;
anim << " {" << endl;
anim << " StraightRail(RailElements[i][1])" << endl;
anim << " rotate y*d" << endl;
anim << " translate trans" << endl;
anim << " #declare trans = trans+vrotate(<0, 0,
RailElements[i][1]>,<0, d, 0>);" << endl;
anim << " }" << endl;
anim << " #break" << endl;
anim << " #case (1)" << endl;
anim << " object" << endl;
anim << " {" << endl;
anim << " BendRail(RailElements[i][2], RailElements[i][1])" <<
endl;
anim << " rotate y*d" << endl;
anim << " translate trans" << endl;
anim << " // begin of Martin's code" << endl;
anim << " #declare dir= select(RailElements[i][1],1,-1,-1);"
<< endl;
anim << " #declare pt= vrotate(x*(RailElements[i][2])*dir,
RailElements[i][1]*y)-x*RailElements[i][2]*dir;" << endl;
anim << " #declare trans= trans+vrotate(pt,y*d);" << endl;
anim << " // end of Martin's code" << endl;
anim << " #declare d = d+RailElements[i][1];" << endl;
anim << " }" << endl;
anim << " #break" << endl;
anim << " #end" << endl;
anim << " #declare i=i+1;" << endl;
anim << "#end" << endl;
anim << endl;
anim << "#declare i=0;" << endl;
anim << "#declare trans=trans_general; // position of first ground
cutout segment (center of front side)" << endl;
anim << "#declare d=d_general; // orientation (degrees) of first
ground cutout segment" << endl;
anim << endl;
anim << "#declare Ground_Cutout =" << endl;
anim << "union" << endl;
anim << "{" << endl;
anim << " #while (i<" << segments << ")" << endl;
anim << " #switch (RailElements[i][0])" << endl;
anim << " #case (0)" << endl;
anim << " object" << endl;
anim << " {" << endl;
anim << " Straight_GroundCutout(RailElements[i][1])" << endl;
anim << " rotate y*d" << endl;
anim << " translate trans" << endl;
anim << " #declare trans = trans+vrotate(<0, 0,
RailElements[i][1]>,<0, d, 0>);" << endl;
anim << " }" << endl;
anim << " #break" << endl;
anim << " #case (1)" << endl;
anim << " object" << endl;
anim << " {" << endl;
anim << " Bend_GroundCutout(RailElements[i][2],
RailElements[i][1])" << endl;
anim << " rotate y*d" << endl;
anim << " translate trans" << endl;
anim << " // begin of Martin's code" << endl;
anim << " #declare dir= select(RailElements[i][1],1,-1,-1);"
<< endl;
anim << " #declare pt= vrotate(x*(RailElements[i][2])*dir,
RailElements[i][1]*y)-x*RailElements[i][2]*dir;" << endl;
anim << " #declare trans= trans+vrotate(pt,y*d);" << endl;
anim << " // end of Martin's code" << endl;
anim << " #declare d = d+RailElements[i][1];" << endl;
anim << " }" << endl;
anim << " #break" << endl;
anim << " #end" << endl;
anim << " #declare i=i+1;" << endl;
anim << " #end" << endl;
anim << "}" << endl;
anim << endl;
anim << "difference" << endl;
anim << "{" << endl;
anim << " plane" << endl;
anim << " {" << endl;
anim << " y, 0" << endl;
anim << " texture { T_Simple_Green }" << endl;
anim << " }" << endl;
anim << " object { Ground_Cutout translate -y*0.45 }" << endl;
anim << "}" << endl;
anim << endl;
// provisional version of makemm: constant speed of camera ride, to
be replaced later on by a speed script
anim << "#declare speed = " << sp << "; // metres/second" << endl;
anim << "#declare fps = " << fps << "; // animation frames per
second" << endl;
anim << endl;
anim << "#if (ani)" << endl;
anim << " camera" << endl;
anim << " {" << endl;
anim << " #switch (clock)" << endl;
unsigned short i = 0; // counter for track segments in animation
sequences loop
unsigned long j = 0; // counter for vector elements in "buffer"
unsigned long start_s = 0; // frame number at beginning of each
animation sequence
unsigned long end_s = 100; // frame number at end of each animation
sequence, provisionally initialized with a dummy value
start_s = 0; //
end_s = 0;
i = 0; // track segment counter
double length; // segment's length in metres
double total_length = 0; // cumulated length of track segments
bool t; // segment type: false = straight, true = curved
double arc; // curved segment's arc size in degrees
double radius; // curved segment's radius width in metres
double compart; // either length or arc size
string comment; // adds information about each track segment
string type; // segment's type (to be printed into comment for each
#range section)
string direction; // curved segment's direction (left or right)
string line(""); // stores current track script line
vector<string> numbers; // stores numerals extracted from line as string
double step = sp/fps; // movement per frame in metres
double remain; // remaining track length of each segment after at
last frame
double offset; // track length allready travelled at fist frame of
segment (for all i>1)
double offset_x; // x component of offset vector
double offset_z; // z component of offset vector
const double pi = 3.141592265359;
double loc_x; // x coordinate of camera position
double loc_z; // z coordinate of camera position
double ldir_x = 0; // x component of look_at vector
const double ldir_y = 0; // y component of look_at vector (fixed)
double ldir_z = 1; // z component of look_at vector (default pointing
at N = 0 degrees azimuth)
string lookat; // vrotate transformation for look_at vector
double start_x; // x coordinate of each segment's starting point
const double start_y = 0; // y coordinate of each segment's starting
point (fixed)
double start_z;
double end_x; // x coordinate of each segment's end point
const double end_y = y + loc_y; // y coordinate of each segment's end
point (fixed)
double end_z; // z coordinate of each segment's end point
double center_x; // x coordinate of center point (curved segments only)
double center_z; // z coordinate of center point (curved segments only)
double arcstep; // distance on curved segment travelled per frame
string arcsign; // clockwise vs. anti-clockwise curving
string arcsign_lookat; // clockwise vs. anti-clockwise curving
double arcoffset; // length offset converted to arc offset
double d_old; // orientation of last segment
double d_end; // orientation at end of current segment;
while (j < buffer.size())
{
line.append(1, buffer.at(j));
if (buffer.at(j)=='\n')
{
i++;
// begin code by 0xdeadbeef
numbers = explode(line, ',');
try
{
t = convert<bool>(numbers.at(0));
}
catch(exception &e)
{
cerr << "Error while processing \"" << numbers.at(0) << "\": "
<< e.what() << endl;
}
try
{
if (!t)
length = convert<double>(numbers.at(1));
else
arc = convert<double>(numbers.at(1));
}
catch(exception &e)
{
cerr << "Error while processing \"" << numbers.at(1) << "\": "
<< e.what() << endl;
}
try
{
if (t)
radius = convert<double>(numbers.at(2));
}
catch(exception &e)
{
cerr << "Error while processing \"" << numbers.at(1) << "\": "
<< e.what() << endl;
}
// end code by 0xdeadbeef
line = "";
if (!t)
{
compart = length;
total_length += length;
comment = " metres straight; total length = ";
if (i==1)
{
d_old = atof(argv[4]);
start_s = 0;
loc_x = sin(d_old*(pi/180))*step;
loc_z = cos(d_old*(pi/180))*step;
start_x = x;
start_z = z;
}
else
{
start_s = end_s + 1;
loc_x = sin(d_end*(pi/180))*step;
loc_z = cos(d_end*(pi/180))*step;
start_x = end_x;
start_z = end_z;
d_old = d_end;
}
d_end = d_old;
end_x = start_x + length*sin(d_end*(pi/180));
end_z = start_z + length*cos(d_end*(pi/180));
end_s = start_s + length/step;
anim << " #range(" << start_s << ", " << end_s << ") //
track segment #" << i << ": " << compart << comment << total_length
<< endl;
remain = length - (end_s - start_s)*step;
if (remain > 0)
offset = step - remain;
else
offset = 0;
offset_x = offset*sin(d_end*(pi/180));
offset_z = offset*cos(d_end*(pi/180));
d_old = d;
anim << " #declare loc = < " << start_x << ", " << loc_y
<< ", " << start_z << " > + < " << offset_x << ", " << 0 << ", " <<
offset_z << "> + < " << loc_x << "* (clock-" << start_s << "), " << 0 <<
", " << loc_z << " * (clock-" << start_s << ")>;" << endl;
anim << " #declare ldir = vrotate(<" << ldir_x << ", "
<< ldir_y << ", " << ldir_z << ">, y*" << d_end << ");" << endl;
}
else
{
compart = abs(arc);
length = compart * (pi/180) * radius;
total_length += length;
arcstep = step / (pi * radius) * 180;
if (i==1)
{
start_s = 0;
start_x = x;
start_z = z;
d_old = atof(argv[4]);
}
else
{
start_s = end_s + 1;
start_x = end_x;
start_z = end_z;
d_old = d_end;
}
d_end = d_old+arc;
if (arc > 0)
{
direction = "right ";
center_x = radius * sin((d_old+90)*(pi/180));
center_z = radius * cos((d_old+90)*(pi/180));
arcsign = "-";
arcsign_lookat = "+";
//arcterm = "-90+arcstep*clock)";
end_x = start_x + center_x + radius *
sin((d_old-90+arc)*(pi/180));
end_z = start_z + center_z + radius *
cos((d_old-90+arc)*(pi/180));
// loc_x = radius * sin((d-90
}
else
{
direction = "left ";
center_x = radius * sin((d_old-90)*(pi/180));
center_z = radius * cos((d_old-90)*(pi/180));
arcsign = "+";
arcsign_lookat = "-";
// arcterm = "+90-arcstep*clock)";
end_x = start_x + center_x + radius *
sin((d_old+90+arc)*(pi/180));
end_z = start_z + center_z + radius *
cos((d_old+90+arc)*(pi/180));
}
end_s = start_s + length/step;
remain = length - (end_s - start_s)*step;
if (remain > 0)
offset = step - remain;
else
offset = 0;
arcoffset = offset / (radius * pi) * 180;
comment = " degrees " + direction;
comment += "turn; total length = ";
anim << " #range(" << start_s << ", " << end_s << ") //
track segment #" << i << ": " << compart << comment << total_length
<< endl;
anim << " #declare loc = < " << start_x << ", " << loc_y
<< ", " << start_z << " > + < " << center_x << ", " << 0 << ", " <<
center_z << " > + " << radius << " * <sin(radians("<< d_old << arcsign
<< "90" << arcsign_lookat << arcoffset << arcsign_lookat << "( " <<
arcstep << " * ( clock-" << start_s << ")))), " << 0 << ",
cos(radians("<< d_old << arcsign << "90" << arcsign_lookat << arcoffset
<< arcsign_lookat << "( " << arcstep << " * ( clock-" << start_s <<
"))))>;" << endl;
anim << " #declare ldir = vrotate(<" << ldir_x << ", "
<< ldir_y << ", " << ldir_z << ">, y*(" << d_old << arcsign_lookat <<
arcoffset << arcsign_lookat << "(" << arcstep << "*(clock - " << start_s
<< "))));" << endl;
}
anim << " location loc" << endl;
anim << " look_at loc+ldir" << endl;
anim << " #break" << endl;
}
j++;
}
anim << " #end" << endl;
anim << " angle 40" << endl;
anim << " }" << endl;
anim << "#end" << endl;
return 0;
}
// end of code
Have fun!
See you in Khyberspace!
Yadgar
Post a reply to this message
|
|