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:
Any feedback is welcome.
Youtube clip of relative movement demo
And here's the script used in the youtube clip:
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();