Animation and Tangents

I have read a few threads this one and this one

However, when I read articles on de Casteljau like this one They all talk about having the control points. This is even more confusing to me in collada, I have a tangent for x and y.

The other thing thats confusing to me is everyone talks about 2D. For every dimension do I need to do something? I read that time has to be one of the dimensions, but I really dont understand how I’m supposed to plug that in? does my vector then become Vector2(t, x)?

Also, the notation that some people use is very confusing to me in some of the threads. Sorry, i’ve been working on this for about a day and cant seem to come up with anything in google that represents an example of how to convert what collada gives you into the points that you need to do these equations.

Which basically says to me, i’m googling the wrong thing or just dont understand. I guess my main problem is why are the tangents only 2D? And how to I come up with my control points

What I’m thinking is that my code will look something like


//values from Collada file
Vector3 PlotPoint(Vector3 p0, Vector2 xt_out0, Vector2 yt_out0, Vector3 p1, Vector2 xt_in0, Vector2 yt_in0, float t)
{
   Vector3 c0 = //convert tangents to control point
   Vector3 c1 = //convert tangents to control point

   return (1-t)3p0+3t(1-t)2c1+3t2(1-t)c1+t3p1;
}

unless I’m way off, or if anyone can steer me in the right direction I would very much appreciate it.


   <animation>
      <source id="node-Box01_translation.X-input">
        <float_array id="node-Box01_translation.X-input-array" count="3">0 1.5 3.333333</float_array>
        <technique_common>
          <accessor source="#node-Box01_translation.X-input-array" count="3" stride="1">
            <param name="TIME" type="float"/>
          </accessor>
        </technique_common>
      </source>
      <source id="node-Box01_translation.X-output">
        <float_array id="node-Box01_translation.X-output-array" count="3">0 10 0</float_array>
        <technique_common>
          <accessor source="#node-Box01_translation.X-output-array" count="3" stride="1">
            <param name="X" type="float"/>
          </accessor>
        </technique_common>
      </source>
      <source id="node-Box01_translation.X-intangent">
        <float_array id="node-Box01_translation.X-intangent-array" count="6">-0.3329306 0 1.0005 10 2.722833 0</float_array>
        <technique_common>
          <accessor source="#node-Box01_translation.X-intangent-array" count="3" stride="2">
            <param name="X" type="float"/>
            <param name="Y" type="float"/>
          </accessor>
        </technique_common>
      </source>
      <source id="node-Box01_translation.X-outtangent">
        <float_array id="node-Box01_translation.X-outtangent-array" count="6">0.4995 0 2.1105 10 3.666264 0</float_array>
        <technique_common>
          <accessor source="#node-Box01_translation.X-outtangent-array" count="3" stride="2">
            <param name="X" type="float"/>
            <param name="Y" type="float"/>
          </accessor>
        </technique_common>
      </source>
      <source id="node-Box01_translation.X-interpolation">
        <Name_array id="node-Box01_translation.X-interpolation-array" count="3">BEZIER BEZIER BEZIER</Name_array>
        <technique_common>
          <accessor source="#node-Box01_translation.X-interpolation-array" count="3" stride="1">
            <param name="INTERPOLATION" type="name"/>
          </accessor>
        </technique_common>
      </source>
      <source id="node-Box01_translation.Y-input">
        <float_array id="node-Box01_translation.Y-input-array" count="3">0 1.5 3.333333</float_array>
        <technique_common>
          <accessor source="#node-Box01_translation.Y-input-array" count="3" stride="1">
            <param name="TIME" type="float"/>
          </accessor>
        </technique_common>
      </source>
      <source id="node-Box01_translation.Y-output">
        <float_array id="node-Box01_translation.Y-output-array" count="3">0 4.865171 10.09859</float_array>
        <technique_common>
          <accessor source="#node-Box01_translation.Y-output-array" count="3" stride="1">
            <param name="Y" type="float"/>
          </accessor>
        </technique_common>
      </source>
      <source id="node-Box01_translation.Y-intangent">
        <float_array id="node-Box01_translation.Y-intangent-array" count="6">-0.3329306 0 1.0005 3.351898 2.722833 10.09859</float_array>
        <technique_common>
          <accessor source="#node-Box01_translation.Y-intangent-array" count="3" stride="2">
            <param name="X" type="float"/>
            <param name="Y" type="float"/>
          </accessor>
        </technique_common>
      </source>
      <source id="node-Box01_translation.Y-outtangent">
        <float_array id="node-Box01_translation.Y-outtangent-array" count="6">0.4995 0 2.1105 6.714727 3.666264 10.09859</float_array>
        <technique_common>
          <accessor source="#node-Box01_translation.Y-outtangent-array" count="3" stride="2">
            <param name="X" type="float"/>
            <param name="Y" type="float"/>
          </accessor>
        </technique_common>
      </source>
      <source id="node-Box01_translation.Y-interpolation">
        <Name_array id="node-Box01_translation.Y-interpolation-array" count="3">BEZIER BEZIER BEZIER</Name_array>
        <technique_common>
          <accessor source="#node-Box01_translation.Y-interpolation-array" count="3" stride="1">
            <param name="INTERPOLATION" type="name"/>
          </accessor>
        </technique_common>
      </source>
      <source id="node-Box01_translation.Z-input">
        <float_array id="node-Box01_translation.Z-input-array" count="3">0 1.5 3.333333</float_array>
        <technique_common>
          <accessor source="#node-Box01_translation.Z-input-array" count="3" stride="1">
            <param name="TIME" type="float"/>
          </accessor>
        </technique_common>
      </source>
      <source id="node-Box01_translation.Z-output">
        <float_array id="node-Box01_translation.Z-output-array" count="3">0 2.458767 0</float_array>
        <technique_common>
          <accessor source="#node-Box01_translation.Z-output-array" count="3" stride="1">
            <param name="Z" type="float"/>
          </accessor>
        </technique_common>
      </source>
      <source id="node-Box01_translation.Z-intangent">
        <float_array id="node-Box01_translation.Z-intangent-array" count="6">-0.3329306 0 1.0005 2.458767 2.722833 0</float_array>
        <technique_common>
          <accessor source="#node-Box01_translation.Z-intangent-array" count="3" stride="2">
            <param name="X" type="float"/>
            <param name="Y" type="float"/>
          </accessor>
        </technique_common>
      </source>
      <source id="node-Box01_translation.Z-outtangent">
        <float_array id="node-Box01_translation.Z-outtangent-array" count="6">0.4995 0 2.1105 2.458767 3.666264 0</float_array>
        <technique_common>
          <accessor source="#node-Box01_translation.Z-outtangent-array" count="3" stride="2">
            <param name="X" type="float"/>
            <param name="Y" type="float"/>
          </accessor>
        </technique_common>
      </source>
      <source id="node-Box01_translation.Z-interpolation">
        <Name_array id="node-Box01_translation.Z-interpolation-array" count="3">BEZIER BEZIER BEZIER</Name_array>
        <technique_common>
          <accessor source="#node-Box01_translation.Z-interpolation-array" count="3" stride="1">
            <param name="INTERPOLATION" type="name"/>
          </accessor>
        </technique_common>
      </source>
      <source id="node-Box01_rotationZ.ANGLE-input">
        <float_array id="node-Box01_rotationZ.ANGLE-input-array" count="3">0 1.5 3.333333</float_array>
        <technique_common>
          <accessor source="#node-Box01_rotationZ.ANGLE-input-array" count="3" stride="1">
            <param name="TIME" type="float"/>
          </accessor>
        </technique_common>
      </source>
      <source id="node-Box01_rotationZ.ANGLE-output">
        <float_array id="node-Box01_rotationZ.ANGLE-output-array" count="3">0 0 0</float_array>
        <technique_common>
          <accessor source="#node-Box01_rotationZ.ANGLE-output-array" count="3" stride="1">
            <param name="ANGLE" type="float"/>
          </accessor>
        </technique_common>
      </source>
      <source id="node-Box01_rotationZ.ANGLE-intangent">
        <float_array id="node-Box01_rotationZ.ANGLE-intangent-array" count="6">-0.3329306 0 1.0005 0 2.722833 0</float_array>
        <technique_common>
          <accessor source="#node-Box01_rotationZ.ANGLE-intangent-array" count="3" stride="2">
            <param name="X" type="float"/>
            <param name="Y" type="float"/>
          </accessor>
        </technique_common>
      </source>
      <source id="node-Box01_rotationZ.ANGLE-outtangent">
        <float_array id="node-Box01_rotationZ.ANGLE-outtangent-array" count="6">0.4995 0 2.1105 0 3.666264 0</float_array>
        <technique_common>
          <accessor source="#node-Box01_rotationZ.ANGLE-outtangent-array" count="3" stride="2">
            <param name="X" type="float"/>
            <param name="Y" type="float"/>
          </accessor>
        </technique_common>
      </source>
      <source id="node-Box01_rotationZ.ANGLE-interpolation">
        <Name_array id="node-Box01_rotationZ.ANGLE-interpolation-array" count="3">BEZIER BEZIER BEZIER</Name_array>
        <technique_common>
          <accessor source="#node-Box01_rotationZ.ANGLE-interpolation-array" count="3" stride="1">
            <param name="INTERPOLATION" type="name"/>
          </accessor>
        </technique_common>
      </source>
      <source id="node-Box01_rotationY.ANGLE-input">
        <float_array id="node-Box01_rotationY.ANGLE-input-array" count="3">0 1.5 3.333333</float_array>
        <technique_common>
          <accessor source="#node-Box01_rotationY.ANGLE-input-array" count="3" stride="1">
            <param name="TIME" type="float"/>
          </accessor>
        </technique_common>
      </source>
      <source id="node-Box01_rotationY.ANGLE-output">
        <float_array id="node-Box01_rotationY.ANGLE-output-array" count="3">0 0 0</float_array>
        <technique_common>
          <accessor source="#node-Box01_rotationY.ANGLE-output-array" count="3" stride="1">
            <param name="ANGLE" type="float"/>
          </accessor>
        </technique_common>
      </source>
      <source id="node-Box01_rotationY.ANGLE-intangent">
        <float_array id="node-Box01_rotationY.ANGLE-intangent-array" count="6">-0.3329306 0 1.0005 0 2.722833 0</float_array>
        <technique_common>
          <accessor source="#node-Box01_rotationY.ANGLE-intangent-array" count="3" stride="2">
            <param name="X" type="float"/>
            <param name="Y" type="float"/>
          </accessor>
        </technique_common>
      </source>
      <source id="node-Box01_rotationY.ANGLE-outtangent">
        <float_array id="node-Box01_rotationY.ANGLE-outtangent-array" count="6">0.4995 0 2.1105 0 3.666264 0</float_array>
        <technique_common>
          <accessor source="#node-Box01_rotationY.ANGLE-outtangent-array" count="3" stride="2">
            <param name="X" type="float"/>
            <param name="Y" type="float"/>
          </accessor>
        </technique_common>
      </source>
      <source id="node-Box01_rotationY.ANGLE-interpolation">
        <Name_array id="node-Box01_rotationY.ANGLE-interpolation-array" count="3">BEZIER BEZIER BEZIER</Name_array>
        <technique_common>
          <accessor source="#node-Box01_rotationY.ANGLE-interpolation-array" count="3" stride="1">
            <param name="INTERPOLATION" type="name"/>
          </accessor>
        </technique_common>
      </source>
      <source id="node-Box01_rotationX.ANGLE-input">
        <float_array id="node-Box01_rotationX.ANGLE-input-array" count="3">0 1.5 3.333333</float_array>
        <technique_common>
          <accessor source="#node-Box01_rotationX.ANGLE-input-array" count="3" stride="1">
            <param name="TIME" type="float"/>
          </accessor>
        </technique_common>
      </source>
      <source id="node-Box01_rotationX.ANGLE-output">
        <float_array id="node-Box01_rotationX.ANGLE-output-array" count="3">0 0 0</float_array>
        <technique_common>
          <accessor source="#node-Box01_rotationX.ANGLE-output-array" count="3" stride="1">
            <param name="ANGLE" type="float"/>
          </accessor>
        </technique_common>
      </source>
      <source id="node-Box01_rotationX.ANGLE-intangent">
        <float_array id="node-Box01_rotationX.ANGLE-intangent-array" count="6">-0.3329306 0 1.0005 0 2.722833 0</float_array>
        <technique_common>
          <accessor source="#node-Box01_rotationX.ANGLE-intangent-array" count="3" stride="2">
            <param name="X" type="float"/>
            <param name="Y" type="float"/>
          </accessor>
        </technique_common>
      </source>
      <source id="node-Box01_rotationX.ANGLE-outtangent">
        <float_array id="node-Box01_rotationX.ANGLE-outtangent-array" count="6">0.4995 0 2.1105 0 3.666264 0</float_array>
        <technique_common>
          <accessor source="#node-Box01_rotationX.ANGLE-outtangent-array" count="3" stride="2">
            <param name="X" type="float"/>
            <param name="Y" type="float"/>
          </accessor>
        </technique_common>
      </source>
      <source id="node-Box01_rotationX.ANGLE-interpolation">
        <Name_array id="node-Box01_rotationX.ANGLE-interpolation-array" count="3">BEZIER BEZIER BEZIER</Name_array>
        <technique_common>
          <accessor source="#node-Box01_rotationX.ANGLE-interpolation-array" count="3" stride="1">
            <param name="INTERPOLATION" type="name"/>
          </accessor>
        </technique_common>
      </source>
      <source id="node-Box01_scale-input">
        <float_array id="node-Box01_scale-input-array" count="3">0 1.5 3.333333</float_array>
        <technique_common>
          <accessor source="#node-Box01_scale-input-array" count="3" stride="1">
            <param name="TIME" type="float"/>
          </accessor>
        </technique_common>
      </source>
      <source id="node-Box01_scale-output">
        <float_array id="node-Box01_scale-output-array" count="9">1 1 1 1 1 1 1 1 1</float_array>
        <technique_common>
          <accessor source="#node-Box01_scale-output-array" count="3" stride="3">
            <param name="X" type="float"/>
            <param name="Y" type="float"/>
            <param name="Z" type="float"/>
          </accessor>
        </technique_common>
      </source>
      <source id="node-Box01_scale-intangent">
        <float_array id="node-Box01_scale-intangent-array" count="18">-0.3329306 1 -0.3329306 1 -0.3329306 1 1.0005 1 1.0005 1 1.0005 1 2.722833 1 2.722833 1 2.722833 1</float_array>
        <technique_common>
          <accessor source="#node-Box01_scale-intangent-array" count="3" stride="6">
            <param name="X" type="float"/>
            <param name="Y" type="float"/>
            <param name="X" type="float"/>
            <param name="Y" type="float"/>
            <param name="X" type="float"/>
            <param name="Y" type="float"/>
          </accessor>
        </technique_common>
      </source>
      <source id="node-Box01_scale-outtangent">
        <float_array id="node-Box01_scale-outtangent-array" count="18">0.4995 1 0.4995 1 0.4995 1 2.1105 1 2.1105 1 2.1105 1 3.666264 1 3.666264 1 3.666264 1</float_array>
        <technique_common>
          <accessor source="#node-Box01_scale-outtangent-array" count="3" stride="6">
            <param name="X" type="float"/>
            <param name="Y" type="float"/>
            <param name="X" type="float"/>
            <param name="Y" type="float"/>
            <param name="X" type="float"/>
            <param name="Y" type="float"/>
          </accessor>
        </technique_common>
      </source>
      <source id="node-Box01_scale-interpolation">
        <Name_array id="node-Box01_scale-interpolation-array" count="3">BEZIER BEZIER BEZIER</Name_array>
        <technique_common>
          <accessor source="#node-Box01_scale-interpolation-array" count="3" stride="1">
            <param name="INTERPOLATION" type="name"/>
          </accessor>
        </technique_common>
      </source>
      <source id="node-Box01_InverseScaleAxisRotation-input">
        <float_array id="node-Box01_InverseScaleAxisRotation-input-array" count="3">0 1.5 3.333333</float_array>
        <technique_common>
          <accessor source="#node-Box01_InverseScaleAxisRotation-input-array" count="3" stride="1">
            <param name="TIME" type="float"/>
          </accessor>
        </technique_common>
      </source>
      <source id="node-Box01_InverseScaleAxisRotation-output">
        <float_array id="node-Box01_InverseScaleAxisRotation-output-array" count="12">0 0 0 0 0 0 0 0 0 0 0 0</float_array>
        <technique_common>
          <accessor source="#node-Box01_InverseScaleAxisRotation-output-array" count="3" stride="4">
            <param name="X" type="float"/>
            <param name="Y" type="float"/>
            <param name="Z" type="float"/>
            <param name="ANGLE" type="float"/>
          </accessor>
        </technique_common>
      </source>
      <source id="node-Box01_InverseScaleAxisRotation-interpolation">
        <Name_array id="node-Box01_InverseScaleAxisRotation-interpolation-array" count="3">LINEAR LINEAR LINEAR</Name_array>
        <technique_common>
          <accessor source="#node-Box01_InverseScaleAxisRotation-interpolation-array" count="3" stride="1">
            <param name="INTERPOLATION" type="name"/>
          </accessor>
        </technique_common>
      </source>
      <source id="node-Box01_ScaleAxisRotation-input">
        <float_array id="node-Box01_ScaleAxisRotation-input-array" count="3">0 1.5 3.333333</float_array>
        <technique_common>
          <accessor source="#node-Box01_ScaleAxisRotation-input-array" count="3" stride="1">
            <param name="TIME" type="float"/>
          </accessor>
        </technique_common>
      </source>
      <source id="node-Box01_ScaleAxisRotation-output">
        <float_array id="node-Box01_ScaleAxisRotation-output-array" count="12">0 0 0 0 0 0 0 0 0 0 0 0</float_array>
        <technique_common>
          <accessor source="#node-Box01_ScaleAxisRotation-output-array" count="3" stride="4">
            <param name="X" type="float"/>
            <param name="Y" type="float"/>
            <param name="Z" type="float"/>
            <param name="ANGLE" type="float"/>
          </accessor>
        </technique_common>
      </source>
      <source id="node-Box01_ScaleAxisRotation-interpolation">
        <Name_array id="node-Box01_ScaleAxisRotation-interpolation-array" count="3">LINEAR LINEAR LINEAR</Name_array>
        <technique_common>
          <accessor source="#node-Box01_ScaleAxisRotation-interpolation-array" count="3" stride="1">
            <param name="INTERPOLATION" type="name"/>
          </accessor>
        </technique_common>
      </source>
      <sampler id="node-Box01_translation.X-sampler">
        <input semantic="INPUT" source="#node-Box01_translation.X-input"/>
        <input semantic="OUTPUT" source="#node-Box01_translation.X-output"/>
        <input semantic="IN_TANGENT" source="#node-Box01_translation.X-intangent"/>
        <input semantic="OUT_TANGENT" source="#node-Box01_translation.X-outtangent"/>
        <input semantic="INTERPOLATION" source="#node-Box01_translation.X-interpolation"/>
      </sampler>
      <sampler id="node-Box01_translation.Y-sampler">
        <input semantic="INPUT" source="#node-Box01_translation.Y-input"/>
        <input semantic="OUTPUT" source="#node-Box01_translation.Y-output"/>
        <input semantic="IN_TANGENT" source="#node-Box01_translation.Y-intangent"/>
        <input semantic="OUT_TANGENT" source="#node-Box01_translation.Y-outtangent"/>
        <input semantic="INTERPOLATION" source="#node-Box01_translation.Y-interpolation"/>
      </sampler>
      <sampler id="node-Box01_translation.Z-sampler">
        <input semantic="INPUT" source="#node-Box01_translation.Z-input"/>
        <input semantic="OUTPUT" source="#node-Box01_translation.Z-output"/>
        <input semantic="IN_TANGENT" source="#node-Box01_translation.Z-intangent"/>
        <input semantic="OUT_TANGENT" source="#node-Box01_translation.Z-outtangent"/>
        <input semantic="INTERPOLATION" source="#node-Box01_translation.Z-interpolation"/>
      </sampler>
      <sampler id="node-Box01_rotationZ.ANGLE-sampler">
        <input semantic="INPUT" source="#node-Box01_rotationZ.ANGLE-input"/>
        <input semantic="OUTPUT" source="#node-Box01_rotationZ.ANGLE-output"/>
        <input semantic="IN_TANGENT" source="#node-Box01_rotationZ.ANGLE-intangent"/>
        <input semantic="OUT_TANGENT" source="#node-Box01_rotationZ.ANGLE-outtangent"/>
        <input semantic="INTERPOLATION" source="#node-Box01_rotationZ.ANGLE-interpolation"/>
      </sampler>
      <sampler id="node-Box01_rotationY.ANGLE-sampler">
        <input semantic="INPUT" source="#node-Box01_rotationY.ANGLE-input"/>
        <input semantic="OUTPUT" source="#node-Box01_rotationY.ANGLE-output"/>
        <input semantic="IN_TANGENT" source="#node-Box01_rotationY.ANGLE-intangent"/>
        <input semantic="OUT_TANGENT" source="#node-Box01_rotationY.ANGLE-outtangent"/>
        <input semantic="INTERPOLATION" source="#node-Box01_rotationY.ANGLE-interpolation"/>
      </sampler>
      <sampler id="node-Box01_rotationX.ANGLE-sampler">
        <input semantic="INPUT" source="#node-Box01_rotationX.ANGLE-input"/>
        <input semantic="OUTPUT" source="#node-Box01_rotationX.ANGLE-output"/>
        <input semantic="IN_TANGENT" source="#node-Box01_rotationX.ANGLE-intangent"/>
        <input semantic="OUT_TANGENT" source="#node-Box01_rotationX.ANGLE-outtangent"/>
        <input semantic="INTERPOLATION" source="#node-Box01_rotationX.ANGLE-interpolation"/>
      </sampler>
      <sampler id="node-Box01_scale-sampler">
        <input semantic="INPUT" source="#node-Box01_scale-input"/>
        <input semantic="OUTPUT" source="#node-Box01_scale-output"/>
        <input semantic="IN_TANGENT" source="#node-Box01_scale-intangent"/>
        <input semantic="OUT_TANGENT" source="#node-Box01_scale-outtangent"/>
        <input semantic="INTERPOLATION" source="#node-Box01_scale-interpolation"/>
      </sampler>
      <sampler id="node-Box01_InverseScaleAxisRotation-sampler">
        <input semantic="INPUT" source="#node-Box01_InverseScaleAxisRotation-input"/>
        <input semantic="OUTPUT" source="#node-Box01_InverseScaleAxisRotation-output"/>
        <input semantic="INTERPOLATION" source="#node-Box01_InverseScaleAxisRotation-interpolation"/>
      </sampler>
      <sampler id="node-Box01_ScaleAxisRotation-sampler">
        <input semantic="INPUT" source="#node-Box01_ScaleAxisRotation-input"/>
        <input semantic="OUTPUT" source="#node-Box01_ScaleAxisRotation-output"/>
        <input semantic="INTERPOLATION" source="#node-Box01_ScaleAxisRotation-interpolation"/>
      </sampler>
      <channel source="#node-Box01_translation.X-sampler" target="node-Box01/translation.X"/>
      <channel source="#node-Box01_translation.Y-sampler" target="node-Box01/translation.Y"/>
      <channel source="#node-Box01_translation.Z-sampler" target="node-Box01/translation.Z"/>
      <channel source="#node-Box01_rotationZ.ANGLE-sampler" target="node-Box01/rotationZ.ANGLE"/>
      <channel source="#node-Box01_rotationY.ANGLE-sampler" target="node-Box01/rotationY.ANGLE"/>
      <channel source="#node-Box01_rotationX.ANGLE-sampler" target="node-Box01/rotationX.ANGLE"/>
      <channel source="#node-Box01_scale-sampler" target="node-Box01/scale"/>
      <channel source="#node-Box01_InverseScaleAxisRotation-sampler" target="node-Box01/InverseScaleAxisRotation"/>
      <channel source="#node-Box01_ScaleAxisRotation-sampler" target="node-Box01/ScaleAxisRotation"/>
    </animation>

Did you read Chapter 4: Programming Guide - Curve Interpolation from the COLLADA 1.5 specification?