Motor animation


RE: Motor animation
#5
I try to use your 8860.lua to isolate the engine script and try my Motor_animation.lua with this

Code:
--[[ Advanced animated mechanics for the 8860 set, extensively using the aniTools module. Copyright Roland Melkert 2017 Free for non-commercial use. Version 2017-12-29 --]] --==Options============================================================================================================= --[[ local doLenStats=false --prints info about minimal needed animation length and estimates POV-Ray rendering time. local frtA=35 --normal radiosity local frtB=3.5*60 --HQ radiosity local doLeftChairTiltDemo=true --left or right chair tilt demo ]] --==Includes============================================================================================================ genTools=require('genTools') aniTools=require('aniTools') --==Sub actors========================================================================================================== function initEngine(actor)  --Engine table  local result={}  --Animation elements  result.mainAxleAngle=actor:addAniElm(aniTools.aniElm(0))  result.pistonRodPosOri={}  result.pistonTopPosOri={}  local m=ldc.matrix() --can use a single one as aniElm clones it.  for i=1,4 do    result.pistonRodPosOri[i]=actor:addAniElm(aniTools.aniElm(m))    result.pistonTopPosOri[i]=actor:addAniElm(aniTools.aniElm(m))  end  result.coverVis=actor:addAniElm(aniTools.aniElm(true))  result.coverPos=actor:addAniElm(aniTools.aniElm(0))  --Joints  local sf=ldc.subfile()  local ZZ=ldc.vector(0, 0, -1) --negative to force positive angles for forward motion.  local mainAxleRef=sf:getRef('axe_motor.ldr')  actor:addJoint(aniTools.angleJoint(mainAxleRef, result.mainAxleAngle, ZZ))  result.pistonRodJoint={}  result.pistonTopJoint={}  local c=mainAxleRef:getPos()  for i=1,4 do    --Use relative posOri joints for both pistons and tops.    -- This simplifies the below maths as we can assume everything is relative to points along the main axle.    local ref=sf:getRef('piston.ldr', i)    c:setZ(ref:getPos():getZ())    result.pistonRodJoint[i]=actor:addJoint(aniTools.posOriJoint(ref, result.pistonRodPosOri[i], c, false, ldc.matrix()))    result.pistonTopJoint[i]=actor:addJoint(aniTools.posOriJoint(sf:getRef('2851.dat', i), result.pistonTopPosOri[i], c, false, ldc.matrix()))  end  --All axles are depended on de main engine axle, and thus normally would/could be handled in the engine apply function below.  -- But the gearbox is depended on the resulting drive axle angle, so in order to animate that non static (gear shifts) this angle must be known/available during sequence processing.  -- For this to be possible actions must be used, so lets define a custom one doing all axles in one go.  result.depsAction=function(self)    result=aniTools.depAction(0)    result.engine=self    result.calc=function(self, time)    end    return result  end  result.apply=function(self)    --The pistons are always depended on a 'normal' animation element, so we can handle their final position in this apply funciton outside normal sequence processing.    -- This allows for a slightly more efficient way of dealing with all of them in one go and removes the need to worry about it during sequencing.    --We need to calculate their orientation changes resulting from the cylinder constrains.    local mainAxleOri=ldc.matrix()    mainAxleOri:setRotate(self.mainAxleAngle.value, 0, 0, -1)    for i=1,4 do      --All related joints maintain a center along the main axle.      -- So we need the relative position of the piston (in rest) to that.      local rpNeg=genTools.IF(i>2, 1, -1) --The rods are connect left and right in pairs.      local bpNeg=genTools.IF((i%2)==0, 1, -1) --The heads go from left to right, odd being at the positive side of X      --The rods are connected to the offcenter axle's      local p1=ldc.vector(rpNeg*16, 0, 0)      --Rotate it to its current position.      p1:transform(mainAxleOri)      --The head is normally located 60 units further away.      local blockPos=ldc.vector(bpNeg*(60+16), 0, 0)      --Now we get the pistons 'Y' direction in local space directly from its original reference.      local yDir=self.pistonRodJoint[i].orgAbsPosOri:getOriYRow()      --How far is the piston position from the line the piston moves on.      -- getDistance also returns the (pos/neg) distance from the line's position to p1 when based upon the normalized line vector.      local dist, mul=p1:getDistance(blockPos, yDir)      --Use this to calculate the (shortest) position on the movement line in relation to the piston position.      local pShort=blockPos+yDir*mul      --These two points together with the unknown top position form a triangle.      -- We use this to calculate the distance of the 'used' part of the movement line in relation to the nearest point on it.      local s=math.acos(dist/60)      s=math.sin(s)*60      --And then use that distance to move the 'near' point along the line.      -- which is the position of the top.      local p2=pShort-yDir*s      --Now we need to orientate the piston so the joint can place it correctly.      -- Local Y goes from piston to top, note neg due to LDraw.      local pistonY=p1-p2      -- Local Z never changes as the axle is parallel to it, so get it from the original reference.      local pistonZ=self.pistonRodJoint[i].orgAbsPosOri:getOriZRow()      -- And having two, we can get the third as the crossproduct because everything needs to be perpendicular.      local pistonX=pistonY:getCross(pistonZ)      --Use this and the calculated position to construct a matrix.      local posOri=ldc.matrix()      posOri:setOriRows(pistonX, pistonY, pistonZ) --Do note we can't do it in the matrix constructor function as that expects 'columns', you could invert it later though.      posOri:setPos(p1)      --Apply to the aniElm      self.pistonRodJoint[i].elm.value:set(posOri)      --The top piston only needs its position changed, but as we are using relative joints we also need to apply the original top orientation.      posOri:setOri(self.pistonTopJoint[i].orgAbsPosOri)      posOri:setPos(p2)      --Apply to the aniElm      self.pistonTopJoint[i].elm.value:set(posOri)    end  end  return result end --==Main actor========================================================================================================== function carActor()  --Start with a basic actor table.  local result=aniTools.actor()  --Split mechanics / control elements into logical sub tables.  result.engine=initEngine(result) -- This handles the engine axles and pistons.  --Override the apply function so we can do all the auto dependencies.  -- This could also be done using custom dependency actions.  -- But there is no real advantage to that method in a large animation like this one.  --Buffer the default apply function as we are overriding it to do some auto dependencies.  -- You could skip this if you don't use joints in an animation, but we do.  result.orgApply=result.apply  result.apply=function(self)    self.engine:apply()    -- The default function processes all joints so it must be called in our version too.    self:orgApply()  end  return result end function camActor(story)  --Initial/rest state 3rd person camera.  local cam=ldc.camera(3, ldc.vector(46.4297, -27.8264, -53.1873),  2074.9246,  69.8029,  35.1886, 0)  --Register it as an output camera, the returned cam object is a DIFFERENT one as it needs to be a 'linked' one.  cam=story:addCamera(cam)  --Create an actor for this output camera.  result=story:addActor(aniTools.cameraActor(cam))  --Easy to use spin action generator.  result.spin=function(self, seq, ofs, len)    seq:addAction(aniTools.diffAction(self.yaw, ofs, len, 360))    return len  end  return result end --==Events============================================================================================================== function onStart()  movie=aniTools.story()  local car=movie:addActor(carActor())  print (car) --  local cam=camActor(movie)  --Add the main sequence to the story  local mainSeq=movie:addSequence(aniTools.sequence());  -- Main dependency actions.  mainSeq:addAction(car.engine:depsAction())  --Engine speed  local driveSeq=aniTools.sequence()  driveSeq:addAction(aniTools.accelAction(car.engine.mainAxleAngle, 0, 2, 0, 150))  driveSeq:addAction(aniTools.speedAction(car.engine.mainAxleAngle, 2, nil, 150))  driveSeq:addAction(aniTools.accelAction(car.engine.mainAxleAngle, 0, 2, 150, 0))  driveSeq.finLen=function(self, len) self.actions[2].len=len-4  self.actions[3].ofs=len-2 end --The length of motion is set at the end of storyboarding.  --Put together the story.  local ofs=0  local len=0  local driveOfs=ofs  mainSeq:addRef(driveSeq, ofs, nil)  --Done setting up the story  movie:prep() --If not here it will be automatically done in the first apply call, which might cause a 'too slow playback' error in complicated animations.  if doLenStats then    print('Length needed: ', ofs, ', est render time: ', genTools.round(ofs*25*frtA/60/60, 2), ' hours, HQ: ', genTools.round(ofs*25*frtB/60/60, 2), ' hours.')  end end function onFrame()  movie:apply(ldc.animation():getFrameTime()) end --==Register============================================================================================================ function register()  local ani=ldc.animation('Demo')  ani:setLength(10)  ani:setEvent('start', 'onStart')  ani:setEvent('frame', 'onFrame') end register()

but I've got this message :


Code:
[string "Motor_animation.lua"]:57: Active refline link needed.


I can't solve it.
Reply
« Next Oldest | Next Newest »



Messages In This Thread
Motor animation - by NEMOOZ - 2018-07-29, 19:04
RE: Motor animation - by Roland Melkert - 2018-07-31, 11:22
RE: Motor animation - by NEMOOZ - 2018-08-07, 18:33
RE: Motor animation - by Roland Melkert - 2018-08-07, 18:49
RE: Motor animation - by NEMOOZ - 2018-09-02, 13:56
RE: Motor animation - by Roland Melkert - 2018-09-02, 19:10

Forum Jump:


Users browsing this thread: 1 Guest(s)