Creative Communities of the World Forums

The peer to peer support community for media production professionals.

Activity Forums Adobe After Effects Expressions Rewriting ValueAtTime with After effects Syntax

  • Rewriting ValueAtTime with After effects Syntax

    Posted by Mohannad Talafeeh on January 26, 2014 at 6:13 am

    Ok, so my question is how we would write the (valueAtTime) form scratch using the After Effects syntax (Java script)as if it never exists , Dan Ebberts on my other post clarified that every programing environment has its own conditions so it’s hard to write the code , but what I want for now is the code in After effects (if it can be done ) just to know the procedures needed to accomplish that functionality , after I grasp the key procedures of that code , I will do my best to rewrite it withing my goal language roles , so is it possible to write it and how can it be done , hope that Dan can help on this one .
    Best

    Mohannad Talafeeh replied 12 years, 7 months ago 2 Members · 8 Replies
  • 8 Replies
  • Xavier Gomez

    January 26, 2014 at 1:15 pm

    The post-expression value seems completely out of reach.
    For pre-expression (keys) it is cubic Bezier (for both value and time). For 1D properties, it is not that difficult, but for 2D+ ones it not straightforward at all, since at a point or another you will have to compute the arclength parametrization of the path, and find out how the initial and final speed variables are interpreted to move on the entire path along time. If javascript is your language, it will be slow++.
    Not mentionning that it also seems impossible to know for Custom type properties, post and pre expression.

    Seems crazy project. Good luck;)

    Xavier.

  • Mohannad Talafeeh

    January 26, 2014 at 5:45 pm

    Thanks Xavier
    My property are all 1D properties, as for the process it self , what took my interest is that (valueAtTime) is extremely fast almost real-time , it seems its not doing any expensive calculations at all, I’ve tried writing my own edition using nested for-loops but even for few frames it was very slow not mentioning it’s inaccuracy ,I believe that its a fairly simple processes which consist of 2D vector where the first slot contains the value and the next one contains time, so whenever we ask about a value given the time , it should retrieve that value , but as for the 1D property expression how you would go about doing that.

    Best

  • Xavier Gomez

    January 26, 2014 at 7:39 pm

    Yes for 1D properties it is 2D vector as you say, but its components time and values are both cubic functions of an invisible parameter, say u (the Bezier parameter), ie between keys n and n+1, time = cubic function of u, and value = another cubic function of u. The coefficients for time depends on the keys time and in/out temporalEase.influence, while for value they depend on the keys values and temporalEase.speed.

    To retrieve the property value at a given time t0, you need first to find the key interval (n, n+1), retrieve the keyTime(n/n+1), keyValue(n/n+1), keyOutTemporalEase(n), keyInTemporalEase(n+1), solve the cubic equation time(u) = t0, which gives you a value u0, then plug this u0 into the equation for the value.

    Man, if you intend to loop this over hundreds of keyframes with javascript, better get a cup of coffee every time you press the script button. With the built-in function it takes less than a millisecond.

    Xavier.

  • Mohannad Talafeeh

    January 26, 2014 at 8:01 pm

    Thanks Xavier
    I understand that this would take a huge amount of execution time , but what makes me sure that it is the wrong approach is because valueAtTime would do this in no time , meaning it is doing the job with much simpler and minimal procedures , and these producers is what I want .

    Best

  • Xavier Gomez

    January 26, 2014 at 8:32 pm

    AE is c++ based, has instant access to its own variables, can (and does) cache tons of things (as you can see when you open the graph editor: it’s all there), probably has some smart way to find cubic roots by refining some lookup tables, i have no idea of how it works internally, but what is sure, sorry, is that the principle for valueAtTime is written 2 posts above.

    Xavier.

  • Mohannad Talafeeh

    January 28, 2014 at 7:56 am

    Thank you very much Xavier
    Seems that I should find some other approaches instead of using that function, I’ll think of it , but thank you for all the information you supplied it’s really interesting specially the arc length calculations approach .

  • Xavier Gomez

    January 28, 2014 at 11:23 am

    Hi again,
    unless you want to do also 2D/3D props, you don’t need to calculate arclengths. Here are more details for 1D, without the part that solves the cubic equation (search google for that, propably on Wikipedia their is a detailed solution). I’m really wondering why you don’t want to use the built-in valueAtTime()…

    Xavier.

    function valueAtTime(prop, t0)
    {
    if ( !(prop instanceof Property) || prop.propertyValueType !== PropertyValueType.OneD || prop.expressionEnabled) return “hi”;

    var N=prop.numKeys, n, t, t1, t2, DT, easeIn, easeOut, p0,p1,p2,p3, a0,a1,a2,a3, roots, k, u0;

    if (N===0) return prop.value;

    n = prop.nearestKeyIndex(t0); if (prop.keyTime(n)>t0) n–;

    if (n===0) return prop.keyValue(1);
    if (n===N) return prop.keyValue(N);
    if (t0-prop.keyTime(n)<0.0005 || prop.keyOutInterpolationType(n) === KeyframeInterpolationType.HOLD) return prop.keyValue(n);

    t1 = prop.keyTime(n);
    t2 = prop.keyTime(n+1);
    DT = t2-t1;
    t = (t0-t1)/DT;

    easeOut = prop.keyOutTemporalEase(n)[0];
    easeIn = prop.keyInTemporalEase(n+1)[0];

    // time :

    // time control points (bezier):
    p0 = 0;
    p1 = easeOut.influence/100;
    p2 = 1-easeIn.influence/100;
    p3=1;

    // same, standard basis:
    a0 = p0; a1 = 3*(p1-p0); a3 = 3*(p2-p1); a2 = a3-a1; a3 = (p3-p0)-a3;

    // solve a0 + a1*u + a2*u*u + a3*u*u*u = t and call u0 the unique solution in [0,1]
    roots = solve(a0 + a1*u + a2*u*u + a3*u*u*u = t); // not provided
    for (k=0; k less than roots.length; k++) {u0=roots[k]; if (0<=u0 && u0<=1) break;};

    // value :

    // value control points (bezier):
    p0 = prop.keyValue(n);
    p3 = prop.keyValue(n+1);
    p1 = p0 + easeOut.speed * DT * easeOut.influence/100;
    p2 = p3 – easeIn.speed * DT * easeIn.influence/100;
    // same, standard basis:
    a0 = p0; a1 = 3*(p1-p0); a3 = 3*(p2-p1); a2 = a3-a1; a3 = (p3-p0)-a3;

    return a0+u0*(a1+u0*(a2+u0*a3));
    };

  • Mohannad Talafeeh

    January 28, 2014 at 1:31 pm

    Dear Xavier
    Thank you for this comprehensive reply,I haven’t tried the code yet but let me answer you for the first part of your reply .
    Essentially I’m creating a script that perform a cretin function , but this script will not be for After Effects , it was meant to be used in an another motion software .why do I’m writing it inside of After Effects ?
    well,because AE was a much convenient coding environment because of its ability to work with (properties and values and time….)among many other things that I found very helpful , so the hole thing inside of AE was a bunch of expressions distributed on several layers which eventual performed the job that I needed . The whole reason of using AE for that process was only for solving the problems and make it easier for me to handle them .The next step was to rewrite the code on my desired software withe its syntax (not Java scripts) , the problem was that there is no equivalent for the following functions (linear,ease,valueAtTime)but I’v manged to to write my own ones after I studied there principle , the valueAtTime was the problem,I cant figure out how to write it (and for 1D parameters only), if I could write it , then my script will be done and works perfectly,this is only aspect that is missing , if that functions was built-in then I would not have this issue at all.
    Best

We use anonymous cookies to give you the best experience we can.
Our Privacy policy | GDPR Policy