Script to create a turntable animator

Forums: Script to create a turntable animator
Forum for OctaneRender Lua scripting examples, discussion and support.

Script to create a turntable animator

Postby stratified » Thu Dec 19, 2013 11:07 pm

stratified Thu Dec 19, 2013 11:07 pm
Hi all,

Today we will show you how to set up an animator on the thin lens camera to do a turntable animation. We will use part of this script later to finish our turntable animation tutorial. All you have to do is select the camera to animate and run the script. After running this script, you should see a time line and when you scrub through it it's doing a turntable animation. If not we have a bug ;)

First we set up some presets to control the number of frames, the rotation angle and the shutter time (for camera motion blur):

Code: Select all
-- the number of frames in the animation
local nbFrames = 50
-- the rotation angle of the turntable animation
-- positive value for clockwise rotation, negative for anti-clockwise
local rotAngle = -360
-- camera shutter time for motion blur (0 for no motion blur)
local shutterTime = 0.03


Lets get the camera node the user has selected and check if it's really a thinlens camera (selection in Lua was introduced in Octane 1.23):

Code: Select all
-- Get the current selected node. (should be a single selection)
local camNode = octane.project.getSelection()[1]
if camNode == nil then error("no node selected") end
if camNode:getProperties().type ~= octane.NT_CAM_THINLENS then error("no camera node selected") end


Next we define a little helper function orbit which calculates a new camera position based on the passed in yaw angle. This function returns the new position:

Code: Select all
-- Calculates a new rotated position for the turntable anim.
--
-- @param   yaw
--      yaw rotation angle (radians)
-- @param   position
--      camera position value
-- @param   target
--      camera target value
-- @param   up
--      camera up vector value
-- @return
--      the new camera position rotated around the up vector over the
--      yaw angle
local function orbit(yaw, position, target, up)
    local v = octane.vec

    local viewDir = v.sub(target, position)
    local right   = v.normalized(v.cross(viewDir, up))

    viewDir = v.rotate(viewDir, up, yaw)
    return v.sub(target, viewDir)
end


What we need to do now is create a list of all the camera positions, 1 position for each frame. We do this by calculating a new position for each frame based on the original camera position and target:

Code: Select all
-- Get some information about the camera
local camTarget   = camNode:getPinValue(octane.P_TARGET)
local camPosition = camNode:getPinValue(octane.P_POSITION)
local camUp       = camNode:getPinValue(octane.P_UP)

-- calculate the camera position for each frame
positions = {}
for i=1,nbFrames do
    local angle = math.rad( (i - 1) / nbFrames * rotAngle)
    table.insert(positions, orbit(angle, camPosition, camTarget, camUp))
end


Now that we have a list of positions, we use this list to set up an animator on the node connected to the position pin of the camera:

Code: Select all
-- hook up the position on the camera's position node
camNode:getConnectedNode(octane.P_POSITION):setAnimator(octane.A_VALUE, { 0 }, positions, 1 / nbFrames)


To finish, we set the camera shutter time in the render engine:

Code: Select all
-- set the shutter time for motion blur
octane.render.setShutterTime(shutterTime)


If all went well, you should have something like this:

Code: Select all
--
-- Sets up a turntable animation on the selected camera node.
--

-- the number of frames in the animation
local nbFrames = 50
-- the rotation angle of the turntable animation
-- positive value for clockwise rotation, negative for anti-clockwise
local rotAngle = -360
-- camera shutter time for motion blur (0 for no motion blur)
local shutterTime = 0.03

-- Get the current selected node. (should be a single selection)
local camNode = octane.project.getSelection()[1]
if camNode == nil then error("no node selected") end
if camNode:getProperties().type ~= octane.NT_CAM_THINLENS then error("no camera node selected") end


-- Calculates a new rotated position for the turntable anim.
--
-- @param   yaw
--      yaw rotation angle (radians)
-- @param   position
--      camera position value
-- @param   target
--      camera target value
-- @param   up
--      camera up vector value
-- @return
--      the new camera position rotated around the up vector over the
--      yaw angle
local function orbit(yaw, position, target, up)
    local v = octane.vec

    local viewDir = v.sub(target, position)
    local right   = v.normalized(v.cross(viewDir, up))

    viewDir = v.rotate(viewDir, up, yaw)
    return v.sub(target, viewDir)
end


-- Get some information about the camera
local camTarget   = camNode:getPinValue(octane.P_TARGET)
local camPosition = camNode:getPinValue(octane.P_POSITION)
local camUp       = camNode:getPinValue(octane.P_UP)

-- calculate the camera position for each frame
positions = {}
for i=1,nbFrames do
    local angle = math.rad( (i - 1) / nbFrames * rotAngle)
    table.insert(positions, orbit(angle, camPosition, camTarget, camUp))
end

-- hook up the position on the camera's position node
camNode:getConnectedNode(octane.P_POSITION):setAnimator(octane.A_VALUE, { 0 }, positions, 1 / nbFrames)

-- set the shutter time for motion blur
octane.render.setShutterTime(shutterTime)


In a next post we'll re-use this code to finish our turntable animation script. If something isn't clear, please do ask.

cheers,
Thomas
User avatar
stratified
OctaneRender Team
OctaneRender Team
 
Posts: 945
Joined: Wed Aug 15, 2012 6:32 am
Location: Auckland, New Zealand

Return to Lua Scripting


Who is online

Users browsing this forum: No registered users and 14 guests

Tue Apr 23, 2024 7:58 pm [ UTC ]