diff options
| author | Ian C <ianc@noddybox.co.uk> | 2010-08-18 14:38:34 +0000 | 
|---|---|---|
| committer | Ian C <ianc@noddybox.co.uk> | 2010-08-18 14:38:34 +0000 | 
| commit | 19bbd5822593c7198dd54eb0f5d38fa1ed8d8fb7 (patch) | |
| tree | 97f7f8849c3a8282ba571a64ff2a655cdf5d41aa | |
| parent | 0d2f672482fee91a9642a7cb6eb01fcdded79159 (diff) | |
Reformatted code and altered the attraction rule to something a bit more
correct.  Also added two tests to prove it works.
| -rw-r--r-- | camera.h | 42 | ||||
| -rw-r--r-- | config.cpp | 647 | ||||
| -rw-r--r-- | config.h | 212 | ||||
| -rw-r--r-- | glgrav.cpp | 298 | ||||
| -rw-r--r-- | makefile | 6 | ||||
| -rw-r--r-- | mass.cpp | 142 | ||||
| -rw-r--r-- | mass.h | 188 | ||||
| -rw-r--r-- | matrix.h | 74 | ||||
| -rw-r--r-- | particles.cpp | 12 | ||||
| -rw-r--r-- | particles.h | 44 | ||||
| -rw-r--r-- | sparks.cpp | 20 | ||||
| -rw-r--r-- | sparks.h | 50 | ||||
| -rw-r--r-- | test1.dat | 51 | ||||
| -rw-r--r-- | test2.dat | 53 | 
14 files changed, 1073 insertions, 766 deletions
| @@ -31,27 +31,27 @@  #include "matrix.h"  class Camera -    { -    public: -    	Camera(); -	virtual ~Camera(); - -	// Initially the camera always looks along the Z axis -	// -	void setPos(GLfloat x, GLfloat y, GLfloat z); - -	void addSpeed(GLfloat speed); -	void roll(double angle); -	void pitch(double angle); - -	void setView() const; - -    private: -    	GLfloat	px,py,pz; -	Matrix	direction; -	Matrix	left; -	Matrix	up; -    }; +{ +public: +    Camera(); +    virtual ~Camera(); + +    // Initially the camera always looks along the Z axis +    // +    void setPos(GLfloat x, GLfloat y, GLfloat z); + +    void addSpeed(GLfloat speed); +    void roll(double angle); +    void pitch(double angle); + +    void setView() const; + +private: +    GLfloat	px,py,pz; +    Matrix	direction; +    Matrix	left; +    Matrix	up; +};  #endif @@ -36,60 +36,66 @@ Config::Config()  {      int f; -    m_error=""; +    m_error = "";      for(f=0;f<num_flags;f++) -	m_flag[f]=false; +    { +	m_flag[f] = false; +    } -    m_collide=none; +    m_collide = none; -    m_light=""; -    m_lr=m_lg=m_lb=1.0f; +    m_light = ""; +    m_lr = 1.0f; +    m_lg = 1.0f; +    m_lb = 1.0f; -    m_const=0.0; +    m_const = 0.0; -    m_x=0.0f; -    m_y=0.0f; -    m_z=0.0f; -    m_yaw=0.0f; +    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_glid = 0; +    m_glid_no = 0; +    m_glid_idx = 0; -    m_scale=1.0; +    m_scale = 1.0; -    m_particles=false; +    m_particles = false; -    m_plane=xy_plane; +    m_plane = xy_plane; -    m_look_at=-1; -    m_travel_as=-1; +    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_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_sparks = false; -    m_winw=640; -    m_winh=480; +    m_winw = 640; +    m_winh = 480; -    m_max_mass=1000000; +    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; +    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; +    }  } @@ -98,24 +104,24 @@ Config::~Config()  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} -		}; +    } 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; @@ -128,37 +134,37 @@ bool Config::read(const string& fname,vector<Mass>& mass)      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++;  			} +			f++; +		    }  		    if (!found) -			{ +		    {  			m_error="Illegal argument to enable : " + arg[0];  			throw m_error; -			} +		    }  		    break; @@ -166,22 +172,22 @@ bool Config::read(const string& fname,vector<Mass>& mass)  		    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++;  			} +			f++; +		    }  		    if (!found) -			{ +		    {  			m_error="Illegal argument to disable : " + arg[0];  			throw m_error; -			} +		    }  		    break; @@ -189,22 +195,22 @@ bool Config::read(const string& fname,vector<Mass>& mass)  		    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++;  			} +			f++; +		    }  		    if (!found) -			{ +		    {  			m_error="Illegal argument to collide : " + arg[0];  			throw m_error; -			} +		    }  		    break; @@ -222,14 +228,16 @@ bool Config::read(const string& fname,vector<Mass>& mass)  			 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])), @@ -239,20 +247,22 @@ bool Config::read(const string& fname,vector<Mass>& mass)  				  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]); @@ -271,7 +281,7 @@ bool Config::read(const string& fname,vector<Mass>& mass)  			int f;  			for(f=0;f<num;f++) -			    { +			{  			    genRadial(&nm,parent,  				      makeName(name,f+1),ms,  				      dist,ang,spd, @@ -284,16 +294,18 @@ bool Config::read(const string& fname,vector<Mass>& mass)  			    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: @@ -312,34 +324,36 @@ bool Config::read(const string& fname,vector<Mass>& mass)  		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; +			int num=toInt(arg[1]); +			string name=arg[0]; +			int f; -		    for(f=0;f<num;f++) +			for(f=0;f<num;f++)  			{ -			string ss; +			    string ss; -			ss=makeName(name,f+1); +			    ss=makeName(name,f+1); -			if (findMass(mass,ss,idx)) +			    if (findMass(mass,ss,idx))  			    { -			    m_look.push_back(ss); +				m_look.push_back(ss);  			    } -			else +			    else  			    { -			    m_error="Unknown object in mlook : " + ss; -			    throw m_error; +				m_error="Unknown object in mlook : " + ss; +				throw m_error;  			    }  			}  		    } @@ -347,42 +361,44 @@ bool Config::read(const string& fname,vector<Mass>& mass)  		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]; @@ -392,76 +408,80 @@ bool Config::read(const string& fname,vector<Mass>& mass)  		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]), @@ -469,38 +489,39 @@ bool Config::read(const string& fname,vector<Mass>& mass)  					  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; +			int num=toInt(arg[1]); +			string name=arg[0]; +			int f; -		    for(f=0;f<num;f++) +			for(f=0;f<num;f++)  			{ -			string ss=makeName(name,f+1); +			    string ss=makeName(name,f+1); -			if (findMass(mass,ss,idx)) +			    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])); +				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 +			    else  			    { -			    m_error="Unknown object in mring : " + ss; -			    throw m_error; +				m_error="Unknown object in mring : " + ss; +				throw m_error;  			    }  			}  		    } @@ -508,103 +529,103 @@ bool Config::read(const string& fname,vector<Mass>& mass)  		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)) +				    parent.getTexture(id))  				mass[idx].setRingTexture(id);  			    else -				{ +			    {  				m_error="ring_reuse object has no texture : " + -									arg[1]; +				    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)) +					parent.getTexture(id))  				    mass[idx].setRingTexture(id);  				else -				    { +				{  				    m_error="ring_mreuse object has " -				    		"no texture : " + arg[2]; +					"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: @@ -618,22 +639,22 @@ bool Config::read(const string& fname,vector<Mass>& mass)  		    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++;  			} +			f++; +		    }  		    if (!found) -			{ +		    {  			m_error="Illegal argument to plane : " + arg[0];  			throw m_error; -			} +		    }  		    break; @@ -653,34 +674,36 @@ bool Config::read(const string& fname,vector<Mass>& mass)  		    found=false;  		    for(sidx=0;sidx<m_look.size();sidx++) -		    	if (m_look[sidx]==arg[0]) -			    { +			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]) -			    { +		    { +			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: @@ -712,22 +735,24 @@ bool Config::read(const string& fname,vector<Mass>& mass)  		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 @@ -858,15 +883,19 @@ bool Config::CompareNoCase(const string& s1, const string& s2)      p2=s2.c_str();      while((*p1)&&(tolower(*p1)==tolower(*p2))) -    	{ +    {  	p1++;  	p2++; -	} +    }      if (tolower(*p1)-tolower(*p2)) +    {      	return false; +    }      else +    {      	return true; +    }  } @@ -880,64 +909,84 @@ Config::GetWordStatus Config::getWord(ifstream& file, string& word,      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; +	    { +		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; -			} +	    { +		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 (at_term) -		    	done=true; -		    else -		    	if (c!='\n') -			    word+=c; +		if (in_error) +		{ +		    if (term==",") +		    { +			return GWTooFewArgs;  		    } -		else +		    else if (term==";")  		    { -		    bool in_ignore=(ignore.find(c)!=string::npos); - -		    if (!in_ignore) -		    	{ -			word+=c; -			in_word=true; -			} +			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;  } @@ -947,44 +996,44 @@ 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	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; @@ -992,7 +1041,7 @@ bool Config::getCommand(ifstream& file, Config::Command& cmd,      int f;      switch (getWord(file,word," \t\n"," \t\n")) -	{ +    {  	case GWEof:  	    cmd=cmd_eof;  	    return false; @@ -1001,40 +1050,40 @@ bool Config::getCommand(ifstream& file, Config::Command& cmd,  	    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; -	} +	return false; +    }      arg.clear();      for(f=0;f<expect;f++) -    	{ +    {  	string error;  	switch (getWord(file,word," \t\n",(f==expect-1) ? ";" : ",")) -	    { +	{  	    case GWOK: -	    	break; +		break;  	    case GWTooManyArgs:  		cmd=cmd_error; @@ -1055,10 +1104,10 @@ bool Config::getCommand(ifstream& file, Config::Command& cmd,  		cmd=cmd_error;  		m_error="Syntax error in " + cmd_string;  		return false; -	    } +	}  	arg.push_back(word); -	} +    }      return true;  } @@ -1071,10 +1120,10 @@ double Config::toDouble(const string& s)      r=strtod(s.c_str(),&p);      if (*p) -	{ +    {  	m_error="Invalid floating point number : " + s; -    	throw m_error; -	} +	throw m_error; +    }      return r;  } @@ -1094,10 +1143,10 @@ int Config::toInt(const string& s)      i=static_cast<int>(strtol(s.c_str(),&p,0));      if (*p) -	{ +    {  	m_error="Invalid integer : " + s; -    	throw m_error; -	} +	throw m_error; +    }      return i;  } @@ -1111,10 +1160,10 @@ size_t Config::toSize(const string& s)      i=static_cast<size_t>(strtol(s.c_str(),&p,0));      if (*p) -	{ +    {  	m_error="Invalid integer : " + s; -    	throw m_error; -	} +	throw m_error; +    }      return i;  } @@ -1123,10 +1172,10 @@ size_t Config::toSize(const string& s)  bool Config::toYesNo(const string& s)  {      if (s!="yes" && s!="no") -	{ +    {  	m_error="Invalid yes/no : " + s;      	throw m_error; -	} +    }      return s=="yes";  } @@ -1140,28 +1189,30 @@ bool Config::bindTexture(const string& name, int w, int h, GLuint id)      int x,y;      if (!(fp=fopen(name.c_str(),"r"))) -	{ +    {  	m_error="file " + name + " not found"; -    	return false; -	} +	return false; +    }      mem=new GLubyte[w*h*3];      for(y=0;y<h;y++) -    	for(x=w-1;x>=0;x--) -	    { +    { +	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); @@ -1189,7 +1240,7 @@ void Config::genRadial(Mass **newMass, const Mass& parent,      parent.getDelta(pdx,pdy,pdz);      switch(m_plane) -    	{ +    {  	case xy_plane:  	    ox=px+dist*sin(ang);  	    oy=py-dist*cos(ang); @@ -1223,7 +1274,7 @@ void Config::genRadial(Mass **newMass, const Mass& parent,  	default:  	    m_error="INTERNAL ERROR: invalid plane defined";  	    throw m_error; -	} +    }      dx+=pdx;      dy+=pdy; @@ -32,142 +32,148 @@  #include "mass.h"  class Config -    { -    public: -	enum Flag {solid, lighting, texture, fog, num_flags}; -	enum Collide {none, merge, delta_merge, shatter}; +{ +public: +    enum Flag {solid, lighting, texture, fog, num_flags}; +    enum Collide {none, merge, delta_merge, shatter}; -    	Config(); -	virtual ~Config(); +    Config(); +    virtual ~Config(); -	// Note that the vector is added to.  It must be cleared beforehand -	// if required. -	// -	bool read(const string& file, vector<Mass>& mass); +    // Note that the vector is added to.  It must be cleared beforehand +    // if required. +    // +    bool read(const string& file, vector<Mass>& mass); -	void getCamera(GLfloat& x, GLfloat& y, GLfloat& z, GLfloat& yaw) const; +    void getCamera(GLfloat& x, GLfloat& y, GLfloat& z, GLfloat& yaw) const; -	bool enabled(Flag flag) const; -	Collide collide() const; -	string light(GLfloat v[4]) const; -	double gravConst() const; -	double scale() const; +    bool enabled(Flag flag) const; +    Collide collide() const; +    string light(GLfloat v[4]) const; +    double gravConst() const; +    double scale() const; -	void windowSize(int& w,int& h) const; +    void windowSize(int& w,int& h) const; -	void getShatter(int& num, double& delta, -			double& min_mass, double& max_mass, -			int& shield) const; +    void getShatter(int& num, double& delta, +		    double& min_mass, double& max_mass, +		    int& shield) const; -	bool sparksDefined() const; +    bool sparksDefined() const; -    	void getSparks(int& num, GLfloat& alpha_dec, GLfloat& alpha_min, -		       int& length, GLfloat& delta) const; +    void getSparks(int& num, GLfloat& alpha_dec, GLfloat& alpha_min, +		   int& length, GLfloat& delta) const; -	size_t maxMass() const; +    size_t maxMass() const; -	// Args set to -1 if undefined -	// -	void getLookAndTravel(int& look, int &travel) const; +    // Args set to -1 if undefined +    // +    void getLookAndTravel(int& look, int &travel) const; -	bool particlesDefined() const; +    bool particlesDefined() const; -	void getParticles(GLfloat& alpha_dec, GLfloat& alpha_min, -			  GLfloat& size) const; +    void getParticles(GLfloat& alpha_dec, GLfloat& alpha_min, +		      GLfloat& size) const; -	void getFog(GLfloat& dist, GLfloat& r, GLfloat& g, GLfloat& b, -		    bool& fog_light); +    void getFog(GLfloat& dist, GLfloat& r, GLfloat& g, GLfloat& b, +		bool& fog_light); -	void look(vector<string>& l) const; +    void look(vector<string>& l) const; -	string error() const; +    string error() const; -    private: -	enum Plane {xy_plane, xz_plane, yz_plane}; +private: +    enum Plane {xy_plane, xz_plane, yz_plane}; -	Plane	m_plane; +    Plane		m_plane; -    	string	m_error; -	bool	m_flag[num_flags]; -	Collide	m_collide; -	double	m_const; -	GLfloat	m_x,m_y,m_z,m_pitch,m_yaw; +    string		m_error; +    bool		m_flag[num_flags]; +    Collide		m_collide; +    double		m_const; +    GLfloat		m_x; +    GLfloat		m_y; +    GLfloat		m_z; +    GLfloat		m_pitch; +    GLfloat		m_yaw; -	double	m_scale; +    double		m_scale; -	string	m_light; -	GLfloat	m_lr,m_lg,m_lb; +    string		m_light; +    GLfloat		m_lr; +    GLfloat		m_lg; +    GLfloat		m_lb; -	vector<string>	m_look; -	int	m_look_at; -	int	m_travel_as; +    vector<string>	m_look; +    int			m_look_at; +    int			m_travel_as; -	bool	m_particles; -	GLfloat	m_p_adec; -	GLfloat	m_p_amin; -	GLfloat	m_p_size; +    bool		m_particles; +    GLfloat		m_p_adec; +    GLfloat		m_p_amin; +    GLfloat		m_p_size; -	GLuint	*m_glid; -	int	m_glid_no; -	int	m_glid_idx; +    GLuint		*m_glid; +    int			m_glid_no; +    int			m_glid_idx; -	int	m_s_no; -	double	m_s_delta; -	double	m_s_min; -	double	m_s_max; -	int	m_s_shield; +    int			m_s_no; +    double		m_s_delta; +    double		m_s_min; +    double		m_s_max; +    int			m_s_shield; -	bool	m_sparks; -	int	m_sp_no; -	GLfloat	m_sp_adec; -	GLfloat	m_sp_amin; -	int	m_sp_length; -	GLfloat	m_sp_delta; +    bool		m_sparks; +    int			m_sp_no; +    GLfloat		m_sp_adec; +    GLfloat		m_sp_amin; +    int			m_sp_length; +    GLfloat		m_sp_delta; -	int	m_winw; -	int	m_winh; +    int			m_winw; +    int			m_winh; -	size_t	m_max_mass; +    size_t		m_max_mass; -	GLfloat	m_fog_dist; -	GLfloat	m_fog_r; -	GLfloat	m_fog_g; -	GLfloat	m_fog_b; -	bool	m_fog_light; +    GLfloat		m_fog_dist; +    GLfloat		m_fog_r; +    GLfloat		m_fog_g; +    GLfloat		m_fog_b; +    bool		m_fog_light; -	enum Command {enable_cmd, disable_cmd, collide_cmd, const_cmd, -		      body_cmd, radial_cmd, light_cmd, camera_cmd, look_cmd, -		      texture_cmd, num_texture_cmd, reuse_cmd, particles_cmd, -		      shatter_cmd, multiple_cmd, mreuse_cmd, plane_cmd, -		      scale_cmd, look_at_cmd, travel_as_cmd, window_size_cmd, -		      sparks_cmd, max_mass_cmd, mlook_cmd, -		      ring_cmd, mring_cmd, ring_texture_cmd, ring_reuse_cmd, -		      ring_mreuse_cmd, fog_cmd, -		      cmd_eof, cmd_error}; +    enum Command {enable_cmd, disable_cmd, collide_cmd, const_cmd, +		  body_cmd, radial_cmd, light_cmd, camera_cmd, look_cmd, +		  texture_cmd, num_texture_cmd, reuse_cmd, particles_cmd, +		  shatter_cmd, multiple_cmd, mreuse_cmd, plane_cmd, +		  scale_cmd, look_at_cmd, travel_as_cmd, window_size_cmd, +		  sparks_cmd, max_mass_cmd, mlook_cmd, +		  ring_cmd, mring_cmd, ring_texture_cmd, ring_reuse_cmd, +		  ring_mreuse_cmd, fog_cmd, +		  cmd_eof, cmd_error}; -	enum GetWordStatus {GWOK, GWEof, GWSyntax, -			    GWTooFewArgs, GWTooManyArgs}; +    enum GetWordStatus {GWOK, GWEof, GWSyntax, +			GWTooFewArgs, GWTooManyArgs}; -	bool CompareNoCase(const string& s1, const string& s2); -	GetWordStatus getWord(ifstream& fp, string& word, -			      const string& ignore, const string& term); -	bool getCommand(ifstream& fp, Command& cmd, vector<string>& val); +    bool CompareNoCase(const string& s1, const string& s2); +    GetWordStatus getWord(ifstream& fp, string& word, +			  const string& ignore, const string& term); +    bool getCommand(ifstream& fp, Command& cmd, vector<string>& val); -	void 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); +    void 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 toDouble(const string& s); -	GLfloat toGLfloat(const string& s); -	int toInt(const string& s); -	size_t toSize(const string& s); -	bool toYesNo(const string& s); - -	bool bindTexture(const string& name, int w, int h, GLuint id); - -	string makeName(string& name, int no); -    }; +    double toDouble(const string& s); +    GLfloat toGLfloat(const string& s); +    int toInt(const string& s); +    size_t toSize(const string& s); +    bool toYesNo(const string& s); + +    bool bindTexture(const string& name, int w, int h, GLuint id); + +    string makeName(string& name, int no); +};  #endif @@ -84,21 +84,21 @@ static bool		fog_light=false;  static GLfloat		fog_col[4]={0.0f,0.0f,0.0f,1.0f};  static struct -	{ -	GLfloat	x,y,z; -	GLfloat	ang; -	GLfloat	speed; -	} camera={0.0f,0.0f,0.0f,0.0f,0.0f}; +{ +    GLfloat	x,y,z; +    GLfloat	ang; +    GLfloat	speed; +} camera={0.0f,0.0f,0.0f,0.0f,0.0f};  static struct -	{ -	int	mx,my; -	bool	lmb; -	bool	shift; -	bool	ctrl; -	bool	pgup; -	bool	pgdn; -	} control; +{ +    int		mx,my; +    bool	lmb; +    bool	shift; +    bool	ctrl; +    bool	pgup; +    bool	pgdn; +} control;  static void	Reshape(int w,int h);  static void	Mouse(int b,int s, int x, int y); @@ -139,10 +139,10 @@ int main(int argc, char *argv[])      mass.clear();      if (!config.read(argc == 2 ? argv[1] : "dat",mass)) -    	{ +    {  	cerr << "Config file reading failed : \n" << config.error() << endl;  	exit(1); -	} +    }      config.getCamera(camera.x,camera.y,camera.z,camera.ang); @@ -154,41 +154,45 @@ int main(int argc, char *argv[])      fog=config.enabled(Config::fog);      if (config.particlesDefined()) -    	{ +    {  	GLfloat adec,amin;  	config.getParticles(adec,amin,particleSize);  	particles=new Particles(adec,amin);  	render_particles=true; -	} +    }      else +    {  	render_particles=false; +    }      if (config.sparksDefined()) -    	{ +    {  	int num,len;  	GLfloat adec,amin,delta;  	config.getSparks(num,adec,amin,len,delta); -    	sparks=new Sparks(num,adec,amin,len,delta); +	sparks=new Sparks(num,adec,amin,len,delta);  	render_sparks=true; -	} +    }      else +    {  	render_sparks=false; +    }      config.windowSize(width,height);      width=max(width,100);      height=max(height,100); -#   ifdef DEBUG -	{ +#ifdef DEBUG +    {  	vector<Mass>::size_type f;  	for(f=0;f<mass.size();f++)  	    cout << "Initial : " << mass[f] << endl; -	} -#   endif +    } +#endif      glutDisplayFunc(Display);      glutMouseFunc(Mouse); @@ -227,35 +231,35 @@ int main(int argc, char *argv[])      glutAddMenuEntry("None",MENU_LOOK+LOOK_NONE);      for(li=0;li<look.size();li++) -    	{ +    {  	glutSetMenu(travel_menu);  	glutAddMenuEntry(look[li].c_str(),MENU_TRAVEL+li);  	glutSetMenu(look_menu);  	glutAddMenuEntry(look[li].c_str(),MENU_LOOK+li); -	} +    }      // Create frame skip menu      //      frame_skip_menu=glutCreateMenu(FrameSkipMenu);      for(f=0;f<20;f++) -    	{ +    {  	char s[64];  	int skip;  	if (f) -	    { +	{  	    skip=f+1;  	    sprintf(s,"Draw every %d frames",skip); -	    } +	}  	else -	    { +	{  	    skip=f;  	    strcpy(s,"No frame skip"); -	    } +	}  	glutAddMenuEntry(s,MENU_FRAME_SKIP+skip); -	} +    }      glutSetMenu(menu);      glutAddSubMenu("Travel as",travel_menu); @@ -266,21 +270,23 @@ int main(int argc, char *argv[])      // Create optional debug menu      // -#   ifdef DEBUG -	{ +#ifdef DEBUG +    {  	debug_menu=glutCreateMenu(DebugMenu);  	glutAddMenuEntry("Dump Objects",DBG_DUMPOBJ);  	glutSetMenu(menu);  	glutAddSubMenu("DEBUG",debug_menu); -	} -#   endif +    } +#endif      // Open GL initialisation      //      glShadeModel(GL_SMOOTH);      if (!light) -    	glDisable(GL_LIGHTING); +    { +	glDisable(GL_LIGHTING); +    }      glEnable(GL_DEPTH_TEST);      glEnable(GL_COLOR_MATERIAL); @@ -292,7 +298,7 @@ int main(int argc, char *argv[])      glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);      if (fog) -    	{ +    {  	GLfloat dist;  	config.getFog(dist,fog_col[0],fog_col[1],fog_col[2],fog_light); @@ -303,7 +309,7 @@ int main(int argc, char *argv[])  	glFogi(GL_FOG_MODE,GL_LINEAR);  	glClearColor(fog_col[0],fog_col[1],fog_col[2],1.0); -	} +    }      // Enter the main loop      // @@ -332,12 +338,12 @@ static void Mouse(int b,int s, int x, int y)      int mod=glutGetModifiers();      if (b==GLUT_LEFT_BUTTON) -    	{ +    {  	control.lmb=(s==GLUT_DOWN);  	control.shift=mod&GLUT_ACTIVE_SHIFT;  	control.ctrl=mod&GLUT_ACTIVE_CTRL; -	} +    }  } @@ -355,7 +361,7 @@ static void Menu(int item)  #endif      switch (item) -    	{ +    {  	case MENU_SOLID:  	    solid=!solid;  	    SetOption(MENU_SOLID,"Solid",solid); @@ -366,7 +372,9 @@ static void Menu(int item)  	    SetOption(MENU_LIGHTING,"Lighting",light);  	    if (!light) +	    {  		glDisable(GL_LIGHTING); +	    }  	    break;  	case MENU_TEXTURE: @@ -390,21 +398,25 @@ static void Menu(int item)  	case MENU_FOG:  	    if (config.enabled(Config::fog)) -	    	{ +	    {  		fog=!fog;  		SetOption(MENU_FOG,"Fog",fog);  		if (fog) +		{  		    glClearColor(fog_col[0],fog_col[1],fog_col[2],1.0); +		}  		else +		{  		    glClearColor(0.0f,0.0f,0.0f,1.0);  		} +	    }  	    break;  	case MENU_QUIT:  	    exit(EXIT_SUCCESS);  	    break; -	} +    }  } @@ -419,7 +431,9 @@ static void TravelMenu(int item)      travel_as=item-MENU_TRAVEL;      if (travel_as!=LOOK_NONE and look_at==travel_as) +    {      	travel_as=old; +    }  } @@ -434,7 +448,9 @@ static void LookMenu(int item)      look_at=item-MENU_LOOK;      if (look_at!=LOOK_NONE and look_at==travel_as) +    {      	look_at=old; +    }  } @@ -454,12 +470,14 @@ static void DebugMenu(int item)      vector<Mass>::size_type f;      switch (item) -    	{ +    {  	case DBG_DUMPOBJ:  	    for(f=0;f<mass.size();f++) +	    {  	    	cout << mass[f] << endl; +	    }  	    break; -	} +    }  }  #endif @@ -467,9 +485,13 @@ static void DebugMenu(int item)  static void SetOption(int opt, string text, bool flag)  {      if (flag) +    {      	text+=" Off"; +    }      else +    {      	text+=" On"; +    }      glutChangeToMenuEntry(opt,text.c_str(),opt);  } @@ -478,7 +500,7 @@ static void SetOption(int opt, string text, bool flag)  static void Key(int key, int mx, int my)  {      switch(key) -    	{ +    {  	case GLUT_KEY_PAGE_DOWN:  	    control.pgdn=true;  	    break; @@ -489,7 +511,7 @@ static void Key(int key, int mx, int my)  	default:  	    break; -	} +    }  } @@ -500,7 +522,7 @@ static void SetView()      glLoadIdentity();      if ((look_at!=LOOK_NONE)&&(findMass(mass,look[look_at],lm))) -	{ +    {  	double x,y,z;  	lm.getPosition(x,y,z); @@ -513,12 +535,12 @@ static void SetView()  		  static_cast<GLdouble>(camera.z),  		  x,y,z,  		  0.0,1.0,0.0); -	} +    }      else -	{ +    {  	glRotatef(360.0-camera.ang,0.0f,1.0f,0.0f);  	glTranslatef(-camera.x,-camera.y,-camera.z); -	} +    }  } @@ -528,11 +550,11 @@ static void DrawMasses(Mass::DrawItem item)      Mass lm;      for(i=mass.begin();i!=mass.end();i++) -	{ +    {  	SetView();  	if (light) -	    { +	{  	    GLfloat light[4];  	    GLfloat pos[4];  	    string name; @@ -540,7 +562,7 @@ static void DrawMasses(Mass::DrawItem item)  	    name=config.light(light);  	    if (name!=i->getName() && findMass(mass,name,lm)) -	    	{ +	    {  		double x,y,z;  		lm.getPosition(x,y,z); @@ -557,17 +579,17 @@ static void DrawMasses(Mass::DrawItem item)  		if (fog)  		    glEnable(GL_FOG); -		} +	    }  	    else -		{ +	    {  		if (!fog_light)  		    glDisable(GL_FOG);  		glDisable(GL_LIGHTING); -		}  	    } +	}  	i->draw(solid,texture,item); -	} +    }  } @@ -575,10 +597,10 @@ static void Display(void)  {      Mass lm; -    /* Looking up/down doesn't work yet... -    */ +    // Looking up/down doesn't work yet... +    //      if ((travel_as!=LOOK_NONE)&&(findMass(mass,look[travel_as],lm))) -	{ +    {  	double x,y,z;  	lm.getPosition(x,y,z); @@ -586,19 +608,23 @@ static void Display(void)  	camera.x=static_cast<GLfloat>(x);  	camera.y=static_cast<GLfloat>(y);  	camera.z=static_cast<GLfloat>(z); -	} +    }      else -    	{ +    {  	GLPrint("Pos: %d,%d,%d",(int)camera.x,(int)camera.y,(int)camera.z);  	GLPrint("Angle: %d",(int)camera.ang); -	} +    }      glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);      if (fog) +    {  	glEnable(GL_FOG); +    }      else +    {  	glDisable(GL_FOG); +    }      DrawMasses(Mass::eMass); @@ -611,19 +637,21 @@ static void Display(void)      glDisable(GL_TEXTURE_2D);      if (fog) +    {  	glEnable(GL_FOG); +    }      if (particles && render_particles) -    	{ +    {  	glPointSize(particleSize);  	particles->draw(); -	} +    }      if (sparks && render_sparks) -	{ +    {  	glPointSize(1); -    	sparks->draw(); -	} +	sparks->draw(); +    }      glDisable(GL_BLEND); @@ -655,35 +683,51 @@ static void Shatter(vector<Mass>& mv, Mass& m,int no,double delta,int shield)      texture=m.getTexture(id);      for(f=0;f<no;f++) +    {  	if (mv.size()<config.maxMass()) -	    { +	{  	    npx=px+RND(size*2)-size;  	    npy=py+RND(size*2)-size;  	    npz=pz+RND(size*2)-size;  	    if (npx<px) +	    {  		ndx=dx-DRand()*delta; +	    }  	    else +	    {  		ndx=dx+DRand()*delta; +	    }  	    if (npy<py) +	    {  		ndy=dy-DRand()*delta; +	    }  	    else +	    {  		ndy=dy+DRand()*delta; +	    }  	    if (npz<pz) +	    {  		ndz=dz-DRand()*delta; +	    }  	    else +	    {  		ndz=dz+DRand()*delta; +	    }  	    Mass m(name,nm,config.scale(),  		   npx,npy,npz,ndx,ndy,ndz,r,g,b,0.5,shield);  	    if (texture) +	    {  		m.setTexture(id); +	    }  	    mv.push_back(m); -	    } +	} +    }  } @@ -702,27 +746,27 @@ static void HandleCollision(Config::Collide collide,      int shield;      switch(collide) -    	{ +    {  	case Config::merge:  	    if (m1.getMass()>=m2.getMass()) -	    	{ +	    {  		win=&m1;  		lose=&m2;  		del[idx2]=true; -		} +	    }  	    else -	    	{ +	    {  		win=&m2;  		lose=&m1;  		del[idx1]=true; -		} +	    }  	    merge_mass=win->getMass()+lose->getMass();  	    win->reset(merge_mass);  	    if (sparks) -	    	{ +	    {  		double x1,y1,z1;  		double x2,y2,z2; @@ -730,25 +774,25 @@ static void HandleCollision(Config::Collide collide,  		m2.getPosition(x2,y2,z2);  		sparks->add(x1+(x2-x1)/2, -			    y1+(y2-y1)/2, -			    z1+(z2-z1)/2); -		} +			y1+(y2-y1)/2, +			z1+(z2-z1)/2); +	    }  	    break;  	case Config::delta_merge:  	    if (m1.getMass()>=m2.getMass()) -	    	{ +	    {  		win=&m1;  		lose=&m2;  		del[idx2]=true; -		} +	    }  	    else -	    	{ +	    {  		win=&m2;  		lose=&m1;  		del[idx1]=true; -		} +	    }  	    win->getDelta(odx,ody,odz);  	    lose->getDelta(dx,dy,dz); @@ -762,7 +806,7 @@ static void HandleCollision(Config::Collide collide,  	    win->reset(merge_mass,odx,ody,odz);  	    if (sparks) -	    	{ +	    {  		double x1,y1,z1;  		double x2,y2,z2; @@ -770,9 +814,9 @@ static void HandleCollision(Config::Collide collide,  		m2.getPosition(x2,y2,z2);  		sparks->add(x1+(x2-x1)/2, -			    y1+(y2-y1)/2, -			    z1+(z2-z1)/2); -		} +			y1+(y2-y1)/2, +			z1+(z2-z1)/2); +	    }  	    break; @@ -780,23 +824,23 @@ static void HandleCollision(Config::Collide collide,  	    config.getShatter(no,delta,min,max,shield);  	    if (m1.getMass()<min || m2.getMass()<min) -		{ +	    {  		HandleCollision(Config::merge,del,mv,m1,m2,idx1,idx2);  		return; -		} +	    }  	    if ((m1.getMass()<max && m2.getMass()>=max) ||  		    (m2.getMass()<max && m1.getMass()>=max)) -		{ +	    {  		HandleCollision(Config::merge,del,mv,m1,m2,idx1,idx2);  		return; -		} +	    }  	    Shatter(mv,m1,no,delta,shield);  	    Shatter(mv,m2,no,delta,shield);  	    if (sparks) -	    	{ +	    {  		double x1,y1,z1;  		double x2,y2,z2; @@ -804,9 +848,9 @@ static void HandleCollision(Config::Collide collide,  		m2.getPosition(x2,y2,z2);  		sparks->add(x1+(x2-x1)/2, -			    y1+(y2-y1)/2, -			    z1+(z2-z1)/2); -		} +			y1+(y2-y1)/2, +			z1+(z2-z1)/2); +	    }  	    del[idx1]=true;  	    del[idx2]=true; @@ -818,7 +862,7 @@ static void HandleCollision(Config::Collide collide,  	default:  	    break; -	} +    }  } @@ -832,24 +876,38 @@ static void Update(void)      new_mass=mass;      for(f=0;f<mass.size();f++) +    {      	del_mass.push_back(false); +    }      for(f=0;f<mass.size();f++) +    {      	for(r=0;r<mass.size();r++) +	{  	    if (f!=r && !del_mass[f] && !del_mass[r]) +	    {  	    	if (new_mass[f].calcAttraction(mass[r],config.gravConst())) +		{  		    HandleCollision  			    (config.collide(),  			     del_mass,new_mass,new_mass[f],mass[r],f,r); +		} +	    } +	} +    }      mass.clear();      for(f=0;f<new_mass.size();f++) +    {      	if (f>mass.size() || !del_mass[f]) +	{  	    mass.push_back(new_mass[f]); +	} +    }      for(f=0;f<mass.size();f++) -	{ +    {  	GLfloat r,g,b;  	double x,y,z;  	double px,py,pz; @@ -861,6 +919,7 @@ static void Update(void)  	mass[f].getPreviousPosition(px,py,pz);  	if (particles && !mass[f].isMassless()) +	{  	    particles->add(static_cast<GLfloat>(x),  			   static_cast<GLfloat>(y),  			   static_cast<GLfloat>(z), @@ -868,70 +927,95 @@ static void Update(void)  			   static_cast<GLfloat>(py),  			   static_cast<GLfloat>(pz),  			   r,g,b); -	} +    	} +    }      mva=(control.mx-(width/2))/(100.0f*width/800.0);      if (mva<-0.5 || mva>0.5) -	{ +    {  	camera.ang-=mva;  	if (camera.ang<0.0) +	{  	    camera.ang+=360.0; +	}  	else if (camera.ang>=360.0) +	{  	    camera.ang-=360.0;  	} +    }      if (control.pgup) +    {      	camera.y+=10; +    }      if (control.pgdn) +    {      	camera.y-=10; +    }      control.pgup=false;      control.pgdn=false;      if (control.lmb) -    	{ +    {  	if (camera.speed<20.0) +	{  	    camera.speed+=0.5; +	}  	if (control.ctrl) +	{  	    camera.speed*=10; +	}  	if (control.shift) -	    { +	{  	    camera.x+=(GLfloat)(sin(camera.ang*M_PI/180.0)*camera.speed);  	    camera.z+=(GLfloat)(cos(camera.ang*M_PI/180.0)*camera.speed); -	    } +	}  	else -	    { +	{  	    camera.x-=(GLfloat)(sin(camera.ang*M_PI/180.0)*camera.speed);  	    camera.z-=(GLfloat)(cos(camera.ang*M_PI/180.0)*camera.speed); -	    } +	}  	if (control.ctrl) +	{  	    camera.speed/=10;  	} +    }      else -    	{ +    {  	if (camera.speed>0.0) +	{  	    camera.speed-=0.5; +	}  	if (camera.speed<0.0) +	{  	    camera.speed+=0.5;  	} +    }      frame++;      if (sparks) +    {  	sparks->update(); +    }      if (particles) +    {  	particles->update(); +    }      if (!frame_skip || (frame%frame_skip)==0) +    {  	glutPostWindowRedisplay(win); +    }  } @@ -38,14 +38,14 @@ HEADERS	=	global.h	\  OBJECTS	=	$(SOURCES:.cpp=.o) -# NOTE1: Use these libs for GNU/linux.  They should work with any unix that has -#	 X11 too. +# NOTE1: Use these libs for GNU/linux.  They should give a head-start to any +#	 UNIX that has X11/OpenGL.  #  #LIBS	=	-L/usr/X11R6/lib -lglut -lGLU -lGL -lX11 -lXext -lXi -lXmu -lm  LIBS	=	-L/usr/X11R6/lib -lglut -lGLU -lGL -lX11 -lXext -lm -# NOTE2: Use thes libs for cygwin +# NOTE2: Use thes libs for cygwin -- currently broken  #  #LIBS	=	-lglut32 -lglu32 -lopengl32 @@ -69,9 +69,9 @@ Mass::Mass()  Mass::Mass(const string& name, double mass, double scale, -	   double posx, double posy, double posz, -	   double dx, double dy, double dz, -	   GLfloat r, GLfloat g, GLfloat b, double rot, int shield) +	double posx, double posy, double posz, +	double dx, double dy, double dz, +	GLfloat r, GLfloat g, GLfloat b, double rot, int shield)  {      m_name=name; @@ -97,12 +97,14 @@ Mass::Mass(const string& name, double mass, double scale,      m_shield=shield;      if (m_mass<=0.0) -	{ -    	m_mass=0.0001; +    { +	m_mass=0.0001;  	m_massless=true; -	} +    }      else -    	m_massless=false; +    { +	m_massless=false; +    }      m_ring=false;      m_ring_textured=false; @@ -126,8 +128,8 @@ Mass::~Mass()  // ---------------------------------------- PUBLIC MEMBERS  //  void Mass::setRing(double from, double to,  -		   GLfloat r, GLfloat g, GLfloat b, GLfloat alpha, -		   double rot, double ang) +	GLfloat r, GLfloat g, GLfloat b, GLfloat alpha, +	double rot, double ang)  {      m_ring=true;      m_ring_from=from; @@ -159,10 +161,10 @@ bool Mass::getTexture(GLuint& id) const  void Mass::setRingTexture(GLuint id)  {      if (m_ring) -    	{ +    {  	m_ring_textured=true;  	m_ring_id=id; -	} +    }  } @@ -238,12 +240,14 @@ void Mass::reset(double mass, double dx, double dy, double dz)      m_dz=dz;      if (m_mass<=0.0) -	{ -    	m_mass=0.0001; +    { +	m_mass=0.0001;  	m_massless=true; -	} +    }      else -    	m_massless=false; +    { +	m_massless=false; +    }  } @@ -253,12 +257,14 @@ void Mass::reset(double mass)      calcSize();      if (m_mass<=0.0) -	{ -    	m_mass=0.0001; +    { +	m_mass=0.0001;  	m_massless=true; -	} +    }      else -    	m_massless=false; +    { +	m_massless=false; +    }  } @@ -270,37 +276,59 @@ bool Mass::calcAttraction(Mass& m, double gr_const)      double dx,dy,dz;      if (m.m_massless) -    	return false; +    { +	return false; +    }      dist=calcDistance2(m,dx,dy,dz);      if (dist==0.0) -    	return !m_massless; +    { +	return !m_massless; +    }      if (dist<(m_size + m.m_size) && (m_shield==0 || m.m_shield==0)) -    	collide=true; +    { +	collide=true; +    }      else -    	collide=false; +    { +	collide=false; +    } + +    // ga=((gr_const*m.m_mass)*(gr_const*m_mass))/(dist*gr_const); -    ga=((gr_const*m.m_mass)*(gr_const*m_mass))/(dist*gr_const); +    ga=gr_const * (m_mass / dist);      if (m_x<m.m_x) +    {  	m_dx+=ga/(m_mass/dx); +    }      if (m_x>m.m_x) +    {  	m_dx-=ga/(m_mass/dx); +    }      if (m_y<m.m_y) +    {  	m_dy+=ga/(m_mass/dy); +    }      if (m_y>m.m_y) +    {  	m_dy-=ga/(m_mass/dy); +    }      if (m_z<m.m_z) +    {  	m_dz+=ga/(m_mass/dz); +    }      if (m_z>m.m_z) +    {  	m_dz-=ga/(m_mass/dz); +    }      return collide && !m_massless;  } @@ -320,7 +348,9 @@ void Mass::move()      m_ring_ang+=m_ring_rot;      if (m_shield) -    	m_shield--; +    { +	m_shield--; +    }  } @@ -330,7 +360,7 @@ void Mass::draw(bool solid, bool texture, Mass::DrawItem item) const      GLUquadric *q;      if (m_massless && item==eMass) -    	{ +    {  	GLboolean l=glIsEnabled(GL_LIGHTING);  	glDisable(GL_LIGHTING); @@ -340,65 +370,79 @@ void Mass::draw(bool solid, bool texture, Mass::DrawItem item) const  	glEnd();  	if (l) +	{  	    glEnable(GL_LIGHTING);  	} +    }      else -	{ +    {  	// Render the object  	//  	if (item==eMass && (q=gluNewQuadric())) -	    { +	{  	    glColor4f(m_r,m_g,m_b,1.0f);  	    glTranslated(m_x,m_y,m_z);  	    if (!solid) +	    {  		gluQuadricDrawStyle(q,GLU_LINE); +	    }  	    gluQuadricNormals(q,GLU_SMOOTH);  	    if (m_textured && texture && solid) -		{ +	    {  		glEnable(GL_TEXTURE_2D);  		glBindTexture(GL_TEXTURE_2D,m_texture_id);  		gluQuadricTexture(q,1); -		} +	    }  	    else +	    {  		glDisable(GL_TEXTURE_2D); +	    }  	    if (m_ang!=0.0) +	    {  		glRotated(m_ang,0.0,1.0,0.0); +	    }  	    glRotated(90.0,1.0,0.0,0.0);  	    gluSphere(q,m_size,sp,sp);  	    gluDeleteQuadric(q); -	    } +	}  	// Render the ring (if present)  	//  	if (m_ring && item==eRing && (q=gluNewQuadric())) -	    { +	{  	    glColor4f(m_rr,m_rg,m_rb,m_ring_alpha);  	    glTranslated(m_x,m_y,m_z);  	    if (!solid) +	    {  		gluQuadricDrawStyle(q,GLU_LINE); +	    }  	    gluQuadricNormals(q,GLU_SMOOTH);  	    if (m_ring_textured && texture && solid) -		{ +	    {  		glEnable(GL_TEXTURE_2D);  		glBindTexture(GL_TEXTURE_2D,m_ring_id);  		gluQuadricTexture(q,1); -		} +	    }  	    else +	    {  		glDisable(GL_TEXTURE_2D); +	    }  	    glRotated(m_ring_tilt,1.0,0.0,0.0);  	    if (m_ring_ang!=0.0) +	    {  		glRotated(-m_ring_ang,0.0,0.0,1.0); +	    }  	    gluDisk(q,m_size*m_ring_from,m_size*m_ring_to,sp,1); @@ -409,8 +453,8 @@ void Mass::draw(bool solid, bool texture, Mass::DrawItem item) const  	    gluDisk(q,m_size*m_ring_from,m_size*m_ring_to,sp,1);  	    gluDeleteQuadric(q); -	    }  	} +    }  } @@ -432,7 +476,9 @@ void Mass::calcSize()      m_size=pow(m_size,0.333333333333333333333)*m_scale;      if (m_size<1.0) -    	m_size=1.0; +    { +	m_size=1.0; +    }  } @@ -441,13 +487,13 @@ void Mass::calcSize()  ostream& operator<<(ostream& os, const Mass& m)  {      os << "Name " << m.m_name << "  (mass " << m.m_mass -       << ", size " << m.m_size << ", shield " << m.m_shield << ")"  << endl -       << "    P (" << m.m_x << ", " << m.m_y << ", " << m.m_z << ")" << endl -       << "    D (" << m.m_dx << ", " << m.m_dy << ", " << m.m_dz << ")" << endl -       << "    R (" << m.m_rot << ", " << m.m_ang << ")" << endl -       << "    T (" << m.m_textured << ", " << m.m_texture_id << ")" << endl -       << " Ring (" << m.m_ring << ", " << m.m_ring_from  -	    << ", " << m.m_ring_to << ")" << endl; +	<< ", size " << m.m_size << ", shield " << m.m_shield << ")"  << endl +	<< "    P (" << m.m_x << ", " << m.m_y << ", " << m.m_z << ")" << endl +	<< "    D (" << m.m_dx << ", " << m.m_dy << ", " << m.m_dz << ")" << endl +	<< "    R (" << m.m_rot << ", " << m.m_ang << ")" << endl +	<< "    T (" << m.m_textured << ", " << m.m_texture_id << ")" << endl +	<< " Ring (" << m.m_ring << ", " << m.m_ring_from  +	<< ", " << m.m_ring_to << ")" << endl;      return os;  } @@ -458,11 +504,13 @@ bool findMass(vector<Mass>& m, const string& name, Mass& ret)      vector<Mass>::const_iterator i;      for(i=m.begin();i!=m.end();i++) +    {  	if (i->getName()==name) -	    { +	{  	    ret=*i;  	    return true; -	    } +	} +    }      return false;  } @@ -470,8 +518,12 @@ bool findMass(vector<Mass>& m, const string& name, Mass& ret)  bool findMass(vector<Mass>& m, const string& name, vector<Mass>::size_type& i)  {      for(i=0;i<m.size();i++) +    {  	if (m[i].getName()==name) +	{  	    return true; +	} +    }      return false;  } @@ -30,100 +30,100 @@  #include "global.h"  class Mass -    { -    public: -	enum DrawItem {eMass, eRing}; - -	Mass(); -    	Mass(const string& name, double mass, double scale, -	     double posx, double posy, double posz, -	     double dx, double dy, double dz, -	     GLfloat r, GLfloat g, GLfloat b, -	     double rot, int sheild=0); -	virtual ~Mass(); - -	// Define a ring -	// -	void setRing(double from, double to,  -		     GLfloat r, GLfloat g, GLfloat b, GLfloat alpha, -		     double rot, double angle); - -	// Set up an Open GL texture ID to use.  It is assumed that -	// texturing is not used till this member is called. -	// -	// The get function returns true if a texture has been assigned. -	// -	void setTexture(GLuint id); -	bool getTexture(GLuint& id) const; - -	void setRingTexture(GLuint id); -	bool getRingTexture(GLuint& id) const; - -	// Get Mass information -	// -	string getName() const; -	double getMass() const; -	double getSize() const; -	void getPosition(double& x, double& y, double& z) const; -	void getPreviousPosition(double& x, double& y, double& z) const; -	void getDelta(double& dx, double& dy, double& dz) const; -	void getColour(GLfloat& r, GLfloat& g, GLfloat& b) const; - -	bool isMassless() const; - -	// All resetting of various controls for collisions -	// -	void reset(double mass, double dx, double dy, double dz); -	void reset(double mass); - -	// Attract the object to the provided mass.  Note that the supplied -	// mass is left unaltered. -	// -	// Returns true if the two objects have collided -	// -	bool calcAttraction(Mass& m, double gr_const); - -	// Move the mass along it's delta -	// -	void move(); - -	void draw(bool solid, bool texture, DrawItem item) const; - -	// Streaming -	// -	friend ostream& operator<<(ostream& os, const Mass& m); - -    private: -	string	m_name; -	double	m_size; -    	double	m_mass; -	double	m_scale; -	double	m_x,m_y,m_z; -	double	m_prevx,m_prevy,m_prevz; -	double	m_dx,m_dy,m_dz; -	GLfloat	m_r,m_g,m_b; - -	bool	m_massless; - -	double	m_rot; -	double	m_ang; - -	int	m_shield; - -	bool	m_textured; -	GLuint	m_texture_id; - -	bool	m_ring; -	double	m_ring_from,m_ring_to; -	double	m_ring_rot,m_ring_ang,m_ring_tilt; -	GLfloat	m_rr,m_rg,m_rb; -	GLfloat	m_ring_alpha; -	bool	m_ring_textured; -	GLuint	m_ring_id; - -	double	calcDistance2(Mass& m, double& dx, double& dy, double& dz); -	void	calcSize(); -    }; +{ +public: +    enum DrawItem {eMass, eRing}; + +    Mass(); +    Mass(const string& name, double mass, double scale, +	 double posx, double posy, double posz, +	 double dx, double dy, double dz, +	 GLfloat r, GLfloat g, GLfloat b, +	 double rot, int sheild=0); +    virtual ~Mass(); + +    // Define a ring +    // +    void setRing(double from, double to,  +		 GLfloat r, GLfloat g, GLfloat b, GLfloat alpha, +		 double rot, double angle); + +    // Set up an Open GL texture ID to use.  It is assumed that +    // texturing is not used till this member is called. +    // +    // The get function returns true if a texture has been assigned. +    // +    void setTexture(GLuint id); +    bool getTexture(GLuint& id) const; + +    void setRingTexture(GLuint id); +    bool getRingTexture(GLuint& id) const; + +    // Get Mass information +    // +    string getName() const; +    double getMass() const; +    double getSize() const; +    void getPosition(double& x, double& y, double& z) const; +    void getPreviousPosition(double& x, double& y, double& z) const; +    void getDelta(double& dx, double& dy, double& dz) const; +    void getColour(GLfloat& r, GLfloat& g, GLfloat& b) const; + +    bool isMassless() const; + +    // All resetting of various controls for collisions +    // +    void reset(double mass, double dx, double dy, double dz); +    void reset(double mass); + +    // Attract the object to the provided mass.  Note that the supplied +    // mass is left unaltered. +    // +    // Returns true if the two objects have collided +    // +    bool calcAttraction(Mass& m, double gr_const); + +    // Move the mass along it's delta +    // +    void move(); + +    void draw(bool solid, bool texture, DrawItem item) const; + +    // Streaming +    // +    friend ostream& operator<<(ostream& os, const Mass& m); + +private: +    string	m_name; +    double	m_size; +    double	m_mass; +    double	m_scale; +    double	m_x,m_y,m_z; +    double	m_prevx,m_prevy,m_prevz; +    double	m_dx,m_dy,m_dz; +    GLfloat	m_r,m_g,m_b; + +    bool	m_massless; + +    double	m_rot; +    double	m_ang; + +    int		m_shield; + +    bool	m_textured; +    GLuint	m_texture_id; + +    bool	m_ring; +    double	m_ring_from,m_ring_to; +    double	m_ring_rot,m_ring_ang,m_ring_tilt; +    GLfloat	m_rr,m_rg,m_rb; +    GLfloat	m_ring_alpha; +    bool	m_ring_textured; +    GLuint	m_ring_id; + +    double	calcDistance2(Mass& m, double& dx, double& dy, double& dz); +    void	calcSize(); +};  // Routine to find masses from a vector of them @@ -30,51 +30,59 @@  #include "global.h"  template <class Ty> class Matrix +{ +public: +    Matrix()      { -    public: -    	Matrix() -	{ -	    int a,b; - -	    for(a=0;a<3;a++) -		for(b=0;b<3;b++) -		    mat[a][b]=0; -	} +	int a,b; -	~Matrix() +	for(a=0;a<3;a++)  	{ +	    for(b=0;b<3;b++) +	    { +		mat[a][b]=0; +	    }  	} +    } -	void identity() -	{ -	    int a,b; +    ~Matrix() +    { +    } -	    for(a=0;a<3;a++) -		for(b=0;b<3;b++) -		    mat[a][b]=(a==b) ? 1:0; -	} +    void identity() +    { +	int a,b; -	void set(Ty x, Ty y, Ty z) +	for(a=0;a<3;a++)  	{ -	    identity(); -	    mat[0][0]=x; -	    mat[1][1]=y; -	    mat[2][2]=z; -	    mat[3][3]=1; +	    for(b=0;b<3;b++) +	    { +		mat[a][b]=(a==b) ? 1:0; +	    }  	} +    } -	void get(Ty& x, Ty& y, Ty& z) -	{ -	    x=mat[0][0]; -	    y=mat[1][1]; -	    z=mat[2][2]; -	} +    void set(Ty x, Ty y, Ty z) +    { +	identity(); +	mat[0][0] = x; +	mat[1][1] = y; +	mat[2][2] = z; +	mat[3][3] = 1; +    } + +    void get(Ty& x, Ty& y, Ty& z) +    { +	x = mat[0][0]; +	y = mat[1][1]; +	z = mat[2][2]; +    } -	Matrix& operator*(Matrix<Ty>& m); +    Matrix& operator*(Matrix<Ty>& m); -    private: -	Ty	mat[4][4]; -    }; +private: +    Ty	mat[4][4]; +};  #endif diff --git a/particles.cpp b/particles.cpp index 2603397..2bd9139 100644 --- a/particles.cpp +++ b/particles.cpp @@ -66,13 +66,13 @@ void Particles::draw()      glBegin(GL_LINES);      for(i=m_list.begin();i!=m_list.end();i++) -	{ +    {  	i->a-=m_alpha_dec;  	glColor4f(i->r,i->g,i->b,i->a);  	glVertex3f(i->x1,i->y1,i->z1);  	glVertex3f(i->x2,i->y2,i->z2); -	} +    }      glEnd();  } @@ -85,17 +85,19 @@ void Particles::update()      // Delete dead particles      //      i=m_list.begin(); -     +      while ((i!=m_list.end())&&(i->a<=m_alpha_min)) -    	{ +    {  	m_list.pop_front();  	i=m_list.begin(); -	} +    }      // Update them      //      for(i=m_list.begin();i!=m_list.end();i++) +    {  	i->a-=m_alpha_dec; +    }  }  // END OF FILE // diff --git a/particles.h b/particles.h index 2619fb1..226dbf2 100644 --- a/particles.h +++ b/particles.h @@ -31,31 +31,31 @@  #include <list>  class Particles +{ +public: +    Particles(GLfloat alpha_dec, GLfloat alpha_min); +    virtual ~Particles(); + +    void add(GLfloat x1, GLfloat y1, GLfloat z1, +	     GLfloat x2, GLfloat y2, GLfloat z2, +	     GLfloat r, GLfloat g, GLfloat b); + +    void draw(); +    void update(); + +private: +    struct Point      { -    public: -    	Particles(GLfloat alpha_dec, GLfloat alpha_min); -	virtual ~Particles(); - -	void add(GLfloat x1, GLfloat y1, GLfloat z1, -		 GLfloat x2, GLfloat y2, GLfloat z2, -		 GLfloat r, GLfloat g, GLfloat b); - -	void draw(); -	void update(); - -    private: -    	struct Point -	    { -	    GLfloat	r,g,b,a; -	    GLfloat	x1,y1,z1; -	    GLfloat	x2,y2,z2; -	    }; - -	list<Point>		m_list; -	GLfloat			m_alpha_dec; -	GLfloat			m_alpha_min; +	GLfloat	r,g,b,a; +	GLfloat	x1,y1,z1; +	GLfloat	x2,y2,z2;      }; +    list<Point>		m_list; +    GLfloat		m_alpha_dec; +    GLfloat		m_alpha_min; +}; +  #endif  // END OF FILE // @@ -27,7 +27,7 @@ static const char id[]="$Id$";  #include "sparks.h"  Sparks::Sparks(int num, GLfloat alpha_dec, GLfloat alpha_min, -	       int len, GLfloat delta) +	int len, GLfloat delta)  {      m_num=max(num,1);      m_alpha_dec=alpha_dec; @@ -53,7 +53,7 @@ void Sparks::add(GLfloat ox, GLfloat oy, GLfloat oz)      p.life=m_life;      for(f=0;f<m_num;f++) -    	{ +    {  	p.dx=DRand()*m_delta*2-m_delta;  	p.dy=DRand()*m_delta*2-m_delta;  	p.dz=DRand()*m_delta*2-m_delta; @@ -65,7 +65,7 @@ void Sparks::add(GLfloat ox, GLfloat oy, GLfloat oz)  	p.alpha=1.0f;  	m_list.push_back(p); -	} +    }  } @@ -76,17 +76,17 @@ void Sparks::update()      // Delete dead sparks      //      i=m_list.begin(); -     +      while ((i!=m_list.end())&&(i->alpha<=m_alpha_min)) -    	{ +    {  	m_list.pop_front();  	i=m_list.begin(); -	} +    }      // Update them      //      for(i=m_list.begin();i!=m_list.end();i++) -    	{ +    {  	i->x1+=i->dx;  	i->y1+=i->dy;  	i->z1+=i->dz; @@ -96,7 +96,7 @@ void Sparks::update()  	i->z2+=i->dz;  	i->alpha-=m_alpha_dec; -	} +    }  } @@ -109,12 +109,12 @@ void Sparks::draw()      glBegin(GL_LINES);      for(i=m_list.begin();i!=m_list.end();i++) -    	{ +    {  	glColor4f(1.0,1.0,0.0,i->alpha);  	glVertex3f(i->x1,i->y1,i->z1);  	glColor4f(0.5,0.0,0.0,i->alpha);  	glVertex3f(i->x2,i->y2,i->z2); -	} +    }      glEnd();  } @@ -31,37 +31,37 @@  #include <list>  class Sparks -    { -    public: -    	Sparks(int num, GLfloat alpha_dec, GLfloat alpha_min, -	       int len, GLfloat delta); -	virtual ~Sparks(); +{ +public: +    Sparks(int num, GLfloat alpha_dec, GLfloat alpha_min, +	   int len, GLfloat delta); +    virtual ~Sparks(); -	void add(GLfloat ox, GLfloat oy, GLfloat oz); +    void add(GLfloat ox, GLfloat oy, GLfloat oz); -	void draw(); +    void draw(); -	void update(); +    void update(); -    private: -    	struct Point -	    { -	    GLfloat	x1,y1,z1; -	    GLfloat	x2,y2,z2; -	    GLfloat	dx,dy,dz; -	    GLfloat	alpha; -	    int		life; -	    }; +private: +    struct Point +    { +	GLfloat	x1,y1,z1; +	GLfloat	x2,y2,z2; +	GLfloat	dx,dy,dz; +	GLfloat	alpha; +	int		life; +    }; -	list<Point>		m_list; +    list<Point>		m_list; -	int			m_num; -	GLfloat			m_alpha_min; -	GLfloat			m_alpha_dec; -	int			m_life; -	int			m_len; -	GLfloat			m_delta; -    }; +    int			m_num; +    GLfloat		m_alpha_min; +    GLfloat		m_alpha_dec; +    int			m_life; +    int			m_len; +    GLfloat		m_delta; +};  #endif diff --git a/test1.dat b/test1.dat new file mode 100644 index 0000000..d98a851 --- /dev/null +++ b/test1.dat @@ -0,0 +1,51 @@ +# For this test the two objects should fall into the centre with the same +# acceleration, independent of their mass. +# +camera 0.0, 0.0, -1000.0, 0.0; + +enable solid; +enable lighting; +disable texture; + +collide none; + +const 0.001; + +scale 10; + + +body 	centre, +	100, +	0,0,0, +	0,0,0, +	1,1,1, +	0; + +light centre,1,1,1; + + +plane xy; + +radial	mass1, +	1, +	centre, +	500, +	90, +	0, +	1,0,0, +	0; + +radial	mass2, +	2, +	centre, +	500, +	270, +	0, +	0,1,0, +	0; + +look centre; +look mass1; +look mass2; + +look_at centre; diff --git a/test2.dat b/test2.dat new file mode 100644 index 0000000..48b7c27 --- /dev/null +++ b/test2.dat @@ -0,0 +1,53 @@ +# For this test the two objects should orbit around the centre with the same +# acceleration, independent of their mass. +# +camera 0.0, 0.0, -1000.0, 0.0; + +enable solid; +enable lighting; +disable texture; + +collide none; + +const 0.001; + +scale 10; + + +body 	centre, +	100, +	0,0,0, +	0,0,0, +	1,1,1, +	0; + +light centre,1,1,1; + + +plane xy; + +radial	mass1, +	1, +	centre, +	300, +	90, +	1, +	1,0,0, +	0; + +radial	mass2, +	2, +	centre, +	300, +	270, +	1, +	0,1,0, +	0; + +look centre; +look mass1; +look mass2; + +look_at centre; + +particles 0.0001,0.0,1.0; | 
