Exemplo n.º 1
0
/*!
SLCamera::calcMinMax calculates the axis alligned minimum and maximum point of
the camera position and the 4 near clipping plane points.
*/
void SLCamera::calcMinMax(SLVec3f &minV, SLVec3f &maxV)
{
   SLScene* s = SLScene::current;
   SLSceneView* sv = s->activeSV();
   SLVec3f P[5];
   SLfloat aspect = (float)sv->scrW() / (float)sv->scrH();
   SLfloat tanFov = tan(_fov*SL_DEG2RAD*0.5f);
   SLfloat tN = tanFov * _clipNear; //top near
   SLfloat rN = tN * aspect;        //right near

   // frustum pyramid lines
   P[0].set(0,0,0);

   // around near clipping plane
   P[1].set( rN, tN,-_clipNear);
   P[2].set( rN,-tN,-_clipNear);
   P[3].set(-rN,-tN,-_clipNear);
   P[4].set(-rN, tN,-_clipNear);

   // init min & max points
   minV.set( FLT_MAX,  FLT_MAX,  FLT_MAX);
   maxV.set(-FLT_MAX, -FLT_MAX, -FLT_MAX);

   // calc min and max point of all vertices
   for (SLuint i=0; i<5; ++i)
   {  if (P[i].x < minV.x) minV.x = P[i].x;
      if (P[i].x > maxV.x) maxV.x = P[i].x;
      if (P[i].y < minV.y) minV.y = P[i].y;
      if (P[i].y > maxV.y) maxV.y = P[i].y;
      if (P[i].z < minV.z) minV.z = P[i].z;
      if (P[i].z > maxV.z) maxV.z = P[i].z;
   }
}
Exemplo n.º 2
0
/*!
*/
SLCol4f SLPhotonMapper::trace(SLRay* ray)
{  
   SLScene* s = SLScene::current;
   SLCol4f color(s->backColor());
   
   return color;
}
Exemplo n.º 3
0
/*! 
SLCamera::onDoubleTouch gets called whenever two fingers touch a handheld
screen.
*/
SLbool SLCamera::onTouch2Down(const SLint x1, const SLint y1,
                              const SLint x2, const SLint y2)
{	
   SLScene* s = SLScene::current;
   SLSceneView* sv = s->activeSV();
   
   // Determine the lookAt point by ray cast
   eyeToPixelRay((SLfloat)sv->scrWdiv2(), 
                 (SLfloat)sv->scrHdiv2(), &_lookAtRay);
   s->root3D()->hit(&_lookAtRay);
   
   _oldTouchPos1.set((SLfloat)x1, (SLfloat)y1);
   _oldTouchPos2.set((SLfloat)x2, (SLfloat)y2);
   return true;
}
Exemplo n.º 4
0
/*! 
SLCamera::onMouseWheel event handler moves camera forwards or backwards
*/
SLbool SLCamera::onMouseWheel(const SLint delta, const SLKey mod)
{  
   SLScene* s = SLScene::current;
   SLSceneView* sv = s->activeSV();
   SLfloat sign = (SLfloat)SL_sign(delta);
   
   if (_camAnim==turntableYUp || _camAnim==turntableZUp) //....................
   {  if (mod==KeyNone)
      {  
         // Determine the lookAt point by ray cast
         eyeToPixelRay((SLfloat)sv->scrWdiv2(), 
                       (SLfloat)sv->scrHdiv2(), &_lookAtRay);
         s->root3D()->hit(&_lookAtRay);
         if (_lookAtRay.length < FLT_MAX) 
            _lookAtRay.hitPoint = _lookAtRay.origin + 
                                  _lookAtRay.dir*_lookAtRay.length;
         
         // Scale the mouse delta by the lookAt distance
         SLfloat lookAtDist;
         if (_lookAtRay.length < FLT_MAX && _lookAtRay.hitShape)
         {  lookAtDist = _lookAtRay.length;
         }
         else lookAtDist = _focalDist;
                  
         _vm.translation(_vm.m(12),_vm.m(13),_vm.m(14) + sign*lookAtDist*_dPos);
         _lookAtRay.length = FLT_MAX;
         setWMandState();
      }
      if (mod==KeyCtrl)
      {  _eyeSeparation *= (1.0f + sign*0.1f);
      }
      if (mod==KeyAlt)
      {  _fov += sign*5.0f;
         currentFOV = _fov;
      }
      if (mod==KeyShift)
      {  _focalDist *= (1.0f + sign*0.05f);
         
      }
      return true;
   }
   else if (_camAnim==walkingYUp || _camAnim==walkingZUp) //...................
   {  
      _speedLimit *= (1.0f + sign*0.1f);
   }
   return false;
}
Exemplo n.º 5
0
//-----------------------------------------------------------------------------
//! Gets called whenever a mouse button gets pressed.
SLbool SLCamera::onMouseDown(const SLMouseButton button, 
                             const SLint x, const SLint y, const SLKey mod)
{  
    SLScene* s = SLScene::current;

    // Determine the lookAt point by ray cast
    eyeToPixelRay((SLfloat)(_scrW>>1), (SLfloat)(_scrH>>1), &_lookAtRay);
    //eyeToPixelRay(x, y, &_lookAtRay);
   
    if (s->root3D()) s->root3D()->hitRec(&_lookAtRay);
    
    // Init both position in case that the second finger came with delay
    _oldTouchPos1.set((SLfloat)x, (SLfloat)y);
    _oldTouchPos2.set((SLfloat)x, (SLfloat)y);
   
    return false;
}  
Exemplo n.º 6
0
//-----------------------------------------------------------------------------
//! Gets called whenever a mouse button gets pressed.
SLbool SLCamera::onMouseDown(const SLMouseButton button, 
                             const SLint x, const SLint y, const SLKey mod)
{  
   SLScene* s = SLScene::current;
   SLSceneView* sv = s->activeSV();
   
   // Determine the lookAt point by ray cast
   eyeToPixelRay((SLfloat)sv->scrWdiv2(), 
                 (SLfloat)sv->scrHdiv2(), &_lookAtRay);
   s->root3D()->hit(&_lookAtRay);
   
   // Init both position in case that the second finger came with delay
   _oldTouchPos1.set((SLfloat)x, (SLfloat)y);
   _oldTouchPos2.set((SLfloat)x, (SLfloat)y);
   
   return false;
}  
Exemplo n.º 7
0
/*!
SLMaterial::activate applies the material parameter to the global render state
and activates the attached shader
*/
void SLMaterial::activate(SLGLState* state, SLShape* shape)
{      
   SLScene* s = SLScene::current;
   SLSceneView* sv = s->activeSV();

   // Deactivate shader program of the current active material
   if (current && current->shaderProg()) 
      current->shaderProg()->endShader();

   // Set this material as the current material
   current = this;

   // If no shader program is attached add the default shader program
   if (!_shaderProg)
   {  if (_textures.size()>0)
           shaderProg(s->shaderProgs(PerVrtBlinnTex));
      else shaderProg(s->shaderProgs(PerVrtBlinn));
   }

   // Check if shader had compile error and the error texture should be shown
   if (_shaderProg && _shaderProg->name().find("ErrorTex")!=string::npos)
   {  _textures.clear();
      _textures.push_back(new SLGLTexture("CompileError.png"));
   }
   
   // Set material in the state
   state->matAmbient    = _ambient;
   state->matDiffuse    = _diffuse;
   state->matSpecular   = _specular;
   state->matEmissive   = _emission;
   state->matShininess  = _shininess;
   
   // Determine use of shaders & textures
   SLbool useTexture = !(sv->drawBits()->get(SL_DB_TEXOFF) || 
                         shape->drawBits()->get(SL_DB_TEXOFF));
                            
   // Enable or disable texturing
   if (useTexture && _textures.size()>0)
   {  for (SLuint i=0; i<_textures.size(); ++i)
         _textures[i]->bindActive(i);
   }
    
   // Activate the shader program now
   shaderProg()->beginUse(this);
}
Exemplo n.º 8
0
/*! This method is used for object picking. The calculation is the same as for
primary rays in Ray Tracing.
*/
void SLCamera::eyeToPixelRay(SLfloat x, SLfloat y, SLRay* ray)
{  
   SLScene* s = SLScene::current;
   SLSceneView* sv = s->activeSV();
   SLfloat  hw, hh, pixel; 
   SLVec3f  dir, EYE, LA, LU, LR, C, TL;
      
   // calculate half window width & height in world coords     
   hh = tan(SL_DEG2RAD*_fov/2); 
   hw = hh * sv->scrWdivH();

   // calculate the size of a pixel in world coords. 
   // height & width must be equal because perspective is undistorted.
   pixel = hw * 2 / sv->scrW();

   // get camera vectors
   _vm.lookAt(&EYE, &LA, &LU, &LR);

   // calculate a vector to the center (C) of the top left (TL) pixel
   C = LA;
   TL = C - hw*LR + hh*LU  +  pixel/2*LR - pixel/2*LU;

   // Calculate direction of ray
   dir = TL + pixel*x*LR - pixel*y*LU;
   
   // Fill in ray parameters
   dir.normalize();
   ray->origin.set(EYE);
   ray->setDir(dir);
   ray->length = FLT_MAX;
   ray->depth = 1;
   ray->contrib = 1.0f; 
   ray->type = PRIMARY;
   ray->x = x;
   ray->y = y;  
   ray->hitTriangle = 0;
   ray->hitMat = 0;
   ray->hitNormal.set(SLVec3f::ZERO);
   ray->hitPoint.set(SLVec3f::ZERO); 
   ray->originMat = &SLMaterial::AIR;
   ray->originTria = 0;
}
Exemplo n.º 9
0
/*!
SLButton::closeAll closes all menus except the root menu
*/
void SLButton::closeAll()
{  
    SLScene* s = SLScene::current;
    SLButton* mnu2D = s->menu2D();
    if (!mnu2D) return;
    mnu2D->hideAndReleaseRec();
    mnu2D->drawBits()->off(SL_DB_HIDDEN);

    // update world matrices & AABBs
    _stateGL->pushModelViewMatrix();
    _stateGL->modelViewMatrix.identity();
    mnu2D->translation(0, 0, 0);
    mnu2D->updateAABBRec();

    _stateGL->popModelViewMatrix();
   
    newMenuPos.set(0,0);
    oldMenuPos.set(0,0);
    buttonDown = 0;
    buttonParent = 0;
}
Exemplo n.º 10
0
/*! 
SLCamera::onMouseWheel event handler moves camera forwards or backwards
*/
SLbool SLCamera::onMouseWheel(const SLint delta, const SLKey mod)
{  
    SLScene* s = SLScene::current;
    SLfloat sign = (SLfloat)SL_sign(delta);
   
    if (_camAnim==turntableYUp || _camAnim==turntableZUp) //....................
    {   if (mod==KeyNone)
        {  
            // Determine the lookAt point by ray cast
            eyeToPixelRay((SLfloat)(_scrW>>1),
                        (SLfloat)(_scrH>>1), &_lookAtRay);

            if (s->root3D()) s->root3D()->hitRec(&_lookAtRay);

            if (_lookAtRay.length < FLT_MAX) 
                _lookAtRay.hitPoint = _lookAtRay.origin + 
                                      _lookAtRay.dir*_lookAtRay.length;
         
            // Scale the mouse delta by the lookAt distance
            SLfloat lookAtDist;
            if (_lookAtRay.length < FLT_MAX && _lookAtRay.hitNode)
                 lookAtDist = _lookAtRay.length;
            else lookAtDist = _focalDist;
                  
            translate(SLVec3f(0, 0, -sign*lookAtDist*_dPos), TS_Object);

            _lookAtRay.length = FLT_MAX;
        }
        if (mod==KeyCtrl)
        {   _eyeSeparation *= (1.0f + sign*0.1f);
        }
        if (mod==KeyAlt)
        {   _fov += sign*5.0f;
            currentFOV = _fov;
        }
        if (mod==KeyShift)
        {  _focalDist *= (1.0f + sign*0.05f);
        }
        return true;
    }
Exemplo n.º 11
0
/*!
SLButton::onMouseUp handles events and returns true if refresh is needed. This
method holds the main functionality for the buttons command execution as well
as the hiding and showing of the sub menus.
*/
SLbool SLButton::onMouseUp(const SLMouseButton button, 
                           const SLint x, const SLint y, const SLKey mod)
{  
    SLScene* s = SLScene::current;
    SLButton* mnu2D = s->menu2D();
    SLButton* btn = 0; // button pointer for various loops
    if (!mnu2D) return false;

    // GUI space is bottom left!
    SLint h = _sv->scrH()-y;
   
    if (x > _aabb.minWS().x && x < _aabb.maxWS().x &&
        h > _aabb.minWS().y && h < _aabb.maxWS().y && 
        !_drawBits.get(SL_DB_HIDDEN))
    {
        if (buttonDown==this)
        { 
            // For a command execute it
            if (_command != C_menu) 
            {  _isDown = false;
            
                // Toggle checkable buttons
                if (_isCheckable && !_radioParent)
                    _isChecked = !_isChecked;
            
                // For radio buttons uncheck others
                if (_radioParent)
                    _radioParent->checkRadioRec();
            
                // Hide all menus again
                if (_closeOnClick)
                    closeAll();

                /////////////////////////
                _sv->onCommand(_command);
                /////////////////////////

                if (_closeOnClick)
                    return true;
            }
            else if (_children.size()>0)
            {  
                // if another menu on the same or higher level is open hide it first
                if (buttonParent && buttonParent!=this && buttonParent->depth()>=_depth)
                {  
                    while (buttonParent && buttonParent->depth() >= depth())
                    {   for (auto child : buttonParent->children())
                            child->drawBits()->set(SL_DB_HIDDEN, true);
                        buttonParent->isDown(false);
                        buttonParent = (SLButton*)buttonParent->parent();
                    }
                }
         
                // show my submenu buttons         
                btn = (SLButton*)_children[0];
                if (btn && btn->drawBits()->get(SL_DB_HIDDEN))
                {  
                    for (auto child : _children)
                        child->drawBits()->set(SL_DB_HIDDEN, false);
                    buttonParent = this;
                } 
                else // submenu is already open so close everything
                {   if (buttonDown==mnu2D)
                    {   mnu2D->hideAndReleaseRec();
                        mnu2D->drawBits()->off(SL_DB_HIDDEN);
                        buttonParent = 0;
                    } else
                    {   if (buttonParent)
                        {  
                            for (auto child : buttonParent->children())
                                child->drawBits()->set(SL_DB_HIDDEN, true);
                            buttonParent->isDown(false);
                            buttonParent = (SLButton*)(buttonParent->parent());
                        }
                    }
                }
            }
         
            // Move menu left or right
            if (buttonParent)
            {   newMenuPos.set(-buttonParent->minX()+minMenuPos.x, 0);
                if (newMenuPos != oldMenuPos) 
                {  
                    mnu2D->translate(newMenuPos.x - oldMenuPos.x, 0, 0, TS_object);
               
                    // update AABB's
                    _stateGL->pushModelViewMatrix();
                    _stateGL->modelViewMatrix.identity();
                    oldMenuPos.set(newMenuPos);
                    mnu2D->updateAABBRec();
                    _stateGL->popModelViewMatrix();
                }
            }
         
            buttonDown = 0;
            return true;
        }
        else // mouse up on a different button, so release it
        {  if (buttonDown)
            {  buttonDown->_isDown = false;
            buttonDown = 0;
            return true;
            }
        }
    }
   
    // check sub menus
    for (auto child : _children)
    {   if (child->onMouseUp(button, x, y, mod))
            return true;
    }
   
    // check if mouse down was on this button and the up was on the scene
    if (_isDown && buttonDown==this)
    {   closeAll();
        return true;
    }
    return false;
}
Exemplo n.º 12
0
/*!
Applies the view transform to the modelview matrix depending on the eye:
eye=-1 for left, eye=1 for right
*/
void SLCamera::setView(SLSceneView* sv, const SLEye eye)
{  
    SLScene* s = SLScene::current;
   
    SLMat4f vm = updateAndGetWMI();

    if (eye == centerEye)
    {   _stateGL->modelViewMatrix.identity();
        _stateGL->viewMatrix.setMatrix(vm);
    } 
    else // stereo viewing
    {
        if (_projection == stereoSideBySideD)
        {  
            // half interpupilar disqtance
            //_eyeSeparation = s->oculus()->interpupillaryDistance(); update old rift code
            SLfloat halfIPD = (SLfloat)eye * _eyeSeparation * -0.5f;
            
            SLMat4f trackingPos;
            if (_useDeviceRot)
            {
                // get the oculus or mobile device orientation
                SLQuat4f rotation;
                if (s->oculus()->isConnected())
                {
                    rotation = s->oculus()->orientation(eye);
                    trackingPos.translate(-s->oculus()->position(eye));
                }
                else rotation = sv->deviceRotation();

                SLfloat rotX, rotY, rotZ;
                rotation.toMat4().toEulerAnglesZYX(rotZ, rotY, rotX);
                //SL_LOG("rotx : %3.1f, roty: %3.1f, rotz: %3.1f\n", rotX*SL_RAD2DEG, rotY*SL_RAD2DEG, rotZ*SL_RAD2DEG);
                SLVec3f viewAdjust = s->oculus()->viewAdjust(eye) * _unitScaling;
                SLMat4f vmEye(SLMat4f(viewAdjust.x, viewAdjust.y, viewAdjust.z) * rotation.inverted().toMat4() * trackingPos * vm);
                _stateGL->modelViewMatrix = vmEye;
                _stateGL->viewMatrix = vmEye;
            } 
            else
            {      
                SLMat4f vmEye(SLMat4f(halfIPD, 0.0f, 0.f) * vm);
                _stateGL->modelViewMatrix = vmEye;
                _stateGL->viewMatrix = vmEye;
            }
        }
        else
        {
            // Get central camera vectors eye, lookAt, lookUp out of the view matrix vm
            SLVec3f EYE, LA, LU, LR;
            vm.lookAt(&EYE, &LA, &LU, &LR);
   
            // Shorten LR to half of the eye dist (eye=-1 for left, eye=1 for right)
            LR *= _eyeSeparation * 0.5f * (SLfloat)eye;
      
            // Set the OpenGL view matrix for the left eye
            SLMat4f vmEye;
            vmEye.lookAt(EYE+LR, EYE + _focalDist*LA+LR, LU);
            _stateGL->modelViewMatrix = vmEye;
            _stateGL->viewMatrix = vmEye;
        }
    } 
}
Exemplo n.º 13
0
/*! Draws the background as a flat 2D rectangle with a height and a width on two
triangles with zero in the bottom left corner: <br>
          w
       +-----+
       |    /|
       |   / |
    h  |  /  |
       | /   |
       |/    |
     0 +-----+
       0

We render the quad as a triangle strip: <br>
     0         2
       +-----+
       |    /|
       |   / |
       |  /  |
       | /   |
       |/    |
       +-----+
     1         3
*/
void SLBackground::render(SLint widthPX, SLint heightPX)
{
    SLGLState* stateGL = SLGLState::getInstance();
    SLScene* s = SLScene::current;

    // Set orthographic projection
    stateGL->projectionMatrix.ortho(0.0f, (SLfloat)widthPX, 0.0f, (SLfloat)heightPX, 0.0f, 1.0f);
    stateGL->modelViewMatrix.identity();

    // Combine modelview-projection matrix
    SLMat4f mvp(stateGL->projectionMatrix * stateGL->modelViewMatrix);
    
    stateGL->depthTest(false);
    stateGL->multiSample(false);

    // Get shader program
    SLGLProgram* sp = _texture ? s->programs(SP_TextureOnly) : s->programs(SP_colorAttribute);
    sp->useProgram();
    sp->uniformMatrix4fv("u_mvpMatrix", 1, (SLfloat*)&mvp);

    // Create or update buffer for vertex position and indices
    if (_resX != widthPX || _resY != heightPX || !_vao.id())
    {
        _resX = widthPX;
        _resY = heightPX;
        _vao.clearAttribs();

        // Float array with vertex X & Y of corners
        SLVVec2f P = {{0.0f, (SLfloat)_resY}, {0.0f, 0.0f},
                      {(SLfloat)_resX, (SLfloat)_resY}, {(SLfloat)_resX, 0.0f}}; 
        _vao.setAttrib(AT_position, sp->getAttribLocation("a_position"), &P);
        
        // Indexes for a triangle strip
        SLVushort I = {0,1,2,3};
        _vao.setIndices(&I);

        if(_texture)
        {   // Float array of texture coordinates
            SLVVec2f T = {{0.0f, 1.0f}, {0.0f, 0.0f}, {1.0f, 1.0f}, {1.0f, 0.0f}};
            _vao.setAttrib(AT_texCoord, sp->getAttribLocation("a_texCoord"), &T);
            _vao.generate(4);
        } else
        {   // Float array of colors of corners
            SLVVec3f C = {{_colors[0].r, _colors[0].g, _colors[0].b},
                          {_colors[1].r, _colors[1].g, _colors[1].b},
                          {_colors[2].r, _colors[2].g, _colors[2].b},
                          {_colors[3].r, _colors[3].g, _colors[3].b}};            
            _vao.setAttrib(AT_color, sp->getAttribLocation("a_color"), &C);
            _vao.generate(4);
        }
    }

    // draw a textured or colored quad
    if(_texture)
    {   _texture->bindActive(0);
        sp->uniform1i("u_texture0", 0);
    }

    ///////////////////////////////////////
    _vao.drawElementsAs(PT_triangleStrip);
    ///////////////////////////////////////
}
Exemplo n.º 14
0
/*!
Photons are scattered (or absorbed) according to surface properties. 
This is done by russian roulette.
Photons are stored on diffuse surfaces only.
*/
void SLPhotonMapper::photonScatter(SLRay* photon, 
                                   SLVec3f power, 
                                   SLPhotonType photonType)//, SLint RGB)
{
   SLScene* s = SLScene::current;      // scene shortcut
   s->root3D()->hit(photon);
   
   if (photon->length < SL_FLOAT_MAX)
   {  
      //photons "absorbed" by luminaire
      if (typeid(*photon->hitShape)==typeid(SLLightSphere) ||
          typeid(*photon->hitShape)==typeid(SLLightRect)) 
         return;

      //abort if maps are full or depth>100
      if((_mapCaustic->isFull() && _mapGlobal->isFull()) || 
         photon->depth>100) //physically plausible ;-)
         return;
      
      photon->normalizeNormal();
      SLMaterial* mat = photon->hitMat;

      //store photon if diffuse surface and not from light
      if (photon->nodeDiffuse() && photonType!=LIGHT)//photon->type()!=PRIMARY)
      {
         if(photonType!=CAUSTIC)
            _mapGlobal->store(photon->hitPoint,photon->dir,power);
         else
         {
            _mapCaustic->store(photon->hitPoint,photon->dir,power);
            return; // caustic photons "die" on diffuse surfaces
         }
      }

      //calculate average of materials
      SLfloat avgDiffuse     = (mat->diffuse().x+mat->diffuse().y+mat->diffuse().z)/3.0f;
      SLfloat avgSpecular    = (mat->specular().x+mat->specular().y+mat->specular().z)/3.0f;
      SLfloat avgTransmission= (mat->transmission().x+mat->transmission().y+mat->transmission().z)/3.0f;
      SLfloat eta            = _russianRandom->Random();

      //Decide type of photon (Global or Caustic) if from light
      if (photonType == LIGHT)
      {
         if ((eta*(avgDiffuse+avgSpecular+avgTransmission))<=avgDiffuse)
            photonType=GLOBAL;
         else
            photonType=CAUSTIC;
      }

      //Russian Roulette
      if (eta <= avgDiffuse) 
      {
         //scattered diffuse (cosine distribution around normal)
         SLRay scattered;
         photon->diffuseMC(&scattered);
         //adjust power
         power.x*=(mat->diffuse().x/avgDiffuse);
         power.y*=(mat->diffuse().y/avgDiffuse);
         power.z*=(mat->diffuse().z/avgDiffuse);

         ++SLRay::diffusePhotons;
         photonScatter(&scattered, power, photonType);

         
      }
      else if (eta <= avgDiffuse+avgSpecular)
      {
         //scatter toward perfect specular direction
         SLRay scattered;
         photon->reflect(&scattered);
         
         //scatter around perfect reflected direction only if material not perfect
         if(photon->hitMat->shininess() < SLMaterial::PERFECT)
         {
            //rotation matrix
            SLMat3f rotMat;
            SLVec3f rotAxis((SLVec3f(0.0,0.0,1.0) ^ scattered.dir).normalize());
            SLfloat rotAngle=acos(scattered.dir.z);//z*scattered.dir()
            rotMat.rotation(rotAngle*180.0/SL_PI,rotAxis);
            photon->reflectMC(&scattered,rotMat);
         }
         
         //avoid scattering into surface
         if (scattered.dir*photon->hitNormal >= 0.0f)
         {
            //adjust power
            power.x*=(mat->specular().x/avgSpecular);
            power.y*=(mat->specular().y/avgSpecular);
            power.z*=(mat->specular().z/avgSpecular);

            ++SLRay::reflectedPhotons;
            photonScatter(&scattered,power,photonType);
         }
      }
      else if (eta <= avgDiffuse+avgSpecular+avgTransmission) //scattered refracted
      {
         //scatter toward perfect transmissive direction
         SLRay scattered;
         photon->refract(&scattered);
         
         //scatter around perfect transmissive direction only if material not perfect
         if(photon->hitMat->translucency() < SLMaterial::PERFECT)
         {
            //rotation matrix
            SLMat3f rotMat;
            SLVec3f rotAxis((SLVec3f(0.0,0.0,1.0) ^ scattered.dir).normalize());
            SLfloat rotAngle=acos(scattered.dir.z);//z*scattered.dir()
            rotMat.rotation(rotAngle*180.0/SL_PI,rotAxis);
            photon->refractMC(&scattered,rotMat);
         }
         SLVec3f N = -photon->hitNormal;
         if(scattered.type==REFLECTED) N*=-1.0;  //In case of total reflection invert the Normal
         
         if (scattered.dir*N >= 0.0f)
         {
            //adjust power
            power.x*=(mat->transmission().x/avgTransmission);
            power.y*=(mat->transmission().y/avgTransmission);
            power.z*=(mat->transmission().z/avgTransmission);
            if(scattered.type==TRANSMITTED) ++SLRay::refractedPhotons; else ++SLRay::tirPhotons;
            photonScatter(&scattered,power,photonType);
         }
      }
      else //absorbed [rest in peace]
      {
      }
   }
}
Exemplo n.º 15
0
/*! 
SLCamera::onTouch2Move gets called whenever two fingers move on a handheld 
screen.
*/
SLbool SLCamera::onTouch2Move(const SLint x1, const SLint y1,
                              const SLint x2, const SLint y2)
{	
   SLScene* s = SLScene::current;
   SLSceneView* sv = s->activeSV();
   SLVec2f now1((SLfloat)x1, (SLfloat)y1);
   SLVec2f now2((SLfloat)x2, (SLfloat)y2);
   SLVec2f delta1(now1-_oldTouchPos1);
   SLVec2f delta2(now2-_oldTouchPos2);
   
   // Average out the deltas over the last 4 events for correct 1 pixel moves
   static SLuint  cnt=0;
   static SLVec2f d1[4];
   static SLVec2f d2[4];
   d1[cnt%4] = delta1;
   d2[cnt%4] = delta2;
   SLVec2f avgDelta1(d1[0].x+d1[1].x+d1[2].x+d1[3].x, d1[0].y+d1[1].y+d1[2].y+d1[3].y);
   SLVec2f avgDelta2(d2[0].x+d2[1].x+d2[2].x+d2[3].x, d2[0].y+d2[1].y+d2[2].y+d2[3].y);
   avgDelta1 /= 4.0f;
   avgDelta2 /= 4.0f;
   cnt++;
      
   SLfloat r1, phi1, r2, phi2;
   avgDelta1.toPolar(r1, phi1);
   avgDelta2.toPolar(r2, phi2);
    
   // Scale the mouse delta by the lookAt distance
   SLfloat lookAtDist;
   if (_lookAtRay.length < FLT_MAX)
        lookAtDist = _lookAtRay.length;
   else lookAtDist = _focalDist;
         
   // scale factor depending on the space sice at focal dist
   SLfloat spaceH = tan(SL_DEG2RAD*_fov/2) * lookAtDist * 2.0f;
   SLfloat spaceW = spaceH * sv->scrWdivH();
   
   //SL_LOG("avgDelta1: (%05.2f,%05.2f), dPhi=%05.2f\n", avgDelta1.x, avgDelta1.y, SL_abs(phi1-phi2));
   
   // if fingers move parallel slide camera vertically or horizontally
   if (SL_abs(phi1-phi2) < 0.2f)
   {  
      // Calculate center between finger points
      SLVec2f nowCenter((now1+now2)*0.5f);
      SLVec2f oldCenter((_oldTouchPos1+_oldTouchPos2)*0.5f);
      
      // For first move set oldCenter = nowCenter
      if (oldCenter == SLVec2f::ZERO) oldCenter = nowCenter;
      
      SLVec2f delta(nowCenter - oldCenter);

      // scale to 0-1
      delta.x /= (SLfloat)sv->scrW();
      delta.y /= (SLfloat)sv->scrH();

      // scale to space size
      delta.x *= spaceW;
      delta.y *= spaceH;
      
      if (_camAnim==turntableYUp || _camAnim==turntableZUp)
      {           
         // apply delta to x- and y-position
         _vm.translation(_vm.m(12) + delta.x,
                         _vm.m(13) - delta.y,
                         _vm.m(14));

         setWMandState();
      } 
      else if (_camAnim == walkingYUp || _camAnim == walkingZUp)
      {
      	_maxSpeed.x = delta.x * 100.0f,
         _maxSpeed.z = delta.y * 100.0f;
      }

   } else // Two finger pinch
   {  
      // Calculate vector between fingers
      SLVec2f nowDist(now2 - now1);
      SLVec2f oldDist(_oldTouchPos2-_oldTouchPos1);
      
      // For first move set oldDist = nowDist
      if (oldDist == SLVec2f::ZERO) oldDist = nowDist;
      
      SLfloat delta = oldDist.length() - nowDist.length();

      if (_camAnim==turntableYUp)
      {  // scale to 0-1
         delta /= (SLfloat)sv->scrH();

         // scale to space height
         delta *= spaceH*2;
         
         // apply delta to the z-position
         _vm.translation(_vm.m(12),
                         _vm.m(13),
                         _vm.m(14) - delta);

         setWMandState();
      } 
      else if (_camAnim == walkingYUp)
      {  
         // change field of view
         _fov += SL_sign(delta) * 0.5f;
         currentFOV = _fov;
      }
   }

   _oldTouchPos1.set((SLfloat)x1, (SLfloat)y1);
   _oldTouchPos2.set((SLfloat)x2, (SLfloat)y2);
   return true;
}
Exemplo n.º 16
0
//-----------------------------------------------------------------------------
//! Gets called whenever the mouse is moved.
SLbool SLCamera::onMouseMove(const SLMouseButton button, 
                             const SLint x, const SLint y, const SLKey mod)
{  
   SLScene* s = SLScene::current;
   SLSceneView* sv = s->activeSV();
   
   if (button == ButtonLeft) //================================================
   {         
      // Get camera vectors: eye pos., lookAt, lookUp, lookRight
      SLVec3f eye, LA, LU, LR;
      _vm.lookAt(&eye, &LA, &LU, &LR);
      
      // The lookAt and lookUp point in VS
      SLVec3f laP = eye + _focalDist * LA;
         
      // Determine rotation point as the center of the AABB of the hitShape
      SLVec3f rtP;
      if (_lookAtRay.length < FLT_MAX && _lookAtRay.hitShape)
           rtP = _lookAtRay.hitShape->aabb()->centerWS();
      else rtP = laP;
      
      // Determine rot angles around x- & y-axis
      SLfloat dY = (_oldTouchPos1.y-y) * _rotFactor;
      SLfloat dX = (_oldTouchPos1.x-x) * _rotFactor;

      if (_camAnim==turntableYUp) //.......................................
      {
         // Apply rotation around the lookAt point
         SLMat4f rot;
         rot.translate(rtP);
         rot.rotate(-dY, LR);
         rot.rotate(-dX, SLVec3f(0,1,0));
         rot.translate(-rtP);
         _vm *= rot;
      }
      else if (_camAnim==turntableZUp) //..................................
      {
         // Apply rotation around the lookAt point
         SLMat4f rot;
         rot.translate(rtP);
         rot.rotate(-dY, LR);
         rot.rotate(-dX, SLVec3f(0,0,1));
         rot.translate(-rtP);
         _vm *= rot;
      }
      else if (_camAnim==walkingYUp) //....................................
      {
         dY *= 0.5f;
         dX *= 0.5f;

         // Apply rotation around the lookRight and the Y-axis
         SLMat4f rot;
         rot.rotate(-dY, LR);
         rot.rotate(-dX, SLVec3f(0,1,0));
         
         // rotate eye position
         LA.set(rot*LA);
         _vm.lookAt(eye, eye+LA*_focalDist, SLVec3f(0,1,0));
      }
      else if (_camAnim==walkingZUp) //....................................
      {
         dY *= 0.5f;
         dX *= 0.5f;

         // Apply rotation around the lookRight and the Z-axis
         SLMat4f rot;
         rot.rotate(-dY, LR);
         rot.rotate(-dX, SLVec3f(0,0,1));

         // rotate eye position
         LA.set(rot*LA);
         _vm.lookAt(eye, eye+LA*_focalDist, SLVec3f(0,0,1));
      }
            
      setWMandState();
      _oldTouchPos1.set((SLfloat)x,(SLfloat)y);
      return true;
   } 
   else
   if (button == ButtonMiddle) //==============================================
   {  if (_camAnim==turntableYUp || _camAnim==turntableZUp)
      {  
         // Calculate the fraction delta of the mouse movement
         SLVec2f dMouse(x-_oldTouchPos1.x, _oldTouchPos1.y-y);
         dMouse.x /= (SLfloat)sv->scrW();
         dMouse.y /= (SLfloat)sv->scrH();
         
         // Scale the mouse delta by the lookAt distance
         SLfloat lookAtDist;
         if (_lookAtRay.length < FLT_MAX)
              lookAtDist = _lookAtRay.length;
         else lookAtDist = _focalDist;

         // scale factor depending on the space sice at focal dist
         SLfloat spaceH = tan(SL_DEG2RAD*_fov/2) * lookAtDist * 2.0f;
         SLfloat spaceW = spaceH * sv->scrWdivH();

         dMouse.x *= spaceW;
         dMouse.y *= spaceH;
         
         if (mod==KeyCtrl)
         {  _vm.translation(_vm.m(12) + dMouse.x,
                            _vm.m(13),
                            _vm.m(14) + dMouse.y);
         } else
         {  _vm.translation(_vm.m(12) + dMouse.x,
                            _vm.m(13) + dMouse.y,
                            _vm.m(14));
         }
         setWMandState();
         _oldTouchPos1.set((SLfloat)x,(SLfloat)y); 
         return true;
      }
   } //========================================================================
   return false;
}