00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
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
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
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
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
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
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
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
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
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
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
00296 _functor.vertex(Vec3(r,0.0f,topz));
00297 _functor.vertex(Vec3(r,0.0f,basez));
00298
00299 _functor.end();
00300
00301
00302
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
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
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