From 99778e9b85bd4a16a9055587a273446068577100 Mon Sep 17 00:00:00 2001 From: Ian C Date: Tue, 2 May 2006 19:12:46 +0000 Subject: This commit was generated by cvs2svn to compensate for changes in r2, which included commits to RCS files with non-trunk default branches. --- mass.cpp | 479 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 479 insertions(+) create mode 100644 mass.cpp (limited to 'mass.cpp') 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_xm.m_x) + m_dx-=ga/(m_mass/dx); + + if (m_ym.m_y) + m_dy-=ga/(m_mass/dy); + + if (m_zm.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& m, const string& name, Mass& ret) +{ + vector::const_iterator i; + + for(i=m.begin();i!=m.end();i++) + if (i->getName()==name) + { + ret=*i; + return true; + } + + return false; +} + +bool findMass(vector& m, const string& name, vector::size_type& i) +{ + for(i=0;i