diff options
Diffstat (limited to 'config.cpp')
-rw-r--r-- | config.cpp | 1248 |
1 files changed, 1248 insertions, 0 deletions
diff --git a/config.cpp b/config.cpp new file mode 100644 index 0000000..ebfd68b --- /dev/null +++ b/config.cpp @@ -0,0 +1,1248 @@ +// +// glgrav - OpenGL N-Body gravity simulator +// +// Copyright (C) 2003 Ian Cowburn (ianc@noddybox.demon.co.uk) +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// ------------------------------------------------------------------------- +// +// Data file handling +// +static const char id[]="$Id$"; + +#include "config.h" + +#include <cctype> +#include <GL/gl.h> + +#define RAD(x) ((x)*(M_PI/180.0)) + +// ---------------------------------------- CONSTRUCTION/DESTRUCTION +// +Config::Config() +{ + int f; + + m_error=""; + + for(f=0;f<num_flags;f++) + m_flag[f]=false; + + m_collide=none; + + m_light=""; + m_lr=m_lg=m_lb=1.0f; + + m_const=0.0; + + m_x=0.0f; + m_y=0.0f; + m_z=0.0f; + m_yaw=0.0f; + + m_glid=0; + m_glid_no=0; + m_glid_idx=0; + + m_scale=1.0; + + m_particles=false; + + m_plane=xy_plane; + + m_look_at=-1; + m_travel_as=-1; + + m_s_no=10; + m_s_delta=5.0; + m_s_min=10.0; + m_s_max=1000.0; + m_s_shield=100; + + m_sparks=false; + + m_winw=640; + m_winh=480; + + m_max_mass=1000000; + + m_fog_dist=0.0f; + m_fog_r=0.0f; + m_fog_g=0.0f; + m_fog_b=0.0f; + m_fog_light=false; +} + +Config::~Config() +{ + if (m_glid) + delete[] m_glid; +} + + +// ---------------------------------------- PUBLIC MEMBERS +// +bool Config::read(const string& fname,vector<Mass>& mass) +{ + static struct + { + Command cmd; + string token; + int val; + } enum_list[]= + { + {enable_cmd,"solid",static_cast<int>(solid)}, + {enable_cmd,"lighting",static_cast<int>(lighting)}, + {enable_cmd,"texture",static_cast<int>(texture)}, + {collide_cmd,"none",static_cast<int>(none)}, + {collide_cmd,"merge",static_cast<int>(merge)}, + {collide_cmd,"delta_merge",static_cast<int>(delta_merge)}, + {collide_cmd,"shatter",static_cast<int>(shatter)}, + {plane_cmd,"xy",static_cast<int>(xy_plane)}, + {plane_cmd,"xz",static_cast<int>(xz_plane)}, + {plane_cmd,"yz",static_cast<int>(yz_plane)}, + {cmd_error,"",0} + }; + + Mass parent; + Mass *nm; + Command cmd; + vector<string> arg; + ifstream file(fname.c_str()); + bool found; + int f; + vector<Mass>::size_type idx; + vector<string>::size_type sidx; + + if (!file) + { + m_error="File not found : " + fname; + return false; + } + + try + { + while(getCommand(file,cmd,arg)) + { + switch(cmd) + { + case enable_cmd: + f=0; + found=false; + while(enum_list[f].token!="") + { + if (enum_list[f].cmd==enable_cmd && + CompareNoCase(enum_list[f].token,arg[0])) + { + found=true; + m_flag[static_cast<Flag>(enum_list[f].val)]=true; + break; + } + f++; + } + + if (!found) + { + m_error="Illegal argument to enable : " + arg[0]; + throw m_error; + } + + break; + + case disable_cmd: + f=0; + found=false; + while(enum_list[f].token!="") + { + if (enum_list[f].cmd==enable_cmd && + CompareNoCase(enum_list[f].token,arg[0])) + { + found=true; + m_flag[static_cast<Flag>(enum_list[f].val)]=false; + break; + } + f++; + } + + if (!found) + { + m_error="Illegal argument to disable : " + arg[0]; + throw m_error; + } + + break; + + case collide_cmd: + f=0; + found=false; + while(enum_list[f].token!="") + { + if (enum_list[f].cmd==collide_cmd && + CompareNoCase(enum_list[f].token,arg[0])) + { + found=true; + m_collide=static_cast<Collide>(enum_list[f].val); + break; + } + f++; + } + + if (!found) + { + m_error="Illegal argument to collide : " + arg[0]; + throw m_error; + } + + break; + + case const_cmd: + m_const=toDouble(arg[0]); + break; + + case body_cmd: + nm= + new Mass + (arg[0], toDouble(arg[1]), m_scale, + toDouble(arg[2]), toDouble(arg[3]), toDouble(arg[4]), + toDouble(arg[5]), toDouble(arg[6]), toDouble(arg[7]), + toGLfloat(arg[8]), toGLfloat(arg[9]), + toGLfloat(arg[10]), toDouble(arg[11])); + + if (mass.size()<m_max_mass) + mass.push_back(*nm); + + delete nm; + break; + + case radial_cmd: + if (findMass(mass,arg[2],parent)) + { + genRadial(&nm,parent, + arg[0],toDouble(arg[1]), + toDouble(arg[3]),RAD(toDouble(arg[4])), + toDouble(arg[5]), + toGLfloat(arg[6]),toGLfloat(arg[7]), + toGLfloat(arg[8]), + toDouble(arg[9])); + + if (mass.size()<m_max_mass) + mass.push_back(*nm); + + delete nm; + } + else + { + m_error="Unknown parent in radial : " + arg[2]; + throw m_error; + } + break; + + case multiple_cmd: + if (findMass(mass,arg[4],parent)) + { + string name=arg[0]; + int num=toInt(arg[1]); + double ms=toDouble(arg[2]); + double ms_i=toDouble(arg[3]); + double dist=toDouble(arg[5]); + double dist_i=toDouble(arg[6]); + double ang=toDouble(arg[7]); + double ang_i=toDouble(arg[8]); + double spd=toDouble(arg[9]); + double spd_i=toDouble(arg[10]); + GLfloat r=toGLfloat(arg[11]); + GLfloat g=toGLfloat(arg[12]); + GLfloat b=toGLfloat(arg[13]); + double rot=toDouble(arg[14]); + + int f; + + for(f=0;f<num;f++) + { + genRadial(&nm,parent, + makeName(name,f+1),ms, + dist,ang,spd, + r,g,b, + rot); + + ms+=ms_i; + dist+=dist_i; + ang+=ang_i; + spd+=spd_i; + + if (mass.size()<m_max_mass) + mass.push_back(*nm); + + delete nm; + } + } + else + { + m_error="Unknown parent in multiple : " + arg[4]; + throw m_error; + } + break; + + case light_cmd: + m_light=arg[0]; + m_lr=toGLfloat(arg[1]); + m_lg=toGLfloat(arg[2]); + m_lb=toGLfloat(arg[3]); + break; + + case camera_cmd: + m_x=toGLfloat(arg[0]); + m_y=toGLfloat(arg[1]); + m_z=toGLfloat(arg[2]); + m_yaw=toGLfloat(arg[3]); + break; + + case look_cmd: + if (findMass(mass,arg[0],parent)) + m_look.push_back(arg[0]); + else + { + m_error="Unknown object in look : " + arg[0]; + throw m_error; + } + break; + + case mlook_cmd: + { + int num=toInt(arg[1]); + string name=arg[0]; + int f; + + for(f=0;f<num;f++) + { + string ss; + + ss=makeName(name,f+1); + + if (findMass(mass,ss,idx)) + { + m_look.push_back(ss); + } + else + { + m_error="Unknown object in mlook : " + ss; + throw m_error; + } + } + } + break; + + case texture_cmd: + if (!m_glid) + { + m_error="texture used without preceeding num_texture"; + throw m_error; + } + + if (findMass(mass,arg[0],idx)) + { + if (m_glid_no==m_glid_idx) + { + m_error="more textures than expected"; + throw m_error; + } + + GLuint id=m_glid[m_glid_idx++]; + + if (bindTexture(arg[1],toInt(arg[2]),toInt(arg[3]),id)) + mass[idx].setTexture(id); + else + { + m_error="Failed to bind texture : " + m_error; + throw m_error; + } + } + else + { + m_error="Unknown object in texture : " + arg[0]; + throw m_error; + } + break; + + case num_texture_cmd: + if (m_glid) + { + m_error="num_texture used more than once"; + throw m_error; + } + + m_glid_no=toInt(arg[0]); + m_glid=new GLuint[m_glid_no]; + glGenTextures(m_glid_no,m_glid); + + break; + + case reuse_cmd: + if (findMass(mass,arg[0],idx)) + { + if (findMass(mass,arg[1],parent)) + { + GLuint id; + + if (parent.getTexture(id) || + parent.getRingTexture(id)) + mass[idx].setTexture(id); + else + { + m_error="reuse object has no texture : " + + arg[1]; + throw m_error; + } + } + else + { + m_error="Unknown object in reuse : " + arg[1]; + throw m_error; + } + } + else + { + m_error="Unknown object in reuse : " + arg[0]; + throw m_error; + } + break; + + case mreuse_cmd: + if (findMass(mass,arg[2],parent)) + { + int num=toInt(arg[1]); + string name=arg[0]; + int f; + + for(f=0;f<num;f++) + { + string ss=makeName(name,f+1); + + if (findMass(mass,ss,idx)) + { + GLuint id; + + if (parent.getTexture(id) || + parent.getRingTexture(id)) + mass[idx].setTexture(id); + else + { + m_error="mreuse object has no texture : " + + arg[2]; + throw m_error; + } + } + else + { + m_error="Unknown object in mreuse : " + ss; + throw m_error; + } + } + } + else + { + m_error="Unknown object in mreuse : " + arg[2]; + throw m_error; + } + break; + + case ring_cmd: + if (findMass(mass,arg[0],idx)) + { + mass[idx].setRing(toDouble(arg[1]),toDouble(arg[2]), + toGLfloat(arg[3]), + toGLfloat(arg[4]), + toGLfloat(arg[5]), + toGLfloat(arg[6]), + toDouble(arg[7]), + toDouble(arg[8])); + } + else + { + m_error="Unknown object in ring : " + arg[0]; + throw m_error; + } + break; + + case mring_cmd: + { + int num=toInt(arg[1]); + string name=arg[0]; + int f; + + for(f=0;f<num;f++) + { + string ss=makeName(name,f+1); + + if (findMass(mass,ss,idx)) + { + mass[idx].setRing(toDouble(arg[2]),toDouble(arg[3]), + toGLfloat(arg[4]), + toGLfloat(arg[5]), + toGLfloat(arg[6]), + toGLfloat(arg[7]), + toDouble(arg[8]), + toDouble(arg[9])); + } + else + { + m_error="Unknown object in mring : " + ss; + throw m_error; + } + } + } + break; + + case ring_texture_cmd: + if (!m_glid) + { + m_error="ring used without preceeding num_texture"; + throw m_error; + } + + if (findMass(mass,arg[0],idx)) + { + if (m_glid_no==m_glid_idx) + { + m_error="more textures than expected"; + throw m_error; + } + + GLuint id=m_glid[m_glid_idx++]; + + if (bindTexture(arg[1],toInt(arg[2]),toInt(arg[3]),id)) + mass[idx].setRingTexture(id); + else + { + m_error="Failed to bind texture : " + m_error; + throw m_error; + } + } + else + { + m_error="Unknown object in ring : " + arg[0]; + throw m_error; + } + break; + + case ring_reuse_cmd: + if (findMass(mass,arg[0],idx)) + { + if (findMass(mass,arg[1],parent)) + { + GLuint id; + + if (parent.getRingTexture(id) || + parent.getTexture(id)) + mass[idx].setRingTexture(id); + else + { + m_error="ring_reuse object has no texture : " + + arg[1]; + throw m_error; + } + } + else + { + m_error="Unknown object in ring_reuse : " + arg[1]; + throw m_error; + } + } + else + { + m_error="Unknown object in ring_reuse : " + arg[0]; + throw m_error; + } + break; + + case ring_mreuse_cmd: + if (findMass(mass,arg[2],parent)) + { + int num=toInt(arg[1]); + string name=arg[0]; + int f; + + for(f=0;f<num;f++) + { + string ss=makeName(name,f+1); + + if (findMass(mass,ss,idx)) + { + GLuint id; + + if (parent.getRingTexture(id) || + parent.getTexture(id)) + mass[idx].setRingTexture(id); + else + { + m_error="ring_mreuse object has " + "no texture : " + arg[2]; + throw m_error; + } + } + else + { + m_error="Unknown object in ring_mreuse : " + ss; + throw m_error; + } + } + } + else + { + m_error="Unknown object in ring_mreuse : " + arg[2]; + throw m_error; + } + break; + + case particles_cmd: + m_particles=true; + m_p_adec=toGLfloat(arg[0]); + m_p_amin=toGLfloat(arg[1]); + m_p_size=toGLfloat(arg[2]); + break; + + case plane_cmd: + f=0; + found=false; + while(enum_list[f].token!="") + { + if (enum_list[f].cmd==plane_cmd && + CompareNoCase(enum_list[f].token,arg[0])) + { + found=true; + m_plane=static_cast<Plane>(enum_list[f].val); + break; + } + f++; + } + + if (!found) + { + m_error="Illegal argument to plane : " + arg[0]; + throw m_error; + } + + break; + + case shatter_cmd: + m_s_no=toInt(arg[0]); + m_s_delta=toDouble(arg[1]); + m_s_min=toDouble(arg[2]); + m_s_max=toDouble(arg[3]); + m_s_shield=toInt(arg[4]); + break; + + case scale_cmd: + m_scale=toDouble(arg[0]); + break; + + case look_at_cmd: + found=false; + + for(sidx=0;sidx<m_look.size();sidx++) + if (m_look[sidx]==arg[0]) + { + m_look_at=sidx; + found=true; + } + + if (!found) + { + m_error="Illegal argument to look_at : " + arg[0]; + throw m_error; + } + break; + + case travel_as_cmd: + found=false; + + for(sidx=0;sidx<m_look.size();sidx++) + if (m_look[sidx]==arg[0]) + { + m_travel_as=sidx; + found=true; + } + + if (!found) + { + m_error="Illegal argument to travel_as : " + arg[0]; + throw m_error; + } + break; + + case window_size_cmd: + m_winw=toInt(arg[0]); + m_winh=toInt(arg[1]); + break; + + case sparks_cmd: + m_sparks=true; + m_sp_no=toInt(arg[0]); + m_sp_adec=toGLfloat(arg[1]); + m_sp_amin=toGLfloat(arg[2]); + m_sp_length=toInt(arg[3]); + m_sp_delta=toGLfloat(arg[4]); + break; + + case max_mass_cmd: + m_max_mass=toInt(arg[0]); + break; + + case fog_cmd: + m_flag[fog]=true; + m_fog_dist=toGLfloat(arg[0]); + m_fog_r=toGLfloat(arg[1]); + m_fog_g=toGLfloat(arg[2]); + m_fog_b=toGLfloat(arg[3]); + m_fog_light=toYesNo(arg[4]); + break; + + default: + break; + } + } + } + catch(...) + { + file.close(); + return false; + } + + if (cmd==cmd_eof) + { + file.close(); + return true; + } + else + return false; +} + +void Config::getCamera(GLfloat& x, GLfloat& y, GLfloat& z, GLfloat& yaw) const +{ + x=m_x; + y=m_y; + z=m_z; + yaw=m_yaw; +} + +bool Config::enabled(Config::Flag flag) const +{ + return m_flag[flag]; +} + +Config::Collide Config::collide() const +{ + return m_collide; +} + +string Config::light(GLfloat v[4]) const +{ + v[0]=m_lr; + v[1]=m_lg; + v[2]=m_lb; + v[3]=1.0f; + return m_light; +} + +double Config::gravConst() const +{ + return m_const; +} + +double Config::scale() const +{ + return m_scale; +} + +void Config::look(vector<string>& l) const +{ + l=m_look; +} + +bool Config::particlesDefined() const +{ + return m_particles; +} + +void Config::getParticles(GLfloat& alpha_dec, GLfloat& alpha_min, + GLfloat& size ) const +{ + alpha_dec=m_p_adec; + alpha_min=m_p_amin; + size=m_p_size; +} + +void Config::getLookAndTravel(int& look, int &travel) const +{ + look=m_look_at; + travel=m_travel_as; +} + +void Config::getShatter(int& num, double& delta, + double& min_mass, double& max_mass, int& shield) const +{ + num=m_s_no; + delta=m_s_delta; + min_mass=m_s_min; + max_mass=m_s_max; + shield=m_s_shield; +} + + +bool Config::sparksDefined() const +{ + return m_sparks; +} + + +void Config::getSparks(int& num, GLfloat& alpha_dec, GLfloat& alpha_min, + int& length, GLfloat& delta) const +{ + num=m_sp_no; + alpha_dec=m_sp_adec; + alpha_min=m_sp_amin; + length=m_sp_length; + delta=m_sp_delta; +} + + +size_t Config::maxMass() const +{ + return m_max_mass; +} + + +void Config::getFog(GLfloat& dist, GLfloat& r, GLfloat& g, GLfloat& b, + bool& fog_light) +{ + dist=m_fog_dist; + r=m_fog_r; + g=m_fog_g; + b=m_fog_b; + fog_light=m_fog_light; +} + +void Config::windowSize(int& w, int& h) const +{ + w=m_winw; + h=m_winh; +} + + +string Config::error() const +{ + return m_error; +} + + +// ---------------------------------------- PRIVATE MEMBERS +// +bool Config::CompareNoCase(const string& s1, const string& s2) +{ + const char *p1,*p2; + + p1=s1.c_str(); + p2=s2.c_str(); + + while((*p1)&&(tolower(*p1)==tolower(*p2))) + { + p1++; + p2++; + } + + if (tolower(*p1)-tolower(*p2)) + return false; + else + return true; +} + + +Config::GetWordStatus Config::getWord(ifstream& file, string& word, + const string& ignore, const string& term) +{ + bool done=false; + bool in_word=false; + bool in_comment=false; + string not_allowed; + char c; + + if (term==";") + not_allowed=","; + else if (term==",") + not_allowed=";"; + else + not_allowed=",;"; + + word=""; + + while(!done) + { + file.get(c); + + if (file.eof()) + return GWEof; + + if (in_comment) + { + if (c=='\n') + in_comment=false; + } + else + { + if (c=='#') + in_comment=true; + else + if (in_word) + { + bool at_term=(term.find(c)!=string::npos); + bool in_error=(not_allowed.find(c)!=string::npos); + + if (in_error) + { + if (term==",") + return GWTooFewArgs; + else if (term==";") + return GWTooManyArgs; + else + return GWSyntax; + } + + if (at_term) + done=true; + else + if (c!='\n') + word+=c; + } + else + { + bool in_ignore=(ignore.find(c)!=string::npos); + + if (!in_ignore) + { + word+=c; + in_word=true; + } + } + } + } + + return GWOK; +} + + +bool Config::getCommand(ifstream& file, Config::Command& cmd, + vector<string>& arg) +{ + static struct + { + string cmd; + Command token; + int args; + } cmd_list[]= + { + {"enable",enable_cmd,1}, + {"disable",disable_cmd,1}, + {"collide",collide_cmd,1}, + {"const",const_cmd,1}, + {"body",body_cmd,12}, + {"radial",radial_cmd,10}, + {"light",light_cmd,4}, + {"camera",camera_cmd,4}, + {"look",look_cmd,1}, + {"texture",texture_cmd,4}, + {"num_texture",num_texture_cmd,1}, + {"reuse",reuse_cmd,2}, + {"particles",particles_cmd,3}, + {"shatter",shatter_cmd,5}, + {"multiple",multiple_cmd,15}, + {"mreuse",mreuse_cmd,3}, + {"plane",plane_cmd,1}, + {"scale",scale_cmd,1}, + {"look_at",look_at_cmd,1}, + {"travel_as",travel_as_cmd,1}, + {"window_size",window_size_cmd,2}, + {"sparks",sparks_cmd,5}, + {"max_mass",max_mass_cmd,1}, + {"mlook",mlook_cmd,2}, + {"ring",ring_cmd,9}, + {"mring",mring_cmd,10}, + {"ring_texture",ring_texture_cmd,4}, + {"ring_reuse",ring_reuse_cmd,2}, + {"ring_mreuse",ring_mreuse_cmd,3}, + {"fog",fog_cmd,5}, + {"",cmd_error,1} + }; + + string word; + string cmd_string; + int expect; + int f; + + switch (getWord(file,word," \t\n"," \t\n")) + { + case GWEof: + cmd=cmd_eof; + return false; + case GWSyntax: + m_error="Syntax error in command " + word; + return false; + default: + break; + } + + f=0; + cmd=cmd_error; + + while(cmd_list[f].cmd!="") + { + if (CompareNoCase(cmd_list[f].cmd,word)) + { + cmd_string=word; + cmd=cmd_list[f].token; + expect=cmd_list[f].args; + break; + } + + f++; + } + + if (cmd==cmd_error) + { + m_error="Unrecognised command " + word; + return false; + } + + arg.clear(); + + for(f=0;f<expect;f++) + { + string error; + + switch (getWord(file,word," \t\n",(f==expect-1) ? ";" : ",")) + { + case GWOK: + break; + + case GWTooManyArgs: + cmd=cmd_error; + m_error="Too many arguments in " + cmd_string; + return false; + + case GWTooFewArgs: + cmd=cmd_error; + m_error="Too few arguments in " + cmd_string; + return false; + + case GWEof: + cmd=cmd_error; + m_error="Unexpected EOF in " + cmd_string; + return false; + + case GWSyntax: + cmd=cmd_error; + m_error="Syntax error in " + cmd_string; + return false; + } + + arg.push_back(word); + } + + return true; +} + +double Config::toDouble(const string& s) +{ + double r; + char *p; + + r=strtod(s.c_str(),&p); + + if (*p) + { + m_error="Invalid floating point number : " + s; + throw m_error; + } + + return r; +} + + +GLfloat Config::toGLfloat(const string& s) +{ + return static_cast<GLfloat>(toDouble(s)); +} + + +int Config::toInt(const string& s) +{ + int i; + char *p; + + i=static_cast<int>(strtol(s.c_str(),&p,0)); + + if (*p) + { + m_error="Invalid integer : " + s; + throw m_error; + } + + return i; +} + + +size_t Config::toSize(const string& s) +{ + size_t i; + char *p; + + i=static_cast<size_t>(strtol(s.c_str(),&p,0)); + + if (*p) + { + m_error="Invalid integer : " + s; + throw m_error; + } + + return i; +} + + +bool Config::toYesNo(const string& s) +{ + if (s!="yes" && s!="no") + { + m_error="Invalid yes/no : " + s; + throw m_error; + } + + return s=="yes"; +} + + +bool Config::bindTexture(const string& name, int w, int h, GLuint id) +{ + FILE *fp; + ifstream file(name.c_str()); + GLubyte *mem; + int x,y; + + if (!(fp=fopen(name.c_str(),"r"))) + { + m_error="file " + name + " not found"; + return false; + } + + mem=new GLubyte[w*h*3]; + + for(y=0;y<h;y++) + for(x=w-1;x>=0;x--) + { + mem[x*3+y*w*3]=fgetc(fp); + mem[x*3+y*w*3+1]=fgetc(fp); + mem[x*3+y*w*3+2]=fgetc(fp); + + if (feof(fp)) + { + fclose(fp); + m_error="file " + name + " to short"; + delete[] mem; + return false; + } + } + + fclose(fp); + + glBindTexture(GL_TEXTURE_2D,id); + glTexImage2D(GL_TEXTURE_2D,0,3,w,h,0,GL_RGB,GL_UNSIGNED_BYTE,mem); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); + + delete[] mem; + + return true; +} + +void Config::genRadial(Mass **newMass, const Mass& parent, + const string& name, double mass, + double dist, double ang, double spd, + GLfloat r, GLfloat g, GLfloat b, double rot) +{ + double px,py,pz; + double pdx,pdy,pdz; + double ox,oy,oz; + double dx,dy,dz; + + parent.getPosition(px,py,pz); + parent.getDelta(pdx,pdy,pdz); + + switch(m_plane) + { + case xy_plane: + ox=px+dist*sin(ang); + oy=py-dist*cos(ang); + oz=pz; + ang+=RAD(90); + dx=spd*sin(ang); + dy=-spd*cos(ang); + dz=0.0; + break; + + case xz_plane: + ox=px+dist*sin(ang); + oy=py; + oz=pz-dist*cos(ang); + ang+=RAD(90); + dx=spd*sin(ang); + dy=0.0; + dz=-spd*cos(ang); + break; + + case yz_plane: + ox=px; + oy=py+dist*sin(ang); + oz=pz-dist*cos(ang); + ang+=RAD(90); + dx=0.0; + dy=spd*sin(ang); + dz=-spd*cos(ang); + break; + + default: + m_error="INTERNAL ERROR: invalid plane defined"; + throw m_error; + } + + dx+=pdx; + dy+=pdy; + dz+=pdz; + + *newMass=new Mass(name, mass, m_scale, ox,oy,oz, dx,dy,dz, r,g,b,rot); +} + + +string Config::makeName(string& name, int no) +{ + char s[1024]; + string n; + + sprintf(s,"%s %d",name.c_str(),no); + n=s; + + return n; +} + + +// END OF FILE // |