| 249 | | osg::Node* createRainEffect(const osg::BoundingBox& bb, const osg::Vec3& velocity, unsigned int numParticles, bool useShaders) |
| 250 | | { |
| 251 | | osg::Geode* geode = new osg::Geode; |
| 252 | | |
| 253 | | osg::Geometry* quad_geometry = 0; |
| 254 | | osg::Geometry* line_geometry = 0; |
| 255 | | osg::Geometry* point_geometry = 0; |
| 256 | | |
| 257 | | #if 0 |
| 258 | | quad_geometry = new PrecipitationGeometry; |
| 259 | | quad_geometry->setUseVertexBufferObjects(true); |
| 260 | | quad_geometry->setInitialBound(bb); |
| 261 | | geode->addDrawable(quad_geometry); |
| 262 | | |
| 263 | | osg::StateSet* quad_stateset = quad_geometry->getOrCreateStateSet(); |
| 264 | | { |
| | 280 | static osg::ref_ptr<osg::Geometry> quad_geometry = 0; |
| | 281 | static osg::ref_ptr<osg::StateSet> quad_stateset = 0; |
| | 282 | |
| | 283 | static osg::ref_ptr<osg::Geometry> line_geometry = 0; |
| | 284 | static osg::ref_ptr<osg::StateSet> line_stateset = 0; |
| | 285 | |
| | 286 | static osg::ref_ptr<osg::Geometry> point_geometry = 0; |
| | 287 | static osg::ref_ptr<osg::StateSet> point_stateset = 0; |
| | 288 | |
| | 289 | void setUpGeometries(unsigned int numParticles) |
| | 290 | { |
| | 291 | { |
| | 292 | quad_geometry = new osg::Geometry; |
| | 293 | quad_geometry->setUseVertexBufferObjects(true); |
| | 294 | |
| | 295 | quad_stateset = new osg::StateSet; |
| 314 | | #endif |
| 315 | | |
| 316 | | |
| 317 | | createGeometry(numParticles, quad_geometry, line_geometry, point_geometry); |
| | 340 | |
| | 341 | createGeometry(numParticles, quad_geometry.get(), line_geometry.get(), point_geometry.get()); |
| | 342 | |
| | 343 | } |
| | 344 | |
| | 345 | |
| | 346 | osg::Node* createRainEffect(const osg::BoundingBox& bb, const osg::Vec3& velocity) |
| | 347 | { |
| | 348 | osg::LOD* lod = new osg::LOD; |
| | 349 | |
| | 350 | float nearDistance = 100.0; |
| | 351 | float farDistance = 200.0; |
| | 352 | |
| | 353 | // high res LOD. |
| | 354 | { |
| | 355 | osg::Geode* highres_geode = new osg::Geode; |
| | 356 | |
| | 357 | PrecipitationGeometry* geometry = new PrecipitationGeometry; |
| | 358 | |
| | 359 | highres_geode->addDrawable(geometry); |
| | 360 | |
| | 361 | geometry->setInitialBound(bb); |
| | 362 | geometry->setInternalGeometry(quad_geometry.get()); |
| | 363 | geometry->setStateSet(quad_stateset.get()); |
| | 364 | |
| | 365 | lod->addChild( highres_geode, 0.0f, nearDistance ); |
| | 366 | } |
| | 367 | |
| | 368 | // low res LOD |
| | 369 | { |
| | 370 | osg::Geode* lowres_geode = new osg::Geode; |
| | 371 | |
| | 372 | PrecipitationGeometry* geometry = new PrecipitationGeometry; |
| | 373 | |
| | 374 | lowres_geode->addDrawable(geometry); |
| | 375 | |
| | 376 | geometry->setInitialBound(bb); |
| | 377 | geometry->setInternalGeometry(point_geometry.get()); |
| | 378 | geometry->setStateSet(point_stateset.get()); |
| | 379 | |
| | 380 | lod->addChild( lowres_geode, nearDistance, farDistance ); |
| | 381 | } |
| 334 | | osg::Uniform* dv_i_Uniform = new osg::Uniform("dv_i",dv_i); |
| 335 | | osg::Uniform* dv_j_Uniform = new osg::Uniform("dv_j",dv_j); |
| 336 | | osg::Uniform* dv_k_Uniform = new osg::Uniform("dv_k",dv_k); |
| 337 | | |
| 338 | | osg::Uniform* inversePeriodUniform = new osg::Uniform("inversePeriod",1.0f/period); |
| 339 | | osg::Uniform* startTime = new osg::Uniform("startTime",0.0f); |
| | 398 | static osg::Uniform* dv_i_Uniform = new osg::Uniform("dv_i",dv_i); |
| | 399 | static osg::Uniform* dv_j_Uniform = new osg::Uniform("dv_j",dv_j); |
| | 400 | static osg::Uniform* dv_k_Uniform = new osg::Uniform("dv_k",dv_k); |
| | 401 | |
| | 402 | static osg::Uniform* inversePeriodUniform = new osg::Uniform("inversePeriod",1.0f/period); |
| | 403 | static osg::Uniform* startTime = new osg::Uniform("startTime",0.0f); |
| 366 | | geode->setCullCallback(new CullCallback(previousModelViewUniform)); |
| 367 | | |
| 368 | | } |
| 369 | | |
| 370 | | |
| 371 | | |
| 372 | | |
| 373 | | |
| 374 | | return geode; |
| 375 | | } |
| 376 | | /* |
| 377 | | osg::Node* createSnowEffect(const osg::BoundingBox& bb, const osg::Vec3& velocity, unsigned int numParticles, bool useShaders) |
| 378 | | { |
| 379 | | osg::Geometry* geometry = new osg::Geometry; |
| 380 | | |
| 381 | | osg::StateSet* stateset = geometry->getOrCreateStateSet(); |
| 382 | | |
| 383 | | // set up geometry. |
| 384 | | { |
| 385 | | |
| 386 | | // per vertex properties |
| 387 | | osg::Vec3Array* vertices = new osg::Vec3Array(numParticles); |
| 388 | | osg::FloatArray* offsets = new osg::FloatArray(numParticles); |
| 389 | | |
| 390 | | for(unsigned int i=0; i< numParticles; ++i) |
| 391 | | { |
| 392 | | (*vertices)[i].set(random(bb.xMin(), bb.xMax()), random(bb.yMin(),bb.yMax()), bb.zMax()); |
| 393 | | (*offsets)[i] = random(0.0, 1.0); |
| 394 | | } |
| 395 | | |
| 396 | | geometry->setVertexArray(vertices); |
| 397 | | geometry->setTexCoordArray(0, offsets); |
| 398 | | |
| 399 | | // overall attributes |
| 400 | | osg::Vec4Array* colours = new osg::Vec4Array(1); |
| 401 | | (*colours)[0].set(1.0f,1.0f,1.0f,1.0f); |
| 402 | | geometry->setColorArray(colours); |
| 403 | | geometry->setColorBinding(osg::Geometry::BIND_OVERALL); |
| 404 | | |
| 405 | | geometry->addPrimitiveSet(new osg::DrawArrays(GL_POINTS, 0, numParticles)); |
| 406 | | } |
| 407 | | |
| 408 | | // set up state. |
| 409 | | { |
| 410 | | // time taken to get from start to the end of cycle |
| 411 | | float period = fabs((bb.zMax()-bb.zMin()) / velocity.z()); |
| 412 | | |
| 413 | | // distance between start point and end of cyclce |
| 414 | | osg::Vec3 delta = velocity * period; |
| 415 | | |
| 416 | | // set up uniforms |
| 417 | | osg::Uniform* deltaUniform = new osg::Uniform("delta",delta); |
| 418 | | osg::Uniform* inversePeriodUniform = new osg::Uniform("inversePeriod",1.0f/period); |
| 419 | | osg::Uniform* startTime = new osg::Uniform("startTime",0.0f); |
| 420 | | |
| 421 | | osg::Program* program = new osg::Program; |
| 422 | | stateset->setAttribute(program); |
| 423 | | |
| 424 | | // get shaders from source |
| 425 | | program->addShader(osg::Shader::readShaderFile(osg::Shader::VERTEX, osgDB::findDataFile("snow.vert"))); |
| 426 | | program->addShader(osg::Shader::readShaderFile(osg::Shader::FRAGMENT, osgDB::findDataFile("snow.frag"))); |
| 427 | | |
| 428 | | stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF); |
| 429 | | |
| 430 | | stateset->addUniform(deltaUniform); |
| 431 | | stateset->addUniform(inversePeriodUniform); |
| 432 | | stateset->addUniform(startTime); |
| 433 | | } |
| 434 | | |
| 435 | | geometry->setInitialBound(bb); |
| 436 | | |
| 437 | | |
| 438 | | osg::Geode* geode = new osg::Geode; |
| 439 | | geode->addDrawable(geometry); |
| 440 | | |
| 441 | | return geode; |
| 442 | | } |
| 443 | | */ |
| 444 | | osg::Node* createModel(osg::Node* loadedModel, bool useShaders) |
| | 428 | lod->setCullCallback(new CullCallback(previousModelViewUniform)); |
| | 429 | |
| | 430 | } |
| | 431 | |
| | 432 | |
| | 433 | return lod; |
| | 434 | } |
| | 435 | |
| | 436 | osg::Node* createCellRainEffect(const osg::BoundingBox& bb, const osg::Vec3& velocity, unsigned int numParticles) |
| | 437 | { |
| | 438 | |
| | 439 | unsigned int numX = 50; |
| | 440 | unsigned int numY = 50; |
| | 441 | unsigned int numCells = numX*numY; |
| | 442 | unsigned int numParticlesPerCell = numParticles/numCells; |
| | 443 | |
| | 444 | setUpGeometries(numParticlesPerCell); |
| | 445 | |
| | 446 | std::cout<<"Effect total number of particles = "<<numParticles<<std::endl; |
| | 447 | std::cout<<"Number of cells = "<<numCells<<std::endl; |
| | 448 | std::cout<<"Number of particles per cell = "<<numParticlesPerCell<<std::endl; |
| | 449 | std::cout<<"Cell width = "<<(bb.xMax()-bb.xMin())/(float)(numX)<<std::endl; |
| | 450 | std::cout<<"Cell length = "<<(bb.yMax()-bb.yMin())/(float)(numY)<<std::endl; |
| | 451 | std::cout<<"Cell height = "<<(bb.zMax()-bb.zMin())<<std::endl; |
| | 452 | |
| | 453 | osg::Group* group = new osg::Group; |
| | 454 | for(unsigned int i=0; i<numX; ++i) |
| | 455 | { |
| | 456 | for(unsigned int j=0; j<numX; ++j) |
| | 457 | { |
| | 458 | osg::BoundingBox bbLocal(bb.xMin() + ((bb.xMax()-bb.xMin())*(float)i)/(float)(numX), |
| | 459 | bb.yMin() + ((bb.yMax()-bb.yMin())*(float)j)/(float)(numY), |
| | 460 | bb.zMin(), |
| | 461 | bb.xMin() + ((bb.xMax()-bb.xMin())*(float)(i+1))/(float)(numX), |
| | 462 | bb.yMin() + ((bb.yMax()-bb.yMin())*(float)(j+1))/(float)(numY), |
| | 463 | bb.zMax()); |
| | 464 | |
| | 465 | group->addChild(createRainEffect(bbLocal, velocity)); |
| | 466 | } |
| | 467 | } |
| | 468 | return group; |
| | 469 | } |
| | 470 | |
| | 471 | osg::Node* createModel(osg::Node* loadedModel, bool /*useShaders*/) |