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

physics/Cylinder.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: Cylinder.cpp 1031 2004-02-11 20:46:36Z jungd $
00019   $Revision: 1.10 $
00020   $Date: 2004-02-11 15:46:36 -0500 (Wed, 11 Feb 2004) $
00021   $Author: jungd $
00022  
00023 ****************************************************************************/
00024 
00025 #include <physics/Cylinder>
00026 
00027 #include <base/Externalizer>
00028 #include <gfx/VisualTriangles>
00029 #include <physics/Material>
00030 #include <physics/OBBCollisionModel>
00031 #include <physics/GJKCollisionModel>
00032 
00033 #include <osg/Group>
00034 #include <osg/Geode>
00035 #include <osg/LOD>
00036 #include <osg/ShapeDrawable>
00037 
00038 using physics::Cylinder;
00039 using physics::MassProperties;
00040 using physics::CollisionModel;
00041 using physics::OBBCollisionModel;
00042 using physics::GJKCollisionModel;
00043 
00044 using gfx::Segment3;
00045 using gfx::VisualTriangles;
00046 
00047 using osg::Node;
00048 using osg::Group;
00049 using osg::Geode;
00050 using osg::LOD;
00051 using osg::Vec3;
00052 using osg::Vec2;
00053 
00054 
00055 Cylinder::Cylinder() 
00056   : _height(1.0), _radius(1.0), massPropertiesCached(false)
00057 {
00058 }
00059 
00060 Cylinder::Cylinder(Real height, Real radius) 
00061   : _height(height), _radius(radius), massPropertiesCached(false)
00062 {
00063   if (_radius<0) _radius=consts::epsilon;
00064 }
00065 
00066 Cylinder::Cylinder(const Cylinder& c) 
00067   : _height(c._height), _radius(c._radius), massPropertiesCached(false)
00068 {
00069 }
00070 
00071 Cylinder::~Cylinder()
00072 {
00073 }
00074  
00075 
00076 const MassProperties& Cylinder::getMassProperties(ref<const Material> material) const 
00077 {
00078   if (massPropertiesCached && (density == material->density()))
00079     return massProperties;
00080 
00081   density = material->density();
00082   Real volume = consts::Pi*Math::sqr(_radius)*_height;
00083   massProperties.mass = volume*density;
00084 
00085   const Real m = massProperties.mass;
00086   Matrix3 Ibody;
00087   Ibody.e(1,1) = m*Math::sqr(_radius)/4.0 + m*Math::sqr(_height)/12.0;
00088   Ibody.e(2,2) = Ibody.e(1,1);
00089   Ibody.e(3,3) = m*Math::sqr(_radius)/2.0;
00090 
00091   massProperties.setIbody(Ibody);
00092   massProperties.centerOfMass = Point3(0.0,0.0,0.0);
00093 
00094   massPropertiesCached = true;
00095   return massProperties;
00096 }
00097 
00098 
00099 
00100 Segment3 Cylinder::shortestSegmentBetween(const base::Transform& t, const Point3& p) const
00101 {
00102   Unimplemented;
00103 }
00104 
00105 
00106 Segment3 Cylinder::shortestSegmentBetween(const base::Transform& t, const gfx::Segment3& s) const
00107 {
00108   Logln("Warning: Cylinder-Segment3 distance unimplemented");
00109   Point3 b(consts::maxInt, consts::maxInt, consts::maxInt);
00110   return Segment3(-b,b);
00111 }
00112 
00113 
00114 Segment3 Cylinder::shortestSegmentBetween(const base::Transform& t, const gfx::Triangle3& tri) const
00115 {
00116   Unimplemented;
00117 }
00118 
00119 
00120 Segment3 Cylinder::shortestSegmentBetween(const base::Transform& t, const gfx::Quad3& q) const
00121 {
00122   Unimplemented;
00123 }
00124 
00125 
00126 Segment3 Cylinder::shortestSegmentBetween(const base::Transform& t1, ref<const Shape> s, const base::Transform& t2) const
00127 {
00128   Unimplemented;
00129 }
00130 
00131 
00132 
00133 
00134 osg::Node* Cylinder::createOSGCylinder(Visual::Attributes visualAttributes,
00135                                        Int slices, Int stacks) const
00136 {
00137   bool onlyVerts = ((visualAttributes & Visual::VerticesOnly) != 0);
00138   
00139   osg::ref_ptr<osg::ShapeDrawable> shapeDrawable = new osg::ShapeDrawable(new osg::Cylinder(osg::Vec3(0.0f,0.0f,0.0f),radius(),height()));
00140   osg::ref_ptr<osg::TessellationHints> tessHints = new osg::TessellationHints();
00141   tessHints->setTargetNumFaces(slices*stacks);
00142   tessHints->setTessellationMode(osg::TessellationHints::USE_TARGET_NUM_FACES);
00143   tessHints->setCreateNormals(!onlyVerts);
00144   tessHints->setCreateTextureCoords(!onlyVerts);
00145   shapeDrawable->setTessellationHints(&(*tessHints));
00146 
00147   osg::Geode* geode = new osg::Geode();
00148   geode->addDrawable(&(*shapeDrawable));
00149   return geode;
00150 }
00151 
00152 
00153 
00154 osg::Node* Cylinder::createOSGVisual(Visual::Attributes visualAttributes) const
00155 {
00156   if ((node!=0) && (attributes==visualAttributes))
00157     return &(*node);
00158 
00159   Real r = Math::maximum(0.5,radius());
00160   Real h = Math::maximum(1.0,height());
00161 
00162   osg::Node* node0 = createOSGCylinder(visualAttributes, Int(52*r), (h<40)?Int(12*h):2000);
00163   osg::Node* node1 = createOSGCylinder(visualAttributes, Int(40*r), (h<40)?Int(8*h):1300);
00164   osg::Node* node2 = createOSGCylinder(visualAttributes, Int(20*r), (h<40)?Int(4*h):700);
00165   osg::Node* node3 = createOSGCylinder(visualAttributes, 8, 1);
00166   
00167   osg::LOD* lod = new osg::LOD();
00168   lod->setName("Cylinder");
00169   lod->addChild(node0);
00170   lod->addChild(node1);
00171   lod->addChild(node2);
00172   lod->addChild(node3);
00173 
00174   lod->setRange(0,0,2.0);
00175   lod->setRange(1,2.0,16.0);
00176   lod->setRange(2,16.0,120.0*Math::maximum(r,h));
00177   lod->setRange(3,120.0*Math::maximum(r,h),consts::Infinity);
00178 
00179   if (!(visualAttributes & Visual::ShowAxes))
00180     node = lod;
00181   else {
00182     Group* group = new Group();
00183     group->addChild( lod );
00184     group->addChild( createOSGAxes(base::Dimension3(2.0*radius(),2.0*radius(),height())) );
00185     node = group;
00186   }
00187 
00188   attributes = visualAttributes;
00189   return &(*node);
00190 }
00191 
00192 
00193 
00194 base::ref<CollisionModel> Cylinder::getCollisionModel(CollisionModel::CollisionModelType modelType) const
00195 {
00196   if ((collisionModel!=0) && 
00197       ((this->modelType==modelType) || (modelType==CollisionModel::AnyModel)))
00198     return collisionModel;
00199   
00200   collisionModel = Shape::getCollisionModel(modelType);
00201   this->modelType=modelType;
00202 
00203   return collisionModel;
00204 }
00205 
00206 
00207 void Cylinder::serialize(base::Serializer& s)
00208 {
00209   s(_height)(_radius);
00210 
00211   if (s.isInput()) {
00212     massPropertiesCached = false;
00213     node = 0;
00214     collisionModel = ref<CollisionModel>(0);
00215   }
00216 }
00217 
00218 
00219 
00220 bool Cylinder::formatSupported(String format, Real version, ExternalizationType type) const
00221 { 
00222   return ( (format=="xml") && (version==1.0) ); 
00223 }
00224 
00225 
00226 void Cylinder::externalize(base::Externalizer& e, String format, Real version)
00227 {
00228   if (format == "") format = "xml";
00229                                                                                                                                                                                                     
00230   if (!formatSupported(format,version,e.ioType()))
00231     throw std::invalid_argument(Exception(String("format ")+format+" v"+base::realToString(version)+" unsupported"));
00232                                                                                                                                                                                                     
00233   if (e.isOutput()) {
00234     Unimplemented;                                                                                                                                                                                                 
00235   }
00236   else {
00237     Unimplemented;                                                                                                                                                                                                 
00238   }
00239 }
00240 
00241 

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