00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "waterdyn3d.h"
00025 #include "skyBox.h"
00026 #include "glob.h"
00027
00028 typedef std::vector< osg::ref_ptr<osg::Image> > ImageList;
00029
00030 class findNodeVisitor : public osg::NodeVisitor
00031 {
00032 private:
00033 std::string searchName;
00034
00035 public:
00036 typedef std::vector<osg::Node*> TNodeList;
00037 TNodeList results;
00038 findNodeVisitor() : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN){}
00039 void setSearchName (const std::string &searchName){this->searchName=searchName;results.clear();}
00040 virtual void apply (osg::Node &searchNode){
00041 if (searchNode.getName().compare(0, searchName.length(),searchName)==0)
00042 results.push_back (&searchNode);
00043 traverse(searchNode);
00044 }
00045 };
00046
00047 osg::Node* clip_object_with_plane(osg::Node* subgraph, osg::Vec3 plane_norm, osg::Vec3 plane_point)
00048 {
00049 osg::Group* rootnode = new osg::Group;
00050
00051
00052
00053
00054 osg::StateSet* stateset = new osg::StateSet;
00055
00056 osg::PolygonMode* polymode = new osg::PolygonMode;
00057 polymode->setMode(osg::PolygonMode::FRONT_AND_BACK,osg::PolygonMode::LINE);
00058 stateset->setAttributeAndModes(polymode,osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON);
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080 osg::MatrixTransform* transform= new osg::MatrixTransform;
00081
00082 osg::ClipNode* clipnode = new osg::ClipNode;
00083
00084
00085 osg::Plane plane(plane_norm,plane_point);
00086
00087
00088 clipnode->addClipPlane(new osg::ClipPlane(0,plane));
00089 clipnode->setCullingActive(false);
00090
00091 transform->addChild(clipnode);
00092 rootnode->addChild(transform);
00093
00094
00095
00096 osg::Group* clipped_subgraph = new osg::Group;
00097
00098 clipped_subgraph->setStateSet(clipnode->getStateSet());
00099 clipped_subgraph->addChild(subgraph);
00100 rootnode->addChild(clipped_subgraph);
00101
00102 return rootnode;
00103 }
00104
00105 osg::Node* clip_object_with_box(osg::Node* subgraph, osg::BoundingBox bb)
00106 {
00107 osg::Group* rootnode = new osg::Group;
00108
00109
00110
00111
00112 osg::StateSet* stateset = new osg::StateSet;
00113
00114 osg::PolygonMode* polymode = new osg::PolygonMode;
00115 polymode->setMode(osg::PolygonMode::FRONT_AND_BACK,osg::PolygonMode::LINE);
00116 stateset->setAttributeAndModes(polymode,osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON);
00117
00118
00119
00120
00121
00122
00123
00124 osg::MatrixTransform* transform= new osg::MatrixTransform;
00125
00126 osg::ClipNode* clipnode = new osg::ClipNode;
00127
00128
00129 clipnode->createClipBox(bb);
00130 clipnode->setCullingActive(false);
00131
00132 transform->addChild(clipnode);
00133 rootnode->addChild(transform);
00134
00135
00136
00137 osg::Group* clipped_subgraph = new osg::Group;
00138
00139 clipped_subgraph->setStateSet(clipnode->getStateSet());
00140 clipped_subgraph->addChild(subgraph);
00141 rootnode->addChild(clipped_subgraph);
00142
00143 return rootnode;
00144 }
00145
00146
00147
00148 osg::Node* createWaterNode(osg::Node* scene, waterPlan* water1)
00149 {
00150
00151
00152 osg::MatrixTransform* rootNode = new osg::MatrixTransform;
00153
00154
00155
00156 osg::ColorMask* rootColorMask = new osg::ColorMask;
00157 rootColorMask->setMask(true,true,true,true);
00158
00159
00160
00161 osg::Depth* rootDepth = new osg::Depth;
00162 rootDepth->setFunction(osg::Depth::LESS);
00163 rootDepth->setRange(0.0,1.0);
00164
00165 osg::StateSet* rootStateSet = scene->getOrCreateStateSet();
00166 rootStateSet->setAttribute(rootColorMask);
00167 rootStateSet->setAttribute(rootDepth);
00168
00169 rootNode->setStateSet(rootStateSet);
00170
00171
00172
00173 {
00174
00175
00176
00177 osg::Stencil* stencil = new osg::Stencil;
00178 stencil->setFunction(osg::Stencil::ALWAYS,1,~0u);
00179 stencil->setOperation(osg::Stencil::KEEP, osg::Stencil::KEEP, osg::Stencil::REPLACE);
00180
00181
00182 osg::ColorMask* colorMask = new osg::ColorMask;
00183 colorMask->setMask(false,false,false,false);
00184
00185 osg::StateSet* statesetBin1 = new osg::StateSet();
00186 statesetBin1->setRenderBinDetails(1,"RenderBin");
00187 statesetBin1->setMode(GL_CULL_FACE,osg::StateAttribute::OFF);
00188 statesetBin1->setAttributeAndModes(stencil,osg::StateAttribute::ON);
00189 statesetBin1->setAttribute(colorMask);
00190
00191
00192 osg::Geode* geode = new osg::Geode;
00193 geode->addDrawable(water1->getOrCreateDrawable());
00194
00195 geode->setStateSet(statesetBin1);
00196
00197 rootNode->addChild(geode);
00198
00199 }
00200
00201
00202
00203
00204 {
00205 osg::Stencil* stencil = new osg::Stencil;
00206 stencil->setFunction(osg::Stencil::ALWAYS,0,~0u);
00207 stencil->setOperation(osg::Stencil::KEEP, osg::Stencil::KEEP, osg::Stencil::REPLACE);
00208
00209 osg::StateSet* statesetBin2 = new osg::StateSet();
00210 statesetBin2->setRenderBinDetails(2,"RenderBin");
00211 statesetBin2->setAttributeAndModes(stencil,osg::StateAttribute::ON);
00212
00213
00214 osg::Group* groupBin2 = new osg::Group();
00215 groupBin2->setStateSet(statesetBin2);
00216
00217
00218 rootNode->addChild(groupBin2);
00219 }
00220
00221
00222 {
00223
00224
00225 osg::Stencil* stencil = new osg::Stencil;
00226 stencil->setFunction(osg::Stencil::EQUAL,1,~0u);
00227 stencil->setOperation(osg::Stencil::KEEP, osg::Stencil::KEEP, osg::Stencil::KEEP);
00228
00229
00230 osg::ColorMask* colorMask = new osg::ColorMask;
00231 colorMask->setMask(false,false,false,false);
00232
00233
00234 osg::Depth* depth = new osg::Depth;
00235 depth->setFunction(osg::Depth::ALWAYS);
00236 depth->setRange(1.0,2.0);
00237
00238 osg::StateSet* statesetBin3 = new osg::StateSet();
00239 statesetBin3->setRenderBinDetails(3,"RenderBin");
00240 statesetBin3->setMode(GL_CULL_FACE,osg::StateAttribute::OFF);
00241 statesetBin3->setAttributeAndModes(stencil,osg::StateAttribute::ON);
00242 statesetBin3->setAttribute(colorMask);
00243 statesetBin3->setAttribute(depth);
00244
00245
00246
00247
00248 osg::Geode* geode = new osg::Geode;
00249 geode->addDrawable(water1->getOrCreateDrawable());
00250
00251 geode->setStateSet(statesetBin3);
00252
00253 rootNode->addChild(geode);
00254
00255 }
00256
00257
00258 {
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269 float z=water1->getZ();
00270
00271
00272
00273
00274 osg::ClipPlane* clipplane1 = new osg::ClipPlane;
00275 clipplane1->setClipPlane(0.0,0.0,-1.0,z);
00276 clipplane1->setClipPlaneNum(0);
00277
00278 osg::ClipNode* clipNode = new osg::ClipNode;
00279 clipNode->addClipPlane(clipplane1);
00280
00281 osg::StateSet* dstate = clipNode->getOrCreateStateSet();
00282 dstate->setRenderBinDetails(4,"RenderBin");
00283 dstate->setMode(GL_CULL_FACE,osg::StateAttribute::OVERRIDE|osg::StateAttribute::OFF);
00284
00285 osg::Stencil* stencil = new osg::Stencil;
00286 stencil->setFunction(osg::Stencil::EQUAL,1,~0u);
00287 stencil->setOperation(osg::Stencil::KEEP, osg::Stencil::KEEP, osg::Stencil::KEEP);
00288 dstate->setAttributeAndModes(stencil,osg::StateAttribute::ON);
00289
00290
00291 osg::MatrixTransform* reverseMatrix = new osg::MatrixTransform;
00292 reverseMatrix->setStateSet(dstate);
00293
00294 reverseMatrix->preMult(osg::Matrix::translate(0.0f,0.0f,-z)*
00295 osg::Matrix::scale(1.0f,1.0f,-1.0f)*
00296 osg::Matrix::translate(0.0f,0.0f,z));
00297
00298 reverseMatrix->addChild(scene);
00299
00300 clipNode->addChild(reverseMatrix);
00301
00302 rootNode->addChild(clipNode);
00303
00304 }
00305
00306
00307
00308 {
00309
00310
00311 osg::Depth* depth = new osg::Depth;
00312 depth->setFunction(osg::Depth::ALWAYS);
00313
00314 osg::Stencil* stencil = new osg::Stencil;
00315 stencil->setFunction(osg::Stencil::EQUAL,1,~0u);
00316 stencil->setOperation(osg::Stencil::KEEP, osg::Stencil::KEEP, osg::Stencil::ZERO);
00317
00318
00319 osg::BlendFunc* trans = new osg::BlendFunc;
00320 trans->setFunction(osg::BlendFunc::SRC_ALPHA,osg::BlendFunc::ONE_MINUS_SRC_ALPHA);
00321
00322
00323
00324 osg::StateSet* statesetBin5 = water1->getOrCreateGeodeWater(water1->createMirrorTexturedState())->getOrCreateStateSet();
00325
00326 statesetBin5->setRenderBinDetails(5,"RenderBin");
00327 statesetBin5->setMode(GL_CULL_FACE,osg::StateAttribute::OFF);
00328 statesetBin5->setAttributeAndModes(stencil,osg::StateAttribute::ON);
00329 statesetBin5->setAttributeAndModes(trans,osg::StateAttribute::ON);
00330 statesetBin5->setAttribute(depth);
00331
00332
00333
00334
00335
00336
00337 osg::Geode* geode = water1->getOrCreateGeodeWater(statesetBin5);
00338
00339 rootNode->addChild(geode);
00340
00341 }
00342
00343 return rootNode;
00344 }
00345
00346 osg::StateSet* createMirrorTexturedState(const std::string& filename)
00347 {
00348 osg::StateSet* dstate = new osg::StateSet;
00349
00350
00351
00352 dstate->setMode(GL_CULL_FACE,osg::StateAttribute::OFF|osg::StateAttribute::PROTECTED);
00353
00354 return dstate;
00355
00356 osg::Image* image = osgDB::readImageFile(filename.c_str());
00357 if (image)
00358 {
00359 osg::Texture2D* texture = new osg::Texture2D;
00360 texture->setImage(image);
00361 texture->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::REPEAT);
00362 texture->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::REPEAT);
00363 dstate->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON|osg::StateAttribute::PROTECTED);
00364
00365 }
00366
00367 return dstate;
00368 }
00369
00370 osg::Node* createWaterNodeWithoutMirror(osg::Node* scene, osg::Geode* mirrors)
00371 {
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385 osg::MatrixTransform* rootNode = new osg::MatrixTransform;
00386
00387
00388
00389 osg::BlendFunc* trans = new osg::BlendFunc;
00390 trans->setFunction(osg::BlendFunc::DST_COLOR,osg::BlendFunc::SRC_ALPHA);
00391
00392 osg::StateSet* statesetBin5 = createMirrorTexturedState("Textures/eau.bmp");
00393
00394 statesetBin5->setRenderBinDetails(5,"RenderBin");
00395 statesetBin5->setMode(GL_CULL_FACE,osg::StateAttribute::OFF);
00396 statesetBin5->setAttributeAndModes(trans,osg::StateAttribute::ON);
00397
00398
00399 osg::Group* grp = new osg::Group;
00400 grp->addChild(mirrors);
00401 grp->setStateSet(statesetBin5);
00402
00403 rootNode->addChild(grp);
00404
00405 return rootNode;
00406 }
00407
00408
00409
00410
00411
00412
00413 osg::Group* initWater(osg::ref_ptr<osg::Group> scene,osgProducer::Viewer* viewer, osg::Node* terrainNode, bool isfog)
00414 {
00415 osg::ref_ptr<osg::Group> scene_all = new osg::Group();
00416 scene_all->addChild(scene.get());
00417
00418
00419
00420
00421
00422
00423 bool fog=false;
00424
00425
00426
00427 float xmin_water1=-80;
00428 float xmax_water1=100;
00429 float ymin_water1=0;
00430 float ymax_water1=100;
00431 float z_water1=-8.8;
00432
00433 float xmin_water2=10;
00434 float xmax_water2=20;
00435 float ymin_water2=1;
00436 float ymax_water2=-50;
00437 float z_water2=-15.8;
00438
00439 osg::Vec3 plan_water1 = osg::Vec3(0,0,-1);
00440 osg::Vec3 plan_water2 = osg::Vec3(0,0,-1);
00441 osg::Vec3 point_water1 = osg::Vec3(0,0,3.2);
00442 osg::Vec3 point_water2 = osg::Vec3(0,0,4.0);
00443 osg::BoundingBox bb_water1(xmin_water1,33.5,z_water1,xmax_water1,ymax_water1+100,z_water1+20.0);
00444 osg::Vec3 plan_water1_upper;
00445 plan_water1_upper.set(plan_water1.x(),plan_water1.y(),plan_water1.z());
00446
00447
00448
00449
00450
00451
00452
00453
00457
00458
00459 osg::LOD * lod ;
00460 osg::PositionAttitudeTransform * pat;
00461 FogCube* fogcube ;
00462
00463 osg::Vec4 dark_blue = osg::Vec4(0.0, 0.0, 0.15, 0.9);
00464
00465 if(isfog)
00466 {
00467 osg::Node *terrainNodeUnderWater1 = clip_object_with_box(terrainNode, bb_water1);
00468
00469
00470
00472 std::cout << "Création du brouillard sur le terrain immergé..." <<std::endl;
00473
00474 fogcube = new FogCube();
00475 fogcube->setMode(osg::Fog::LINEAR);
00476 fogcube->setColor(dark_blue);
00477 fogcube->setDensity(0.075);
00478 fogcube->setCube(xmin_water1,xmax_water1,ymin_water1,ymax_water1,-10,0.0);
00479 fogcube->setStart(2.0);
00480 fogcube->setEnd(50.0);
00481 fogcube->addFog(terrainNodeUnderWater1);
00482
00483
00484
00485
00487 lod = new osg::LOD;
00488 lod->setRangeMode(osg::LOD::DISTANCE_FROM_EYE_POINT);
00489 lod->setCenterMode(osg::LOD::USE_BOUNDING_SPHERE_CENTER);
00490
00491
00492 pat = new osg::PositionAttitudeTransform();
00493 pat->addChild(terrainNodeUnderWater1);
00494 pat->setScale(osg::Vec3(1.5,1.5,2.5));
00495 pat->setPosition(osg::Vec3(-50,-50,-17.9));
00496 lod->addChild(pat,0,70.0);
00497
00498 pat = new osg::PositionAttitudeTransform();
00499 pat->addChild(terrainNodeUnderWater1);
00500 pat->setScale(osg::Vec3(1.5,1.5,2.5));
00501 pat->setPosition(osg::Vec3(-50,-50,-17.2));
00502 lod->addChild(pat,70.0,350.0);
00503
00504 pat = new osg::PositionAttitudeTransform();
00505 pat->addChild(terrainNodeUnderWater1);
00506 pat->setScale(osg::Vec3(1.5,1.5,2.5));
00507 pat->setPosition(osg::Vec3(-50,-50,-16.8));
00508 lod->addChild(pat,350.0,10000.0);
00509
00510 scene_all->addChild(lod);
00511 }
00512
00513
00515 pat = new osg::PositionAttitudeTransform();
00516 pat->addChild(terrainNode);
00517 pat->setScale(osg::Vec3(1.5,1.5,2.5));
00518 pat->setPosition(osg::Vec3(-50,-50,-18));
00519 scene->addChild(pat);
00520
00522 std::cout << "Création du barrage..." <<std::endl;
00523 osg::Node * damNode = osgDB::readNodeFile("Models/barrage/dam.osg");
00524
00529 findNodeVisitor fnv;
00530 fnv.setSearchName("barrageHaut");
00531 damNode->accept(fnv);
00532 osg::Node *damNodeTop =fnv.results[0] ;
00533 fnv.setSearchName("barrageDerriere");
00534 damNode->accept(fnv);
00535 osg::Node *damNodeUnderWater1 =fnv.results[0] ;
00536 fnv.setSearchName("barrageDevantFinal");
00537 damNode->accept(fnv);
00538 osg::Node *damNodeNotUnderWater1 =fnv.results[0] ;
00539 fnv.setSearchName("barrageDevant2");
00540 damNode->accept(fnv);
00541 osg::Node *damNodeNotUnderWater2 =fnv.results[0] ;
00542
00543 osg::Group* gr_dam = new osg::Group();
00544 gr_dam->addChild(damNodeTop);
00545 gr_dam->addChild(damNodeUnderWater1);
00546 gr_dam->addChild(damNodeNotUnderWater1);
00547 gr_dam->addChild(damNodeNotUnderWater2);
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558 if(isfog)
00559 {
00560 std::cout << "Création des fog sur la parties immergées du barrage..." <<std::endl;
00562 fogcube = new FogCube();
00563 fogcube->setMode(osg::Fog::LINEAR);
00564 fogcube->setColor(dark_blue);
00565 fogcube->setStart(0.0);
00566 fogcube->setEnd(40.0);
00567 fogcube->setDensity(0.075);
00568
00569 fogcube->setCube(xmin_water1,xmax_water1,ymin_water1,ymax_water1,0,50.0);
00570 fogcube->addDynamicFogCoords(damNodeUnderWater1);
00571 }
00572
00575 pat_dam = new osg::PositionAttitudeTransform();
00576 pat_dam->addChild(gr_dam);
00577 osg::Quat* quaternion = new osg::Quat();
00578 quaternion->makeRotate(1.57,1,0,0);
00579 pat_dam->setAttitude(*quaternion);
00580
00581 pat_dam->setPosition(osg::Vec3(-21.5,16.5,5.0));
00582 scene_all->addChild(pat_dam);
00583
00584
00585
00586
00589 std::cout << "Création du plan d'eau 1..." <<std::endl;
00590 waterPlan* water1 = new waterPlan();
00591 water1->setDeplacementWater(osg::Vec4f(-0.04,0.02,0.02,0.02));
00592 water1->setPlan(xmin_water1,xmax_water1,ymin_water1,ymax_water1,z_water1);
00593 water1->createMirrorSurfaceForTheDam(14.3);
00594
00595
00596 osg::ref_ptr<osg::Node> sceneAndWater = createWaterNode(scene.get(),water1);
00597 scene_all->addChild(sceneAndWater.get());
00598
00599
00603 if(isfog)
00604 {
00605 osg::Geode * p = water1->createGeodeUnderWater(14.3,-0.05);
00606 osg::Node * plan_dessous_water1 = createWaterNodeWithoutMirror(scene_all.get(),p);
00607 fogcube = new FogCube();
00608 fogcube->setMode(osg::Fog::LINEAR);
00609 fogcube->setColor(dark_blue);
00610 fogcube->setStart(0.0);
00611 fogcube->setEnd(10.0);
00612 fogcube->setDensity(0.075);
00613
00614 fogcube->addFog(p);
00615
00617 lod = new osg::LOD;
00618 lod->setRangeMode(osg::LOD::DISTANCE_FROM_EYE_POINT);
00619 lod->setCenterMode(osg::LOD::USE_BOUNDING_SPHERE_CENTER);
00620 lod->addChild(plan_dessous_water1,0,400.0);
00621 scene_all->addChild(lod);
00622 }
00623
00624
00625
00626
00628 std::cout << "Création du plan d'eau 2..." <<std::endl;
00629 waterPlan* water2 = new waterPlan();
00630 water2->setDeplacementWater(osg::Vec4f(-0.02,0.03,0.02,0.02));
00631 water2->setTexture("",3);
00632 water2->setPlan(xmin_water2,xmax_water2,ymin_water2,ymax_water2,z_water2);
00633 water2->createMirrorSurface();
00634 scene_all->addChild(water2->getOrCreateGeodeWater(water2->createMirrorTexturedState()));
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655 viewer->setSceneData(scene_all.get());
00656 viewer->setRealizeCallback((osgProducer::OsgCameraGroup::RealizeCallback*)waterPlan::getStateCallback(water1->getOrCreateGeodeWater(),water2->getOrCreateGeodeWater()));
00657
00658 return scene_all.get();
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677 }
00678
00679
00680
00681