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

physics/Torus.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: Torus.cpp 1031 2004-02-11 20:46:36Z jungd $
00019   $Revision: 1.8 $
00020   $Date: 2004-02-11 15:46:36 -0500 (Wed, 11 Feb 2004) $
00021   $Author: jungd $
00022  
00023 ****************************************************************************/
00024 
00025 #include <physics/Torus>
00026 #include <physics/Material>
00027 #include <gfx/VisualTriangles>
00028 
00029 #include <osg/Group>
00030 #include <osg/Geode>
00031 #include <osg/LOD>
00032 
00033 
00034 using physics::Torus;
00035 using physics::MassProperties;
00036 using physics::CollisionModel;
00037 
00038 using gfx::Segment3;
00039 using gfx::VisualTriangles;
00040 
00041 using osg::Node;
00042 using osg::Group;
00043 using osg::Geode;
00044 using osg::LOD;
00045 using osg::Vec3;
00046 using osg::Vec2;
00047 
00048 
00049 Torus::Torus(Real innerRadius, Real outerRadius) 
00050   : _innerRadius(innerRadius), _outerRadius(outerRadius)
00051 {
00052 }
00053 
00054 Torus::Torus(const Torus& t) 
00055   : _innerRadius(t._innerRadius), _outerRadius(t._outerRadius)
00056 {
00057 }
00058 
00059 Torus::~Torus()
00060 {
00061 }
00062 
00063 
00064 const MassProperties& Torus::getMassProperties(ref<const Material> material) const 
00065 {
00066   if (massPropertiesCached && (density == material->density()))
00067     return massProperties;
00068 
00069   density = material->density();
00070   massProperties = MassProperties(VisualTriangles(*this),material);
00071 
00072   massPropertiesCached = true;
00073   return massProperties;
00074 }
00075 
00076 
00077 Segment3 Torus::shortestSegmentBetween(const base::Transform& t, const Point3& p) const
00078 {
00079   Unimplemented;
00080 }
00081 
00082 
00083 Segment3 Torus::shortestSegmentBetween(const base::Transform& t, const gfx::Segment3& s) const
00084 {
00085   Unimplemented;
00086 }
00087 
00088 
00089 Segment3 Torus::shortestSegmentBetween(const base::Transform& t, const gfx::Triangle3& tri) const
00090 {
00091   Unimplemented;
00092 }
00093 
00094 
00095 Segment3 Torus::shortestSegmentBetween(const base::Transform& t, const gfx::Quad3& q) const
00096 {
00097   Unimplemented;
00098 }
00099 
00100 
00101 Segment3 Torus::shortestSegmentBetween(const base::Transform& t1, ref<const Shape> s, const base::Transform& t2) const
00102 {
00103   Unimplemented;
00104 }
00105 
00106 
00107 
00108 osg::Node* Torus::createOSGTorus(Visual::Attributes visualAttributes,
00109                                  Int sides, Int rings) const
00110 {
00111   bool onlyVerts = ((visualAttributes & Visual::VerticesOnly) != 0);
00112 
00113   SInt i, j;
00114   Real theta, phi, theta1;
00115   Real cosTheta, sinTheta;
00116   Real cosTheta1, sinTheta1;
00117   Real ringDelta, sideDelta;
00118 
00119   Real cosPhi, sinPhi, dist;
00120 
00121   sideDelta = 2.0 * consts::Pi / Real(sides);
00122   ringDelta = 2.0 * consts::Pi / Real(rings);  
00123 
00124   theta = 0.0;
00125   cosTheta = 1.0;
00126   sinTheta = 0.0;
00127 
00128   array<Vec3>& coords = *new array<Vec3>(rings*(sides*2+2));
00129   array<Vec3>& normals = *new array<Vec3>(rings*(sides*2+2));
00130   //array<Vec2>& texCoords = *new array<Vec2>(rings*(sides*2+2)); // !!! implement
00131   array<int>& lengths = *new array<int>(rings);
00132   for(Int i=0; i<rings; i++)
00133     lengths[i] = sides*2+2;
00134 
00135   Int index=0;
00136 
00137   for (i = rings - 1; i>= 0;i--) {
00138     theta1 = theta + ringDelta;
00139     cosTheta1 = Math::cos(theta1);
00140     sinTheta1 = Math::sin(theta1);
00141 
00142     phi = (sides+1)*sideDelta;//0.0;
00143     for (j = sides; j>=0; j--) {
00144       phi = phi - sideDelta;
00145       cosPhi = Math::cos(phi);
00146       sinPhi = Math::sin(phi);
00147       dist = outerRadius() + (innerRadius() * cosPhi);
00148       
00149       if (!onlyVerts) {
00150         normals[index] = Vec3(cosTheta1 * cosPhi, sinPhi, -sinTheta1 * cosPhi);
00151         normals[index+1] = Vec3(cosTheta * cosPhi, sinPhi, -sinTheta * cosPhi);
00152       }
00153       coords[index] = Vec3(cosTheta1 * dist, innerRadius() * sinPhi, -sinTheta1 * dist);
00154       coords[index+1] = Vec3(cosTheta * dist, innerRadius() * sinPhi, -sinTheta * dist);
00155       index+=2;
00156       
00157     }
00158     theta = theta1;
00159     cosTheta = cosTheta1;
00160     sinTheta = sinTheta1;
00161   }
00162 
00163 
00164   GeoSet* torus = new GeoSet();
00165   torus->setPrimType(GeoSet::QUAD_STRIP);
00166   torus->setNumPrims(rings);
00167   torus->setCoords(coords.c_array());
00168   torus->setPrimLengths(lengths.c_array());
00169   if (!onlyVerts) {
00170     torus->setNormals(normals.c_array());
00171     torus->setNormalBinding(osg::GeoSet::BIND_PERVERTEX);
00172     //torus->setTextureCoords(texCoords.c_array());
00173     //torus->setTextureBinding(osg::GeoSet::BIND_PERVERTEX);
00174   }
00175 
00176   osg::Geode* geode = new osg::Geode();
00177   geode->addDrawable(torus);
00178 
00179   return geode;
00180 }
00181 
00182 
00183 osg::Node* Torus::createOSGVisual(Visual::Attributes visualAttributes) const
00184 {
00185   if ((node!=0) && (attributes==visualAttributes))
00186     return &(*node);
00187 
00188   Real ri = Math::maximum(1.0,innerRadius()*2.0);
00189   Real ro = Math::maximum(1.0,outerRadius()*2.0);
00190 
00191   osg::Node* node0 = createOSGTorus(visualAttributes, Int(22*ri), Int(22*ro));
00192   osg::Node* node1 = createOSGTorus(visualAttributes, Int(16*ri), Int(16*ro));
00193   osg::Node* node2 = createOSGTorus(visualAttributes, Int(8*ri), Int(12*ro));
00194   osg::Node* node3 = createOSGTorus(visualAttributes, 6, 8);
00195   
00196   osg::LOD* lod = new osg::LOD();
00197   lod->setName("Torus");
00198   lod->addChild(node0);
00199   lod->addChild(node1);
00200   lod->addChild(node2);
00201   lod->addChild(node3);
00202 
00203   lod->setRange(0,0,2.0);
00204   lod->setRange(1,2.0,16.0);
00205   lod->setRange(2,16.0,120.0*ro);
00206   lod->setRange(3,120.0*ro,consts::Infinity);
00207 
00208   if (!(visualAttributes & Visual::ShowAxes))
00209     node = lod;
00210   else {
00211     Group* group = new Group();
00212     group->addChild( lod );
00213     group->addChild( createOSGAxes(base::Dimension3(outerRadius(),innerRadius(),outerRadius())*2.0) );
00214     node = group;
00215   }
00216 
00217   attributes = visualAttributes;
00218   return &(*node);
00219 }
00220 
00221 
00222 
00223 base::ref<CollisionModel> Torus::getCollisionModel(CollisionModel::CollisionModelType modelType) const
00224 {
00225   if ((collisionModel!=0) && 
00226       ((this->modelType==modelType) || (modelType==CollisionModel::AnyModel)))
00227     return collisionModel;
00228   
00229   collisionModel = Shape::getCollisionModel(modelType);
00230   this->modelType=modelType;
00231 
00232   return collisionModel;
00233 }
00234 
00235 void Torus::serialize(base::Serializer& s)
00236 {
00237   s(_innerRadius)(_outerRadius);
00238 
00239   if (s.isInput()) {
00240     massPropertiesCached = false;
00241     node = 0;
00242     collisionModel = ref<CollisionModel>(0);
00243   }
00244 }
00245 

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