00001
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 #include "ShadowManager.h"
00033 #include "SoShadowCaster.h"
00034 #include "SoShadowVolume.h"
00035
00036
00037 #ifdef _WIN32
00038 #include <windows.h>
00039 #endif
00040
00041
00042 #include <GL/gl.h>
00043
00044
00045
00046
00047
00066 CShadowManager::CShadowManager(SoSeparator *sr, SoEnvironment * env)
00067 : sceneRoot(sr),
00068 environment(env)
00069 {
00070
00071 if ( this->sceneRoot == NULL )
00072 {
00073 this->printError("Your scene root node is NULL.");
00074 }
00075 else
00076 {
00077 fprintf(stdout,"\nShadows generated by Shadow Engine v %s\n",SE_VERSION);
00078 sceneRoot->ref();
00079
00080 }
00081
00082 first = TRUE;
00083 sceneType = SHADOWS;
00084 psceneType = &sceneType;
00085
00086 objectIndex = 0;
00087 lightIndex = 0;
00088
00089
00090 settings = new struct TShadowSettings;
00091 settings->method = zpass;
00092 settings->dropShadows = TRUE;
00093 settings->fDepth = 150.f;
00094 this->method2algorithm();
00095 ONDEBUG( this->printSettings() );
00096
00097
00098 shadowCastersRoot = new SoSeparator;
00099 shadowCastersRoot->setName("ShadowCastersRoot");
00100 shadowCastersRoot->ref();
00101
00102
00103 shadowSceneRoot = new SoSeparator;
00104 shadowSceneRoot->setName("ShadowSceneRoot");
00105 shadowSceneRoot->ref();
00106
00107
00108 shadowLightsRoot = new SoSeparator;
00109 shadowLightsRoot->setName("shadowLightsRoot");
00110 shadowLightsRoot->ref();
00111
00112 switchNode = new SoSwitch;
00113 sceneNoShadows = new SoSeparator;
00114 sceneWithShadows = new SoSeparator;
00115 sceneWithShadowVolumes = new SoSeparator;
00116
00117
00118 switchNode->addChild(sceneWithShadows);
00119 switchNode->addChild(sceneNoShadows);
00120 switchNode->addChild(sceneWithShadowVolumes);
00121
00122
00123 if ( environment == NULL )
00124 {
00125 ONDEBUG( printf("look for env node\n") );
00126
00127 environment = this->findEnvironmentNode();
00128 if ( environment == NULL )
00129 {
00130 ONDEBUG( printf("my own env\n") );
00131 environment = new SoEnvironment;
00132
00133 environment->ambientColor.setValue(SbColor(1.f, 1.f, 1.f));
00134 environment->ambientIntensity.setValue(0.2f);
00135 this->shadowSceneRoot->addChild(environment);
00136 }
00137 }
00138 environment->ref();
00139
00140 shadowSceneRoot->addChild(switchNode);
00141
00142 this->switchNode->whichChild.setValue(CShadowManager::SHADOWS);
00143 }
00144
00145
00149 CShadowManager::~CShadowManager()
00150 {
00151 ONDEBUG( printf("--CShadowManager::destructor()\n") );
00152
00153 if ( this->sceneRoot != NULL )
00154 sceneRoot->unref();
00155
00156 environment->unref();
00157
00158 shadowCastersRoot->removeAllChildren();
00159 shadowCastersRoot->unref();
00160 shadowCastersRoot = NULL;
00161
00162 shadowLightsRoot->removeAllChildren();
00163 shadowLightsRoot->unref();
00164 shadowLightsRoot = NULL;
00165
00166 shadowSceneRoot->removeAllChildren();
00167 shadowSceneRoot->unref();
00168 shadowSceneRoot = NULL;
00169
00170 switchNode = NULL;
00171 }
00172
00173
00177 void CShadowManager::createShadows()
00178 {
00179 ONDEBUG( printf("--CShadowManager::createShadows()\n") );
00180
00181 int cnt = this->shadowLightsRoot->getNumChildren();
00182 ONDEBUG( printf("--CShadowManager:: SVN cnt: %d\n",cnt) );
00183 for (int i = 0; i < cnt; i++)
00184 {
00185 SoShadowLight * slight = static_cast<SoShadowLight *>(this->shadowLightsRoot->getChild(i));
00186 slight->createShadowVolumes();
00187 }
00188
00189 if ( this->sceneRoot != NULL )
00190 this->sceneRoot->touch();
00191 }
00192
00193
00199 void CShadowManager::setSceneType(enum CShadowManager::SCENE_TYPE type)
00200 {
00201 this->sceneType = type;
00202
00203
00204 }
00205
00206
00212 enum CShadowManager::SCENE_TYPE CShadowManager::getSceneType()
00213 {
00214 return this->sceneType;
00215 }
00216
00217
00223 void CShadowManager::setManager(TShadowSettings * s)
00224 {
00225 settings = s;
00226 this->method2algorithm();
00227 this->createShadows();
00228 }
00229
00230
00236 const struct TShadowSettings * CShadowManager::readSettings()
00237 {
00238 return this->settings;
00239 }
00240
00241
00247 void CShadowManager::setMethod(enum TShadowMethod newMethod)
00248 {
00249 enum TShadowAlgorithm old = this->algorithm;
00250 this->settings->method = newMethod;
00251 this->method2algorithm();
00252 if ( old != this->algorithm )
00253 {
00254 ONDEBUG ( printf("setMethod: new algorithm => createShadows\n"); );
00255 this->createShadows();
00256 }
00257 else
00258 {
00259 ONDEBUG ( printf("setMethod: algorithm is not updated\n"); );
00260 }
00261 ONDEBUG ( printSettings() );
00262 }
00263
00264
00270 void CShadowManager::setSVDepth(float newfDepth)
00271 {
00272 this->settings->fDepth = newfDepth;
00273 this->createShadows();
00274 ONDEBUG ( printSettings() );
00275 }
00276
00277
00281 void CShadowManager::printSettings()
00282 {
00283 char * a = "";
00284 char * m = "";
00285 char * ds = "";
00286 switch (settings->method)
00287 {
00288 case zpass: m = "z-pass"; break;
00289 case zfail: m = "z-fail"; break;
00290 case autoset: m = "autoset"; break;
00291 default: m = "unknown"; break;
00292 }
00293 algorithm == zpassAlg ? a = "z-pass alg." : a = "z-fail alg.";
00294 settings->dropShadows ? ds = "shadows" : ds = "shadow volumes";
00295
00296 printf("\nSM Settings:\n");
00297 printf(" method: %s\n", m);
00298 printf(" algorithm: %s\n", a);
00299 printf(" show: %s\n", ds);
00300 printf(" far depth: %.2f\n\n", settings->fDepth);
00301 }
00302
00303
00309 TShadowAlgorithm * CShadowManager::getAlgorithm()
00310 {
00311 return &algorithm;
00312 }
00313
00314
00318 void CShadowManager::method2algorithm()
00319 {
00320 ONDEBUG(printf("CShadowManager::method2algorithm\n"));
00321 switch ( settings->method )
00322 {
00323 case zpass: algorithm = zpassAlg; break;
00324
00325 case zfail: algorithm = zfailAlg; break;
00326
00327 case autoset:
00328
00329 algorithm = zfailAlg;
00330 break;
00331
00332 default: algorithm = zfailAlg; break;
00333 }
00334 }
00335
00336
00345 void CShadowManager::disableSensors()
00346 {
00347
00348 int cnt = this->shadowCastersRoot->getNumChildren();
00349 ONDEBUG( printf(" disableSensors: SVN has %d children:\n",cnt));
00350 if ( cnt > 0 ) {
00351 for (int i = 0; i < cnt; i++ ) {
00352 SoShadowCaster * caster = (SoShadowCaster *) this->shadowCastersRoot->getChild(i);
00353 caster->getMoveSensor()->detach();
00354 caster->getShapeSensor()->detach();
00355 }
00356 }
00357 }
00358
00359
00363 void CShadowManager::enableSensors()
00364 {
00365
00366 int cnt = this->shadowCastersRoot->getNumChildren();
00367 ONDEBUG( printf(" enableSensors: SVN has %d children:\n",cnt));
00368 if ( cnt > 0 ) {
00369 for (int i = 0; i < cnt; i++ ) {
00370 SoShadowCaster * caster = (SoShadowCaster *) this->shadowCastersRoot->getChild(i);
00371 caster->getMoveSensor()->attach(caster->path);
00372 caster->getShapeSensor()->attach(caster->objectRoot);
00373 }
00374 }
00375 }
00376
00379
00380
00386 SoEnvironment * CShadowManager::getEnvironmentNode()
00387 {
00388 return this->environment;
00389 }
00390
00391
00399 void CShadowManager::setAmbientIntensity(float val)
00400 {
00401 this->environment->ambientIntensity.setValue(val);
00402 }
00403
00413 SoEnvironment * CShadowManager::findEnvironmentNode()
00414 {
00415 if ( this->sceneRoot != NULL )
00416 {
00417 SoSearchAction * sa = new SoSearchAction;
00418 sa->setType(SoEnvironment::getClassTypeId());
00419 sa->setSearchingAll(FALSE);
00420 sa->apply(this->sceneRoot);
00421
00422 SoPath * nodePath = sa->getPath();
00423 if ( nodePath == NULL ) {
00424 ONDEBUG( printf("SoEnvironment not FOUND\n") );
00425 return NULL;
00426 }
00427 else
00428 {
00429 if (nodePath->getTail()->isOfType(SoEnvironment::getClassTypeId()))
00430 {
00431 ONDEBUG( printf("SoEnvironment is FOUND !!!\n") );
00432 SoEnvironment * env = (SoEnvironment*) nodePath->getTail();
00433 return env;
00434 }
00435 }
00436 }
00437 return NULL;
00438 }
00439
00442
00449 void CShadowManager::lightMoveCallback(void * userdata, SoSensor *s)
00450 {
00451 ONDEBUG( printf("CShadowManager::lightMoveCallback for one light\n") );
00452
00453 SoShadowLight * slight = static_cast<SoShadowLight *> (userdata);
00454 slight->createShadowVolumes();
00455 }
00456
00457
00463 void CShadowManager::addLight(SoLight * light)
00464 {
00465 ONDEBUG( printf("addLight:\n") );
00466 int i = 0;
00467 int cnt = 0;
00468
00469
00470 SoSearchAction * sa = new SoSearchAction;
00471 sa->setNode(light);
00472 sa->setSearchingAll(FALSE);
00473 sa->apply(this->sceneRoot);
00474
00475 SoPath * nodePath = sa->getPath();
00476
00477 if ( nodePath == NULL ) {
00478 printError("addLight (warning): Light was not found in the scene graph.\nTherefore it was not added in the Shadow Manager\n");
00479 }
00480 else
00481 {
00482 bool found = FALSE;
00483
00484
00485
00486 cnt = this->shadowLightsRoot->getNumChildren();
00487 if ( cnt > 0 )
00488 {
00489 for (int i = 0; i < cnt; i++ )
00490 {
00491 SoShadowLight * slight = (SoShadowLight *) this->shadowLightsRoot->getChild(i);
00492 if ( slight->getLight() == light )
00493 {
00494 found = TRUE;
00495 }
00496 }
00497 }
00498
00499 if ( !found )
00500 {
00501
00502
00503 SbString lindex(lightIndex);
00504 SbString lname = "ShadowLight_";
00505 lname += lindex;
00506 ONDEBUG( printf(" sh light name: %s\n",lname.getString()) );
00507
00508 light->ref();
00509 SoShadowLight * slight = new SoShadowLight(this, light);
00510 slight->setName(lname);
00511 slight->setLightName(lightIndex);
00512
00513
00514 SoNodeSensor * lightSensor = new SoNodeSensor(this->lightMoveCallback, slight);
00515 lightSensor->attach((SoNode *) light);
00516 slight->setSensor(lightSensor);
00517
00518 this->shadowLightsRoot->addChild(slight);
00519
00520
00521 int cntc = this->shadowCastersRoot->getNumChildren();
00522 ONDEBUG( printf(" add light: num. casters: %d\n",cntc));
00523 if ( cntc > 0 ) {
00524 for (int i = 0; i < cntc; i++ ) {
00525 SoShadowCaster * caster = (SoShadowCaster *) this->shadowCastersRoot->getChild(i);
00526
00527
00528
00529 SbString cindex(caster->getCasterName());
00530 SbString vname = "SV_L";
00531 vname += lindex;
00532 vname += "_C";
00533 vname += cindex;
00534 ONDEBUG( printf(" sh light name: %s\n",vname.getString()) );
00535
00536
00537 SoShadowVolume * volume = new SoShadowVolume(slight, caster->getCasterName());
00538 volume->setName(vname);
00539 slight->addVolume(volume);
00540
00541 ONDEBUG( fprintf(stdout," child %d: %s\n",i,caster->getName().getString()) );
00542 }
00543 }
00544
00545 lightIndex++;
00546
00547 this->createShadows();
00548 } else {
00549 this->printError("Light is already present.");
00550 }
00551 }
00552 ONDEBUG(
00553 printf(" num. lights %d \n", this->shadowLightsRoot->getNumChildren() );
00554 );
00555 this->checkLights();
00556 ONDEBUG( printf("addLight end\n\n") );
00557 }
00558
00559
00570 void CShadowManager::removeLight(SoLight * light)
00571 {
00572 ONDEBUG( printf("removeLight:\n") );
00573
00574 int i = 0;
00575
00576 if ( light == NULL )
00577 {
00578 this->printError("Light is NULL.");
00579 }
00580 else
00581 {
00582 int cnt = this->shadowLightsRoot->getNumChildren();
00583 if ( cnt > 0 )
00584 {
00585 for ( i = 0; i < cnt; i++ )
00586 {
00587 SoShadowLight * slight = (SoShadowLight *) this->shadowLightsRoot->getChild(i);
00588 if ( slight->getLight() == light )
00589 {
00590 this->shadowLightsRoot->removeChild(i);
00591
00592 this->createShadows();
00593 light->unref();
00594 break;
00595 }
00596 }
00597 if ( i == cnt )
00598 this->printError("Light is not in SM.");
00599 }
00600 }
00601
00602 ONDEBUG(
00603 checkLights();
00604 printf(" lights %d \n", this->shadowLightsRoot->getNumChildren() );
00605 printf("removeLight end\n\n");
00606 );
00607 }
00608
00609
00613 void CShadowManager::checkLights()
00614 {
00615 bool found = FALSE;
00616
00617 int cnt = this->shadowLightsRoot->getNumChildren();
00618 if ( cnt > 0 )
00619 {
00620 for (int i = 0; i < cnt; i++ )
00621 {
00622 SoShadowLight * slight = (SoShadowLight *) this->shadowLightsRoot->getChild(i);
00623
00624 slight->getLight()->on.enableNotify(FALSE);
00625 SbBool s = slight->getLight()->on.getValue();
00626 char * status = "";
00627 s ? status = "on" : status = "off";
00628
00629 char * typ = "";
00630 if (slight->getLight()->getTypeId() == SoDirectionalLight::getClassTypeId() )
00631 typ = "SoDirectionalLight";
00632 else if (slight->getLight()->getTypeId() == SoDirectionalLightManip::getClassTypeId() )
00633 typ = "SoDirectionalLightManip";
00634 else if (slight->getLight()->getTypeId() == SoPointLight::getClassTypeId() )
00635 typ = "SoPointLight";
00636 else if (slight->getLight()->getTypeId() == SoPointLightManip::getClassTypeId() )
00637 typ = "SoPointLightManip";
00638 else if (slight->getLight()->getTypeId() == SoSpotLight::getClassTypeId() )
00639 typ = "SoSpotLight";
00640 else if (slight->getLight()->getTypeId() == SoSpotLightManip::getClassTypeId() )
00641 typ = "SoSpotLightManip";
00642 else
00643 typ = "Unknown light type";
00644
00645 ONDEBUG( fprintf(stdout," light %d: %s %s\n",i,status,typ) );
00646 }
00647 }
00648
00649 }
00650
00653
00664 void CShadowManager::objectMoveCallback(void * userdata, SoSensor *s)
00665 {
00666 ONDEBUG( printf("@@@caster path CB\n") );
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682 SoShadowCaster * caster = static_cast<SoShadowCaster *>(userdata);
00683
00684 ONDEBUG( printf("@@@caster path CB called by %s\n", caster->getName().getString()) );
00685
00686
00687 SoDataSensor *mySensor = (SoDataSensor *)s;
00688
00689 SoNode *changedNode = mySensor->getTriggerNode();
00690 SoField *changedField = mySensor->getTriggerField();
00691
00692 if ( changedNode != NULL ) {
00693 ONDEBUG( printf(" The node named '%s' changed\n", changedNode->getName().getString()) );
00694 if ( changedNode->getTypeId().isDerivedFrom(SoTransformation::getClassTypeId()) )
00695 {
00696
00697 if ( !changedNode->isOfType(SoScale::getClassTypeId()) ) {
00698 ONDEBUG( printf(" create shadow volume for the caster (not a scale tr.)\n") );
00699 caster->setMoved(TRUE);
00700 caster->createShadowVolumes();
00701 } else {
00702 ONDEBUG( printf(" create shadow volume: scale transform\n") );
00703 caster->createFaceModel();
00704 caster->createShadowVolumes();
00705 }
00706 }
00707 else
00708 {
00709
00710
00711
00712
00713 if ( changedField == NULL )
00714 {
00715
00716
00717
00718
00719
00720 }
00721 }
00722 }
00723 else
00724 {
00725 ONDEBUG( printf(" changedNode is NULL \n") );
00726 }
00727
00728 ONDEBUG( printf("@@@caster path CB done\n") );
00729 }
00730
00731
00738 void CShadowManager::objectShapeCallback(void * userdata, SoSensor *s)
00739 {
00740 ONDEBUG( printf("###caster shape CB\n") );
00741
00742 SoShadowCaster * caster = static_cast<SoShadowCaster *>(userdata);
00743
00744
00745 SoDataSensor * mySensor = (SoDataSensor *) s;
00746
00747 SoNode *changedNode = mySensor->getTriggerNode();
00748 SoField *changedField = mySensor->getTriggerField();
00749
00750 if ( changedNode != NULL ) {
00751 ONDEBUG( printf(" The node named '%s' changed\n", changedNode->getName().getString()) );
00752
00753 if (changedField == NULL)
00754 {
00755
00756 ONDEBUG( printf(" changedField == NULL\n") );
00757 if ( changedNode->isOfType(SoSeparator::getClassTypeId()) ) {
00758 ONDEBUG( printf(" added %d \n",caster->getCasterName()) );
00759
00760 caster->createFaceModel();
00761
00762 caster->createShadowVolumes();
00763 }
00764
00765 }
00766
00767 }
00768 else
00769 {
00770 ONDEBUG( printf(" changedNode is NULL in shape CB\n") );
00771 }
00772 ONDEBUG( printf("###caster shape CB\n") );
00773 }
00774
00782 int CShadowManager::findObject(SoSeparator * object)
00783 {
00784
00785 int found = -1;
00786 int cnt = this->shadowCastersRoot->getNumChildren();
00787 if ( cnt > 0 )
00788 {
00789 for (int i = 0; i < cnt; i++ )
00790 {
00791 SoShadowCaster * caster = (SoShadowCaster *) this->shadowCastersRoot->getChild(i);
00792 if ( caster->getObjectNode() == object )
00793 {
00794 ONDEBUG( printf("findObject: Object is already in SM: %d\n", caster->getCasterName()) );
00795 return caster->getCasterName();
00796 }
00797 }
00798 }
00799 ONDEBUG( printf("findObject: Object is not in SM\n") );
00800 return found;
00801 }
00802
00803
00817 void CShadowManager::addObject(SoSeparator * object)
00818 {
00819 ONDEBUG( printf("add Object\n") );
00820 int i = 0;
00821
00822
00823 SoSearchAction * sa = new SoSearchAction;
00824 sa->setNode(object);
00825 sa->setSearchingAll(FALSE);
00826 sa->apply(this->sceneRoot);
00827
00828
00829 SoPath * nodePath = sa->getPath();
00830 if ( nodePath == NULL ) {
00831 printError("addObject (warning): Object was not found in the scene graph.\nTherefore it was not added in the Shadow Manager.\n");
00832 }
00833 else
00834 {
00835 if ( findObject(object) < 0 )
00836 {
00837
00838 SoShadowCaster * caster = new SoShadowCaster(this, object);
00839 caster->setCasterName(objectIndex);
00840 this->shadowCastersRoot->addChild(caster);
00841 objectIndex++;
00842
00843
00844 object->ref();
00845
00846
00847 SoPathSensor * objectSensor = new SoPathSensor(this->objectMoveCallback, caster);
00848 objectSensor->setPriority(0);
00849 objectSensor->attach(nodePath);
00850 caster->setMoveSensor(objectSensor);
00851
00852 caster->path = nodePath;
00853
00854
00855 SoNodeSensor * objectSensorC = new SoNodeSensor(this->objectShapeCallback, caster);
00856 objectSensorC->attach((SoNode *) object);
00857 objectSensorC->setPriority(0);
00858 caster->setShapeSensor(objectSensorC);
00859
00860
00861
00862 int cnt = this->shadowLightsRoot->getNumChildren();
00863 if ( cnt > 0 )
00864 {
00865 for (int i = 0; i < cnt; i++ )
00866 {
00867 SoShadowLight * slight = (SoShadowLight *) this->shadowLightsRoot->getChild(i);
00868
00869
00870
00871 SbString cindex(caster->getCasterName());
00872 SbString lindex(slight->getLightName());
00873 SbString vname = "SV_L";
00874 vname += lindex;
00875 vname += "_C";
00876 vname += cindex;
00877 ONDEBUG( printf(" sh volume name: %s\n",vname.getString()) );
00878
00879
00880 SoShadowVolume * volume = new SoShadowVolume(slight, caster->getCasterName());
00881 volume->setName(vname);
00882
00883 slight->addVolume(volume);
00884 }
00885 }
00886
00887 ONDEBUG( printf(" child %d: %s\n",i,caster->getName().getString()) );
00888 ONDEBUG( printf(" add obj: volume added\n") );
00889 ONDEBUG( printf(" The new caster has %d children.\n", caster->getNumChildren()) );
00890
00891
00892
00893
00894 object->touch();
00895 ONDEBUG( this->printMsg(" Object was added.") );
00896
00897 } else {
00898 this->printError("Object is already present.");
00899 }
00900 }
00901 ONDEBUG( checkObjects() );
00902 ONDEBUG( printf("add object done\n\n") );
00903 }
00904
00905
00914 void CShadowManager::removeObject(SoSeparator * object)
00915 {
00916
00917 ONDEBUG( printf("remove object\n") );
00918
00919 int found = -1;
00920 int cnt = this->shadowCastersRoot->getNumChildren();
00921 if ( cnt > 0 )
00922 {
00923 for (int i = 0; i < cnt; i++ )
00924 {
00925 SoShadowCaster * caster = (SoShadowCaster *) this->shadowCastersRoot->getChild(i);
00926 if ( caster->getObjectNode() == object )
00927 {
00928 ONDEBUG( printf(" removing caster: %d\n", caster->getCasterName()) );
00929 found = caster->getCasterName();
00930
00931
00932 int cntl = this->shadowLightsRoot->getNumChildren();
00933 for (int j = 0; j < cntl; j++ )
00934 {
00935 SoShadowLight * slight = (SoShadowLight *) this->shadowLightsRoot->getChild(j);
00936 slight->deleteVolume(caster->getCasterName());
00937 }
00938
00939 this->shadowCastersRoot->removeChild(i);
00940
00941 object->unref();
00942
00943 break;
00944
00945
00946 }
00947 }
00948 }
00949 if ( found < 0 ) {
00950 this->printError("removeObject: object not found.");
00951 }
00952 ONDEBUG( checkObjects() );
00953 ONDEBUG( printf("remove object done\n\n") );
00954
00955 }
00956
00957
00966 void CShadowManager::createObjectsShadows(SoSeparator * object)
00967 {
00968 ONDEBUG( printf("recreateObjectsShadows\n") );
00969
00970 int found = -1;
00971 int cnt = this->shadowCastersRoot->getNumChildren();
00972 if ( cnt > 0 )
00973 {
00974 for (int i = 0; i < cnt; i++ )
00975 {
00976 SoShadowCaster * caster = (SoShadowCaster *) this->shadowCastersRoot->getChild(i);
00977 if ( caster->getObjectNode() == object )
00978 {
00979 found = 1;
00980 caster->createFaceModel();
00981 caster->createShadowVolumes();
00982 }
00983 }
00984 }
00985 if ( found < 0 ) {
00986 this->printError("recreateObjectsShadows: object not found.");
00987 }
00988 ONDEBUG( printf("recreateObjectsShadows done\n\n") );
00989 }
00990
00991
00995 void CShadowManager::checkObjects()
00996 {
00997 int cnt = this->shadowCastersRoot->getNumChildren();
00998 ONDEBUG( fprintf(stdout,"\nSVN has %d children:\n",cnt) );
00999 if ( cnt > 0 ) {
01000 for (int i = 0; i < cnt; i++ ) {
01001 SoShadowCaster * caster = (SoShadowCaster *) this->shadowCastersRoot->getChild(i);
01002 ONDEBUG( fprintf(stdout," child %d: %s\n",i,caster->getName().getString()) );
01003 }
01004 }
01005 ONDEBUG( fprintf(stdout,"\n") );
01006 }
01007
01008
01014 void CShadowManager::createCasterVolumes(int index)
01015 {
01016 int cnt = this->shadowLightsRoot->getNumChildren();
01017 if ( cnt > 0 )
01018 {
01019 for (int i = 0; i < cnt; i++ )
01020 {
01021 SoShadowLight * slight = (SoShadowLight *) this->shadowLightsRoot->getChild(i);
01022
01023 int vcnt = slight->getNumVolumes();
01024 if ( vcnt > 0 )
01025 {
01026 for (int j = 0; j < vcnt; j++ )
01027 {
01028
01029 SoShadowVolume * volume = (SoShadowVolume *) slight->getVolume(j);
01030 if ( volume->getCasterName() == index )
01031 {
01032 volume->create();
01033 }
01034 }
01035 }
01036 }
01037 }
01038 }
01039
01040
01043
01049 void CShadowManager::createShadowScene()
01050 {
01051 ONDEBUG( printf("creating shadow scene graph...\n") );
01052
01053
01054 SoCallback * initCallback = new SoCallback;
01055 initCallback->setCallback(initCB, this->shadowLightsRoot);
01056
01057
01058 SoCallback * endCallback = new SoCallback;
01059 endCallback->setCallback(endCB, this->shadowLightsRoot);
01060
01061 ONDEBUG( this->printSettings() );
01062
01063 if ( this->sceneRoot != NULL )
01064 {
01065
01066
01067
01068
01069 this->sceneNoShadows->addChild(this->sceneRoot);
01070
01071
01072
01073
01074 SoSeparator * aboveShadowVloumesRoot = new SoSeparator;
01075 this->sceneWithShadows->addChild(aboveShadowVloumesRoot);
01076
01077 aboveShadowVloumesRoot->addChild(initCallback);
01078 aboveShadowVloumesRoot->addChild(this->sceneRoot);
01079
01080 aboveShadowVloumesRoot->addChild(shadowLightsRoot);
01081 aboveShadowVloumesRoot->addChild(endCallback);
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096 }
01097 }
01098
01099
01105 SoSeparator * CShadowManager::getShadowSceneRoot()
01106 {
01107 if ( first ) {
01108 this->createShadowScene();
01109 first = FALSE;
01110 }
01111 return this->shadowSceneRoot;
01112 }
01113
01114
01120 SoSeparator * CShadowManager::getSceneRoot()
01121 {
01122 return this->sceneRoot;
01123 }
01124
01125
01128
01134 void CShadowManager::printMsg(const char *msg)
01135 {
01136 fprintf(stdout,"SM: %s\n",msg);
01137 }
01138
01139
01145 void CShadowManager::printError(const char *msg)
01146 {
01147 fprintf(stderr,"SM Error: %s\n",msg);
01148 }
01149
01150
01156 void CShadowManager::export(const char * filename)
01157 {
01158 SoOutput output;
01159 if ( output.openFile(filename) ) {
01160 SoWriteAction * writer = new SoWriteAction(&output);
01161 writer->apply(this->shadowLightsRoot);
01162 delete writer;
01163 }
01164 else
01165 {
01166 char * buf = NULL;
01167 sprintf(buf,"Can not open file '%s' for export.",filename);
01168 this->printError(buf);
01169 }
01170 }
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01205
01207
01208
01218 void CShadowManager::initCB(void *userdata, SoAction *action)
01219 {
01220 if (action->isOfType(SoGLRenderAction::getClassTypeId())) {
01221 ONDEBUG(printf("initCB\n"));
01222
01223
01224 glClearDepth(1.0f);
01225
01226 glEnable(GL_DEPTH_TEST);
01227 glDepthFunc(GL_LEQUAL);
01228
01229 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
01230 glEnable(GL_CULL_FACE);
01231
01232
01233 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
01234 glPushAttrib(GL_ENABLE_BIT);
01235
01236 glEnable(GL_LIGHTING);
01237
01238
01239 SoSeparator * lightRoot = (SoSeparator * ) userdata;
01240 int cnt = lightRoot->getNumChildren();
01241 for ( int i = 0; i < cnt; i++ )
01242 {
01243 SoShadowLight * slight = static_cast<SoShadowLight *>(lightRoot->getChild(i));
01244 slight->getLight()->on.enableNotify(FALSE);
01245 slight->status = slight->getLight()->on.getValue();
01246 slight->getLight()->on = FALSE;
01247 slight->getLight()->on.enableNotify(TRUE);
01248 }
01249 }
01250 }
01251
01252
01262 void CShadowManager::endCB(void *userdata, SoAction *action)
01263 {
01264 if (action->isOfType(SoGLRenderAction::getClassTypeId())) {
01265 ONDEBUG(printf("endCB\n"));
01266
01267
01268 SoSeparator * lightRoot = (SoSeparator * ) userdata;
01269 int cnt = lightRoot->getNumChildren();
01270 for ( int i = 0; i < cnt; i++ )
01271 {
01272 SoShadowLight * slight = static_cast<SoShadowLight *>(lightRoot->getChild(i));
01273 slight->getLight()->on.enableNotify(FALSE);
01274 slight->getLight()->on = slight->status;
01275 slight->getLight()->on.enableNotify(TRUE);
01276 }
01277
01278 glDisable(GL_LIGHTING);
01279 glDepthFunc(GL_LEQUAL);
01280 glPopAttrib();
01281 }
01282 }