Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

cylinder.cc

Go to the documentation of this file.
00001 /*
00002   svas_server -- virtual World Server of Svas
00003   Copyright (c) 2001, 2002 David Moreno Montero
00004  
00005  
00006   This program is free software; you can redistribute it and/or modify
00007   it under the terms of the GNU General Public License as published by
00008   the Free Software Foundation; either version 2 of the License, or
00009   (at your option) any later version.
00010  
00011   This program is distributed in the hope that it will be useful, but
00012   WITHOUT ANY WARRANTY; without even the implied warranty of
00013   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014   General Public License for more details.
00015  
00016   You should have received a copy of the GNU General Public License
00017   along with this program; if not, write to the Free Software
00018   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
00019   02111-1307, USA.  
00020 
00021 */
00022 
00023 #include <thread.h>
00024 #include <math.h>
00025 #include "cylinder.h"
00026 #include "log.h"
00027 #include "world.h"
00028 #include "agent.h"
00029 #include "collision.h"
00030 
00031 /**
00032  * It constructs the cylinder with the desired energy,
00033  * mass and position.
00034  *
00035  * There is also an Id of the cylinder into the agent. The main
00036  * cylinder is id=0, the rest are one more number, till 255, where no
00037  * more cylinders will be created.
00038  */
00039 Cylinder::Cylinder(World *_world, Cylinder *_father,
00040            double newEnergy, double newWidth, double newHeight, 
00041            Vector3d newGluePositionBody, bool onAgent){
00042   energy=newEnergy;
00043   width=newWidth;
00044   height=newHeight;
00045   mass=2*M_PI*width*width*height;
00046 
00047   if (onAgent)
00048     father=_father;
00049   world=_world;
00050 
00051   if (NULL==_father){ /// If I dont have father I'm rather anonymous, but @see setNewAgent()
00052     gluePosition=position=newGluePositionBody;
00053     gluePositionBody=Vector3d(0,0,0);
00054     orientationBase=Quaternion(Vector3d(0,1,0),0.1).normalize(); // Extrange orientation, to avoid staying up forever
00055     orientationWorld=orientationBase.toWorld(Vector3d(0,0,1));
00056     orientationWorld.normalize();
00057 
00058     agent=NULL;
00059     cylinderId=0;
00060   }
00061   else{ /// If I have father I depend from him...
00062     //    log <<newGluePositionBody.Y()<<endl;
00063     orientationBase=_father->orientationBase*
00064       Quaternion(Vector3d(0,0,1),newGluePositionBody.Y())*
00065       Quaternion(Vector3d(1,0,0),M_PI/2);
00066 
00067     gluePositionBody=newGluePositionBody;
00068 
00069     orientationWorld=orientationBase.toWorld(Vector3d(0,0,1));
00070 
00071     orientationWorld.normalize();
00072 
00073     gluePosition=position=(_father->orientationWorld*newGluePositionBody.X()*_father->height) + 
00074       (orientationWorld*_father->radius);
00075 
00076     
00077     if (onAgent)
00078       agent=_father->agent;
00079     else
00080       agent=NULL;
00081     cylinderId=agent->getCylinderCount(true);
00082   }
00083 
00084   /// FIXME to get father properties...
00085   velocity=Vector3d(0,0,0);
00086   force=Vector3d(0,0,0);
00087   moment=Vector3d(0,0,0);
00088   angularVelocity=Vector3d(0,0,0);
00089 
00090   updateMomentOfInertia();
00091 
00092   world->addCylinder(this);
00093 }
00094 
00095 /**
00096  * Change the agent parent of this cylinder. This is a consecuence of
00097  * a drop cylinder, when a new agent is born. We must make some little
00098  * things, but in general nothing important change.
00099  *
00100  * This call is only made to the new first-cylinder.
00101  **/
00102 void Cylinder::setNewAgent(Agent *_agent){
00103   unsigned long int i;
00104 
00105   // As it's done in reverse order, even (*this) is changed
00106   for (i=getNumCylinders();i--;){
00107     (*this)(i)->cylinderId=i;
00108     (*this)(i)->agent=_agent;
00109   }
00110   gluePosition=Vector3d(0,0,0);
00111   position=getPosition();
00112 
00113   father=NULL;
00114 }
00115 
00116 /** 
00117  * Free a little dynamically allocated memory
00118  */
00119 Cylinder::~Cylinder(){
00120   unsigned int i;
00121   for (i=son.size();i--;)
00122     delete son[i];
00123   world->delCylinder(this);
00124 }
00125 
00126 /**
00127  * Returns the cylinder with id=n, or NULL if there is not one
00128  */
00129 Cylinder *Cylinder::operator[](unsigned short int n){
00130   if (cylinderId==n)
00131     return this;
00132   unsigned long int i;
00133   for (i=son.size();i--;){
00134     Cylinder *ret;
00135     ret=(*son[i])[n];
00136     if (NULL!=ret)
00137       return ret;
00138   }
00139   return NULL;
00140 }
00141 
00142 /**
00143  * Returns the cylinder number=n, in this agent, or NULL if there is not one
00144  */
00145 Cylinder *Cylinder::operator()(unsigned short int n, unsigned short int &actual){
00146   if (n==actual)
00147     return this;
00148   unsigned long int i;
00149   for (i=son.size();i--;){
00150     Cylinder *ret;
00151     actual++;
00152     ret=(*son[i])(n, actual);
00153     if (NULL!=ret)
00154       return ret;
00155   }
00156   return NULL;
00157 }
00158 
00159 /**
00160  * Returns the number of cylinders that hangs from this one plus this
00161  * one
00162  */
00163 unsigned short int Cylinder::getNumCylinders(){
00164   unsigned int i;
00165   unsigned short int n=0;
00166   for (i=son.size();i--;)
00167     n+=son[i]->getNumCylinders();
00168   return n+1;
00169 }
00170 
00171 /**
00172  * Returns the distance between two cylinders, assuming that this is
00173  * the father of cyl (-1 if not)
00174  */
00175 signed short int Cylinder::dist(Cylinder *cyl){
00176   unsigned int i;
00177   signed int j;
00178   for (i=son.size();i--;)
00179     if (son[i]==cyl)
00180       return 1;
00181     else{
00182       j=son[i]->dist(cyl);
00183       if (j>0)
00184     return j+1;
00185     }
00186   return -1;
00187 }
00188 
00189 /**
00190  * Returns the position of the cylinder:
00191  *
00192  * * if relative is true, it returns the position relative to its parent,
00193  *
00194  * * if it's false, returns it relative to the world
00195  */
00196 Vector3d Cylinder::getPosition(bool relative){ 
00197   if (relative)
00198     return position;
00199   
00200   if (father!=NULL)
00201     return position+(father->getPosition(false));
00202   else
00203     return position;
00204 };
00205 
00206 /**
00207  * Returns the glue position of the cylinder:
00208  *
00209  * * if relative is true, it returns the position relative to its parent,
00210  *
00211  * * if it's false, returns it relative to the world
00212  */
00213 Vector3d Cylinder::getGluePosition(bool relative){ 
00214   if (relative)
00215     return gluePosition;
00216   
00217   if (father!=NULL)
00218     return gluePosition+(father->getGluePosition(false));
00219   else
00220     return gluePosition;
00221 };
00222 
00223 /**
00224  * Returns the centre of gravity. 
00225  *
00226  * The centre of gravity is the centre of this and of this sons.
00227  */
00228 Point3d Cylinder::getCentreOfGravity(void){
00229   return getPosition()+(orientationWorld*length/2);
00230 }
00231 
00232 
00233 /**
00234  * Returns the actual world of this cylinder
00235  */
00236 World *Cylinder::getWorld(){ 
00237   return world;
00238 }
00239 
00240 /**
00241  * Reutrns current mass, and, if true, the pending mass
00242  */
00243 double Cylinder::getMass(bool pending=false){
00244   if (!pending)
00245     return mass;
00246   
00247   long int i;
00248   double ret=0;
00249   for (i=getNumCylinders();i--;){
00250     ret+=(*this)(i)->getMass();
00251   }
00252   return ret;
00253 }

Generated on Mon Jun 17 19:53:44 2002 for Svas Server by doxygen1.2.16