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

physics/Cone.cpp

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

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