Create a gist now

Instantly share code, notes, and snippets.

Embed
Adobe After Effects ExtendScript code
/*
Jim Schmitz
2017.11.27
NYU-ITP 2019
http://ixora.io/itp/
Script for duplicating the special effects of "simulacra" in After Effects.
https://vimeo.com/123006429
My rendition is here: https://vimeo.com/244769141
Created for Gabe's Animation class.
*/
{
function alignFrame()
{
var scriptName = "Align Frame";
var BASEDIR = "D:/Projects/ITP/Animation/ITP Walk";
// is a composition selected?
var activeItem = app.project.activeItem;
if ((activeItem == null) || !(activeItem instanceof CompItem)) {
alert("Please select or open a composition first.", scriptName);
return false;
}
var activeComp = activeItem;
var compName = activeComp.name;
// is there a camera?
var cameraLayer = activeComp.activeCamera;
if (cameraLayer == null) {
alert("Composition has no active camera", scriptName);
}
// is a single layer selected?
var selectedLayers = activeComp.selectedLayers;
if (activeItem.selectedLayers.length != 1) {
alert("Please select a single null layer", scriptName);
return false;
}
// is that single layer a null layer?
var nullLayer = selectedLayers[0];
if (nullLayer == null || !nullLayer.nullLayer) {
alert("Single layer selected must be a null layer", scriptName);
return false;
}
// import the correct image
var frameNum = nullLayer.time / activeComp.frameDuration;
var options = new ImportOptions();
// looks for files in a "frames" subdirectory
options.file = new File(BASEDIR + "/frames/" + compName + "/" + compName + "_" + pad(frameNum, 5) + ".jpg");
var imageLayer = activeComp.layers.add(app.project.importFile(options));
imageLayer.moveBefore(nullLayer);
// gather variables
var camera = cameraLayer.position.value;
var orientation = cameraLayer.orientation.value;
var r0 = nullLayer.position.value;
var width = imageLayer.width;
var theta = 110;
app.beginUndoGroup(scriptName);
// necessary prework
imageLayer.threeDLayer = true;
imageLayer.parent = nullLayer;
nullLayer.orientation.setValue(orientation);
imageLayer.orientation.setValue([0, 0, 0]);
// now do the math
var rot = new RotationMatrix(orientation);
var xp = rot.preMult([1, 0, 0]);
var yp = rot.preMult([0, 1, 0]);
var zp = rot.preMult([0, 0, 1]);
var a = dot(zp, r0 - camera);
var b = (width / 2) / dtan(theta / 2);
var r = camera + a * zp;
var scale = 100 * a / b;
var position = [dot(xp, r - r0), dot(yp, r - r0), 0]
// position into place
imageLayer.scale.setValue([scale, scale, scale]);
imageLayer.position.setValue(position);
// position in time
imageLayer.inPoint = nullLayer.time;
app.endUndoGroup();
return true;
}
alignFrame();
}
// helper functions
function pad(num, size) {
var s = "000000000" + num;
return s.substr(s.length-size);
}
function deg2rad(val) {
// convert radians to degrees
return Math.PI * val / 180;
}
function dcos(value) {
// cos of angle in degrees
return Math.cos(deg2rad(value));
}
function dsin(value) {
// sin of angle in degrees
return Math.sin(deg2rad(value));
}
function dtan(value) {
// tan of angle in degrees
return Math.tan(deg2rad(value));
}
function dot(a, b) {
// dot product
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
}
// Tait-Bryan XYZ rotation matrix
function RotationMatrix(orientation) {
var c1 = dcos(orientation[0]);
var s1 = dsin(orientation[0]);
var c2 = dcos(orientation[1]);
var s2 = dsin(orientation[1]);
var c3 = dcos(orientation[2]);
var s3 = dsin(orientation[2]);
var m11 = c2 * c3;
var m12 = -c2 * s3;
var m13 = s2;
var m21 = c1 * s3 + c3 * s1 * s2;
var m22 = c1 * c3 - s1 * s2 * s3;
var m23 = -c2 * s1;
var m31 = s1 * s3 - c1 * c3 * s2;
var m32 = c3 * s1 + c1 * s2 * s3;
var m33 = c1 * c2;
this.row1 = [m11, m12, m13];
this.row2 = [m21, m22, m23];
this.row3 = [m31, m32, m33];
this.preMult = function(vec) {
return [dot(this.row1, vec),
dot(this.row2, vec),
dot(this.row3, vec)];
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment