00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #include <stdlib.h>
00044 #include <stdio.h>
00045
00046 #include <OSGConfig.h>
00047
00048 #include <OSGGL.h>
00049
00050 #include <OSGAction.h>
00051 #include <OSGCamera.h>
00052 #include <OSGDrawAction.h>
00053 #include <OSGRenderAction.h>
00054 #include <OSGIntersectAction.h>
00055 #include <OSGSimpleMaterial.h>
00056 #include <OSGDVRVolumeTexture.h>
00057 #include <OSGDVRAppearance.h>
00058 #include <OSGBrick.h>
00059 #include <OSGSlicer.h>
00060
00061 #include "OSGDVRVolume.h"
00062 #include "OSGDVRClipObjects.h"
00063 #include "OSGDVRClipper.h"
00064
00065
00066 OSG_USING_NAMESPACE
00067
00072 UInt32 DVRVolume::_extTex3D = Window::invalidExtensionID;
00073
00074
00075
00076 #ifdef OSG_WIN32_CL
00077 #pragma warning( disable : 4355 )
00078 #endif
00079
00081 DVRVolume::DVRVolume(void) :
00082 Inherited ( ),
00083 drawStyleListValid(false),
00084 textureManager (this ),
00085 shadingInitialized(false)
00086 {
00087 SINFO << "DVRVolume::DVRVolume(void) this: " << this << std::endl;
00088
00089 _extTex3D = Window::registerExtension( "GL_EXT_texture3D" );
00090
00091 commonConstructor();
00092 }
00093
00095 DVRVolume::DVRVolume(const DVRVolume &source) :
00096 Inherited (source),
00097 drawStyleListValid(false ),
00098 textureManager (this ),
00099 shadingInitialized(false )
00100 {
00101 SINFO << "DVRVolume::DVRVolume(const DVRVolume &source) this: "
00102 << this << std::endl;
00103
00110
00111 DVRVolumePtr ptr(*this);
00112
00113
00114 SimpleMaterialPtr m = SimpleMaterial::create();
00115
00116 beginEditCP(m);
00117 {
00118 m->setTransparency(0.001f );
00119 m->setLit (false );
00120 m->setDiffuse (Color3f(1.0, 1.0, 1.0));
00121 m->setAmbient (Color3f(1.0, 1.0, 1.0));
00122 }
00123 endEditCP(m);
00124
00125
00126 ChunkMaterialPtr cm = SimpleMaterial::create();
00127
00128
00129 beginEditCP(ptr, RenderMaterialFieldMask | TextureStorageFieldMask);
00130 {
00131 setRenderMaterial(m );
00132 setTextureStorage(cm);
00133 }
00134 endEditCP (ptr, RenderMaterialFieldMask | TextureStorageFieldMask);
00135
00136 commonConstructor();
00137 }
00138
00139 #ifdef OSG_WIN32_CL
00140 #pragma warning( default : 4355 )
00141 #endif
00142
00144 DVRVolume::~DVRVolume(void)
00145 {
00146 SINFO << "~DVRVolume this: "
00147 << this
00148 << std::endl
00149 << "~DVRVolume appearance: "
00150 << getAppearance()
00151 << std::endl
00152 << "~DVRVolume::subRefCP(Appearance)"
00153 << std::endl;
00154
00155 subRefCP(_sfAppearance.getValue());
00156
00157 SINFO << "~DVRVolume::subRefCP(Geometry)"
00158 << std::endl;
00159
00160
00161
00162
00163 subRefCP(_sfGeometry.getValue());
00164
00165 SINFO << "~DVRVolume::subRefCP(Shader)" << std::endl;
00166 SINFO << "~DVRVolume shader: " << getShader() << std::endl;
00167
00168 subRefCP(_sfShader.getValue());
00169
00170 SINFO << "~DVRVolume::subRefCP(RenderMaterial)"
00171 << std::endl
00172 << "~DVRVolume renderMaterial: "
00173 << getRenderMaterial()
00174 << std::endl;
00175
00176 subRefCP(_sfRenderMaterial.getValue());
00177
00178 SINFO << "~DVRVolume::subRefCP(TextureStorage)"
00179 << std::endl
00180 << "~DVRVolume textureStorage: "
00181 << getTextureStorage()
00182 << std::endl;
00183
00184 subRefCP(_sfTextureStorage.getValue());
00185 }
00186
00187
00188
00189
00191 void DVRVolume::adjustVolume(Volume &volume)
00192 {
00193 volume.setValid();
00194 volume.setEmpty();
00195
00196 DVRVolumeTexturePtr tex = DVRVOLUME_PARAMETER(this, DVRVolumeTexture);
00197
00198 if (tex != NullFC)
00199 {
00200 const Vec3f & res = tex->getResolution ();
00201 const Vec3f & slice = tex->getSliceThickness();
00202
00203 Vec3f minBB(-0.5f * res[0] * slice[0],
00204 -0.5f * res[1] * slice[1],
00205 -0.5f * res[2] * slice[2]);
00206
00207 Vec3f maxBB(-minBB);
00208
00209 volume.extendBy(minBB);
00210 volume.extendBy(maxBB);
00211 }
00212 else
00213 {
00214
00215 Vec3f minBB(-0.5, -0.5, -0.5);
00216 Vec3f maxBB( 0.5, 0.5, 0.5);
00217
00218 volume.extendBy(minBB);
00219 volume.extendBy(maxBB);
00220 }
00221 }
00222
00223
00225 void DVRVolume::initMethod(void)
00226 {
00227 DrawAction::registerEnterDefault( getClassType(),
00228 osgTypedMethodFunctor2BaseCPtrRef<Action::ResultE,
00229 DVRVolumePtr,
00230 CNodePtr,
00231 Action *>(&DVRVolume::doDraw));
00232
00233 IntersectAction::registerEnterDefault( getClassType(),
00234 osgTypedMethodFunctor2BaseCPtrRef<Action::ResultE,
00235 DVRVolumePtr,
00236 CNodePtr,
00237 Action *>(&DVRVolume::intersect));
00238
00239 RenderAction::registerEnterDefault( getClassType(),
00240 osgTypedMethodFunctor2BaseCPtrRef<Action::ResultE,
00241 DVRVolumePtr,
00242 CNodePtr,
00243 Action *>(&DVRVolume::render));
00244 }
00245
00246
00248 void DVRVolume::changed(BitVector whichField, UInt32 origin)
00249 {
00250 FDEBUG(("DVRVolume::changed\n"));
00251
00252 if((whichField & BrickStaticMemoryMBFieldMask))
00253 {
00254
00255 if(_sfBrickStaticMemoryMB.getValue() == 0)
00256 {
00257 _sfBrickStaticMemoryMB.setValue(1);
00258 }
00259 }
00260
00261 if((whichField & ShaderFieldMask))
00262 {
00263 shadingInitialized = false;
00264 }
00265
00266 if((whichField & Textures2DFieldMask))
00267 {
00268 shadingInitialized = false;
00269 }
00270
00271 Inherited::changed(whichField, origin);
00272 }
00273
00275 void DVRVolume::dump( UInt32 uiIndent,
00276 const BitVector ) const
00277 {
00278 DVRVolumePtr thisP(*this);
00279
00280 thisP.dump(uiIndent, FCDumpFlags::RefCount);
00281
00282 indentLog(uiIndent, PLOG);
00283 PLOG << "DVRVolume at " << this << std::endl;
00284
00285 indentLog(uiIndent, PLOG);
00286 PLOG << "\trenderMaterial: " << getRenderMaterial() << std::endl;
00287
00288 if (getRenderMaterial() != NullFC)
00289 getRenderMaterial()->dump(uiIndent);
00290
00291 indentLog(uiIndent, PLOG);
00292 PLOG << "\ttextureStorage: " << getTextureStorage() << std::endl;
00293
00294 if (getTextureStorage() != NullFC)
00295 getTextureStorage()->dump(uiIndent);
00296
00297 #if 0
00298 indentLog(uiIndent, PLOG);
00299 PLOG << "\tambient: " << getAmbient() << endl;
00300
00301 indentLog(uiIndent, PLOG);
00302 PLOG << "\tdiffuse: " << getDiffuse() << endl;
00303
00304 indentLog(uiIndent, PLOG);
00305 PLOG << "\tspecular: " << getSpecular() << endl;
00306
00307 indentLog(uiIndent, PLOG);
00308 PLOG << "\tshininess: " << getShininess() << endl;
00309
00310 indentLog(uiIndent, PLOG);
00311 PLOG << "\temission: " << getEmission() << endl;
00312
00313 indentLog(uiIndent, PLOG);
00314 PLOG << "\ttransparency: " << getTransparency() << endl;
00315
00316 indentLog(uiIndent, PLOG);
00317 PLOG << "\tlit: " << getLit() << endl;
00318
00319 indentLog(uiIndent, PLOG);
00320 PLOG << "\tChunks: " << endl;
00321
00322 for(MFStateChunkPtr::const_iterator i = _mfChunks.begin();
00323 i != _mfChunks.end(); i++)
00324 {
00325 indentLog(uiIndent, PLOG);
00326 PLOG << "\t" << *i << endl;
00327 }
00328 #endif
00329
00330 indentLog(uiIndent, PLOG);
00331 PLOG << "DVRVolume end " << this << std::endl;
00332 }
00333
00334
00336 Action::ResultE DVRVolume::doDraw(Action * action )
00337 {
00338
00339
00340 DrawAction *a = dynamic_cast<DrawAction*>(action);
00341
00342 if(a == NULL)
00343 {
00344 SWARNING << "DVRVolume::doDraw - unexpected action" << std::endl;
00345 return Action::Skip;
00346 }
00347
00348 #if 1
00349 Material::DrawFunctor func;
00350
00351 func = osgTypedMethodFunctor1ObjPtr(this, &DVRVolume::draw);
00352
00353
00354 if(a->getMaterial() != NULL)
00355 {
00356 a->getMaterial()->draw( func, a );
00357 }
00358
00359
00360
00361
00362 else
00363 {
00364 draw(a);
00365 }
00366
00367 return Action::Skip;
00368
00369 #else
00370 return draw(a);
00371 #endif
00372
00373 }
00374
00376 Action::ResultE DVRVolume::draw(DrawActionBase *action)
00377 {
00378 FINFO(("DVRVolume::draw\n"));
00379
00380 Window *window = action->getWindow();
00381
00382 if(getShader() != NullFC)
00383 {
00384
00385 TextureManager::TextureMode mode = getTextureMode(window);
00386
00387 FDEBUG(("DVRVolume::draw - using Shader: %s\n",
00388
00389 getShader()->getType().getCName()));
00390
00391
00392 if(shadingInitialized == false)
00393 {
00394
00395 textureManager.clearTextures( getTextureStorage() );
00396
00397
00398 bool result = getShader()->initialize( this, action );
00399
00400 if(result != true)
00401 {
00402 SFATAL << "DVRVolume::draw - error initializing shader"
00403 << std::endl;
00404 }
00405
00407 if(getShader()->useMTSlabs())
00408 mode = TextureManager::TM_2D_Multi;
00409
00410
00411 SINFO << "TextureMode = " << mode << std::endl;
00412
00413 textureManager.buildTextures(getTextureStorage(), this, mode);
00414
00415
00416 clipper.initialize(this);
00417
00418 shadingInitialized = true;
00419 }
00420
00421
00422 Pnt3f eyePointWorld(0.f, 0.f, 0.f);
00423 action->getCameraToWorld().mult(eyePointWorld, eyePointWorld);
00424
00425 Matrix modelMat = action->getActNode()->getToWorld();
00426
00427
00428
00429
00430
00431
00432 Brick *first = textureManager.sortBricks(
00433 action, modelMat, eyePointWorld.subZero(), this, mode);
00434
00435
00436
00437 if(getShowBricks())
00438 {
00439 for(Brick *current = first;
00440 current != NULL;
00441 current = current->getNext())
00442 {
00443 current->renderBrick();
00444 }
00445 }
00446
00447
00448 initializeClipObjects(action, modelMat);
00449
00450
00451
00452
00453
00454 if(mode != TextureManager::TM_3D)
00455 clipper.reset(this);
00456
00458 if(first != NULL)
00459 {
00460 getShader()->activate(this, action);
00461
00462
00463 Brick *prev = NULL;
00464
00465 for(Brick *current = first;
00466 current != NULL;
00467 prev = current, current = current->getNext())
00468 {
00469
00470
00471
00472 if(getDoTextures())
00473 {
00474 if (prev == NULL)
00475 {
00476 current->activateTexture(action);
00477 }
00478 else
00479 {
00480 current->changeFromTexture(action, prev);
00481 }
00482 }
00483
00484
00485 getShader()->brickActivate(this, action, current);
00486
00487
00488 current->renderSlices(this,
00489 action,
00490 getShader(),
00491 &clipper,
00492 mode);
00493 }
00494
00495
00496 prev->deactivateTexture(action);
00497
00498 getShader()->deactivate(this, action);
00499 }
00500 }
00501 else
00502 {
00503
00504 Vec3f min, max;
00505
00506 action->getActNode()->getVolume().getBounds(min, max);
00507
00508 FDEBUG(("DVRVolume::draw dummy geometry - %f %f %f -> %f %f %f\n",
00509 min[0], min[1], min[2], max[0], max[1], max[2]));
00510
00511
00512 UInt32 res[3] = {64, 64, 64};
00513
00514
00515 Real32 offset[3] = {(max[0] - min[0]) / 2 / res[0],
00516 (max[1] - min[1]) / 2 / res[1],
00517 (max[2] - min[2]) / 2 / res[2]};
00518
00519 Real32 inc[3] = {(max[0] - min[0]) / res[0],
00520 (max[1] - min[1]) / res[1],
00521 (max[2] - min[2]) / res[2]};
00522
00523
00524 Real32 value = min[2] + offset[2];
00525
00526 for(UInt32 i = 0; i < res[2]; i++, value += inc[2])
00527 {
00528
00529 glBegin(GL_LINE_LOOP);
00530 {
00531 glVertex3f(min[0] + offset[0], min[1] + offset[1], value);
00532 glTexCoord2f(0.0f + offset[0], 0.0f + offset[1]);
00533
00534 glVertex3f(max[0] - offset[0], min[1] + offset[1], value);
00535 glTexCoord2f(1.0f - offset[0], 0.0f + offset[1]);
00536
00537 glVertex3f(min[0] + offset[0], max[1] - offset[1], value);
00538 glTexCoord2f(0.0f + offset[0], 1.0f - offset[1]);
00539
00540 glVertex3f(max[0] - offset[0], max[1] - offset[1], value);
00541 glTexCoord2f(1.0f - offset[0], 1.0f - offset[1]);
00542 }
00543 glEnd();
00544 }
00545 }
00546
00547 return Action::Skip;
00548
00549
00550 }
00551
00552
00554 Action::ResultE DVRVolume::render(Action *action)
00555 {
00556 FDEBUG(("DVRVolume::render\n"));
00557
00558 RenderAction *a = dynamic_cast<RenderAction *>(action);
00559
00560 Material::DrawFunctor func;
00561
00562 func = osgTypedMethodFunctor1ObjPtr(this, &DVRVolume::draw);
00563
00564 a->dropFunctor(func, &(*getRenderMaterial()));
00565
00566 return Action::Continue;
00567 }
00568
00569
00571 void DVRVolume::commonConstructor( void )
00572 {
00573 drawStyleListValid = false;
00574 shadingInitialized = false;
00575
00576 if(osgLog().getLogLevel() == LOG_DEBUG)
00577 {
00578 FDEBUG(("DVRVolume::commonConstructor: \n"));
00579 dump();
00580 }
00581 }
00582
00583
00585 Action::ResultE DVRVolume::intersect(Action * action)
00586 {
00587 FDEBUG(("DVRVolume::intersect\n"));
00588
00589 IntersectAction *ia = dynamic_cast<IntersectAction*>(action);
00590 #ifndef OSG_2_PREP
00591 const DynamicVolume &vol = ia->getActNode()->getVolume();
00592 #else
00593 const BoxVolume &vol = ia->getActNode()->getVolume();
00594 #endif
00595
00596 if(vol.isValid() && !vol.intersect(ia->getLine()))
00597 {
00598 return Action::Skip;
00599 }
00600
00602
00603 Real32 t, v;
00604 Vec3f norm;
00605
00606 if(vol.intersect(ia->getLine(), t, v))
00607 ia->setHit(t, ia->getActNode(), 0, norm);
00608
00609 return Action::Continue;
00610 }
00611
00612
00614 AttachmentPtr DVRVolume::findParameter(const FieldContainerType &type,
00615 UInt16 binding)
00616 {
00617 DVRAppearancePtr app = getAppearance();
00618
00619 if(osgLog().getLogLevel() == LOG_DEBUG)
00620 {
00621 FDEBUG(("DVRVolume::findParameter: \n"));
00622 type.dump();
00623 }
00624
00625 if(app != NullFC)
00626 return app->findAttachment(type, binding);
00627
00628 SWARNING << "DVRVolume::findParameter - NO such parameter " << std::endl;
00629
00630 return NullFC;
00631 }
00632
00633
00635 AttachmentPtr DVRVolume::findParameter(UInt32 groupId, UInt16 binding)
00636 {
00637 DVRAppearancePtr app = getAppearance();
00638
00639 if(app != NullFC)
00640 return app->findAttachment(groupId, binding);
00641
00642 return NullFC;
00643 }
00644
00645
00647 void DVRVolume::buildDrawStyleList(Window *OSG_CHECK_ARG(win))
00648 {
00649 }
00650
00651
00653 TextureManager::TextureMode DVRVolume::getTextureMode(Window *window)
00654 {
00655 TextureManager::TextureMode mode;
00656
00657 switch(getTextures2D())
00658 {
00659 case 0:
00660 mode = TextureManager::TM_3D;
00661 break;
00662
00663 case 1:
00664 mode = TextureManager::TM_2D;
00665 break;
00666
00667 default:
00668 mode = window->hasExtension(_extTex3D) ?
00669 TextureManager::TM_3D : TextureManager::TM_2D;
00670 }
00671
00672 if(getShader()->useMTSlabs())
00673 mode = TextureManager::TM_2D_Multi;
00674
00675 return mode;
00676 }
00677
00678
00680 void DVRVolume::reload(void)
00681 {
00682 if(getShader() != NullFC)
00683 {
00684 textureManager.clearTextures(getTextureStorage());
00685
00686 shadingInitialized = false;
00687 }
00688 }
00689
00690 void DVRVolume::initializeClipObjects( DrawActionBase *action,
00691 const Matrix &volumeToWorld)
00692 {
00693 DVRClipObjectsPtr clipObjects = DVRVOLUME_PARAMETER(this, DVRClipObjects);
00694
00695 if(clipObjects != NullFC &&
00696 clipObjects->getClipMode() != DVRClipObjects::Off)
00697 {
00698
00699 DVRVolumeTexturePtr tex = DVRVOLUME_PARAMETER(this, DVRVolumeTexture);
00700
00701 if(tex != NullFC)
00702 {
00703 const Vec3f &res = tex->getResolution();
00704 const Vec3f &slice = tex->getSliceThickness();
00705
00706 Vec3f diag(res[0] * slice[0],
00707 res[1] * slice[1],
00708 res[2] * slice[2]);
00709
00710 Vec3f sliceDir;
00711
00712 if(getShader()->useMTSlabs())
00713 {
00714 Slicer::getAASlicingDirection(action,&sliceDir);
00715 }
00716 else
00717 {
00718 switch (getTextures2D())
00719 {
00720 case 0:
00721 Slicer::getSlicingDirection(action, &sliceDir);
00722 break;
00723
00724 case 1:
00725 Slicer::getAASlicingDirection(action, &sliceDir);
00726 break;
00727
00728 default:
00729 Window *window = action->getWindow();
00730
00731 if(window->hasExtension(_extTex3D))
00732 Slicer::getSlicingDirection(action, &sliceDir);
00733 else
00734 Slicer::getAASlicingDirection(action, &sliceDir);
00735 }
00736 }
00737
00738 Plane clipReferencePlane(sliceDir, -0.5f * diag.length());
00739
00740 clipObjects->initialize(volumeToWorld, clipReferencePlane);
00741
00742 clipper.setReferencePlane(clipReferencePlane);
00743 }
00744 }
00745 }
00746
00747
00748
00749
00750
00751 #ifdef __sgi
00752 #pragma set woff 1174
00753 #endif
00754
00755 #ifdef OSG_LINUX_ICC
00756 #pragma warning( disable : 177 )
00757 #endif
00758
00759
00760 namespace
00761 {
00762 static char cvsid_cpp[] = "@(#)$Id: $";
00763 static char cvsid_hpp[] = OSGDVRVOLUME_HEADER_CVSID;
00764 static char cvsid_inl[] = OSGDVRVOLUME_INLINE_CVSID;
00765 }