示例#1
0
/*!
SLCurveBezier::findParamByDist gets parameter s distance in arc length from Q(t1).
Returns max SLfloat if can't find it.
*/
SLfloat SLCurveBezier::findParamByDist(SLfloat t1, SLfloat s)
{
    // ensure that we remain within valid parameter space
    if (s > arcLength(t1, _points[_points.size()-1].w))
        return _points[_points.size()-1].w;

    // make first guess
    SLfloat p = t1 + s*(_points[_points.size()-1].w-_points[0].w)/_totalLength;
    for (SLuint i = 0; i < 32; ++i)
    {
        // compute function value and test against zero
        SLfloat func = arcLength(t1, p) - s;
        if (SL_abs(func) < 1.0e-03f) return p;

        // perform Newton-Raphson iteration step
        SLfloat speed = velocity(p).length();
        assert(SL_abs(speed) > FLT_EPSILON);
        p -= func/speed;
    }

    // done iterating, return failure case
    return FLT_MAX;
}
示例#2
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;
}