| 125 | | osg::Geode* geode = osg::createGeodeForImage(image,s,t); |
| | 125 | float photoWidth = 0.0f; |
| | 126 | float photoHeight = 0.0f; |
| | 127 | float maxWidth = dr._maximumWidth.length(); |
| | 128 | float maxHeight = dr._maximumHeight.length(); |
| | 129 | |
| | 130 | |
| | 131 | if ((s/t)>(maxWidth/maxHeight)) |
| | 132 | { |
| | 133 | // photo wider than tall relative to the required pictures size. |
| | 134 | // so need to clamp the width to the maximum width and then |
| | 135 | // set the height to keep the original photo aspect ratio. |
| | 136 | |
| | 137 | photoWidth = maxWidth; |
| | 138 | photoHeight = photoWidth*(t/s); |
| | 139 | } |
| | 140 | else |
| | 141 | { |
| | 142 | // photo tall than wide relative to the required pictures size. |
| | 143 | // so need to clamp the height to the maximum height and then |
| | 144 | // set the width to keep the original photo aspect ratio. |
| | 145 | |
| | 146 | photoHeight = maxHeight; |
| | 147 | photoWidth = photoHeight*(s/t); |
| | 148 | } |
| | 149 | |
| | 150 | osg::Vec3 halfWidthVector(dr._maximumWidth*(photoWidth*0.5f/maxWidth)); |
| | 151 | osg::Vec3 halfHeightVector(dr._maximumHeight*(photoHeight*0.5f/maxHeight)); |
| | 152 | |
| | 153 | |
| | 154 | // set up the texture. |
| | 155 | osg::Texture2D* texture = new osg::Texture2D; |
| | 156 | texture->setImage(image); |
| | 157 | texture->setFilter(osg::Texture::MIN_FILTER,osg::Texture::LINEAR); |
| | 158 | texture->setFilter(osg::Texture::MAG_FILTER,osg::Texture::LINEAR); |
| | 159 | |
| | 160 | // set up the drawstate. |
| | 161 | osg::StateSet* dstate = new osg::StateSet; |
| | 162 | dstate->setMode(GL_LIGHTING,osg::StateAttribute::OFF); |
| | 163 | dstate->setTextureAttributeAndModes(0, texture,osg::StateAttribute::ON); |
| | 164 | |
| | 165 | // set up the geoset. |
| | 166 | osg::Geometry* geom = new osg::Geometry; |
| | 167 | geom->setStateSet(dstate); |
| | 168 | |
| | 169 | osg::Vec3Array* coords = new osg::Vec3Array(4); |
| | 170 | (*coords)[0] = dr._center - halfWidthVector + halfHeightVector; |
| | 171 | (*coords)[1] = dr._center - halfWidthVector - halfHeightVector; |
| | 172 | (*coords)[2] = dr._center + halfWidthVector - halfHeightVector; |
| | 173 | (*coords)[3] = dr._center + halfWidthVector + halfHeightVector; |
| | 174 | geom->setVertexArray(coords); |
| | 175 | |
| | 176 | osg::Vec2Array* tcoords = new osg::Vec2Array(4); |
| | 177 | (*tcoords)[0].set(0.0f,1.0f); |
| | 178 | (*tcoords)[1].set(0.0f,0.0f); |
| | 179 | (*tcoords)[2].set(1.0f,0.0f); |
| | 180 | (*tcoords)[3].set(1.0f,1.0f); |
| | 181 | geom->setTexCoordArray(0,tcoords); |
| | 182 | |
| | 183 | osg::Vec4Array* colours = new osg::Vec4Array(1); |
| | 184 | (*colours)[0].set(1.0f,1.0f,1.0,1.0f); |
| | 185 | geom->setColorArray(colours); |
| | 186 | geom->setColorBinding(osg::Geometry::BIND_OVERALL); |
| | 187 | |
| | 188 | geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4)); |
| | 189 | |
| | 190 | // set up the geode. |
| | 191 | osg::Geode* geode = new osg::Geode; |
| | 192 | geode->addDrawable(geom); |
| | 193 | |
| | 218 | |
| | 219 | static Page* createPage(Album* album, unsigned int pageNo, const std::string& filename, float width, float height) |
| | 220 | { |
| | 221 | osg::ref_ptr<Page> page = new Page(album, pageNo, filename, width, height); |
| | 222 | if (page.valid()) return page.release(); |
| | 223 | else return 0; |
| | 224 | } |
| | 225 | |
| | 226 | virtual void traverse(osg::NodeVisitor& nv); |
| | 227 | |
| | 228 | void setRotation(float angle) |
| | 229 | { |
| | 230 | _rotation = angle; |
| | 231 | _targetRotation = angle; |
| | 232 | dirtyBound(); |
| | 233 | } |
| | 234 | |
| | 235 | float getRotation() const { return _rotation; } |
| | 236 | |
| | 237 | void rotateTo(float angle, float timeToRotateBy) |
| | 238 | { |
| | 239 | _targetRotation = angle; |
| | 240 | _targetTime = timeToRotateBy; |
| | 241 | } |
| | 242 | |
| | 243 | bool rotating() const { return _targetRotation!=_rotation; } |
| | 244 | |
| | 245 | void setPageVisible(bool visible) { _switch->setSingleChildOn(visible?1:0); } |
| | 246 | |
| | 247 | osg::Switch* getSwitch() { return _switch.get(); } |
| | 248 | const osg::Switch* getSwitch() const { return _switch.get(); } |
| | 249 | |
| | 250 | public: |
| | 251 | |
| | 252 | virtual bool computeLocalToWorldMatrix(osg::Matrix& matrix,osg::NodeVisitor*) const |
| | 253 | { |
| | 254 | if (_referenceFrame==RELATIVE_TO_PARENTS) |
| | 255 | { |
| | 256 | matrix.preMult(getMatrix()); |
| | 257 | } |
| | 258 | else // absolute |
| | 259 | { |
| | 260 | matrix = getMatrix(); |
| | 261 | } |
| | 262 | return true; |
| | 263 | } |
| | 264 | |
| | 265 | /** Get the transformation matrix which moves from world coords to local coords.*/ |
| | 266 | virtual bool computeWorldToLocalMatrix(osg::Matrix& matrix,osg::NodeVisitor*) const |
| | 267 | { |
| | 268 | const osg::Matrix& inverse = getInverseMatrix(); |
| | 269 | |
| | 270 | if (_referenceFrame==RELATIVE_TO_PARENTS) |
| | 271 | { |
| | 272 | matrix.postMult(inverse); |
| | 273 | } |
| | 274 | else // absolute |
| | 275 | { |
| | 276 | matrix = inverse; |
| | 277 | } |
| | 278 | return true; |
| | 279 | } |
| | 280 | |
| | 281 | osg::Matrix getMatrix() const { return _pageOffset*osg::Matrix::rotate(-_rotation,0.0f,0.0f,1.0f); } |
| | 282 | osg::Matrix getInverseMatrix() const { return osg::Matrix::inverse(getMatrix()); } |
| | 283 | |
| | 284 | protected: |
| | 285 | |
| | 286 | Page(Album* album, unsigned int pageNo, const std::string& filename, float width, float height); |
| | 287 | |
| | 288 | float _rotation; |
| | 289 | osg::Matrix _pageOffset; |
| | 290 | |
| | 291 | float _targetRotation; |
| | 292 | float _targetTime; |
| | 293 | float _lastTimeTraverse; |
| | 294 | |
| | 295 | osg::ref_ptr<osg::Switch> _switch; |
| | 296 | |
| | 297 | }; |
| | 298 | |
| | 299 | |
| | 300 | class Album : public osg::Referenced |
| | 301 | { |
| | 302 | public: |
| | 303 | |
| | 304 | Album(osg::ArgumentParser& ap, float width, float height); |
| | 305 | |
| | 306 | osg::Group* getScene() { return _group.get(); } |
| | 307 | |
| | 308 | const osg::Group* getScene() const { return _group.get(); } |
| | 309 | |
| | 310 | osg::Matrix getPageOffset(unsigned int pageNo) const; |
| | 311 | |
| | 312 | bool nextPage(float timeToRotateBy) { return gotoPage(_currentPageNo+1,timeToRotateBy); } |
| | 313 | |
| | 314 | bool previousPage(float timeToRotateBy) { return _currentPageNo>=1?gotoPage(_currentPageNo-1,timeToRotateBy):false; } |
| | 315 | |
| | 316 | bool gotoPage(unsigned int pageNo, float timeToRotateBy); |
| | 317 | |
| | 318 | osg::StateSet* getBackgroundStateSet() { return _backgroundStateSet.get(); } |
| | 319 | |
| | 320 | void setVisibility(); |
| | 321 | |
| | 322 | protected: |
| | 323 | |
| | 324 | typedef std::vector< osg::ref_ptr<Page> > PageList; |
| | 325 | |
| | 326 | osg::ref_ptr<osg::Group> _group; |
| | 327 | PageList _pages; |
| | 328 | |
| | 329 | osg::ref_ptr<osg::StateSet> _backgroundStateSet; |
| | 330 | |
| | 331 | unsigned int _currentPageNo; |
| | 332 | float _radiusOfRings; |
| | 333 | float _startAngleOfPages; |
| | 334 | float _deltaAngleBetweenPages; |
| | 335 | |
| | 336 | }; |
| | 337 | |
| | 338 | |
| | 339 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
| | 340 | |
| | 341 | |
| | 342 | Page::Page(Album* album, unsigned int pageNo, const std::string& filename, float width, float height) |
| | 343 | { |
| | 344 | // set up transform parts. |
| | 345 | _rotation = 0; |
| | 346 | _targetRotation = 0; |
| | 347 | _targetTime = 0; |
| | 348 | _lastTimeTraverse = 0; |
| | 349 | |
| | 350 | _pageOffset = album->getPageOffset(pageNo); |
| | 351 | |
| | 352 | setNumChildrenRequiringUpdateTraversal(1); |
| | 353 | |
| | 354 | |
| | 355 | // set up subgraph |
| | 356 | osgDB::ReaderWriter* readerWriter = osgDB::Registry::instance()->getReaderWriterForExtension("gdal"); |
| | 357 | if (!readerWriter) |
| | 358 | { |
| | 359 | std::cout<<"Error: GDAL plugin not available, cannot preceed with database creation"<<std::endl; |
| | 360 | } |
| | 361 | |
| | 362 | _switch = new osg::Switch; |
| | 363 | |
| | 364 | ImageReaderWriter* rw = g_ImageReaderWriter.get(); |
| | 365 | |
| | 366 | |
| | 367 | // set up non visible page. |
| | 368 | osg::Group* non_visible_page = new osg::Group; |
| | 369 | _switch->addChild(non_visible_page); |
| | 370 | { |
| | 371 | // just an empty group for the time being... will need to create geometry soon. |
| | 372 | osg::Geometry* geom = new osg::Geometry; |
| | 373 | geom->setStateSet(album->getBackgroundStateSet()); |
| | 374 | |
| | 375 | osg::Vec3Array* coords = new osg::Vec3Array(4); |
| | 376 | (*coords)[0].set(0.0f,0.0,height); |
| | 377 | (*coords)[1].set(0.0f,0.0,0); |
| | 378 | (*coords)[2].set(width,0.0,0); |
| | 379 | (*coords)[3].set(width,0.0,height); |
| | 380 | geom->setVertexArray(coords); |
| | 381 | |
| | 382 | osg::Vec3Array* normals = new osg::Vec3Array(1); |
| | 383 | (*normals)[0].set(0.0f,-1.0f,0.0f); |
| | 384 | geom->setNormalArray(normals); |
| | 385 | geom->setNormalBinding(osg::Geometry::BIND_OVERALL); |
| | 386 | |
| | 387 | osg::Vec2Array* tcoords = new osg::Vec2Array(4); |
| | 388 | (*tcoords)[0].set(0.0f,1.0f); |
| | 389 | (*tcoords)[1].set(0.0f,0.0f); |
| | 390 | (*tcoords)[2].set(1.0f,0.0f); |
| | 391 | (*tcoords)[3].set(1.0f,1.0f); |
| | 392 | geom->setTexCoordArray(0,tcoords); |
| | 393 | |
| | 394 | osg::Vec4Array* colours = new osg::Vec4Array(1); |
| | 395 | (*colours)[0].set(1.0f,1.0f,1.0,1.0f); |
| | 396 | geom->setColorArray(colours); |
| | 397 | geom->setColorBinding(osg::Geometry::BIND_OVERALL); |
| | 398 | |
| | 399 | geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_LOOP,0,4)); |
| | 400 | |
| | 401 | // set up the geode. |
| | 402 | osg::Geode* geode = new osg::Geode; |
| | 403 | geode->addDrawable(geom); |
| | 404 | |
| | 405 | |
| | 406 | non_visible_page->addChild(geode); |
| | 407 | } |
| | 408 | |
| | 409 | |
| | 410 | // set up visible page. |
| | 411 | osg::Group* visible_page = new osg::Group; |
| | 412 | _switch->addChild(visible_page); |
| | 413 | |
| | 414 | { |
| | 415 | |
| | 416 | |
| | 417 | osg::Geometry* geom = new osg::Geometry; |
| | 418 | geom->setStateSet(album->getBackgroundStateSet()); |
| | 419 | |
| | 420 | osg::Vec3Array* coords = new osg::Vec3Array(4); |
| | 421 | (*coords)[0].set(0.0f,0.0,height); |
| | 422 | (*coords)[1].set(0.0f,0.0,0); |
| | 423 | (*coords)[2].set(width,0.0,0); |
| | 424 | (*coords)[3].set(width,0.0,height); |
| | 425 | geom->setVertexArray(coords); |
| | 426 | |
| | 427 | osg::Vec3Array* normals = new osg::Vec3Array(1); |
| | 428 | (*normals)[0].set(0.0f,-1.0f,0.0f); |
| | 429 | geom->setNormalArray(normals); |
| | 430 | geom->setNormalBinding(osg::Geometry::BIND_OVERALL); |
| | 431 | |
| | 432 | osg::Vec2Array* tcoords = new osg::Vec2Array(4); |
| | 433 | (*tcoords)[0].set(0.0f,1.0f); |
| | 434 | (*tcoords)[1].set(0.0f,0.0f); |
| | 435 | (*tcoords)[2].set(1.0f,0.0f); |
| | 436 | (*tcoords)[3].set(1.0f,1.0f); |
| | 437 | geom->setTexCoordArray(0,tcoords); |
| | 438 | |
| | 439 | osg::Vec4Array* colours = new osg::Vec4Array(1); |
| | 440 | (*colours)[0].set(1.0f,1.0f,1.0,1.0f); |
| | 441 | geom->setColorArray(colours); |
| | 442 | geom->setColorBinding(osg::Geometry::BIND_OVERALL); |
| | 443 | |
| | 444 | geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4)); |
| | 445 | |
| | 446 | // set up the geode. |
| | 447 | osg::Geode* geode = new osg::Geode; |
| | 448 | geode->addDrawable(geom); |
| | 449 | |
| | 450 | |
| | 451 | visible_page->addChild(geode); |
| | 452 | } |
| | 453 | |
| | 454 | { |
| | 455 | float cut_off_distance = 8.0f; |
| | 456 | float max_visible_distance = 300.0f; |
| | 457 | |
| | 458 | osg::Vec3 center(width*0.5f,0.0f,height*0.5f); |
| | 459 | |
| | 460 | osgText::Text* text = new osgText::Text; |
| | 461 | text->setFont("fonts/arial.ttf"); |
| | 462 | text->setPosition(center); |
| | 463 | text->setCharacterSize(height/20.0f); |
| | 464 | text->setAlignment(osgText::Text::CENTER_CENTER); |
| | 465 | text->setAxisAlignment(osgText::Text::XZ_PLANE); |
| | 466 | text->setColor(osg::Vec4(1.0f,1.0f,0.0f,1.0f)); |
| | 467 | text->setText(std::string("Loading ")+filename); |
| | 468 | |
| | 469 | osg::Geode* geode = new osg::Geode; |
| | 470 | geode->addDrawable(text); |
| | 471 | |
| | 472 | osg::PagedLOD* pagedlod = new osg::PagedLOD; |
| | 473 | pagedlod->setCenter(center); |
| | 474 | pagedlod->setRadius(1.6f); |
| | 475 | pagedlod->setNumChildrenThatCannotBeExpired(2); |
| | 476 | |
| | 477 | pagedlod->setRange(0,max_visible_distance,1e7); |
| | 478 | pagedlod->addChild(geode); |
| | 479 | |
| | 480 | pagedlod->setRange(1,cut_off_distance,max_visible_distance); |
| | 481 | pagedlod->setFileName(1,rw->insertReference(filename,256,width,height)); |
| | 482 | |
| | 483 | pagedlod->setRange(2,0.0f,cut_off_distance); |
| | 484 | pagedlod->setFileName(2,rw->insertReference(filename,1024,width,height)); |
| | 485 | |
| | 486 | visible_page->addChild(pagedlod); |
| | 487 | } |
| | 488 | |
| | 489 | addChild(_switch.get()); |
| | 490 | } |
| | 491 | |
| | 492 | void Page::traverse(osg::NodeVisitor& nv) |
| | 493 | { |
| | 494 | // if app traversal update the frame count. |
| | 495 | if (nv.getVisitorType()==osg::NodeVisitor::UPDATE_VISITOR) |
| | 496 | { |
| | 497 | const osg::FrameStamp* framestamp = nv.getFrameStamp(); |
| | 498 | if (framestamp) |
| | 499 | { |
| | 500 | double t = framestamp->getReferenceTime(); |
| | 501 | |
| | 502 | if (_rotation!=_targetRotation) |
| | 503 | { |
| | 504 | if (t>=_targetTime) _rotation = _targetRotation; |
| | 505 | else _rotation += (_targetRotation-_rotation)*(t-_lastTimeTraverse)/(_targetTime-_lastTimeTraverse); |
| | 506 | |
| | 507 | dirtyBound(); |
| | 508 | } |
| | 509 | |
| | 510 | _lastTimeTraverse = t; |
| | 511 | |
| | 512 | } |
| | 513 | } |
| | 514 | Transform::traverse(nv); |
| | 515 | } |
| | 516 | |
| | 517 | |
| | 518 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
| | 519 | |
| | 520 | Album::Album(osg::ArgumentParser& arguments, float width, float height) |
| | 521 | { |
| | 522 | |
| | 523 | |
| | 524 | typedef std::vector<std::string> FileList; |
| | 525 | FileList fileList; |
| | 526 | |
| | 527 | for(int pos=1;pos<arguments.argc();++pos) |
| | 528 | { |
| | 529 | if (arguments.isString(pos)) fileList.push_back(arguments[pos]); |
| | 530 | } |
| | 531 | |
| | 532 | _radiusOfRings = 0.02; |
| | 533 | _startAngleOfPages = 0.0f; |
| | 534 | _deltaAngleBetweenPages = osg::PI/(float)fileList.size(); |
| | 535 | |
| | 536 | _group = new osg::Group; |
| | 537 | |
| | 538 | _backgroundStateSet = new osg::StateSet; |
| | 539 | _backgroundStateSet->setAttributeAndModes(new osg::PolygonOffset(1.0f,1.0f),osg::StateAttribute::ON); |
| | 540 | |
| | 541 | // load the images. |
| | 542 | unsigned int i; |
| | 543 | for(i=0;i<fileList.size();++i) |
| | 544 | { |
| | 545 | Page* page = Page::createPage(this,_pages.size(),fileList[i], width, height); |
| | 546 | if (page) |
| | 547 | { |
| | 548 | _pages.push_back(page); |
| | 549 | _group->addChild(page); |
| | 550 | } |
| | 551 | } |
| | 552 | |
| | 553 | setVisibility(); |
| | 554 | |
| | 555 | } |
| | 556 | |
| | 557 | osg::Matrix Album::getPageOffset(unsigned int pageNo) const |
| | 558 | { |
| | 559 | float angleForPage = _startAngleOfPages+_deltaAngleBetweenPages*(float)pageNo; |
| | 560 | osg::Vec3 delta(_radiusOfRings*sinf(angleForPage),-_radiusOfRings*cosf(angleForPage),0.0f); |
| | 561 | return osg::Matrix::translate(delta); |
| | 562 | } |
| | 563 | |
| | 564 | bool Album::gotoPage(unsigned int pageNo, float timeToRotateBy) |
| | 565 | { |
| | 566 | if (pageNo>=_pages.size()) return false; |
| | 567 | |
| | 568 | if (pageNo>_currentPageNo) |
| | 569 | { |
| | 570 | for(unsigned int i=_currentPageNo;i<pageNo;++i) |
| | 571 | { |
| | 572 | _pages[i]->rotateTo(osg::PI,timeToRotateBy); |
| | 573 | } |
| | 574 | _pages[pageNo]->setPageVisible(true); |
| | 575 | _currentPageNo = pageNo; |
| | 576 | |
| | 577 | return true; |
| | 578 | } |
| | 579 | else if (pageNo<_currentPageNo) |
| | 580 | { |
| | 581 | for(unsigned int i=pageNo;i<_currentPageNo;++i) |
| | 582 | { |
| | 583 | _pages[i]->rotateTo(0,timeToRotateBy); |
| | 584 | } |
| | 585 | _pages[pageNo]->setPageVisible(true); |
| | 586 | _currentPageNo = pageNo; |
| | 587 | |
| | 588 | return true; |
| | 589 | } |
| | 590 | |
| | 591 | return false; |
| | 592 | } |
| | 593 | |
| | 594 | void Album::setVisibility() |
| | 595 | { |
| | 596 | for(unsigned int i=0;i<_pages.size();++i) |
| | 597 | { |
| | 598 | _pages[i]->setPageVisible(_pages[i]->rotating()); |
| | 599 | } |
| | 600 | |
| | 601 | //_pages[0]->setPageVisible(true); |
| | 602 | //if (_currentPageNo>=1) _pages[_currentPageNo-1]->setPageVisible(true); |
| | 603 | _pages[_currentPageNo]->setPageVisible(true); |
| | 604 | //if (_currentPageNo<_pages.size()-1) _pages[_currentPageNo+1]->setPageVisible(true); |
| | 605 | //_pages[_pages.size()-1]->setPageVisible(true); |
| | 606 | } |
| | 607 | |
| | 608 | |
| | 609 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
| | 610 | |
| | 611 | |
| | 612 | class SlideEventHandler : public osgGA::GUIEventHandler |
| | 613 | { |
| | 614 | public: |
| | 615 | |
| 239 | | } |
| 240 | | |
| 241 | | void SlideEventHandler::operator()(osg::Node* node, osg::NodeVisitor* nv) |
| 242 | | { |
| 243 | | if (_autoSteppingActive && nv->getFrameStamp()) |
| 244 | | { |
| 245 | | double time = nv->getFrameStamp()->getReferenceTime(); |
| 246 | | |
| 247 | | if (_firstTraversal) |
| 248 | | { |
| 249 | | _firstTraversal = false; |
| 250 | | _previousTime = time; |
| 251 | | } |
| 252 | | else if (time-_previousTime>_timePerSlide) |
| 253 | | { |
| 254 | | _previousTime = time; |
| 255 | | |
| 256 | | nextSlide(); |
| 257 | | } |
| 258 | | |
| 259 | | } |
| 260 | | |
| 261 | | traverse(node,nv); |
| 262 | | } |
| 263 | | |
| 264 | | void SlideEventHandler::nextSlide() |
| 265 | | { |
| 266 | | if (_switch->getNumChildren()==0) return; |
| 267 | | |
| 268 | | ++_activeSlide; |
| 269 | | if (_activeSlide>=_switch->getNumChildren()) _activeSlide = 0; |
| 270 | | |
| 271 | | _switch->setSingleChildOn(_activeSlide); |
| 272 | | } |
| 273 | | |
| 274 | | void SlideEventHandler::previousSlide() |
| 275 | | { |
| 276 | | if (_switch->getNumChildren()==0) return; |
| 277 | | |
| 278 | | if (_activeSlide==0) _activeSlide = _switch->getNumChildren()-1; |
| 279 | | else --_activeSlide; |
| 280 | | |
| 281 | | _switch->setSingleChildOn(_activeSlide); |
| 282 | | } |
| 283 | | |
| 284 | | // create a switch containing a set of child each containing a |
| 285 | | // stereo image pair. |
| 286 | | osg::Switch* createScene(const FileList& fileList, float height, float length) |
| 287 | | { |
| 288 | | osgDB::ReaderWriter* readerWriter = osgDB::Registry::instance()->getReaderWriterForExtension("gdal"); |
| 289 | | if (!readerWriter) |
| 290 | | { |
| 291 | | std::cout<<"Error: GDAL plugin not available, cannot preceed with database creation"<<std::endl; |
| 292 | | return 0; |
| 293 | | } |
| 294 | | |
| 295 | | ImageReaderWriter* rw = g_ImageReaderWriter.get(); |
| 296 | | |
| 297 | | osg::Switch* sw = new osg::Switch; |
| 298 | | |
| 299 | | typedef std::vector< osg::ref_ptr<osg::Node> > NodeList; |
| 300 | | NodeList nodes; |
| 301 | | |
| 302 | | // load the images. |
| 303 | | unsigned int i; |
| 304 | | for(i=0;i<fileList.size();++i) |
| 305 | | { |
| 306 | | float cut_off_distance = 8.0f; |
| 307 | | float max_visible_distance = 300.0f; |
| 308 | | |
| 309 | | osg::Vec3 center(0.0f,0.0f,0.0f); |
| 310 | | |
| 311 | | osgText::Text* text = new osgText::Text; |
| 312 | | text->setFont("fonts/arial.ttf"); |
| 313 | | text->setPosition(center); |
| 314 | | text->setCharacterSize(0.1f); |
| 315 | | text->setAlignment(osgText::Text::CENTER_CENTER); |
| 316 | | text->setAxisAlignment(osgText::Text::XZ_PLANE); |
| 317 | | text->setText(fileList[i]); |
| 318 | | |
| 319 | | osg::Geode* geode = new osg::Geode; |
| 320 | | geode->addDrawable(text); |
| 321 | | |
| 322 | | osg::PagedLOD* pagedlod = new osg::PagedLOD; |
| 323 | | pagedlod->setCenter(center); |
| 324 | | pagedlod->setRadius(1.6f); |
| 325 | | pagedlod->setNumChildrenThatCannotBeExpired(2); |
| 326 | | |
| 327 | | pagedlod->setRange(0,max_visible_distance,1e7); |
| 328 | | pagedlod->addChild(geode); |
| 329 | | |
| 330 | | pagedlod->setRange(1,cut_off_distance,max_visible_distance); |
| 331 | | pagedlod->setFileName(1,rw->insertReference(fileList[i],128)); |
| 332 | | |
| 333 | | pagedlod->setRange(2,0.0f,cut_off_distance); |
| 334 | | pagedlod->setFileName(2,rw->insertReference(fileList[i],1024)); |
| 335 | | |
| 336 | | nodes.push_back(pagedlod); |
| 337 | | } |
| 338 | | |
| 339 | | |
| 340 | | if (nodes.empty()) return 0; |
| 341 | | |
| 342 | | osg::Group* front = new osg::Group; |
| 343 | | sw->addChild(front); |
| 344 | | |
| 345 | | unsigned int nodes_across = (unsigned int)ceilf(sqrtf((float)nodes.size()*1.25)); |
| 346 | | unsigned int nodes_down = (unsigned int)ceilf((float)nodes.size()/(float)nodes_across); |
| 347 | | |
| 348 | | float scale = 1.0f/(float)nodes_down; |
| 349 | | |
| 350 | | osg::Vec3 down_delta(0.0f,0.0f,-scale); |
| 351 | | osg::Vec3 across_delta(scale*1.25,0.0f,0.0f); |
| 352 | | osg::Vec3 leftMargin(-down_delta*((float)nodes_down*0.5f)-across_delta*((float)nodes_across*0.5f)); |
| 353 | | |
| 354 | | osg::Vec3 pos = leftMargin; |
| 355 | | i=0; |
| 356 | | |
| 357 | | // front cover background |
| 358 | | { |
| 359 | | osg::Geometry* geometry = createTexturedQuadGeometry(osg::Vec3(-1.25f,0.0f,-1.0f),osg::Vec3(2.5f,0.0f,0.0f),osg::Vec3(0.0f,0.0f,2.0f)); |
| 360 | | osg::Geode* background = new osg::Geode; |
| 361 | | background->addDrawable(geometry); |
| 362 | | front->addChild(background); |
| 363 | | |
| 364 | | osg::StateSet* stateset = geometry->getOrCreateStateSet(); |
| 365 | | stateset->setAttributeAndModes(new osg::PolygonOffset(2.0f,2.0f),osg::StateAttribute::ON); |
| 366 | | stateset->setTextureAttributeAndModes(0,new osg::Texture2D(osgDB::readImageFile("lz.rgb")),osg::StateAttribute::ON); |
| 367 | | } |
| 368 | | |
| 369 | | NodeList::iterator itr; |
| 370 | | for(itr=nodes.begin(); |
| 371 | | itr!=nodes.end(); |
| 372 | | ++itr) |
| 373 | | { |
| 374 | | osg::MatrixTransform* mt = new osg::MatrixTransform; |
| 375 | | mt->setMatrix(osg::Matrix::scale(scale*0.45f,scale*0.45f,scale*0.45f)*osg::Matrix::translate(pos)); |
| 376 | | mt->addChild(itr->get()); |
| 377 | | front->addChild(mt); |
| 378 | | |
| 379 | | i++; |
| 380 | | if ((i%nodes_across)==0) |
| 381 | | { |
| 382 | | leftMargin += down_delta; |
| 383 | | pos = leftMargin; |
| 384 | | } |
| 385 | | else pos += across_delta; |
| 386 | | } |
| 387 | | |
| 388 | | |
| 389 | | for(itr=nodes.begin(); |
| 390 | | itr!=nodes.end(); |
| 391 | | ++itr) |
| 392 | | { |
| 393 | | sw->addChild(itr->get()); |
| 394 | | } |
| 395 | | |
| 396 | | if (sw->getNumChildren()>0) |
| 397 | | { |
| 398 | | // select first child. |
| 399 | | sw->setSingleChildOn(0); |
| 400 | | } |
| 401 | | |
| 402 | | return sw; |