CameraMapper_Setup

All things .jsx

Moderator: Paul Tuersley

Post Reply
Simma
Posts: 98
Joined: June 8th, 2010, 2:57 pm

Here's a script that makes it easy to use DigiEffects Camera Mapper with matchmoved (3D tracked) cameras. It's based on the technique shown by Stephen Wong (http://www.thefoundry.co.uk/products/ca ... /#201_vids) and seems to work pretty good. If you like using 3D compositing and projections in AE, this might save you some time.

* UPDATED to version 1.1. Copy the code or download attached file.

Code: Select all


//////////////////////////////////////////////////////

// Camera Mapper Setup
// by Simon Björk
// Based on a technique shown by Stephen Wong and with a lot of help from Lloyd Alvarez.
// July 2011
// Version 1.1

// Use this script to easily set up a camera projection from a match moved camera. 
//The script is to be used with DigiEffects Camera Mapper plug-in.
// Select your camera and a footage layer.

// Version 1.1 fixed some naming errors.

//////////////////////////////////////////////////////

var myComp = app.project.activeItem;
var selLayers = myComp.selectedLayers;

// Check to see if a camera and a footage layer is selected.
if( selLayers[0]||selLayers[1] instanceof CameraLayer && selLayers[1]||selLayers[0] instanceof AVLayer) {
    
app.beginUndoGroup("CameraMapperSetup");

// If the selected layer is a camera layer do this.
for (var i=0; i<selLayers.length;i++)
    if(selLayers[i] instanceof CameraLayer){
    var myCamera = selLayers[i]
    var dupCamera = myCamera.duplicate();
    }
  
// If the selected layer is a footage layer do this. 
for(var j=0; j<selLayers.length;j++)
    if(selLayers[j] instanceof AVLayer){
    var myLayer = selLayers[j]
    var dupLayer = myLayer.duplicate();
    var layerIndices = new Array();
    layerIndices[layerIndices.length] = dupLayer.index;
    }

// Remove keyframes on the duplicated CameraLayers properys.
for (var i=dupCamera.position.numKeys; i>0; i --) {
    dupCamera.position.removeKey(i);
    }      

for (var i=dupCamera.rotationX.numKeys; i>0; i --) {
    dupCamera.rotationX.removeKey(i);
    }       

for (var i=dupCamera.rotationY.numKeys; i>0; i --) {
    dupCamera.rotationY.removeKey(i);
    }            

for (var i=dupCamera.rotationZ.numKeys; i>0; i --) {
    dupCamera.rotationZ.removeKey(i);
    }
     
// Set the duplicated cameras position and rotation to defult.    
var compHeight = myComp.height/2;
var compWidth = myComp.width/2;
var cameraZoomValue = dupCamera.property("Zoom").value;
       
dupCamera.position.setValue ([compWidth,compHeight,cameraZoomValue*-1]);
dupCamera.rotationX.setValue (0);
dupCamera.rotationY.setValue (0);
dupCamera.rotationZ.setValue (0);
     
// Connect the duplicated layer to the duplicated camera and disable it ( as CameraMapper expects a disabled layer).     
dupLayer.threeDLayer = true;
dupLayer.parent = dupCamera;
dupLayer.enabled = false;

// Pre-compose the duplicated layer and set name to the current frame.
var projectionFrame = myComp.layers.precompose(layerIndices, "ProjectionFrame", false );

// Enable time-remapping of the duplicated layer (inside the new composition) and freeze-frame at the current value.  
var LayerInPreComp = projectionFrame.layer(1);
LayerInPreComp.timeRemapEnabled = true;
LayerInPreComp.timeRemap.setValueAtTime(myComp.time,myComp.time);
var myKeyIndex = LayerInPreComp.timeRemap.nearestKeyIndex(myComp.time);
LayerInPreComp.timeRemap.setInterpolationTypeAtKey(myKeyIndex, KeyframeInterpolationType.LINEAR, KeyframeInterpolationType.HOLD);

// Remove first keyframe.
    if(myComp.time > 0){    
    LayerInPreComp.timeRemap.removeKey(1);
    }

// Remove last keyframe.
LayerInPreComp.timeRemap.removeKey(LayerInPreComp.timeRemap.numKeys);

// Set names based on current frame.
var dispStartFrame = app.project.displayStartFrame;
var dispFrame = myComp.displayStartTime/myComp.frameDuration;

if(dispStartFrame == 1){
    var myFrame = dispFrame + (myComp.time/myComp.frameDuration) +1;
        }else{
        var myFrame = dispFrame + (myComp.time/myComp.frameDuration);
        }
    
projectionFrame.name = "projectionframe_" + myFrame;
dupCamera.name = "projectioncamera_" +myFrame;
      
// Set position and rotation based on original camera.        
var origCameraPosition = myCamera.position.valueAtTime(myComp.time, false);
var origCameraRotationX = myCamera.rotationX.valueAtTime(myComp.time, false);
var origCameraRotationY = myCamera.rotationY.valueAtTime(myComp.time, false);
var origCameraRotationZ = myCamera.rotationZ.valueAtTime(myComp.time, false);

dupCamera.position.setValue(origCameraPosition);
dupCamera.rotationX.setValue(origCameraRotationX);
dupCamera.rotationY.setValue(origCameraRotationY);
dupCamera.rotationZ.setValue(origCameraRotationZ);

// Set expression to scale layer after camera.
dupLayer.scale.expression = "x = (100/thisComp.layer('" + dupCamera.name + "').cameraOption.zoom)*transform.position[2];\r[x,x,x]";

// Move projection camera below original camera.
dupCamera.moveAfter(myCamera);
      
app.endUndoGroup();

// Alert if a camera and a footage layer is not selected.
}else{        
    alert("Please select a camera and a footage layer.");
    }

Attachments
sb_CameraMapper_Setup_v1.1.zip
(1.62 KiB) Downloaded 1221 times
Last edited by Simma on July 25th, 2011, 6:22 pm, edited 2 times in total.
Paul Tuersley
Posts: 704
Joined: June 5th, 2004, 7:59 am
Location: London, UK

The comments mention that it's a bit slow on OS X. It's purely a guess, but maybe it's happening in the loops where you're deleting rotation keyframes.

I have a script where deleting lots of keyframes was causing slowdown, so I switched to this rather hacky method instead:

Code: Select all

theProperty.selected = true;
app.executeCommand(app.findMenuCommandId("Clear"));
Simma
Posts: 98
Joined: June 8th, 2010, 2:57 pm

I think you're right, as there could be a lot of keyframes. But strange that it's slower on Mac, should be the same on PC. I'm not sure if I understand your trick, but I'll try to figure it out and see if it could be used to speed this thing up. Thank you :).
Post Reply