Exemplo n.º 1
0
void keyPressed(KeyEventDetails* const details,
                WindowEventProducer* const TutorialWindow,
                FogStage* const TheFogCore)
{
    if(details->getKey() == KeyEventDetails::KEY_Q &&
       details->getModifiers() & KeyEventDetails::KEY_MODIFIER_COMMAND)
    {
        TutorialWindow->closeWindow();
    }

    switch(details->getKey())
    {
        case KeyEventDetails::KEY_EQUALS:
        case KeyEventDetails::KEY_PLUS:
            TheFogCore->setFogDensity(osgClamp(0.0f, TheFogCore->getFogDensity() + 0.001f, 1.0f));
            break;
        case KeyEventDetails::KEY_MINUS:
            TheFogCore->setFogDensity(osgClamp(0.0f, TheFogCore->getFogDensity() - 0.001f, 1.0f));
            break;
        case KeyEventDetails::KEY_1:
            TheFogCore->setFogMode(FogStage::FOG_MODE_LINEAR);
            break;
        case KeyEventDetails::KEY_2:
            TheFogCore->setFogMode(FogStage::FOG_MODE_EXP);
            break;
        case KeyEventDetails::KEY_3:
            TheFogCore->setFogMode(FogStage::FOG_MODE_EXP2);
            break;
    }
}
ActionBase::ResultE ScreenLOD::renderEnter(Action *action)
{
    RenderAction  *ra        = dynamic_cast<RenderAction*>(action);

    Int32           numLevels = action->getNNodes();
    Int32           index     = 0;
    
    Int32           numCovOverrides = getMFCoverageOverride()->size();
    bool            use_overrides(numCovOverrides > 0);

    if(numLevels > 1)
    {
        if((ra->getScreenLODCoverageThreshold() > 0.f) || use_overrides)
        {
            // -- Compute bounding volume screen coverage of current node -- //
            Matrixr worldToScreen;
#if 1 
            Camera* cam = ra->getCamera();
            Viewport* vp = ra->getViewport();
            cam->getWorldToScreen(worldToScreen, *vp);
#else
            worldToScreen = da->getDrawEnv()->getWorldToScreen();
#endif
            
            const BoxVolume &volume = ra->getActNode()->getVolume();
            Pnt3r min,max;
            volume.getBounds(min, max);
            Pnt3r p[8];
            p[0].setValues(min[0],min[1],min[2]);
            p[1].setValues(max[0],min[1],min[2]);
            p[2].setValues(min[0],max[1],min[2]);
            p[3].setValues(min[0],min[1],max[2]);
            p[4].setValues(max[0],max[1],min[2]);
            p[5].setValues(max[0],min[1],max[2]);
            p[6].setValues(min[0],max[1],max[2]);
            p[7].setValues(max[0],max[1],max[2]);
            
            for(UInt32 i = 0; i<8;i++)
            {
                ra->topMatrix().mult    (p[i], p[i]);
                worldToScreen  .multFull(p[i], p[i]);
            }
            min=p[0];
            max=p[0];
            for(UInt32 i = 0; i<8; i++)
            {
               for(UInt32 j=0; j<2; j++)
               {
                  if(p[i][j] < min[j])
                  {
                    min[j] = p[i][j];
                  }
                  if(p[i][j] > max[j])
                  {
                    max[j] = p[i][j];
                  }
               }
            }
            max[0] = osgClamp(-1.f, max[0], 1.f);
            max[1] = osgClamp(-1.f, max[1], 1.f);
            min[0] = osgClamp(-1.f, min[0], 1.f);
            min[1] = osgClamp(-1.f, min[1], 1.f);
            
            // cbb (coverage bounding box) is the percent of the screen real estate this would cover
            Real32 cbb = (max[0] - min[0]) * (max[1] - min[1]) / 4.f;

            // Default degredation based computation
            if (!use_overrides)
            {
               //Get max LOD number of triangles
               Node *pmax = action->getNode(0);
               DrawableStatsAttachment *st_max = 
                   DrawableStatsAttachment::get(pmax);

               if(st_max == NULL)
               {
                  DrawableStatsAttachment::addTo(pmax);
                  st_max = DrawableStatsAttachment::get(pmax);
               }
               st_max->validate();
   
               //Get min LOD number of triangles
               Node *pmin = action->getNode(numLevels-1);
               DrawableStatsAttachment *st_min = 
                   DrawableStatsAttachment::get(pmin);
               if(st_min == NULL)
               {
                  DrawableStatsAttachment::addTo(pmin);
                  st_min = DrawableStatsAttachment::get(pmin);
               }
               st_min->validate();
   
               // Find out what the average degradation of triangles is each level
               Real32 deg_percent = 1.0 - (st_min->getTriangles() / st_max->getTriangles());
               deg_percent = deg_percent / numLevels;
               if(deg_percent >= 1.0)
               {
                   cbb = ra->getScreenLODCoverageThreshold(); //just pick this lod
               }
   
               Real32 base_percent = ra->getScreenLODCoverageThreshold(); //Above this renders at full res!
               Real32 user_deg_factor = ra->getScreenLODDegradationFactor();
               // While the screen percentage of the object is less that the percent allowed for the current LOD
               // move down a LOD and find out the new allowed percentage
               while(cbb < base_percent)
               {
                   base_percent= base_percent * deg_percent * user_deg_factor;
                   index++;
                   if(index >= numLevels)
                       break;
               }
            }
            // Use override values
            else
            {
                unsigned idx_limit = osgMin(numLevels, numCovOverrides);

                if(cbb > (*(getMFCoverageOverride()))[0])      // If greater then first, use first index
                {
                    index = 0;
                } 
                else if(cbb <= (*(getMFCoverageOverride()))[numCovOverrides-1])    // If greater then max
                {
                    index = (numLevels > numCovOverrides) ? numCovOverrides : (idx_limit-1); 
                }
                else
                {
                    Int32 i = 1;

                    // While: more to check && ! (over[i-1] >= cbb > over[i])
                    while( (i < numCovOverrides) && 
                           !( (cbb <= (*(getMFCoverageOverride()))[i-1]) && 
                              (cbb >  (*(getMFCoverageOverride()))[i]  )   ) )
                    {
                        i++;
                    }
                    index = i;      // clamped below
                }                 
            }
        }
    }

    if (index >= numLevels)
    {
        index=numLevels-1;
    }

    //if (!use_overrides)
    //{
       // See if we have a minimum LOD that we want to maintain
       Int32 lowestLOD = ra->getScreenLODNumLevels();
       if(lowestLOD != 0) // if using a minLOD
       {
         lowestLOD--; // LODS is 0 based, NumLevels is 1 based
         if(index > lowestLOD)
            index = lowestLOD;
       }
    //}

    ra->useNodeList();
    if(ra->isVisible(action->getNode(index)))
    {
        ra->addNode(action->getNode(index));
    }

    return ActionBase::Continue;
}
void RGBColorChooserPanel::updateChooser(void)
{
    Int32 Red,Green,Blue,Alpha;

    Color4f ColorSelected(getColorFromModel());
    //Update the Red Bounded Range
    Red = osgClamp(0.0f, ColorSelected.red(), 1.0f) * 255;
    if(static_cast<Int32>(Red) != _RedModel->getValue())
    {
        _RedModel->setValue(Red);
    }
    _RedSliderTrackBackground->editMFColors()->clear();
    _RedSliderTrackBackground->editMFStops()->clear();
    _RedSliderTrackBackground->editMFColors()->push_back(Color4f(0.0f,
                                                                 ColorSelected.green(),
                                                                 ColorSelected.blue(),
                                                                 ColorSelected.alpha()));
    _RedSliderTrackBackground->editMFStops()->push_back(0.0);
    _RedSliderTrackBackground->editMFColors()->push_back(Color4f(1.0f,
                                                                 ColorSelected.green(),
                                                                 ColorSelected.blue(),
                                                                 ColorSelected.alpha()));
    _RedSliderTrackBackground->editMFStops()->push_back(1.0);

    //Update the Green Bounded Range
    Green = osgClamp(0.0f, ColorSelected.green(), 1.0f) * 255;
    if(static_cast<Int32>(Green) != _GreenModel->getValue())
    {
        _GreenModel->setValue(Green);
    }
    _GreenSliderTrackBackground->editMFColors()->clear();
    _GreenSliderTrackBackground->editMFStops()->clear();
    _GreenSliderTrackBackground->editMFColors()->push_back(Color4f(ColorSelected.red(),
                                                                   0.0f,
                                                                   ColorSelected.blue(),
                                                                   ColorSelected.alpha()));
    _GreenSliderTrackBackground->editMFStops()->push_back(0.0);
    _GreenSliderTrackBackground->editMFColors()->push_back(Color4f(ColorSelected.red(),
                                                                   1.0f,
                                                                   ColorSelected.blue(),
                                                                   ColorSelected.alpha()));
    _GreenSliderTrackBackground->editMFStops()->push_back(1.0);

    //Update the Blue Bounded Range
    Blue = osgClamp(0.0f, ColorSelected.blue(), 1.0f) * 255;
    if(static_cast<Int32>(Blue) != _BlueModel->getValue())
    {
        _BlueModel->setValue(Blue);
    }
    _BlueSliderTrackBackground->editMFColors()->clear();
    _BlueSliderTrackBackground->editMFStops()->clear();
    _BlueSliderTrackBackground->editMFColors()->push_back(Color4f(ColorSelected.red(),
                                                                  ColorSelected.green(),
                                                                  0.0f,
                                                                  ColorSelected.alpha()));
    _BlueSliderTrackBackground->editMFStops()->push_back(0.0);
    _BlueSliderTrackBackground->editMFColors()->push_back(Color4f(ColorSelected.red(),
                                                                  ColorSelected.green(),
                                                                  1.0f,
                                                                  ColorSelected.alpha()));
    _BlueSliderTrackBackground->editMFStops()->push_back(1.0);

    //Update the Alpha Bounded Range
    Alpha = osgClamp(0.0f, ColorSelected.alpha(), 1.0f) * 255;
    if(static_cast<Int32>(Alpha) != _AlphaModel->getValue())
    {
        _AlphaModel->setValue(Alpha);
    }

    if(getIncludeAlpha())
    {
        _AlphaSliderTrackBackground->editMFColors()->clear();
        _AlphaSliderTrackBackground->editMFStops()->clear();
        _AlphaSliderTrackBackground->editMFColors()->push_back(Color4f(ColorSelected.red(),
                                                                       ColorSelected.green(),
                                                                       ColorSelected.blue(),
                                                                       0.0f));
        _AlphaSliderTrackBackground->editMFStops()->push_back(0.0);
        _AlphaSliderTrackBackground->editMFColors()->push_back(Color4f(ColorSelected.red(),
                                                                       ColorSelected.green(),
                                                                       ColorSelected.blue(),
                                                                       1.0f));
        _AlphaSliderTrackBackground->editMFStops()->push_back(1.0);
    }
}
void OcclusionCullingTreeBuilder::testNode(OCRenderTreeNode   *pNode,
                                           DrawEnv             &denv,
                                           RenderPartitionBase *part,
                                           Real32              &scr_percent)
{
    while (pNode != NULL)
    {
    //MATRIX SETUP
        UInt32 uiNextMatrix = pNode->getMatrixStore().first;

        if(uiNextMatrix != 0 && uiNextMatrix != _uiActiveMatrix)
        {
            glLoadMatrixf(pNode->getMatrixStore().second.getValues());

            _uiActiveMatrix = uiNextMatrix;

            _currMatrix.second = pNode->getMatrixStore().second;

            updateTopMatrix(denv);

            denv.setObjectToWorld(_accMatrix);

            ++part->_uiNumMatrixChanges;
        }

        const BoxVolume &volume = pNode->getVolume();
        Pnt3f min,max;

        volume.getBounds(min, max);
        Pnt3f p[8];
        p[0].setValues(min[0],min[1],min[2]);
        p[1].setValues(max[0],min[1],min[2]);
        p[2].setValues(min[0],max[1],min[2]);
        p[3].setValues(min[0],min[1],max[2]);
        p[4].setValues(max[0],max[1],min[2]);
        p[5].setValues(max[0],min[1],max[2]);
        p[6].setValues(min[0],max[1],max[2]);
        p[7].setValues(max[0],max[1],max[2]);

        //std::cout << "OtoW:" << std::endl;
        //std::cout << denv.getObjectToWorld() << std::endl;
        //std::cout << "WtoC:" << std::endl;
        //std::cout << worldToCam << std::endl;
        for(UInt32 i = 0; i<8;i++)
        {
           // std::cout << p[i] << "=>";
            denv.getObjectToWorld().mult    (p[i], p[i]);
            _worldToScreen         .multFull(p[i], p[i]);
            //std::cout << p[i] << "  ";
        }
        min=p[0];
        max=p[0];
        for(UInt32 i = 0; i<8; i++)
        {
           for(UInt32 j=0; j<2; j++)
           {
              if(p[i][j] < min[j])
              {
                min[j] = p[i][j];
              }
              if(p[i][j] > max[j])
              {
                max[j] = p[i][j];
              }
           }
        }
        max[0] = osgClamp(-1.f, max[0], 1.f);
        max[1] = osgClamp(-1.f, max[1], 1.f);
        min[0] = osgClamp(-1.f, min[0], 1.f);
        min[1] = osgClamp(-1.f, min[1], 1.f);

        // cbb is the percent of the screen real estate this would cover
        Real32 cbb = (max[0] - min[0]) * (max[1] - min[1]) / 4.f;

        //std::cout << cur_node << ":" << pix << " ";
        //std::cout << pNode->getScalar() << std::endl;

//Make decision

        if(pNode->hasFunctor() == false) //Nothing to do
        {
            //renderNode
            drawNode(pNode, denv, part);
        }
        else
        {
            //make decision
            //if(0 > 1)
            if(cbb > scr_percent) // Rendering major occluders
            {
                drawNode(pNode, denv, part);
                //scr_percent+=cbb;
            }
            else
            {

                Real32 pcov;
                pcov = sqrt(scr_percent) - sqrt(cbb);
                pcov *= pcov;
                //std::cout << "cbb:" << cbb << " scr_percent:" << scr_percent <<" pcov:" << pcov << std::endl;
                //if(scr_percent - pcov > 0.001)
                if(pcov > _coveredProbThreshold || cbb < 0.001) // If within threshold or reall small
                {
                    //Get triangles
                    DrawableStatsAttachment *st =
                        DrawableStatsAttachment::get(pNode->getNode()->getCore());
                    st->validate();
                    UInt32 triangles = st->getTriangles();

                    if(cbb * _vpWidth * _vpHeight < _minFeatureSize) //small feature culling
                    {
                        StatCollector *sc = _ract->getStatCollector();
                        if(sc != NULL)
                            sc->getElem(statNOccTriangles)->
                                add(triangles);
                        if(_ract->getOcclusionCullingDebug() && pNode->getNode())
                        {
                            pNode->getNode()->setTravMask(
                                pNode->getNode()->getTravMask() |
                                _ract->getOcclusionCulledDebugMask()
                                );
                        }
                        pNode->setIsRendered(true);
                    }
                    else if( triangles <= _minTriangleCount )
                    {
                        drawNode(pNode, denv, part);
                    }
                    else if((_testPendingNodes.size() == _numTestSamples - 1)) // Make sure we have room to draw a test
                    {
                        drawTestResults(denv, part);
                        if(_testPendingNodes.size() == _numTestSamples - 1) // If we are waiting on a result, draw a node
                        {
                            drawNode(pNode, denv, part);
                        }
                        else
                        {
                            drawTestNode(pNode, denv, part); // Made room, go ahead and draw a test node
                        }
                    }
                    else
                    {
                        drawTestNode(pNode, denv, part); //Plenty of room in buffer to draw a test node
                    }
                }
                else
                {
                    drawNode(pNode, denv, part); // Probably not being covered up...draw the real node
                    //scr_percent+=cbb;
                }
            }
            scr_percent += ((1.0 - scr_percent) * cbb);
        }

//DRAW CHILDREN OR GO TO TOP AND DO IT AGAIN
        if(pNode->getFirstChild() != NULL)
        {
            OCRenderTreeNode *child =
                static_cast<OCRenderTreeNode *>(pNode->getFirstChild());

            testNode(child, denv, part, scr_percent);
        }

        pNode = static_cast<OCRenderTreeNode *>(pNode->getBrother());
    }
}
Node *
ColladaLight::createInstanceCommon(
    ColladaLightInstInfo *colInstInfo, domLight::domTechnique_common *tech)
{
    domLightRef light = getDOMElementAs<domLight>();

    OSG_COLLADA_LOG(("ColladaLight::createInstanceCommon id [%s]\n",
                     light->getId()));

    NodeUnrecPtr                                     lightN      = NULL;

    domLight::domTechnique_common::domAmbientRef     ambient     =
        tech->getAmbient();
    domLight::domTechnique_common::domDirectionalRef directional =
        tech->getDirectional();
    domLight::domTechnique_common::domPointRef       point       =
        tech->getPoint();
    domLight::domTechnique_common::domSpotRef        spot        =
        tech->getSpot();

    if(ambient != NULL)
    {
        Color4f lightColor(ambient->getColor()->getValue()[0],
                           ambient->getColor()->getValue()[1],
                           ambient->getColor()->getValue()[2], 1.f);

        LightLoaderState *state =
            getGlobal()->getLoaderStateAs<LightLoaderState>(_loaderStateName);
        OSG_ASSERT(state != NULL);

        LightModelChunkUnrecPtr lmChunk = state->getLightModelChunk();

        if(state->getLightModelChunk() == NULL)
        {
            lmChunk = LightModelChunk::create();
            lmChunk->setAmbient(Color4f(0.f, 0.f, 0.f, 1.f));

            state->setLightModelChunk(lmChunk);

            // only place one instance into the inst queue, it will
            // add the LightModelChunk with the accumulated ambient
            // for the scene
            ColladaInstInfoRefPtr ambientInstInfo =
                ColladaLightAmbientInstInfo::create(
                    colInstInfo->getColInstParent(),
                    dynamic_cast<ColladaInstanceLight *>(
                        colInstInfo->getColInst())        );

            getGlobal()->editInstQueue().push_back(ambientInstInfo);
        }

        lightColor[0] = 
            osgClamp(0.f, lmChunk->getAmbient()[0] + lightColor[0], 1.f);
        lightColor[1] =
            osgClamp(0.f, lmChunk->getAmbient()[1] + lightColor[1], 1.f);
        lightColor[2] =
            osgClamp(0.f, lmChunk->getAmbient()[2] + lightColor[0], 1.f);

        lmChunk->setAmbient(lightColor);
    }

    if(directional != NULL)
    {
        Color4f lightColor(directional->getColor()->getValue()[0],
                           directional->getColor()->getValue()[1],
                           directional->getColor()->getValue()[2], 1.f);

        DirectionalLightUnrecPtr dl = DirectionalLight::create();
        lightN                      = makeNodeFor(dl);

        dl->setBeacon  (colInstInfo->getBeacon());
        dl->setDiffuse (lightColor              );
        dl->setSpecular(lightColor              );
    }

    if(point != NULL)
    {
        Color4f lightColor(point->getColor()->getValue()[0],
                           point->getColor()->getValue()[1],
                           point->getColor()->getValue()[2], 1.f);

        PointLightUnrecPtr pl = PointLight::create();
        lightN                = makeNodeFor(pl);

        Real32 constAtt = 1.f;
        Real32 linAtt   = 0.f;
        Real32 quadAtt  = 0.f;

        if(point->getConstant_attenuation() != NULL)
            constAtt = point->getConstant_attenuation()->getValue();

        if(point->getLinear_attenuation() != NULL)
            linAtt   = point->getLinear_attenuation()->getValue();

        if(point->getQuadratic_attenuation() != NULL)
            quadAtt  = point->getQuadratic_attenuation()->getValue();

        pl->setBeacon              (colInstInfo->getBeacon());
        pl->setDiffuse             (lightColor              );
        pl->setSpecular            (lightColor              );
        pl->setConstantAttenuation (constAtt                );
        pl->setLinearAttenuation   (linAtt                  );
        pl->setQuadraticAttenuation(quadAtt                 );
    }

    if(spot != NULL)
    {
        Color4f lightColor(spot->getColor()->getValue()[0],
                           spot->getColor()->getValue()[1],
                           spot->getColor()->getValue()[2], 1.f);

        SpotLightUnrecPtr sl = SpotLight::create();
        lightN               = makeNodeFor(sl);

        Real32 constAtt =   1.f;
        Real32 linAtt   =   0.f;
        Real32 quadAtt  =   0.f;
        Real32 cutOff   = 180.f;
        Real32 exponent =   0.f;

        if(spot->getConstant_attenuation() != NULL)
            constAtt = spot->getConstant_attenuation()->getValue();

        if(spot->getLinear_attenuation() != NULL)
            linAtt   = spot->getLinear_attenuation()->getValue();

        if(spot->getQuadratic_attenuation() != NULL)
            quadAtt  = spot->getQuadratic_attenuation()->getValue();

        if(spot->getFalloff_angle() != NULL)
            cutOff   = spot->getFalloff_angle()->getValue();

        if(spot->getFalloff_exponent() != NULL)
            exponent = spot->getFalloff_exponent()->getValue();

        sl->setBeacon              (colInstInfo->getBeacon());
        sl->setDiffuse             (lightColor              );
        sl->setSpecular            (lightColor              );
        sl->setConstantAttenuation (constAtt                );
        sl->setLinearAttenuation   (linAtt                  );
        sl->setQuadraticAttenuation(quadAtt                 );
        sl->setSpotCutOff          (osgDegree2Rad(cutOff)   );
        sl->setSpotExponent        (exponent                );
    }

    if(lightN != NULL)
    {
        editInstStore().push_back(lightN);

        if(getGlobal()->getOptions()->getCreateNameAttachments() == true &&
           light->getName()                                      != NULL   )
        {
            setName(lightN, light->getName());
        }
    }

    return lightN;
}