Page 2 of 2 FirstFirst 12
Results 11 to 16 of 16

Thread: Animations in 1.4.1 release notes revision A

  1. #11
    Senior Member
    Join Date
    Aug 2004
    Location
    California
    Posts
    771
    The COLLADA 1.4.1 REVISION A Release Notes explains the curve interpolation semantics.

    Is there something that needs further clarification?

  2. #12
    Senior Member
    Join Date
    Jan 2006
    Location
    Foster City, CA
    Posts
    540
    I think so, yes. The documentation on Spline Curves is perfectly clear. However the documentation on Animation Curves is a bit vague. I understand the description of what's going on with the input and output values. Then in the description of Bezier animation curves the spec says:
    The same equations for cubic Bézier and Hermite interpolation already defined for <spline> are to be used, with the following geometry vector, for parameter j, segment[i]:
    For Bézier:
    • P0 is (INPUT[i] , OUTPUT[j][i])
    • C0 (or T0) is (OUT_TANGENT[0][i] , OUT_TANGENT[j][i])
    • C1 (or T1) is (IN_TANGENT[0][i+1], IN_TANGENT[j][i+1])
    • P1 is (INPUT[i+1], OUTPUT[j][i+1])
    The <spline> equation for Bezier curves is given as
    B(s) = P0(1− s)^3 + 3C0s(1− s)^2 + 3C1s^2 (1− s) + P1s^3 ,s ∈ [0,1]
    So I have my P0, C0, P1, and C1, but what s value do I use? Typically I'm given an input value and I want to find the corresponding output value. If I just evaluate B(s) using the input value I want then I'll get incorrect results. This is what I tried to show two posts ago. I need to solve B(s) to get the s that corresponds to the input value I'm looking for, then plug that s into B(s) to get the output value. That extra step isn't mentioned in the spec.

  3. #13
    Senior Member
    Join Date
    Jul 2004
    Location
    Santa Clara
    Posts
    356
    This is where you need to use a de Casteljau algorithm or other algorithms that are used for that exact purpose -> finding s and B(s) corresponding to the value you are looking for.

    Regards

  4. #14
    Senior Member
    Join Date
    Jan 2006
    Location
    Foster City, CA
    Posts
    540
    As I understand it, the de Casteljau algorithm is an alternative to Bernstein polynomials for evaluating Bezier curves. How would it help us find the roots of a cubic equation? Why not just use the method described here, say? (see Cardano's method)

    But in any case, can we agree that the spec could be more clear about this? If I follow the spec exactly, I end up with a curve B(s) and no s to evaluate it with. I can compute the s given the input value I want to evaluate, but that step isn't mentioned at all. Shouldn't we add a description of that to the spec for completeness?

  5. #15
    Senior Member
    Join Date
    Jul 2004
    Location
    Santa Clara
    Posts
    356
    Shouldn't we add a description of that to the spec for completeness?
    I think what we need is some sample code implementing the algorithm.

  6. #16
    Junior Member
    Join Date
    Jul 2006
    Location
    Montréal
    Posts
    13
    here's our code to evaluate cubic Bezier curves using de Casteljau Subdivision, hoping this helps:

    Code :
    #define INVERTPARAMCUBIC_TOL 1.0e-09
     
    #define INVERTPARAMCUBIC_SMALLERTOL 1.0e-20
     
    #define INVERTPARAMCUBIC_MAXIT 100
     
     
    ...
      case SI_CUBIC:
      {
       CSLCubicKey *l_pPrevKey = ((CSLCubicKey*)(&GetCubicKeyListPtr()[prev_key])); 
       CSLCubicKey *l_pNextKey = ((CSLCubicKey*)(&GetCubicKeyListPtr()[next_key]));
     
     
       float v1 = l_pPrevKey->m_fRightTanX + l_pPrevKey->m_fTime; // OUT_TANGENT[n].X
       float v2 = l_pNextKey->m_fLeftTanX + l_pNextKey->m_fTime;  // IN_TANGENT[n+1].X
     
       // in_fTime = current_time
       // INPUT[n] = l_pPrevKey->m_fTime
       // INPUT[n+1] = l_pNextKey->m_fTime
       float u = InvertParamCubic ( in_fTime, l_pPrevKey->m_fTime, v1, v2, l_pNextKey->m_fTime );
     
       v1 = l_pPrevKey->m_fRightTanY + l_pPrevKey->m_fValue; // OUT_TANGENT[n].Y
       v2 = l_pNextKey->m_fLeftTanY + l_pNextKey->m_fValue;  // OUT_TANGENT[n+1].Y
     
       //
       // Bernstein Evaluation
       //
     
       // OUPUT[n] = l_pPrevKey->m_fValue
       // OUTPUT[n+1] = l_pNextKey->m_fValue
       float c = 3.0f*(v1 - l_pPrevKey->m_fValue);
       float e = 3.0f*(v2 - v1);
     
       m_fLastEvaluation = (((l_pNextKey->m_fValue - l_pPrevKey->m_fValue - e)*u + e - c)*u + c)*u + l_pPrevKey->m_fValue;
     
     
       if ( m_pParameter != NULL )
        m_pParameter->SetFloatValue( m_fLastEvaluation );
     
       break;
      }
    ...
     
     
    float InvertParamCubic ( float Param, float x0, float x1, float x2, float x3 )
    {
     if (Param - x0 < INVERTPARAMCUBIC_SMALLERTOL)
     {
      return 0.0;
     }
     if (x3 - Param < INVERTPARAMCUBIC_SMALLERTOL)
     {
      return 1.0;
     }
     
     long cnt2 = 0;
     
     // de Casteljau Subdivision.
     float u = 0.0f; float v = 1.0f;
     
     while (cnt2 < INVERTPARAMCUBIC_MAXIT) 
     {
      double a = (x0 + x1)*0.5f; double b = (x1 + x2)*0.5f; double c = (x2 + x3)*0.5f;
      double d = (a + b)*0.5f; double e = (b + c)*0.5f; 
      double f = (d + e)*0.5f;
     
      if (fabs(f - Param) < INVERTPARAMCUBIC_TOL) 
      {
       return ClampToZeroOne((u + v)*0.5f);
      }
     
      if (f < Param)
      { 
       x0 = f; x1 = e; x2 = c; u = (u + v)*0.5f;
      }
      else 
      {
       x1 = a; x2 = d; x3 = f; v = (u + v)*0.5f;
      }
     
      cnt2++;
     }
     
     return ClampToZeroOne((u + v)*0.5f);
    }

Page 2 of 2 FirstFirst 12

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •