summaryrefslogtreecommitdiff
path: root/mass.cpp
diff options
context:
space:
mode:
authorIan C <ianc@noddybox.co.uk>2006-05-02 19:12:46 +0000
committerIan C <ianc@noddybox.co.uk>2006-05-02 19:12:46 +0000
commit99778e9b85bd4a16a9055587a273446068577100 (patch)
tree5bd5c5a0fb48f52f306a2a8b19de200800ada7df /mass.cpp
parentf77e2736cea27ddbcaa44ffb28b326846891029e (diff)
This commit was generated by cvs2svn to compensate for changes in r2,
which included commits to RCS files with non-trunk default branches.
Diffstat (limited to 'mass.cpp')
-rw-r--r--mass.cpp479
1 files changed, 479 insertions, 0 deletions
diff --git a/mass.cpp b/mass.cpp
new file mode 100644
index 0000000..e83cf55
--- /dev/null
+++ b/mass.cpp
@@ -0,0 +1,479 @@
+//
+// 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
+//
+// -------------------------------------------------------------------------
+//
+// Mass
+//
+static const char id[]="$Id$";
+
+#include "mass.h"
+
+
+// ---------------------------------------- CONSTRUCT/DESTRUCT/ASSIGN
+//
+Mass::Mass()
+{
+ m_name="";
+
+ m_massless=false;
+ m_mass=1.0;
+ m_scale=1.0;
+ calcSize();
+
+ m_x=0.0;
+ m_y=0.0;
+ m_z=0.0;
+
+ m_dx=0.0;
+ m_dy=0.0;
+ m_dz=0.0;
+
+ m_r=1.0;
+ m_g=1.0;
+ m_b=1.0;
+
+ m_shield=0;
+
+ m_textured=false;
+ m_texture_id=0;
+
+ m_ring=false;
+ m_ring_textured=false;
+ m_ring_id=0;
+ m_rr=0.0;
+ m_rg=0.0;
+ m_rb=0.0;
+ m_ring_alpha=1.0;
+
+ m_prevx=m_x;
+ m_prevy=m_y;
+ m_prevz=m_z;
+}
+
+
+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)
+{
+ m_name=name;
+
+ m_mass=mass;
+ m_scale=scale;
+ calcSize();
+
+ m_x=posx;
+ m_y=posy;
+ m_z=posz;
+
+ m_dx=dx;
+ m_dy=dy;
+ m_dz=dz;
+
+ m_r=r;
+ m_g=g;
+ m_b=b;
+
+ m_rot=rot;
+ m_ang=0;
+
+ m_shield=shield;
+
+ if (m_mass<=0.0)
+ {
+ m_mass=0.0001;
+ m_massless=true;
+ }
+ else
+ m_massless=false;
+
+ m_ring=false;
+ m_ring_textured=false;
+ m_ring_id=0;
+ m_rr=0.0;
+ m_rg=0.0;
+ m_rb=0.0;
+ m_ring_alpha=1.0;
+
+ m_prevx=m_x;
+ m_prevy=m_y;
+ m_prevz=m_z;
+}
+
+
+Mass::~Mass()
+{
+}
+
+
+// ---------------------------------------- PUBLIC MEMBERS
+//
+void Mass::setRing(double from, double to,
+ GLfloat r, GLfloat g, GLfloat b, GLfloat alpha,
+ double rot, double ang)
+{
+ m_ring=true;
+ m_ring_from=from;
+ m_ring_to=to;
+ m_rr=r;
+ m_rg=g;
+ m_rb=b;
+ m_ring_alpha=alpha;
+ m_ring_rot=rot;
+ m_ring_tilt=ang;
+ m_ring_ang=0.0;
+}
+
+
+void Mass::setTexture(GLuint id)
+{
+ m_textured=true;
+ m_texture_id=id;
+}
+
+
+bool Mass::getTexture(GLuint& id) const
+{
+ id=m_texture_id;
+ return m_textured;
+}
+
+
+void Mass::setRingTexture(GLuint id)
+{
+ if (m_ring)
+ {
+ m_ring_textured=true;
+ m_ring_id=id;
+ }
+}
+
+
+bool Mass::getRingTexture(GLuint& id) const
+{
+ id=m_ring_id;
+ return m_ring_textured;
+}
+
+
+string Mass::getName() const
+{
+ return m_name;
+}
+
+
+double Mass::getMass() const
+{
+ return m_mass;
+}
+
+
+double Mass::getSize() const
+{
+ return m_size;
+}
+
+
+bool Mass::isMassless() const
+{
+ return m_massless;
+}
+
+
+void Mass::getPosition(double& x, double& y, double& z) const
+{
+ x=m_x;
+ y=m_y;
+ z=m_z;
+}
+
+
+void Mass::getPreviousPosition(double& x, double& y, double& z) const
+{
+ x=m_prevx;
+ y=m_prevy;
+ z=m_prevz;
+}
+
+
+void Mass::getDelta(double& dx, double& dy, double& dz) const
+{
+ dx=m_dx;
+ dy=m_dy;
+ dz=m_dz;
+}
+
+
+void Mass::getColour(GLfloat& r, GLfloat& g, GLfloat& b) const
+{
+ r=m_r;
+ g=m_g;
+ b=m_b;
+}
+
+
+void Mass::reset(double mass, double dx, double dy, double dz)
+{
+ m_mass=mass;
+ calcSize();
+ m_dx=dx;
+ m_dy=dy;
+ m_dz=dz;
+
+ if (m_mass<=0.0)
+ {
+ m_mass=0.0001;
+ m_massless=true;
+ }
+ else
+ m_massless=false;
+}
+
+
+void Mass::reset(double mass)
+{
+ m_mass=mass;
+ calcSize();
+
+ if (m_mass<=0.0)
+ {
+ m_mass=0.0001;
+ m_massless=true;
+ }
+ else
+ m_massless=false;
+}
+
+
+bool Mass::calcAttraction(Mass& m, double gr_const)
+{
+ bool collide;
+ double dist;
+ double ga;
+ double dx,dy,dz;
+
+ if (m.m_massless)
+ return false;
+
+ dist=calcDistance2(m,dx,dy,dz);
+
+ if (dist==0.0)
+ return !m_massless;
+
+ if (dist<(m_size + m.m_size) && (m_shield==0 || m.m_shield==0))
+ collide=true;
+ else
+ collide=false;
+
+ ga=((gr_const*m.m_mass)*(gr_const*m_mass))/(dist*gr_const);
+
+ 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;
+}
+
+
+void Mass::move()
+{
+ m_prevx=m_x;
+ m_prevy=m_y;
+ m_prevz=m_z;
+
+ m_x+=m_dx;
+ m_y+=m_dy;
+ m_z+=m_dz;
+
+ m_ang+=m_rot;
+ m_ring_ang+=m_ring_rot;
+
+ if (m_shield)
+ m_shield--;
+}
+
+
+void Mass::draw(bool solid, bool texture, Mass::DrawItem item) const
+{
+ const GLint sp=32;
+ GLUquadric *q;
+
+ if (m_massless && item==eMass)
+ {
+ GLboolean l=glIsEnabled(GL_LIGHTING);
+
+ glDisable(GL_LIGHTING);
+ glBegin(GL_POINTS);
+ glColor4f(m_r,m_g,m_b,1.0f);
+ glVertex3d(m_x,m_y,m_z);
+ 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);
+
+ glRotated(180.0,1.0,0.0,0.0);
+
+ glRotated(180.0,0.0,0.0,1.0);
+
+ gluDisk(q,m_size*m_ring_from,m_size*m_ring_to,sp,1);
+
+ gluDeleteQuadric(q);
+ }
+ }
+}
+
+
+// ---------------------------------------- PRIVATE MEMBERS
+//
+double Mass::calcDistance2(Mass& m, double& dx, double& dy, double& dz)
+{
+ dx=abs(m_x-m.m_x);
+ dy=abs(m_y-m.m_y);
+ dz=abs(m_z-m.m_z);
+
+ return sqrt((dx*dx)+(dy*dy)+(dz*dz));
+}
+
+
+void Mass::calcSize()
+{
+ m_size=m_mass*(3.0/4.0)*(1.0/M_PI);
+ m_size=pow(m_size,0.333333333333333333333)*m_scale;
+
+ if (m_size<1.0)
+ m_size=1.0;
+}
+
+
+// ---------------------------------------- OTHER FUNCTIONS
+//
+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;
+
+ return os;
+}
+
+
+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;
+}
+
+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;
+}
+
+// END OF FILE //