Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

physics/Solid.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002   Copyright (C)1996 David Jung <opensim@pobox.com>
00003 
00004   This program/file is free software; you can redistribute it and/or modify
00005   it under the terms of the GNU General Public License as published by
00006   the Free Software Foundation; either version 2 of the License, or
00007   (at your option) any later version.
00008   
00009   This program is distributed in the hope that it will be useful,
00010   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012   GNU General Public License for more details. (http://www.gnu.org)
00013   
00014   You should have received a copy of the GNU General Public License
00015   along with this program; if not, write to the Free Software
00016   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017   
00018   $Id: Solid.cpp 1031 2004-02-11 20:46:36Z jungd $
00019   $Revision: 1.7 $
00020   $Date: 2004-02-11 15:46:36 -0500 (Wed, 11 Feb 2004) $
00021   $Author: jungd $
00022  
00023 ****************************************************************************/
00024 
00025 #include <physics/Solid>
00026 #include <base/ref>
00027 
00028 #include <osg/Node>
00029 #include <osg/Transform>
00030 #include <osg/Geode>
00031 
00032 using physics::Solid;
00033 using physics::Shape;
00034 using physics::Material;
00035 using physics::CollisionModel;
00036 using physics::MassProperties;
00037 
00038 using osg::Node;
00039 using osg::MatrixTransform;
00040 using osg::Geode;
00041 
00042 
00043 Solid::Solid(ref<const Shape> shape, ref<const Material> material)
00044   : Body(shape), material(material)
00045 {
00046 }
00047 
00048 Solid::Solid(const Solid& s)
00049   : Body(s), material(s.material)
00050 {
00051 }
00052 
00053 Solid::~Solid() 
00054 {
00055 }
00056 
00057 
00058 
00059 MassProperties Solid::massProperties() const
00060 {
00061   // not cached in Solid, so calculate from shape & material
00062   //  (concrete derived Solids typically cache mass properties as it is expensive to
00063   //   compute)
00064   MassProperties massProps;
00065   try {
00066 
00067     massProps = getShape()->getMassProperties(material);
00068 
00069   } catch (std::exception& e) {
00070     Logln("Couldn't calculate Mass properties of shape " << getShape()->className() << ", using default.");
00071 
00072     // Set to the mass properties of the bounding box
00073     BoundingBox bb(getShape()->getBoundingBox());
00074     Real dx = bb.getDimension().x;
00075     Real dy = bb.getDimension().y;
00076     Real dz = bb.getDimension().z;
00077 
00078     Real volume = dx*dy*dz;
00079     if (base::equals(volume,0)) {
00080       Logln("Warning: Bounding box of shape is empty.");
00081       dx=dy=dz=volume=1.0;
00082     }
00083 
00084     massProps.mass = volume*material->density();
00085     Real k = massProps.mass/12.0;
00086     Matrix3 Ibody;
00087     Ibody(1,1) = (dy*dy + dz*dz)*k;
00088     Ibody(2,2) = (dx*dx + dz*dz)*k;
00089     Ibody(3,3) = (dx*dx + dy*dy)*k;
00090     massProps.setIbody(Ibody);
00091   }
00092   return massProps;
00093 }
00094 
00095 
00096 
00097 
00098 
00099 
00100 
00101 
00102 void Solid::updateVisual()
00103 {
00104   if (node != 0) {
00105     // sync OSGVisual with current state
00106     Matrix4 m(getOrientation());
00107     m.setTranslationComponent(getPosition());
00108     worldTransform->setMatrix(m);
00109   }
00110 }
00111 
00112 
00113 osg::Node* Solid::createOSGVisual(Visual::Attributes visualAttributes) const
00114 {
00115   if ((node!=0) && (attributes==visualAttributes))
00116     return &(*node);
00117 
00118   if (!getShape()->visualTypeSupported(OSGVisual))
00119     throw std::runtime_error(Exception("Shape doesn't support OSGVisual"));
00120 
00121   osg::Node& shapeNode = *getShape()->createOSGVisual(visualAttributes);
00122 
00123   // Setup Material
00124   if (!getShape()->includesAppearance()) {
00125     shapeNode.setStateSet( &(*material->createState()) );
00126   }
00127 
00128   //  if (visualAttributes & Visual::ShowEdges)
00129   
00130   MatrixTransform* transform = new MatrixTransform();
00131   transform->setName(className());
00132   transform->addChild(&shapeNode);
00133   worldTransform = transform;
00134   
00135   Matrix4 m(getOrientation());
00136   m.setTranslationComponent(getPosition());
00137   worldTransform->setMatrix(m);
00138 
00139   if (visualAttributes & Visual::ShowCollisionModel) {
00140     ref<CollisionModel> collisionModel = getShape()->getCollisionModel(CollisionModel::AnyModel);
00141     if (collisionModel->visualTypeSupported(OSGVisual))
00142       transform->addChild( collisionModel->createOSGVisual(visualAttributes) );
00143   }
00144 
00145   node = transform;
00146   
00147   return &(*node);
00148 }

Generated on Thu Jul 29 15:56:29 2004 for OpenSim by doxygen 1.3.6