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::registerExtension( "GL_EXT_texture3D" );
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 commonConstructor();
00090 }
00091
00093 DVRVolume::DVRVolume(const DVRVolume &source) :
00094 Inherited (source),
00095 drawStyleListValid(false ),
00096 textureManager (this ),
00097 shadingInitialized(false )
00098 {
00099 SINFO << "DVRVolume::DVRVolume(const DVRVolume &source) this: "
00100 << this << std::endl;
00101
00108
00109 DVRVolumePtr ptr(*this);
00110
00111
00112 SimpleMaterialPtr m = SimpleMaterial::create();
00113
00114 beginEditCP(m);
00115 {
00116 m->setTransparency(0.001f );
00117 m->setLit (false );
00118 m->setDiffuse (Color3f(1.0, 1.0, 1.0));
00119 m->setAmbient (Color3f(1.0, 1.0, 1.0));
00120 }
00121 endEditCP(m);
00122
00123
00124 ChunkMaterialPtr cm = SimpleMaterial::create();
00125
00126
00127 beginEditCP(ptr, RenderMaterialFieldMask | TextureStorageFieldMask);
00128 {
00129 setRenderMaterial(m );
00130 setTextureStorage(cm);
00131 }
00132 endEditCP (ptr, RenderMaterialFieldMask | TextureStorageFieldMask);
00133
00134 commonConstructor();
00135 }
00136
00137 #ifdef OSG_WIN32_CL
00138 #pragma warning( default : 4355 )
00139 #endif
00140
00142 DVRVolume::~DVRVolume(void)
00143 {
00144 SINFO << "~DVRVolume this: "
00145 << this
00146 << std::endl
00147 << "~DVRVolume appearance: "
00148 << getAppearance()
00149 << std::endl
00150 << "~DVRVolume::subRefCP(Appearance)"
00151 << std::endl;
00152
00153 subRefCP(_sfAppearance.getValue());
00154
00155 SINFO << "~DVRVolume::subRefCP(Geometry)"
00156 << std::endl;
00157
00158
00159
00160
00161 subRefCP(_sfGeometry.getValue());
00162
00163 SINFO << "~DVRVolume::subRefCP(Shader)" << std::endl;
00164 SINFO << "~DVRVolume shader: " << getShader() << std::endl;
00165
00166 subRefCP(_sfShader.getValue());
00167
00168 SINFO << "~DVRVolume::subRefCP(RenderMaterial)"
00169 << std::endl
00170 << "~DVRVolume renderMaterial: "
00171 << getRenderMaterial()
00172 << std::endl;
00173
00174 subRefCP(_sfRenderMaterial.getValue());
00175
00176 SINFO << "~DVRVolume::subRefCP(TextureStorage)"
00177 << std::endl
00178 << "~DVRVolume textureStorage: "
00179 << getTextureStorage()
00180 << std::endl;
00181
00182 subRefCP(_sfTextureStorage.getValue());
00183 }
00184
00185
00186
00187
00189 void DVRVolume::adjustVolume(Volume &volume)
00190 {
00191 volume.setValid();
00192 volume.setEmpty();
00193
00194 DVRVolumeTexturePtr tex = DVRVOLUME_PARAMETER(this, DVRVolumeTexture);
00195
00196 if (tex != NullFC)
00197 {
00198 Vec3f & res = tex->getResolution ();
00199 Vec3f & slice = tex->getSliceThickness();
00200
00201 Vec3f minBB(-0.5f * res[0] * slice[0],
00202 -0.5f * res[1] * slice[1],
00203 -0.5f * res[2] * slice[2]);
00204
00205 Vec3f maxBB(-minBB);
00206
00207 volume.extendBy(minBB);
00208 volume.extendBy(maxBB);
00209 }
00210 else
00211 {
00212
00213 Vec3f minBB(-0.5, -0.5, -0.5);
00214 Vec3f maxBB( 0.5, 0.5, 0.5);
00215
00216 volume.extendBy(minBB);
00217 volume.extendBy(maxBB);
00218 }
00219 }
00220
00221
00223 void DVRVolume::initMethod(void)
00224 {
00225 DrawAction::registerEnterDefault( getClassType(),
00226 osgTypedMethodFunctor2BaseCPtrRef<Action::ResultE,
00227 DVRVolumePtr,
00228 CNodePtr,
00229 Action *>(&DVRVolume::doDraw));
00230
00231 IntersectAction::registerEnterDefault( getClassType(),
00232 osgTypedMethodFunctor2BaseCPtrRef<Action::ResultE,
00233 DVRVolumePtr,
00234 CNodePtr,
00235 Action *>(&DVRVolume::intersect));
00236
00237 RenderAction::registerEnterDefault( getClassType(),
00238 osgTypedMethodFunctor2BaseCPtrRef<Action::ResultE,
00239 DVRVolumePtr,
00240 CNodePtr,
00241 Action *>(&DVRVolume::render));
00242 }
00243
00244
00246 void DVRVolume::changed(BitVector whichField, UInt32 origin)
00247 {
00248 FDEBUG(("DVRVolume::changed\n"));
00249
00250 if((whichField & BrickStaticMemoryMBFieldMask))
00251 {
00252
00253 if(_sfBrickStaticMemoryMB.getValue() == 0)
00254 {
00255 _sfBrickStaticMemoryMB.setValue(1);
00256 }
00257 }
00258
00259 if((whichField & ShaderFieldMask))
00260 {
00261 shadingInitialized = false;
00262 }
00263
00264 if((whichField & Textures2DFieldMask))
00265 {
00266 shadingInitialized = false;
00267 }
00268
00269 Inherited::changed(whichField, origin);
00270 }
00271
00273 void DVRVolume::dump( UInt32 uiIndent,
00274 const BitVector ) const
00275 {
00276 DVRVolumePtr thisP(*this);
00277
00278 thisP.dump(uiIndent, FCDumpFlags::RefCount);
00279
00280 indentLog(uiIndent, PLOG);
00281 PLOG << "DVRVolume at " << this << std::endl;
00282
00283 indentLog(uiIndent, PLOG);
00284 PLOG << "\trenderMaterial: " << getRenderMaterial() << std::endl;
00285
00286 if (getRenderMaterial() != NullFC)
00287 getRenderMaterial()->dump(uiIndent);
00288
00289 indentLog(uiIndent, PLOG);
00290 PLOG << "\ttextureStorage: " << getTextureStorage() << std::endl;
00291
00292 if (getTextureStorage() != NullFC)
00293 getTextureStorage()->dump(uiIndent);
00294
00295 #if 0
00296 indentLog(uiIndent, PLOG);
00297 PLOG << "\tambient: " << getAmbient() << endl;
00298
00299 indentLog(uiIndent, PLOG);
00300 PLOG << "\tdiffuse: " << getDiffuse() << endl;
00301
00302 indentLog(uiIndent, PLOG);
00303 PLOG << "\tspecular: " << getSpecular() << endl;
00304
00305 indentLog(uiIndent, PLOG);
00306 PLOG << "\tshininess: " << getShininess() << endl;
00307
00308 indentLog(uiIndent, PLOG);
00309 PLOG << "\temission: " << getEmission() << endl;
00310
00311 indentLog(uiIndent, PLOG);
00312 PLOG << "\ttransparency: " << getTransparency() << endl;
00313
00314 indentLog(uiIndent, PLOG);
00315 PLOG << "\tlit: " << getLit() << endl;
00316
00317 indentLog(uiIndent, PLOG);
00318 PLOG << "\tChunks: " << endl;
00319
00320 for(MFStateChunkPtr::const_iterator i = _mfChunks.begin();
00321 i != _mfChunks.end(); i++)
00322 {
00323 indentLog(uiIndent, PLOG);
00324 PLOG << "\t" << *i << endl;
00325 }
00326 #endif
00327
00328 indentLog(uiIndent, PLOG);
00329 PLOG << "DVRVolume end " << this << std::endl;
00330 }
00331
00332
00334 Action::ResultE DVRVolume::doDraw(Action * action )
00335 {
00336
00337
00338 DrawAction *a = dynamic_cast<DrawAction*>(action);
00339
00340 if(a == NULL)
00341 {
00342 SWARNING << "DVRVolume::doDraw - unexpected action" << std::endl;
00343 return Action::Skip;
00344 }
00345
00346 #if 1
00347 Material::DrawFunctor func;
00348
00349 func = osgTypedMethodFunctor1ObjPtr(this, &DVRVolume::draw);
00350
00351
00352 if(a->getMaterial() != NULL)
00353 {
00354 a->getMaterial()->draw( func, a );
00355 }
00356
00357
00358
00359
00360 else
00361 {
00362 draw(a);
00363 }
00364
00365 return Action::Skip;
00366
00367 #else
00368 return draw(a);
00369 #endif
00370
00371 }
00372
00374 Action::ResultE DVRVolume::draw(DrawActionBase *action)
00375 {
00376 FINFO(("DVRVolume::draw\n"));
00377
00378 Window *window = action->getWindow();
00379
00380 if(getShader() != NullFC)
00381 {
00382
00383 TextureManager::TextureMode mode = getTextureMode(window);
00384
00385 FDEBUG(("DVRVolume::draw - using Shader: %s\n",
00386
00387 getShader()->getType().getCName()));
00388
00389
00390 if(shadingInitialized == false)
00391 {
00392
00393 textureManager.clearTextures( getTextureStorage() );
00394
00395
00396 bool result = getShader()->initialize( this, action );
00397
00398 if(result != true)
00399 {
00400 SFATAL << "DVRVolume::draw - error initializing shader"
00401 << std::endl;
00402 }
00403
00405 if(getShader()->useMTSlabs())
00406 mode = TextureManager::TM_2D_Multi;
00407
00408
00409 SINFO << "TextureMode = " << mode << std::endl;
00410
00411 textureManager.buildTextures(getTextureStorage(), this, mode);
00412
00413
00414 clipper.initialize(this);
00415
00416 shadingInitialized = true;
00417 }
00418
00419
00420 Vec3f eyePointWorld;
00421
00422 eyePointWorld.setValue(
00423 action->getCamera()->getBeacon()->getToWorld()[3]);
00424
00425 Matrix modelMat = action->getActNode()->getToWorld();
00426
00427
00428
00429
00430
00431
00432 Brick *first = textureManager.sortBricks(
00433 action, modelMat, eyePointWorld, 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 const DynamicVolume &dv = ia->getActNode()->getVolume();
00591
00592 if(dv.isValid() && !dv.intersect(ia->getLine()))
00593 {
00594 return Action::Skip;
00595 }
00596
00598
00599 Real32 t, v;
00600 Vec3f norm;
00601
00602 if(dv.intersect(ia->getLine(), t, v))
00603 ia->setHit(t, ia->getActNode(), 0, norm);
00604
00605 return Action::Continue;
00606 }
00607
00608
00610 AttachmentPtr DVRVolume::findParameter(const FieldContainerType &type,
00611 UInt16 binding)
00612 {
00613 DVRAppearancePtr app = getAppearance();
00614
00615 if(osgLog().getLogLevel() == LOG_DEBUG)
00616 {
00617 FDEBUG(("DVRVolume::findParameter: \n"));
00618 type.dump();
00619 }
00620
00621 if(app != NullFC)
00622 return app->findAttachment(type, binding);
00623
00624 SWARNING << "DVRVolume::findParameter - NO such parameter " << std::endl;
00625
00626 return NullFC;
00627 }
00628
00629
00631 AttachmentPtr DVRVolume::findParameter(UInt32 groupId, UInt16 binding)
00632 {
00633 DVRAppearancePtr app = getAppearance();
00634
00635 if(app != NullFC)
00636 return app->findAttachment(groupId, binding);
00637
00638 return NullFC;
00639 }
00640
00641
00643 void DVRVolume::buildDrawStyleList(Window *OSG_CHECK_ARG(win))
00644 {
00645 }
00646
00647
00649 TextureManager::TextureMode DVRVolume::getTextureMode(Window *window)
00650 {
00651 TextureManager::TextureMode mode;
00652
00653 switch(getTextures2D())
00654 {
00655 case 0:
00656 mode = TextureManager::TM_3D;
00657 break;
00658
00659 case 1:
00660 mode = TextureManager::TM_2D;
00661 break;
00662
00663 default:
00664 mode = window->hasExtension(_extTex3D) ?
00665 TextureManager::TM_3D : TextureManager::TM_2D;
00666 }
00667
00668 if(getShader()->useMTSlabs())
00669 mode = TextureManager::TM_2D_Multi;
00670
00671 return mode;
00672 }
00673
00674
00676 void DVRVolume::reload(void)
00677 {
00678 if(getShader() != NullFC)
00679 {
00680 textureManager.clearTextures(getTextureStorage());
00681
00682 shadingInitialized = false;
00683 }
00684 }
00685
00686 void DVRVolume::initializeClipObjects( DrawActionBase *action,
00687 const Matrix &volumeToWorld)
00688 {
00689 DVRClipObjectsPtr clipObjects = DVRVOLUME_PARAMETER(this, DVRClipObjects);
00690
00691 if(clipObjects != NullFC &&
00692 clipObjects->getClipMode() != DVRClipObjects::Off)
00693 {
00694
00695 DVRVolumeTexturePtr tex = DVRVOLUME_PARAMETER(this, DVRVolumeTexture);
00696
00697 if(tex != NullFC)
00698 {
00699 Vec3f &res = tex->getResolution();
00700 Vec3f &slice = tex->getSliceThickness();
00701
00702 Vec3f diag(res[0] * slice[0],
00703 res[1] * slice[1],
00704 res[2] * slice[2]);
00705
00706 Vec3f sliceDir;
00707
00708 if(getShader()->useMTSlabs())
00709 {
00710 Slicer::getAASlicingDirection(action,&sliceDir);
00711 }
00712 else
00713 {
00714 switch (getTextures2D())
00715 {
00716 case 0:
00717 Slicer::getSlicingDirection(action, &sliceDir);
00718 break;
00719
00720 case 1:
00721 Slicer::getAASlicingDirection(action, &sliceDir);
00722 break;
00723
00724 default:
00725 Window *window = action->getWindow();
00726
00727 if(window->hasExtension(_extTex3D))
00728 Slicer::getSlicingDirection(action, &sliceDir);
00729 else
00730 Slicer::getAASlicingDirection(action, &sliceDir);
00731 }
00732 }
00733
00734 Plane clipReferencePlane(sliceDir, -0.5f * diag.length());
00735
00736 clipObjects->initialize(volumeToWorld, clipReferencePlane);
00737
00738 clipper.setReferencePlane(clipReferencePlane);
00739 }
00740 }
00741 }
00742
00743
00744
00745
00746
00747 #ifdef __sgi
00748 #pragma set woff 1174
00749 #endif
00750
00751 #ifdef OSG_LINUX_ICC
00752 #pragma warning( disable : 177 )
00753 #endif
00754
00755
00756 namespace
00757 {
00758 static char cvsid_cpp[] = "@(#)$Id: $";
00759 static char cvsid_hpp[] = OSGDVRVOLUME_HEADER_CVSID;
00760 static char cvsid_inl[] = OSGDVRVOLUME_INLINE_CVSID;
00761 }