Creative Communities of the World Forums

The peer to peer support community for media production professionals.

Activity Forums Adobe After Effects Expressions Dynamically Creating Vertex Array

  • Dynamically Creating Vertex Array

    Posted by Michael Hussar on November 24, 2012 at 11:10 pm

    I am a bit of a newb in this area but I’m trying to
    bring myself up to speed.
    Any help is appreciated!

    I have 3 nulls in a comp. (this example below only uses on for simplicity)
    Each null has 3 key frames for position.

    I’m writing code to loop through each keyframe and extract the [x,y]
    position data for each of the nulls on the given keyframe.
    I concatenate the data as a string which I later split out into an
    array that will be used to define the maskshape vertices of
    a mask on a solid layer at the same keyframe as the concatenated
    extracted [x,y] data from the nulls.

    I hope that makes sense to you.

    The problem is that after using the string split command
    I don’t end up with an array as the the javascript documentation
    claims and AFX scripting throws an error saying I don’t have an
    array. Please see code below.


    var vComp = projectItem("compMouth");
    var vNullPos = vComp.layer(1).property("ADBE Transform Group").property("ADBE Position");

    var IT_Tracker_01 = [[169.609649658203,-2.60592651367188]]; //in tangents
    var OT_Tracker_01= [[-160.638397216797,2.46807861328125]]; //out tangents

    var myMask = vComp.layer("mouth").mask(1);
    myProperty = myMask.property("ADBE Mask Shape");
    myPath = myProperty.value;

    var strPosKeyVal = "";

    UpdatePositionXY () ;

    function UpdatePositionXY () {
    // iterate through all KEY FRAMES FOR EACH TRACKER -- ASSUMPTION IS THAT ALL TRACKERS WILL HAVE THE SAME NUMBER OF KEYFRAMES AS THE FIRST TRACKER WHICH IS BEING USED TO GET numKeys
    for (var j = 1; j <= vNullPos.numKeys; j++){

    //iterate through all trackers null for the key frame
    //concatenate all tracker null [x,y] into an array of vertices
    for (var tracker = 1; tracker <= 1; tracker++){
    strPosKeyVal = strPosKeyVal + vComp.layer(tracker).property("ADBE Transform Group").property("ADBE Position").keyValue(j).toString() + "|" ;
    }

    }
    //AT THIS POINT WE WOULD HAVE CONCATENATED ALL THE TRACKERS X,Y INTO A STRING FOR THE J'TH KEYFRAME

    myPath.closed = true;
    myMask.rotoBezier = false;

    strPosKeyVal = strPosKeyVal.substring(0, strPosKeyVal.length-1)

    VertArray = strPosKeyVal.split('|');

    // Build vert Array
    for(var i=0; i<VertArray.length; i++) { // GOES THROUGH EACH OF THE KEYFRAMES AND SETS THE VERTICES TO THE TRACKERS X,Y FOR THAT KEYFRAME
    myPath.inTangents = IT_Tracker_01;
    myPath.outTangents = OT_Tracker_01;
    myPath.vertices = VertArray[i]; // @@@@@@@@@@@@@@@@@@ HERE IS THE PROBLEM -- AFX SAYS THAT THIS IS NOT AN ARRAY
    myProperty.setValueAtTime(i+1,myPath);
    }

    }

    Stuart Simpson replied 12 years, 4 months ago 3 Members · 16 Replies
  • 16 Replies
  • Dan Ebberts

    November 24, 2012 at 11:54 pm

    I’d add a few alert() or $.writeln() statements to find out if strPosKeyVal contains what you’re expecting, the length of VertArray after you do the split, etc. That should help you see what’s going on.

    Dan

  • Michael Hussar

    November 25, 2012 at 12:08 am

    Thanks for the reply Dan.

    I actually did just that and found that
    the value of the string variable gave me exactly
    What I expected but the value of the first item in
    The array was missing the square brackets
    In both the alert and the writeln.
    I thought that once I used the split that it would
    Creat array items with the square brackets.
    This is why I’m confused

  • Dan Ebberts

    November 25, 2012 at 12:38 am

    split() won’t add any brackets. It just creates an array of substrings. So, for example, if you did this:

    var txt = “abc|123”;
    var splitTxt = txt.split(“|”);

    splitTxt would be a 2-element array with “abc” in the first element and “123” in the second.

    Dan

  • Michael Hussar

    November 25, 2012 at 4:16 am

    Is there a way to convert the string array into
    A bracketed tuple array ? Or maybe I’m going about this the wrong way and should be concatenating the position key values in a different way to build my array
    That will be compatible with the mask shape vertex array?

  • Dan Ebberts

    November 25, 2012 at 4:45 am

    You could do something like this:

    var txt = “100.0|200.0”;
    var splitTxt = txt.split(“|”);
    var myArray = [parseFloat(splitTxt[0]),parseFloat(splitTxt[1])];

    Dan

  • Michael Hussar

    November 28, 2012 at 1:54 pm

    Thanks for your help Dan! I was able to work out the problem. Just in case anyone else needs to map tracker nulls to vertex points on a mask, I’ve included the code below.

    Best,

    Michael

    //used to find the comp shown in quotes in the given project and assign to variable.
    var vComp = projectItem("compMouth");
    var vNullPos = vComp.layer(1).property("ADBE Transform Group").property("ADBE Position");

    var V_Trackers =[];
    var IT_Trackers = [[0,0],[0,0],[0,0],[0,0],[0,0]];
    var OT_Trackers = [[0,0],[0,0],[0,0],[0,0],[0,0]];
    var newArray = [];
    var vertsArray = [];
    var strArray = "";

    var myMask = vComp.layer("mouth").mask(1);
    myProperty = myMask.property("ADBE Mask Shape");
    myPath = myProperty.value;

    UpdatePositionXY () ;

    function UpdatePositionXY () {
    // iterate through all KEY FRAMES FOR EACH TRACKER -- ASSUMPTION IS THAT ALL TRACKERS WILL HAVE THE SAME NUMBER OF KEYFRAMES AS THE FIRST TRACKER WHICH IS BEING USED TO GET numKeys
    for (var j = 1; j &lt;= vNullPos.numKeys; j++){

    //Iterate through all tracker null layers for the given key frame and concatenate their position [x,y] data into an array of vertices
    for (var tracker = 1; tracker &lt;= vComp.numLayers-1; tracker++){

    V_Trackers.push(vComp.layer(tracker).property("ADBE Transform Group").property("ADBE Position").keyValue(j)) ;
    $.writeln("------------------------------");
    $.writeln("Mask shape vertex x-y coordinants based onTracker Null " + tracker + " for keyframe " + j + ":" );
    $.writeln(V_Trackers[tracker-1]);

    strArray = V_Trackers[tracker-1].toString();
    strArray = strArray.split(",");

    for (var s = 0; s &lt; strArray.length; s++){
    // $.writeln("This is the " + s + " element of the string array: " + parseFloat(strArray[s]));
    newArray.push(parseFloat(strArray[s]));
    }

    newArray.pop();
    $.writeln(newArray);
    vertsArray.push (newArray)
    newArray = [];

    }
    //CONCATENATED ALL THE TRACKERS X,Y FOR THE J'TH KEYFRAME
    $.writeln("------------------------------");
    $.writeln("These are ALL the mask shape vertex x-y coordinants based on all the tracker nulls for keyframe " + j );
    $.writeln(vertsArray);

    myPath.inTangents = IT_Trackers;
    myPath.outTangents = OT_Trackers;
    myPath.closed = true;
    myMask.rotoBezier = false;
    myPath.vertices = vertsArray;
    myProperty.setValueAtTime(vNullPos.keyTime(j),myPath);

    // Reset for next set of trackers in next key frame
    V_Trackers = [];
    vertsArray = [];
    }

    }

  • Stuart Simpson

    January 2, 2014 at 9:34 pm

    Hi guys,

    This sounds like exactly what I need but I’m a little confused as to how to implement the code above. Could you give me a push in the right direction?

  • Michael Hussar

    January 2, 2014 at 11:57 pm

    Sure. What exactly are you trying to do?

  • Stuart Simpson

    January 9, 2014 at 11:55 am

    Hi Michael,

    Thanks for the response. I want to tween between mask shapes using a time remap connected to layer markers.

    I’ve had this working with say, a position value but I believe that you can’t control mask shapes directly with expressions in a similar way. Is it possible to reference the null positions to control the mask points to achieve the same effect? I’m guessing this might not allow you to control any bezier curves though?

    Best

    Stu

  • Stuart Simpson

    January 9, 2014 at 2:00 pm

    Hi Michael,

    Thanks for the response. I want to tween between mask shapes using a time remap connected to layer markers.

    I’ve had this working with say, a position value, but I believe that you can’t control mask shapes directly with expressions in a similar way. Is it possible to reference the null positions to control the mask points to achieve the same effect? I’m guessing this might not allow you to control any bezier curves though?

    Best

    Stu

Page 1 of 2

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