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

gfx/EnhancedShapeDrawable.cpp

Go to the documentation of this file.
00001 /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield 
00002  *
00003  * This library is open source and may be redistributed and/or modified under  
00004  * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or 
00005  * (at your option) any later version.  The full license is in LICENSE file
00006  * included with this distribution, and on the openscenegraph.org website.
00007  * 
00008  * This library is distributed in the hope that it will be useful,
00009  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00010  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
00011  * OpenSceneGraph Public License for more details.
00012 */
00013 #include <gfx/EnhancedShapeDrawable>
00014 #include <osg/GL>
00015 #include <osg/Notify>
00016 
00017 #include <physics/Capsule>
00018 
00019 using namespace osg;
00020 
00021 using gfx::EnhancedShapeDrawable;
00022 using physics::Capsule;
00023 
00024 
00025 
00026 ///////////////////////////////////////////////////////////////////////////////
00027 //
00028 // draw shape
00029 //
00030 
00031 
00032 class osg::DrawShapeVisitor;
00033 
00034 
00035 
00036 class EnhancedDrawShapeVisitor : public ConstShapeVisitor
00037 {
00038     public:
00039     
00040         EnhancedDrawShapeVisitor(State& state,const TessellationHints* hints):
00041             _state(state),
00042             _hints(hints)
00043         {
00044         }
00045     
00046         virtual void apply(const Capsule&);
00047         
00048         State&              _state;
00049         const TessellationHints*  _hints;
00050 };
00051 
00052 
00053 
00054 void EnhancedDrawShapeVisitor::apply(const Capsule& capsule)
00055 {
00056     glPushMatrix();
00057 
00058         glTranslatef(capsule.getCenter().x(),capsule.getCenter().y(),capsule.getCenter().z());
00059 
00060         if (!capsule.zeroRotation())
00061         {
00062             Matrix rotation(capsule.getRotationMatrix());
00063             glMultMatrix(rotation.ptr());
00064         }
00065 
00066         // evaluate hints
00067         bool createBody = (_hints ? _hints->getCreateBody() : true);
00068         bool createTop = (_hints ? _hints->getCreateTop() : true);
00069         bool createBottom = (_hints ? _hints->getCreateBottom() : true);
00070 
00071         unsigned int numSegments = 40;
00072         if (_hints && _hints->getDetailRatio() != 1.0f) {
00073             float ratio = _hints->getDetailRatio();
00074             numSegments = (unsigned int) (numSegments * ratio);
00075             if (numSegments < MIN_NUM_SEGMENTS)
00076                 numSegments = MIN_NUM_SEGMENTS;
00077         }
00078         
00079         float angleDelta = 2.0f*osg::PI/(float)numSegments;
00080         float texCoordDelta = 1.0f/(float)numSegments;
00081         
00082         float r = cylinder.getRadius();
00083         float h = cylinder.getHeight();
00084         
00085         float basez = -h*0.5f;
00086         float topz = h*0.5f;
00087         
00088         float angle = 0.0f;
00089         float texCoord = 0.0f;
00090 
00091         // cylinder body
00092         if (createBody) {
00093             glBegin(GL_QUAD_STRIP);
00094         
00095             for(unsigned int bodyi=0;
00096                 bodyi<numSegments;
00097                 ++bodyi,angle+=angleDelta,texCoord+=texCoordDelta)
00098             {
00099                 float c = cosf(angle);
00100                 float s = sinf(angle);
00101 
00102                 glNormal3f(c,s,0.0f);
00103 
00104                 glTexCoord2f(texCoord,1.0f);
00105                 glVertex3f(c*r,s*r,topz);
00106 
00107                 glTexCoord2f(texCoord,0.0f);
00108                 glVertex3f(c*r,s*r,basez);
00109             }
00110 
00111             // do last point by hand to ensure no round off errors.
00112             glNormal3f(1.0f,0.0f,0.0f);
00113 
00114             glTexCoord2f(1.0f,1.0f);
00115             glVertex3f(r,0.0f,topz);
00116 
00117             glTexCoord2f(1.0f,0.0f);
00118             glVertex3f(r,0.0f,basez);
00119         
00120             glEnd();
00121         }
00122 
00123         // cylinder top
00124         if (createTop) {
00125             glBegin(GL_TRIANGLE_FAN);
00126         
00127             glNormal3f(0.0f,0.0f,1.0f);
00128             glTexCoord2f(0.5f,0.5f);
00129             glVertex3f(0.0f,0.0f,topz);
00130 
00131             angle = 0.0f;
00132             texCoord = 0.0f;
00133             for(unsigned int topi=0;
00134                 topi<numSegments;
00135                 ++topi,angle+=angleDelta,texCoord+=texCoordDelta)
00136             {
00137                 float c = cosf(angle);
00138                 float s = sinf(angle);
00139 
00140                 glTexCoord2f(c*0.5f+0.5f,s*0.5f+0.5f);
00141                 glVertex3f(c*r,s*r,topz);
00142             }
00143 
00144             glTexCoord2f(1.0f,0.0f);
00145             glVertex3f(r,0.0f,topz);
00146         
00147             glEnd();
00148         }
00149 
00150         // cylinder bottom
00151         if (createBottom) {
00152             glBegin(GL_TRIANGLE_FAN);
00153         
00154             glNormal3f(0.0f,0.0f,-1.0f);
00155             glTexCoord2f(0.5f,0.5f);
00156             glVertex3f(0.0f,0.0f,basez);
00157 
00158             angle = osg::PI*2.0f;
00159             texCoord = 1.0f;
00160             for(unsigned int bottomi=0;
00161                 bottomi<numSegments;
00162                 ++bottomi,angle-=angleDelta,texCoord-=texCoordDelta)
00163             {
00164                 float c = cosf(angle);
00165                 float s = sinf(angle);
00166 
00167                 glTexCoord2f(c*0.5f+0.5f,s*0.5f+0.5f);
00168                 glVertex3f(c*r,s*r,basez);
00169             }
00170 
00171             glTexCoord2f(0.0f,0.0f);
00172             glVertex3f(r,0.0f,basez);
00173         
00174             glEnd();
00175         }
00176 
00177     glPopMatrix();
00178 }
00179 
00180 
00181 
00182 
00183 ///////////////////////////////////////////////////////////////////////////////
00184 //
00185 // Compute bounding of shape
00186 //
00187 
00188 class EnhancedComputeBoundShapeVisitor : public osg::ConstShapeVisitor
00189 {
00190     public:
00191     
00192         EnhancedComputeBoundShapeVisitor(BoundingBox& bb):_bb(bb) {}
00193     
00194         virtual void apply(const Capsule&);
00195         
00196         BoundingBox&    _bb;
00197 };
00198 
00199 
00200 
00201 void EnhancedComputeBoundShapeVisitor::apply(const Capsule& capsule)
00202 {
00203     if (capsule.zeroRotation())
00204     {
00205         Vec3 halfLengths(capsule.radius(),capsule.radius(),capsule.height()*0.5f+capsule.radius());
00206         _bb.expandBy(-halfLengths);
00207         _bb.expandBy(halfLengths);
00208 
00209     }
00210     else
00211     {
00212         float r = capsule.radius();
00213         float z = capsule.height()*0.5f;
00214 
00215         Vec3 base_1(Vec3(-r,-r,-z-r));
00216         Vec3 base_2(Vec3(r,-r,-z-r));
00217         Vec3 base_3(Vec3(r,r,-z-r));
00218         Vec3 base_4(Vec3(-r,r,-z-r));
00219     
00220         Vec3 top_1(Vec3(-r,-r,z+r));
00221         Vec3 top_2(Vec3(r,-r,z+r));
00222         Vec3 top_3(Vec3(r,r,z+r));
00223         Vec3 top_4(Vec3(-r,r,z+r));
00224 
00225         _bb.expandBy(base_1);
00226         _bb.expandBy(base_2);
00227         _bb.expandBy(base_3);
00228         _bb.expandBy(base_4);
00229 
00230         _bb.expandBy(top_1);
00231         _bb.expandBy(top_2);
00232         _bb.expandBy(top_3);
00233         _bb.expandBy(top_4);
00234     }
00235 }
00236 
00237 
00238 
00239 
00240 
00241 ///////////////////////////////////////////////////////////////////////////////
00242 //
00243 // Accept a primtive functor for each of the shapes.
00244 //
00245 
00246 class EnhancedPrimitiveShapeVisitor : public osg::ConstShapeVisitor
00247 {
00248     public:
00249     
00250         EnhancedPrimitiveShapeVisitor(Drawable::PrimitiveFunctor& functor,const TessellationHints* hints):
00251             _functor(functor),
00252             _hints(hints) {}
00253 
00254     
00255         virtual void apply(const Capsule&);
00256         
00257         Drawable::PrimitiveFunctor& _functor;
00258         const TessellationHints*  _hints;
00259 };
00260 
00261 
00262 
00263 void EnhancedPrimitiveShapeVisitor::apply(const Capsule& capsule)
00264 {
00265     unsigned int numSegments = 40;
00266 
00267     float angleDelta = 2.0f*osg::PI/(float)numSegments;
00268 
00269     float texCoordDelta = 1.0/(float)numSegments;
00270 
00271     float r = capsule.radius();
00272     float h = capsule.height();
00273 
00274     float basez = -h*0.5f;
00275     float topz = h*0.5f;
00276 
00277     // cylinder body
00278     _functor.begin(GL_QUAD_STRIP);
00279 
00280         float angle = 0.0f;
00281         float texCoord = 0.0f;
00282         for(unsigned int bodyi=0;
00283             bodyi<numSegments;
00284             ++bodyi,angle+=angleDelta,texCoord+=texCoordDelta)
00285         {
00286 
00287             float c = cosf(angle);
00288             float s = sinf(angle);
00289 
00290             _functor.vertex(Vec3(c*r,s*r,topz));
00291             _functor.vertex(Vec3(c*r,s*r,basez));
00292 
00293         }
00294 
00295         // do last point by hand to ensure no round off errors.
00296         _functor.vertex(Vec3(r,0.0f,topz));
00297         _functor.vertex(Vec3(r,0.0f,basez));
00298 
00299     _functor.end();
00300 
00301 
00302     // cylinder top
00303     _functor.begin(GL_TRIANGLE_FAN);
00304 
00305         _functor.vertex(Vec3(0.0f,0.0f,topz));
00306 
00307         angle = 0.0f;
00308         texCoord = 0.0f;
00309         for(unsigned int topi=0;
00310             topi<numSegments;
00311             ++topi,angle+=angleDelta,texCoord+=texCoordDelta)
00312         {
00313 
00314             float c = cosf(angle);
00315             float s = sinf(angle);
00316 
00317             _functor.vertex(Vec3(c*r,s*r,topz));
00318 
00319         }
00320 
00321         _functor.vertex(Vec3(r,0.0f,topz));
00322 
00323     _functor.end();
00324 
00325     // cylinder bottom
00326     _functor.begin(GL_TRIANGLE_FAN);
00327 
00328         _functor.vertex(Vec3(0.0f,0.0f,basez));
00329 
00330         angle = osg::PI*2.0f;
00331         texCoord = 1.0f;
00332         for(unsigned int bottomi=0;
00333             bottomi<numSegments;
00334             ++bottomi,angle-=angleDelta,texCoord-=texCoordDelta)
00335         {
00336 
00337             float c = cosf(angle);
00338             float s = sinf(angle);
00339 
00340             _functor.vertex(Vec3(c*r,s*r,basez));
00341 
00342         }
00343 
00344         _functor.vertex(Vec3(r,0.0f,basez));
00345 
00346     _functor.end();
00347 }
00348 
00349 
00350 ///////////////////////////////////////////////////////////////////////////////
00351 //
00352 // ShapeDrawable itself..
00353 //
00354 
00355 
00356 EnhancedShapeDrawable::EnhancedShapeDrawable():
00357 {
00358 }
00359 
00360 EnhancedShapeDrawable::EnhancedShapeDrawable(Shape* shape,TessellationHints* hints):
00361   ShapeDrawable(shape, hints)
00362 {
00363 }
00364 
00365 EnhancedShapeDrawable::EnhancedShapeDrawable(const ShapeDrawable& pg,const CopyOp& copyop):
00366     ShapeDrawable(pg,copyop)
00367 {
00368 }
00369 
00370 EnhancedShapeDrawable::~EnhancedShapeDrawable()
00371 {
00372 }
00373 
00374 void ShapeDrawable::drawImplementation(State& state) const
00375 {
00376     if (_shape.valid())
00377     {
00378       if (base::instanceof(*_shape, const 
00379       
00380         glColor4fv(_color.ptr());
00381     
00382         EnhancedDrawShapeVisitor dsv(state,_tessellationHints.get());
00383         
00384         _shape->accept(dsv);
00385     }
00386 }
00387 
00388 void ShapeDrawable::accept(ConstAttributeFunctor&) const
00389 {
00390 }
00391 
00392 void ShapeDrawable::accept(PrimitiveFunctor& pf) const
00393 {
00394     if (_shape.valid())
00395     {
00396         EnhancedPrimitiveShapeVisitor psv(pf,_tessellationHints.get());
00397         _shape->accept(psv);
00398     }
00399 }
00400 
00401 
00402 bool ShapeDrawable::computeBound() const
00403 {
00404     _bbox.init();
00405 
00406 
00407     if (_shape.valid())
00408     {
00409         EnhancedComputeBoundShapeVisitor cbsv(_bbox);
00410         _shape->accept(cbsv);
00411         _bbox_computed = true;
00412 
00413         return true;
00414     }
00415 
00416     return false;
00417 }
00418 

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