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 Pnt3f eyePointWorld(0.f, 0.f, 0.f);
00421 action->getCameraToWorld().mult(eyePointWorld);
00422
00423 Matrix modelMat = action->getActNode()->getToWorld();
00424
00425
00426
00427
00428
00429
00430 Brick *first = textureManager.sortBricks(
00431 action, modelMat, eyePointWorld.subZero(), this, mode);
00432
00433
00434
00435 if(getShowBricks())
00436 {
00437 for(Brick *current = first;
00438 current != NULL;
00439 current = current->getNext())
00440 {
00441 current->renderBrick();
00442 }
00443 }
00444
00445
00446 initializeClipObjects(action, modelMat);
00447
00448
00449
00450
00451
00452 if(mode != TextureManager::TM_3D)
00453 clipper.reset(this);
00454
00456 if(first != NULL)
00457 {
00458 getShader()->activate(this, action);
00459
00460
00461 Brick *prev = NULL;
00462
00463 for(Brick *current = first;
00464 current != NULL;
00465 prev = current, current = current->getNext())
00466 {
00467
00468
00469
00470 if(getDoTextures())
00471 {
00472 if (prev == NULL)
00473 {
00474 current->activateTexture(action);
00475 }
00476 else
00477 {
00478 current->changeFromTexture(action, prev);
00479 }
00480 }
00481
00482
00483 getShader()->brickActivate(this, action, current);
00484
00485
00486 current->renderSlices(this,
00487 action,
00488 getShader(),
00489 &clipper,
00490 mode);
00491 }
00492
00493
00494 prev->deactivateTexture(action);
00495
00496 getShader()->deactivate(this, action);
00497 }
00498 }
00499 else
00500 {
00501
00502 Vec3f min, max;
00503
00504 action->getActNode()->getVolume().getBounds(min, max);
00505
00506 FDEBUG(("DVRVolume::draw dummy geometry - %f %f %f -> %f %f %f\n",
00507 min[0], min[1], min[2], max[0], max[1], max[2]));
00508
00509
00510 UInt32 res[3] = {64, 64, 64};
00511
00512
00513 Real32 offset[3] = {(max[0] - min[0]) / 2 / res[0],
00514 (max[1] - min[1]) / 2 / res[1],
00515 (max[2] - min[2]) / 2 / res[2]};
00516
00517 Real32 inc[3] = {(max[0] - min[0]) / res[0],
00518 (max[1] - min[1]) / res[1],
00519 (max[2] - min[2]) / res[2]};
00520
00521
00522 Real32 value = min[2] + offset[2];
00523
00524 for(UInt32 i = 0; i < res[2]; i++, value += inc[2])
00525 {
00526
00527 glBegin(GL_LINE_LOOP);
00528 {
00529 glVertex3f(min[0] + offset[0], min[1] + offset[1], value);
00530 glTexCoord2f(0.0f + offset[0], 0.0f + offset[1]);
00531
00532 glVertex3f(max[0] - offset[0], min[1] + offset[1], value);
00533 glTexCoord2f(1.0f - offset[0], 0.0f + offset[1]);
00534
00535 glVertex3f(min[0] + offset[0], max[1] - offset[1], value);
00536 glTexCoord2f(0.0f + offset[0], 1.0f - offset[1]);
00537
00538 glVertex3f(max[0] - offset[0], max[1] - offset[1], value);
00539 glTexCoord2f(1.0f - offset[0], 1.0f - offset[1]);
00540 }
00541 glEnd();
00542 }
00543 }
00544
00545 return Action::Skip;
00546
00547
00548 }
00549
00550
00552 Action::ResultE DVRVolume::render(Action *action)
00553 {
00554 FDEBUG(("DVRVolume::render\n"));
00555
00556 RenderAction *a = dynamic_cast<RenderAction *>(action);
00557
00558 Material::DrawFunctor func;
00559
00560 func = osgTypedMethodFunctor1ObjPtr(this, &DVRVolume::draw);
00561
00562 a->dropFunctor(func, &(*getRenderMaterial()));
00563
00564 return Action::Continue;
00565 }
00566
00567
00569 void DVRVolume::commonConstructor( void )
00570 {
00571 drawStyleListValid = false;
00572 shadingInitialized = false;
00573
00574 if(osgLog().getLogLevel() == LOG_DEBUG)
00575 {
00576 FDEBUG(("DVRVolume::commonConstructor: \n"));
00577 dump();
00578 }
00579 }
00580
00581
00583 Action::ResultE DVRVolume::intersect(Action * action)
00584 {
00585 FDEBUG(("DVRVolume::intersect\n"));
00586
00587 IntersectAction *ia = dynamic_cast<IntersectAction*>(action);
00588 const DynamicVolume &dv = ia->getActNode()->getVolume();
00589
00590 if(dv.isValid() && !dv.intersect(ia->getLine()))
00591 {
00592 return Action::Skip;
00593 }
00594
00596
00597 Real32 t, v;
00598 Vec3f norm;
00599
00600 if(dv.intersect(ia->getLine(), t, v))
00601 ia->setHit(t, ia->getActNode(), 0, norm);
00602
00603 return Action::Continue;
00604 }
00605
00606
00608 AttachmentPtr DVRVolume::findParameter(const FieldContainerType &type,
00609 UInt16 binding)
00610 {
00611 DVRAppearancePtr app = getAppearance();
00612
00613 if(osgLog().getLogLevel() == LOG_DEBUG)
00614 {
00615 FDEBUG(("DVRVolume::findParameter: \n"));
00616 type.dump();
00617 }
00618
00619 if(app != NullFC)
00620 return app->findAttachment(type, binding);
00621
00622 SWARNING << "DVRVolume::findParameter - NO such parameter " << std::endl;
00623
00624 return NullFC;
00625 }
00626
00627
00629 AttachmentPtr DVRVolume::findParameter(UInt32 groupId, UInt16 binding)
00630 {
00631 DVRAppearancePtr app = getAppearance();
00632
00633 if(app != NullFC)
00634 return app->findAttachment(groupId, binding);
00635
00636 return NullFC;
00637 }
00638
00639
00641 void DVRVolume::buildDrawStyleList(Window *OSG_CHECK_ARG(win))
00642 {
00643 }
00644
00645
00647 TextureManager::TextureMode DVRVolume::getTextureMode(Window *window)
00648 {
00649 TextureManager::TextureMode mode;
00650
00651 switch(getTextures2D())
00652 {
00653 case 0:
00654 mode = TextureManager::TM_3D;
00655 break;
00656
00657 case 1:
00658 mode = TextureManager::TM_2D;
00659 break;
00660
00661 default:
00662 mode = window->hasExtension(_extTex3D) ?
00663 TextureManager::TM_3D : TextureManager::TM_2D;
00664 }
00665
00666 if(getShader()->useMTSlabs())
00667 mode = TextureManager::TM_2D_Multi;
00668
00669 return mode;
00670 }
00671
00672
00674 void DVRVolume::reload(void)
00675 {
00676 if(getShader() != NullFC)
00677 {
00678 textureManager.clearTextures(getTextureStorage());
00679
00680 shadingInitialized = false;
00681 }
00682 }
00683
00684 void DVRVolume::initializeClipObjects( DrawActionBase *action,
00685 const Matrix &volumeToWorld)
00686 {
00687 DVRClipObjectsPtr clipObjects = DVRVOLUME_PARAMETER(this, DVRClipObjects);
00688
00689 if(clipObjects != NullFC &&
00690 clipObjects->getClipMode() != DVRClipObjects::Off)
00691 {
00692
00693 DVRVolumeTexturePtr tex = DVRVOLUME_PARAMETER(this, DVRVolumeTexture);
00694
00695 if(tex != NullFC)
00696 {
00697 Vec3f &res = tex->getResolution();
00698 Vec3f &slice = tex->getSliceThickness();
00699
00700 Vec3f diag(res[0] * slice[0],
00701 res[1] * slice[1],
00702 res[2] * slice[2]);
00703
00704 Vec3f sliceDir;
00705
00706 if(getShader()->useMTSlabs())
00707 {
00708 Slicer::getAASlicingDirection(action,&sliceDir);
00709 }
00710 else
00711 {
00712 switch (getTextures2D())
00713 {
00714 case 0:
00715 Slicer::getSlicingDirection(action, &sliceDir);
00716 break;
00717
00718 case 1:
00719 Slicer::getAASlicingDirection(action, &sliceDir);
00720 break;
00721
00722 default:
00723 Window *window = action->getWindow();
00724
00725 if(window->hasExtension(_extTex3D))
00726 Slicer::getSlicingDirection(action, &sliceDir);
00727 else
00728 Slicer::getAASlicingDirection(action, &sliceDir);
00729 }
00730 }
00731
00732 Plane clipReferencePlane(sliceDir, -0.5f * diag.length());
00733
00734 clipObjects->initialize(volumeToWorld, clipReferencePlane);
00735
00736 clipper.setReferencePlane(clipReferencePlane);
00737 }
00738 }
00739 }
00740
00741
00742
00743
00744
00745 #ifdef __sgi
00746 #pragma set woff 1174
00747 #endif
00748
00749 #ifdef OSG_LINUX_ICC
00750 #pragma warning( disable : 177 )
00751 #endif
00752
00753
00754 namespace
00755 {
00756 static char cvsid_cpp[] = "@(#)$Id: $";
00757 static char cvsid_hpp[] = OSGDVRVOLUME_HEADER_CVSID;
00758 static char cvsid_inl[] = OSGDVRVOLUME_INLINE_CVSID;
00759 }