Thoughts on animation scripting language


Relative movement framework (was re: Thoughts on ani...)
#33
Hi all,

I've been playing around with lua, and it's even more dynamic than I hoped. So I'm glad I choose it over an own scripting language based on the comments above.

It's so powerful it allows for setting up a generic extremely flexible basic connection system. Something I first considered doing using api functions. But the below script completly handles it using only the (matrix,vector,ref,subfile) LDCad interaction objects.

Given the below script and the demo clip I was hoping to get some feedback suggestions on the current state of the language/api.

Some questions I have are:
  • Is it (somewhat) understandable or do people prefer some more hardcoded solutions for these kinds of animations?
  • Do you think this frame work is good enough for animation you would like to create
  • What kind of lowlevel functions would you like to see for use in custom animations?

Any feedback is welcome.

Youtube clip of relative movement demo

And here's the script used in the youtube clip:

Code:
function register()

  local myAni=ldc.animation('Rel move test');
  myAni:setLength(10); --seconds
  myAni:setFPS(25);
  myAni:setEvent('play', 'preCalcRelMoveDeps');
  myAni:setEvent('frameChange', 'calcRelMoveFrame');
end

function calcRelPos(cur, parent)

  --convert ref's abs pos to it's relative position 'inside' it's parent.
  if cur.ref~=nil then
  
    local pp
  
    if parent.ref~=nil then
      pp=parent.ref:getPos()
    else
      pp=ldc.vector()
    end
    
    cur.relPos=cur.ref:getPos()-pp
  end
  
  --Handle child connections recursively
  if cur.con~=nil then
    for _,con in ipairs(cur.con) do
      calcRelPos(con, cur)
    end
  end

end

function calcCon(cur, parentPosOri)

  --Calculate posOri for this connection
  local posOri=ldc.matrix()
  if cur.calc~=nil then

    --calc placement
    cur.calc(cur, posOri)
    posOri:mulAB(parentPosOri)

    --incl orgOri only in set to compensate for the refereced model's base orientation
    cur.ref:setPosOri(cur.orgOri*posOri)
  end
  
  --Handle child connections recursively
  if cur.con~=nil then
    for _,con in ipairs(cur.con) do
      calcCon(con, posOri)
    end
  end

end

basicAngleCalcFunc=function(cur, posOri)

    --Basic relative single axis placement
    posOri:setRotate(cur.angle, cur.rotAxis)
    posOri:mulTranslateAB(cur.relPos)

end

colorRotateFunc=function(cur, posOri)

    --Basic relative single axis placement
    posOri:setRotate(cur.angle, cur.rotAxis)
    posOri:mulTranslateAB(cur.relPos)
    
    --play with the ref's color
    cur.ref:setColor(math.abs(cur.angle/45))
end

function preCalcRelMoveDeps()

  --link refs
  local sfMain=ldc.subfile();
  arm1=sfMain:getRef(1)
  arm2=sfMain:getRef(2)
  arm3=sfMain:getRef(3)
  arm4=sfMain:getRef(4)

  --Connection blocks
  root={
    con={}
  }
  
  conArm1={
    ref=arm1,
    relPos=ldc.vector(),
    orgOri=arm1:getOri(),
    angle=0,
    rotAxis=ldc.vector(0,0,1),
    calc=basicAngleCalcFunc,
    con={}
  }
  
  conArm2={
    ref=arm2,
    relPos=ldc.vector(),
    orgOri=arm2:getOri(),
    angle=0,
    rotAxis=ldc.vector(0,0,1),
    calc=basicAngleCalcFunc,
    con={}
  }

   conArm3={
    ref=arm3,
    relPos=ldc.vector(),
    orgOri=arm3:getOri(),
    angle=0,
    rotAxis=ldc.vector(0,0,1),
    calc=basicAngleCalcFunc,
    con={}
  }
  
  conArm4={
    ref=arm4,
    relPos=ldc.vector(),
    orgOri=arm4:getOri(),
    angle=0,
    rotAxis=ldc.vector(0,0,1),
    calc=basicAngleCalcFunc,
    con={}
  }  
  
  --Connection tree
  root.con={conArm1}
  conArm1.con={conArm2, conArm4}
  conArm2.con={conArm3}  
    
  --Caluclate rel positions
  calcRelPos(root)
end

function calcRelMoveFrame()

  local curAni=ldc.animation.getCurrent();
  local totTime=curAni:getLength()
  local curTime=totTime*curAni:getFrameNr()/curAni:getFrameCnt()
  
  --calc connection angles for the current frame
  if curTime<3 then
    conArm1.angle=45*curTime/3
  else
    conArm1.angle=45
  end
  
  if curTime>3 then
    if curTime>6 then
      conArm2.angle=-30
    else
      conArm2.angle=-30*(curTime-3)/3
    end
  else
      conArm2.angle=0
  end

  if curTime>6 then
    conArm3.angle=-60*(curTime-6)/4
  else
    conArm3.angle=0
  end
  
  conArm4.angle=curTime/totTime*360*2

  --apply angles
  calcCon(root)
end

register();
Reply
« Next Oldest | Next Newest »



Messages In This Thread
Relative movement framework (was re: Thoughts on ani...) - by Roland Melkert - 2014-07-19, 18:54

Forum Jump:


Users browsing this thread: 2 Guest(s)