| 22 | | |
| 23 | | class ComputeBoundingBoxVisitor : public osg::NodeVisitor |
| 24 | | { |
| 25 | | public: |
| 26 | | ComputeBoundingBoxVisitor(): |
| 27 | | osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) |
| 28 | | { |
| 29 | | } |
| 30 | | |
| 31 | | virtual void reset() |
| 32 | | { |
| 33 | | _matrixStack.clear(); |
| 34 | | _bb.init(); |
| 35 | | } |
| 36 | | |
| 37 | | osg::BoundingBox& getBoundingBox() { return _bb; } |
| 38 | | |
| 39 | | void getPolytope(osg::Polytope& polytope, float margin=0.1) const |
| 40 | | { |
| 41 | | float delta = _bb.radius()*margin; |
| 42 | | polytope.add( osg::Plane(0.0, 0.0, 1.0, -(_bb.zMin()-delta)) ); |
| 43 | | polytope.add( osg::Plane(0.0, 0.0, -1.0, (_bb.zMax()+delta)) ); |
| 44 | | |
| 45 | | polytope.add( osg::Plane(1.0, 0.0, 0.0, -(_bb.xMin()-delta)) ); |
| 46 | | polytope.add( osg::Plane(-1.0, 0.0, 0.0, (_bb.xMax()+delta)) ); |
| 47 | | |
| 48 | | polytope.add( osg::Plane(0.0, 1.0, 0.0, -(_bb.yMin()-delta)) ); |
| 49 | | polytope.add( osg::Plane(0.0, -1.0, 0.0, (_bb.yMax()+delta)) ); |
| 50 | | } |
| 51 | | |
| 52 | | void getBase(osg::Polytope& polytope, float margin=0.1) const |
| 53 | | { |
| 54 | | float delta = _bb.radius()*margin; |
| 55 | | polytope.add( osg::Plane(0.0, 0.0, 1.0, -(_bb.zMin()-delta)) ); |
| 56 | | } |
| 57 | | |
| 58 | | void apply(osg::Node& node) |
| 59 | | { |
| 60 | | traverse(node); |
| 61 | | } |
| 62 | | |
| 63 | | void apply(osg::Transform& transform) |
| 64 | | { |
| 65 | | osg::Matrix matrix; |
| 66 | | if (!_matrixStack.empty()) matrix = _matrixStack.back(); |
| 67 | | |
| 68 | | transform.computeLocalToWorldMatrix(matrix,this); |
| 69 | | |
| 70 | | pushMatrix(matrix); |
| 71 | | |
| 72 | | traverse(transform); |
| 73 | | |
| 74 | | popMatrix(); |
| 75 | | } |
| 76 | | |
| 77 | | void apply(osg::Geode& geode) |
| 78 | | { |
| 79 | | for(unsigned int i=0; i<geode.getNumDrawables(); ++i) |
| 80 | | { |
| 81 | | apply(geode.getDrawable(i)); |
| 82 | | } |
| 83 | | } |
| 84 | | |
| 85 | | void pushMatrix(osg::Matrix& matrix) |
| 86 | | { |
| 87 | | _matrixStack.push_back(matrix); |
| 88 | | } |
| 89 | | |
| 90 | | void popMatrix() |
| 91 | | { |
| 92 | | _matrixStack.pop_back(); |
| 93 | | } |
| 94 | | |
| 95 | | void apply(osg::Drawable* drawable) |
| 96 | | { |
| 97 | | if (_matrixStack.empty()) _bb.expandBy(drawable->getBound()); |
| 98 | | else |
| 99 | | { |
| 100 | | osg::Matrix& matrix = _matrixStack.back(); |
| 101 | | const osg::BoundingBox& dbb = drawable->getBound(); |
| 102 | | if (dbb.valid()) |
| 103 | | { |
| 104 | | _bb.expandBy(dbb.corner(0) * matrix); |
| 105 | | _bb.expandBy(dbb.corner(1) * matrix); |
| 106 | | _bb.expandBy(dbb.corner(2) * matrix); |
| 107 | | _bb.expandBy(dbb.corner(3) * matrix); |
| 108 | | _bb.expandBy(dbb.corner(4) * matrix); |
| 109 | | _bb.expandBy(dbb.corner(5) * matrix); |
| 110 | | _bb.expandBy(dbb.corner(6) * matrix); |
| 111 | | _bb.expandBy(dbb.corner(7) * matrix); |
| 112 | | } |
| 113 | | } |
| 114 | | } |
| 115 | | |
| 116 | | protected: |
| 117 | | |
| 118 | | typedef std::vector<osg::Matrix> MatrixStack; |
| 119 | | |
| 120 | | MatrixStack _matrixStack; |
| 121 | | osg::BoundingBox _bb; |
| 122 | | }; |
| 292 | | osg::Switch* sw = new osg::Switch; |
| 293 | | sw->setEventCallback(new SwitchHandler); |
| 294 | | |
| 295 | | sw->addChild(createCube(FRONT_FACE), true); |
| 296 | | sw->addChild(createCube(FRONT_FACE | BACK_FACE), false); |
| 297 | | sw->addChild(createCube(FRONT_FACE | BACK_FACE | LEFT_FACE), false); |
| 298 | | sw->addChild(createCube(FRONT_FACE | BACK_FACE | LEFT_FACE | RIGHT_FACE), false); |
| 299 | | sw->addChild(createCube(FRONT_FACE | BACK_FACE | LEFT_FACE | RIGHT_FACE | TOP_FACE), false); |
| 300 | | sw->addChild(createCube(FRONT_FACE | BACK_FACE | LEFT_FACE | RIGHT_FACE | TOP_FACE | BOTTOM_FACE), false); |
| 301 | | |
| 302 | | return sw; |
| | 196 | if (arguments.read("-1")) |
| | 197 | { |
| | 198 | osg::Switch* sw = new osg::Switch; |
| | 199 | sw->setEventCallback(new SwitchHandler); |
| | 200 | |
| | 201 | sw->addChild(createCube(FRONT_FACE), true); |
| | 202 | sw->addChild(createCube(FRONT_FACE | BACK_FACE), false); |
| | 203 | sw->addChild(createCube(FRONT_FACE | BACK_FACE | LEFT_FACE), false); |
| | 204 | sw->addChild(createCube(FRONT_FACE | BACK_FACE | LEFT_FACE | RIGHT_FACE), false); |
| | 205 | sw->addChild(createCube(FRONT_FACE | BACK_FACE | LEFT_FACE | RIGHT_FACE | TOP_FACE), false); |
| | 206 | sw->addChild(createCube(FRONT_FACE | BACK_FACE | LEFT_FACE | RIGHT_FACE | TOP_FACE | BOTTOM_FACE), false); |
| | 207 | |
| | 208 | return sw; |
| | 209 | } |
| | 210 | else if (arguments.read("-2")) |
| | 211 | { |
| | 212 | return 0; |
| | 213 | } |
| | 214 | else /*if (arguments.read("-3"))*/ |
| | 215 | { |
| | 216 | return 0; |
| | 217 | } |
| | 218 | |
| 418 | | if (createBase) |
| 419 | | { |
| 420 | | osg::ref_ptr<osg::Group> newGroup = new osg::Group; |
| 421 | | newGroup->addChild(model.get()); |
| 422 | | |
| | 315 | osg::Vec4 lightpos; |
| | 316 | |
| | 317 | if (postionalLight) |
| | 318 | { |
| | 319 | lightpos.set(bb.center().x(), bb.center().y(), bb.zMax() + bb.radius() ,1.0f); |
| | 320 | } |
| | 321 | else |
| | 322 | { |
| | 323 | lightpos.set(0.5f,0.25f,0.8f,0.0f); |
| | 324 | } |
| | 325 | |
| | 326 | |
| | 327 | osg::ref_ptr<osgShadow::ShadowedScene> shadowedScene = new osgShadow::ShadowedScene; |
| | 328 | |
| | 329 | shadowedScene->setRecievesShadowTraversalMask(0x1); |
| | 330 | shadowedScene->setCastsShadowTraversalMask(0x2); |
| | 331 | |
| | 332 | model->setNodeMask(shadowedScene->getCastsShadowTraversalMask()); |
| | 333 | |
| | 334 | if (arguments.read("--sv")) |
| | 335 | { |
| | 336 | osg::ref_ptr<osgShadow::ShadowVolume> sv = new osgShadow::ShadowVolume; |
| | 337 | sv->setDynamicShadowVolumes(updateLightPosition); |
| | 338 | while (arguments.read("--two-sided")) sv->setDrawMode(osgShadow::ShadowVolumeGeometry::STENCIL_TWO_SIDED); |
| | 339 | while (arguments.read("--two-pass")) sv->setDrawMode(osgShadow::ShadowVolumeGeometry::STENCIL_TWO_PASS); |
| | 340 | |
| | 341 | shadowedScene->setShadowTechnique(sv.get()); |
| | 342 | } |
| | 343 | else if (arguments.read("--st")) |
| | 344 | { |
| | 345 | osg::ref_ptr<osgShadow::ShadowTexture> st = new osgShadow::ShadowTexture; |
| | 346 | shadowedScene->setShadowTechnique(st.get()); |
| | 347 | } |
| | 348 | else if (arguments.read("--pssm")) |
| | 349 | { |
| | 350 | osg::ref_ptr<osgShadow::ParallelSplitShadowMap> pssm = new osgShadow::ParallelSplitShadowMap; |
| | 351 | shadowedScene->setShadowTechnique(pssm.get()); |
| | 352 | } |
| | 353 | else /* if (arguments.read("--sm")) */ |
| | 354 | { |
| | 355 | osg::ref_ptr<osgShadow::ShadowMap> sm = new osgShadow::ShadowMap; |
| | 356 | shadowedScene->setShadowTechnique(sm.get()); |
| | 357 | } |
| | 358 | |
| | 359 | if ( arguments.read("--base")) |
| | 360 | { |
| | 361 | |
| 433 | | model = newGroup.get(); |
| 434 | | } |
| 435 | | |
| 436 | | osg::Vec4 lightpos; |
| 437 | | |
| 438 | | if (postionalLight) |
| 439 | | { |
| 440 | | lightpos.set(bb.center().x(), bb.center().y(), bb.zMax() + bb.radius() ,1.0f); |
| 441 | | } |
| 442 | | else |
| 443 | | { |
| 444 | | lightpos.set(0.5f,0.25f,0.8f,0.0f); |
| 445 | | } |
| 446 | | |
| 447 | | |
| 448 | | osg::ref_ptr<osgShadow::ShadowedScene> shadowedScene = new osgShadow::ShadowedScene; |
| 449 | | |
| 450 | | osg::ref_ptr<osgShadow::ShadowVolume> shadowVolume = new osgShadow::ShadowVolume; |
| 451 | | shadowedScene->setShadowTechnique(shadowVolume.get()); |
| 452 | | shadowVolume->setDynamicShadowVolumes(updateLightPosition); |
| | 373 | geode->getOrCreateStateSet()->setTextureAttributeAndModes(0, new osg::Texture2D(osgDB::readImageFile("Images/lz.rgb"))); |
| | 374 | |
| | 375 | shadowedScene->addChild(geode); |
| | 376 | } |
| 456 | | ls->getLight()->setAmbient(osg::Vec4(1.0,0.0,0.0,1.0)); |
| 457 | | ls->getLight()->setDiffuse(osg::Vec4(0.0,1.0,0.0,1.0)); |
| 458 | | |
| | 380 | if ( arguments.read("--coloured-light")) |
| | 381 | { |
| | 382 | ls->getLight()->setAmbient(osg::Vec4(1.0,0.0,0.0,1.0)); |
| | 383 | ls->getLight()->setDiffuse(osg::Vec4(0.0,1.0,0.0,1.0)); |
| | 384 | } |
| | 385 | else |
| | 386 | { |
| | 387 | ls->getLight()->setAmbient(osg::Vec4(0.2,0.2,0.2,1.0)); |
| | 388 | ls->getLight()->setDiffuse(osg::Vec4(0.8,0.8,0.8,1.0)); |
| | 389 | } |
| | 390 | |