コード例 #1
0
ファイル: SLNode.cpp プロジェクト: h3ll5ur7er/SLProject
/*!
Rotates the node around its local origin relative to the space expressed by 'relativeTo'.
*/
void SLNode::rotate(const SLQuat4f& rot, SLTransformSpace relativeTo)
{
    SLQuat4f norm = rot.normalized();
    SLMat4f rotation = rot.toMat4();


    if (relativeTo == TS_object)
    {
        _om *= rotation;
    }
    else if (_parent && relativeTo == TS_world)
    {
        SLMat4f rot;
        rot.translate(updateAndGetWM().translation());
        rot.multiply(rotation);
        rot.translate(-updateAndGetWM().translation());

        _om = _parent->_wm.inverse() * rot * updateAndGetWM();
    }
    else // relativeTo == TS_Parent || relativeTo == TS_World && !_parent
    {
        SLMat4f rot;
        rot.translate(translation());
        rot.multiply(rotation);
        rot.translate(-translation());

        _om.setMatrix(rot * _om);
    }

    needUpdate();
}
コード例 #2
0
ファイル: SLNode.cpp プロジェクト: h3ll5ur7er/SLProject
/*!
Updates the axis aligned bounding box in world space. 
*/
SLAABBox& SLNode::updateAABBRec()
{
    if (_isAABBUpToDate)
        return _aabb;

    // empty the AABB (= max negative AABB)
    if (_meshes.size() > 0 || _children.size() > 0)
    {   _aabb.minWS(SLVec3f( FLT_MAX, FLT_MAX, FLT_MAX));
        _aabb.maxWS(SLVec3f(-FLT_MAX,-FLT_MAX,-FLT_MAX));  
    }

    // Build or update AABB of meshes & merge them to the nodes aabb in WS
    for (auto mesh : _meshes)
    {   SLAABBox aabbMesh;
        mesh->buildAABB(aabbMesh, updateAndGetWM());
        _aabb.mergeWS(aabbMesh);
    }
    
    // Merge children in WS
    for (auto child : _children)
        if (typeid(*child)!=typeid(SLCamera))
            _aabb.mergeWS(child->updateAABBRec());

    // We need min & max also in OS for the uniform grid intersection in OS
    _aabb.fromWStoOS(_aabb.minWS(), _aabb.maxWS(), updateAndGetWMI());

    // For visualizing the nodes orientation we finally update the axis in WS
    _aabb.updateAxisWS(updateAndGetWM());

    _isAABBUpToDate = true;
    return _aabb;
}
コード例 #3
0
ファイル: SLButton.cpp プロジェクト: h3ll5ur7er/SLProject
/*! 
SLButton::buildAABB builds and returns the axis-aligned bounding box.
*/
SLAABBox& SLButton::updateAABBRec()
{  
    // build AABB of subMenus
    SLNode::updateAABBRec();
   
    // calculate min & max in object space
    SLVec3f minOS((SLfloat)_minX, (SLfloat)_minY, -0.01f);
    SLVec3f maxOS((SLfloat)(_minX+_btnW), (SLfloat)(_minY+_btnH), 0.01f);
   
    // enlarge aabb for avoiding rounding errors 
    minOS -= FLT_EPSILON;
    maxOS += FLT_EPSILON;
   
    // apply world matrix: this overwrites the AABB of the group
    _aabb.fromOStoWS(minOS, maxOS, updateAndGetWM());
      
    return _aabb;
}
コード例 #4
0
SLfloat SLLightRect::shadowTestMC(SLRay* ray, // ray of hit point
                                  const SLVec3f& L, // vector from hit point to light
                                  const SLfloat lightDist) // distance to light
{
    SLVec3f SP; // vector hit point to sample point in world coords

    SLfloat randX = rnd01();
    SLfloat randY = rnd01();

    // choose random point on rect as sample
    SP.set(updateAndGetWM().multVec(SLVec3f((randX*_width)-(_width*0.5f), (randY*_height)-(_height*0.5f), 0)) - ray->hitPoint);
    SLfloat SPDist = SP.length();
    SP.normalize();
    SLRay shadowRay(SPDist, SP, ray);

    SLScene::current->root3D()->hitRec(&shadowRay);

    if (shadowRay.length >= SPDist - FLT_EPSILON)
        return 1.0f;
    else
        return 0.0f;
}
コード例 #5
0
/*!
SLLightRect::shadowTest returns 0.0 if the hit point is completely shaded and 
1.0 if it is 100% lighted. A return value inbetween is calculate by the ratio 
of the shadow rays not blocked to the total number of casted shadow rays.
*/
SLfloat SLLightRect::shadowTest(SLRay* ray, // ray of hit point
                               const SLVec3f& L, // vector from hit point to light
                               const SLfloat lightDist) // distance to light
{  
    if (_samples.x==1 && _samples.y==1)
    {  
        // define shadow ray
        SLRay shadowRay(lightDist, L, ray);
            
        SLScene::current->root3D()->hitRec(&shadowRay);

        return (shadowRay.length < lightDist) ? 0.0f : 1.0f;
    } 
    else // do light sampling for soft shadows
    {   SLfloat dw = (SLfloat)_width/(SLfloat)_samples.x; // width of a sample cell
        SLfloat dl = (SLfloat)_height/(SLfloat)_samples.y;// length of a sample cell
        SLint   x, y, hx=_samples.x/2, hy=_samples.y/2;
        SLint   samples = _samples.x*_samples.y;
        SLbool* isSampled = new SLbool[samples];
        SLbool  importantPointsAreLighting = true;
        SLfloat lighted = 0.0f; // return value
        SLfloat invSamples = 1.0f/(SLfloat)(samples);
        SLVec3f SP; // vector hitpoint to samplepoint in world coords

        for (y=0; y<_samples.y; ++y)
        {   for (x=0; x<_samples.x; ++x)
            {  SLint iSP = y*_samples.x + x;
            isSampled[iSP]=false;
            }
        }

        /*
        Important sample points (X) on a 7 by 5 rectangular light.
        If all of them are lighting the hitpoint the sample points
        in between (O) are not tested anymore.

             0   1   2   3   4   5   6         
           +---+---+---+---+---+---+---+
        0  | X | . | . | X | . | . | X |
           +---+---+---+---+---+---+---+
        1  | . | . | . | . | . | . | . |
           +---+---+---+---+---+---+---+
        2  | X | . | . | X | . | . | X |
           +---+---+---+---+---+---+---+
        3  | . | . | . | . | . | . | . |
           +---+---+---+---+---+---+---+
        4  | X | . | . | X | . | . | X |
           +---+---+---+---+---+---+---+
        */

        // Double loop for the important sample points
        for (y=-hy; y<=hy; y+=hy)
        {   for (x=-hx; x<=hx; x+=hx)
            {  SLint iSP = (y+hy)*_samples.x + x+hx;
            isSampled[iSP]=true;
            
            SP.set(updateAndGetWM().multVec(SLVec3f(x*dw, y*dl, 0)) - ray->hitPoint);
            SLfloat SPDist = SP.length();
            SP.normalize();
            SLRay shadowRay(SPDist, SP, ray);

            SLScene::current->root3D()->hitRec(&shadowRay);
            
            if (shadowRay.length >= SPDist-FLT_EPSILON) 
                lighted += invSamples; // sum up the light
            else 
                importantPointsAreLighting = false;
            }
        }

        if (importantPointsAreLighting)
            lighted = 1.0f;
        else
        {  // Double loop for the samplepoints inbetween
            for (y=-hy; y<=hy; ++y)
            {   for (x=-hx; x<=hx; ++x)
                {  SLint iSP = (y+hy)*_samples.x + x+hx;
                    if (!isSampled[iSP])
                    {   SP.set(updateAndGetWM().multVec(SLVec3f(x*dw, y*dl, 0)) - ray->hitPoint);
                        SLfloat SPDist = SP.length();
                        SP.normalize();
                        SLRay shadowRay(SPDist, SP, ray);

                        SLScene::current->root3D()->hitRec(&shadowRay);
                  
                        // sum up the light
                        if (shadowRay.length >= SPDist-FLT_EPSILON) 
                            lighted += invSamples;
                    }
                }
            }
        }
        if (isSampled) delete [] isSampled;
        return lighted;
    }
}