- Timestamp:
- 04/13/06 21:05:26 (7 years ago)
- Files:
-
- 1 modified
Legend:
- Unmodified
- Added
- Removed
-
OpenSceneGraph/trunk/examples/osgprecipitation/osgprecipitation.cpp
r5086 r5087 28 28 float random(float min,float max) { return min + (max-min)*(float)rand()/(float)RAND_MAX; } 29 29 30 struct PrecipatationParameters : public osg::Referenced 31 { 32 PrecipatationParameters(): 33 particleVelocity(0.0,0.0,-5.0), 34 particleSize(0.02), 35 particleColour(0.6, 0.6, 0.6, 1.0), 36 numberOfParticles(10000000), 37 numberOfCellsX(100), 38 numberOfCellsY(100), 39 numberOfCellsZ(1), 40 nearTransition(25.0), 41 farTransition(100.0) 42 {} 43 44 void rain (float intensity) 45 { 46 particleVelocity = osg::Vec3(0.0,0.0,-2.0) + osg::Vec3(0.0,0.0,-10.0)*intensity; 47 particleSize = 0.01 + 0.04*intensity; 48 numberOfParticles = intensity * 100000000; 49 particleColour = osg::Vec4(0.6, 0.6, 0.6, 1.0); 50 } 51 52 void snow(float intensity) 53 { 54 particleVelocity = osg::Vec3(0.0,0.0,-1.0) + osg::Vec3(0.0,0.0,-0.5)*intensity; 55 particleSize = 0.02 + 0.05*intensity; 56 numberOfParticles = intensity * 100000000; 57 particleColour = osg::Vec4(0.8, 0.8, 0.8, 1.0); 58 } 59 60 osg::BoundingBox boundingBox; 61 osg::Vec3 particleVelocity; 62 float particleSize; 63 osg::Vec4 particleColour; 64 unsigned int numberOfParticles; 65 unsigned int numberOfCellsX; 66 unsigned int numberOfCellsY; 67 unsigned int numberOfCellsZ; 68 float nearTransition; 69 float farTransition; 70 }; 71 72 struct PrecipitationCullCallback : public virtual osg::Drawable::CullCallback 73 { 74 PrecipitationCullCallback() {} 75 76 PrecipitationCullCallback(const PrecipitationCullCallback&,const osg::CopyOp&) {} 77 78 META_Object(osg,PrecipitationCullCallback); 79 80 /** do customized cull code, return true if drawable should be culled.*/ 81 virtual bool cull(osg::NodeVisitor* nodeVisitor, osg::Drawable* drawable, osg::State* state) const 82 { 83 osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(nodeVisitor); 84 if (cv) 85 { 86 float distance = nodeVisitor->getDistanceFromEyePoint(drawable->getBound().center(),true); 87 88 // if (distance<-4.0) return true; 89 90 #if 0 91 92 const osg::BoundingBox& bb = drawable->getBound(); 93 const osg::Polytope& frustum = cv->getCurrentCullingSet().getFrustum(); 94 int numPointsInside = 0; 95 for(unsigned int i=0; i<8; ++i) 96 { 97 if (frustum.contains(bb.corner(i))) ++numPointsInside; 98 } 99 100 std::cout<<" "<<drawable->getName()<<" distance "<<distance<<"num Points inside = "<<numPointsInside<<std::endl; 101 102 if (cv->isCulled(drawable->getBound())) 103 { 104 std::cout<<" isCulled "<<drawable->getName()<<std::endl; 105 return true; 106 } 107 #endif 108 109 } 110 111 return false; 112 } 113 }; 114 115 30 116 class PrecipitationGeometry : public osg::Geometry 31 117 { … … 35 121 { 36 122 setSupportsDisplayList(false); 123 124 setCullCallback(new PrecipitationCullCallback()); 37 125 } 38 126 … … 69 157 70 158 _internalGeometry->draw(state); 159 160 161 static int s_frameNumber = 0xffffffff; 162 static unsigned int s_NumberQuads = 0; 163 static unsigned int s_NumberQuadsVertices = 0; 164 static unsigned int s_NumberLines = 0; 165 static unsigned int s_NumberLinesVertices = 0; 166 static unsigned int s_NumberPoints = 0; 167 static unsigned int s_NumberPointsVertices = 0; 168 169 if (s_frameNumber != state.getFrameStamp()->getFrameNumber()) 170 { 171 // std::cout<<"Frame "<< s_frameNumber<<"\tquads "<<s_NumberQuads<<", "<<s_NumberQuadsVertices<<" points "<<s_NumberPoints<<", "<<s_NumberPointsVertices<<std::endl; 172 173 s_NumberQuads = 0; 174 s_NumberLines = 0; 175 s_NumberPoints = 0; 176 s_NumberQuadsVertices = 0; 177 s_NumberLinesVertices = 0; 178 s_NumberPointsVertices = 0; 179 180 s_frameNumber = state.getFrameStamp()->getFrameNumber(); 181 } 182 183 184 if (_internalGeometry->getName()=="quad") 185 { 186 s_NumberQuads++; 187 s_NumberQuadsVertices+= _internalGeometry->getVertexArray()->getNumElements(); 188 } 189 else if (_internalGeometry->getName()=="line") 190 { 191 s_NumberLines++; 192 s_NumberLinesVertices+= _internalGeometry->getVertexArray()->getNumElements(); 193 } 194 else if (_internalGeometry->getName()=="point") 195 { 196 s_NumberPoints++; 197 s_NumberPointsVertices+= _internalGeometry->getVertexArray()->getNumElements(); 198 } 71 199 } 72 200 … … 213 341 if (quad_geometry) 214 342 { 343 quad_geometry->setName("quad"); 344 215 345 quad_vertices = new osg::Vec3Array(numParticles*4); 216 346 quad_offsets = new osg::Vec2Array(numParticles*4); … … 226 356 if (line_geometry) 227 357 { 358 line_geometry->setName("line"); 359 228 360 line_vertices = new osg::Vec3Array(numParticles*2); 229 361 line_offsets = new osg::Vec2Array(numParticles*2); … … 239 371 if (point_geometry) 240 372 { 373 point_geometry->setName("point"); 374 241 375 point_vertices = new osg::Vec3Array(numParticles); 242 376 point_offsets = new osg::Vec2Array(numParticles); … … 353 487 354 488 355 osg::Node* createRainEffect(const osg::BoundingBox& bb, const osg::Vec3& velocity )489 osg::Node* createRainEffect(const osg::BoundingBox& bb, const osg::Vec3& velocity, float nearTransition, float farTransition) 356 490 { 357 491 osg::LOD* lod = new osg::LOD; 358 492 493 494 // distance between start point and end of cyclce 495 osg::Vec3 position(bb.xMin(), bb.yMin(), bb.zMax()); 496 359 497 // time taken to get from start to the end of cycle 360 498 float period = fabs((bb.zMax()-bb.zMin()) / velocity.z()); 361 362 // distance between start point and end of cyclce363 osg::Vec3 position(bb.xMin(), bb.yMin(), bb.zMax());364 499 osg::Vec3 dv_i( bb.xMax()-bb.xMin(), 0.0f, 0.0f ); 365 500 osg::Vec3 dv_j( 0.0f, bb.yMax()-bb.yMin(), 0.0f ); 366 501 osg::Vec3 dv_k( velocity * period ); 367 368 float nearDistance = 25.0;369 float farDistance = 100.0;370 502 371 503 // high res LOD. … … 377 509 highres_geode->addDrawable(geometry); 378 510 511 geometry->setName("highres"); 379 512 geometry->setPosition(position); 380 513 geometry->setInitialBound(bb); … … 382 515 geometry->setStateSet(quad_stateset.get()); 383 516 384 lod->addChild( highres_geode, 0.0f, near Distance);517 lod->addChild( highres_geode, 0.0f, nearTransition ); 385 518 } 386 519 … … 389 522 osg::Geode* lowres_geode = new osg::Geode; 390 523 524 391 525 PrecipitationGeometry* geometry = new PrecipitationGeometry; 392 526 393 527 lowres_geode->addDrawable(geometry); 394 528 529 geometry->setName("lowres"); 395 530 geometry->setPosition(position); 396 531 geometry->setInitialBound(bb); … … 398 533 geometry->setStateSet(point_stateset.get()); 399 534 400 lod->addChild( lowres_geode, near Distance, farDistance);535 lod->addChild( lowres_geode, nearTransition, farTransition ); 401 536 } 402 537 … … 405 540 } 406 541 407 osg::Node* createCellRainEffect(const osg::BoundingBox& bb, const osg::Vec3& velocity, unsigned int numParticles)408 { 409 410 unsigned int numX = 100;411 unsigned int numY = 100;542 osg::Node* createCellRainEffect(const PrecipatationParameters& parameters) 543 { 544 545 unsigned int numX = parameters.numberOfCellsX; 546 unsigned int numY = parameters.numberOfCellsY; 412 547 unsigned int numCells = numX*numY; 413 unsigned int numParticlesPerCell = numParticles/numCells;548 unsigned int numParticlesPerCell = parameters.numberOfParticles/numCells; 414 549 415 550 setUpGeometries(numParticlesPerCell); 416 551 417 std::cout<<"Effect total number of particles = "<<numParticles<<std::endl; 552 const osg::BoundingBox& bb = parameters.boundingBox; 553 554 std::cout<<"Effect total number of particles = "<<parameters.numberOfParticles<<std::endl; 418 555 std::cout<<"Number of cells = "<<numCells<<std::endl; 419 556 std::cout<<"Number of particles per cell = "<<numParticlesPerCell<<std::endl; … … 434 571 bb.zMax()); 435 572 436 group->addChild(createRainEffect(bbLocal, velocity));573 group->addChild(createRainEffect(bbLocal, parameters.particleVelocity, parameters.nearTransition, parameters.farTransition)); 437 574 } 438 575 } … … 444 581 #endif 445 582 446 #if 1447 583 osg::StateSet* stateset = group->getOrCreateStateSet(); 448 584 449 585 // time taken to get from start to the end of cycle 450 float period = fabs((bb.zMax()-bb.zMin()) / velocity.z());586 float period = fabs((bb.zMax()-bb.zMin()) / parameters.particleVelocity.z()); 451 587 452 588 // distance between start point and end of cyclce 453 589 osg::Vec3 dv_i( (bb.xMax()-bb.xMin())/(float)(numX), 0.0f, 0.0f ); 454 590 osg::Vec3 dv_j( 0.0f, (bb.yMax()-bb.yMin())/(float)(numY), 0.0f ); 455 osg::Vec3 dv_k( velocity * period );591 osg::Vec3 dv_k( parameters.particleVelocity * period ); 456 592 457 593 // set up uniforms … … 480 616 stateset->setTextureAttribute(0, texture); 481 617 482 stateset->addUniform(new osg::Uniform("particleColour", osg::Vec4(0.6,0.6,0.6,1.0)));483 stateset->addUniform(new osg::Uniform("particleSize", 0.02f));618 stateset->addUniform(new osg::Uniform("particleColour", parameters.particleColour)); 619 stateset->addUniform(new osg::Uniform("particleSize", parameters.particleSize)); 484 620 485 621 osg::Uniform* previousModelViewUniform = new osg::Uniform("previousModelViewMatrix",osg::Matrix()); … … 487 623 488 624 group->setCullCallback(new CullCallback(previousModelViewUniform)); 489 #endif 625 490 626 491 627 return group; 492 628 } 493 629 494 osg::Node* createModel(osg::Node* loadedModel, bool /*useShaders*/)630 osg::Node* createModel(osg::Node* loadedModel, PrecipatationParameters& parameters) 495 631 { 496 632 osg::Group* group = new osg::Group; … … 507 643 508 644 bb.set( -500, -500, 0, +500, +500, 10); 645 646 parameters.boundingBox = bb; 509 647 510 648 osg::StateSet* stateset = loadedModel->getOrCreateStateSet(); … … 531 669 } 532 670 533 group->addChild(createCellRainEffect( bb, velocity, numParticles));671 group->addChild(createCellRainEffect(parameters)); 534 672 535 673 return group; … … 560 698 viewer.getUsage(*arguments.getApplicationUsage()); 561 699 562 bool shader = true; 563 while (arguments.read("--shader")) shader = true; 564 while (arguments.read("--fixed")) shader = false; 700 PrecipatationParameters parameters; 701 702 float intensity; 703 while (arguments.read("--snow", intensity)) parameters.snow(intensity); 704 while (arguments.read("--rain", intensity)) parameters.rain(intensity); 705 706 float particleSize; 707 while (arguments.read("--particleSize", particleSize)) parameters.particleSize = particleSize; 708 709 osg::Vec3 particleVelocity; 710 while (arguments.read("--particleVelocity", particleVelocity.x(), particleVelocity.y(), particleVelocity.z() )) parameters.particleVelocity = particleVelocity; 711 712 float transition; 713 while (arguments.read("--nearTransition", transition )) parameters.nearTransition = transition; 714 while (arguments.read("--farTransition", transition )) parameters.farTransition = transition; 565 715 566 716 // if user request help write it out to cout. … … 587 737 osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFiles(arguments); 588 738 589 loadedModel = createModel(loadedModel.get(), shader);739 loadedModel = createModel(loadedModel.get(), parameters); 590 740 591 741 // if no model has been successfully loaded report failure.
