Thoughts on animation scripting language


Thoughts on animation scripting language
#1
Hi all, while LDCad 1.3 is still in beta I'm already playing with 1.4 things....

One of those things will be animation, I want to take the all scripting road with this. So the thing I'm trying to decide at the moment is to ether create my own language (based on the one from LD4DStudio) or tie in an existing language (e.g. LUA).

The scripts will do little more then describe relations between groups. For example in case of two gears with the attached axles etc the script will do something like 'a.angle:=-2*b.angle'. A script could also manipulate the group placement matrix directly etc.

While LUA or pearl might be very powerful, it also will be difficult for non programmer users ( I Think) to get started with. A simple custom language on the other hand will be much easier to learn but limited to basic single function formulas etc. Although I could expand the language over time.

In short I find it difficult to decide at the moment, so I was hoping for some additional thoughts.
Reply
Re: Thoughts on animation scripting language
#2
I think an existing language (Lua, Tcl, Python) is the way to go rather than reinventing the wheel and rolling your own. It will also be easier for you as the project maintainer to plugin an exiting framework rather than writing all the code that would be required to implement your own design.
Reply
Re: Thoughts on animation scripting language
#3
I agree with Orion. Lua seems a good candidate to me, elementary use is not too frightening even for a novice like me (I played quite a bit with pbLua for NXT...)
Reply
Re: Thoughts on animation scripting language
#4
I've been looking more into LUA and it seems relatively easy to embed in a c++ program. Only thing I'm worrying about is how to handle matrix math which must be shared with the C++ matrix/vector objects (although I'm thinking using handles would probably work)

It would save alot of dev time if I could embed LUA in say couple of days and spend the rest of my time fine tuning the animation api toolset/interface, so at the moment I'm leaning towards LUA.

Does anyone here have experience embedding LUA, of knows of a better alternative?
Reply
Re: Thoughts on animation scripting language
#5
Maybe you could get some tips from Ralph Hempel...
Reply
Re: Thoughts on animation scripting language
#6
Actually it's surprisingly easy, I downloaded , compiled (into .a) and statically linked lua against the dev version of LDCad in under 15 mins.

Now I have to learn the lua C api, and setup some nice wrapper (management) class for it, which will take far more time Smile

On a side note, if anyone has ideas / suggestions for the general animation api for LDCad I'm open to all suggestions.
Reply
Re: Thoughts on animation scripting language
#7
Roland Melkert Wrote:Actually it's surprisingly easy, I downloaded , compiled (into .a) and statically linked lua against the dev version of LDCad in under 15 mins.

Hmm, when I get back up on the LDDP horse, I'm considering moving plugins to Lua or similar scripting language so I'm glad that integration is easy.
Reply
Re: Thoughts on animation scripting language
#8
Wasn't LDDP a Delphi program? If so you might need to do some more work to get it working through a DLL for example.

Anyway I'm definitely going the LUA way for LDCad 1.4 cause after only one evening of playing around I've got it to put

Quote:Script output: Hallo wereld versie 1

In the log file using this LUA script/chunk:

Code:
msg=ldc.hoi()
ver=ldc.version
ldc.logInfo(msg, 'versie', ver)
Reply
Re: Thoughts on animation scripting language
#9
Yah. But I'm in the process of converting over to Lazarus/FreePascal since I don't feel like paying the extortionary prices to keep current on Delphi and it's cross platform with native widgets. Plus there are Lua-Pascal libraries out there.
Reply
Re: Thoughts on animation scripting language
#10
To echo what others have said, Lua is a solid choice for this -- it seems to be popular with non-programmer artist types in the game-dev world, so I wouldn't worry too much about initial hurdle. In the long term Lua will scale up for larger scripts, and you can move to LuaJIT for better performance.
Reply
Re: Thoughts on animation scripting language
#11
I did read about LUAJit, but I decided to use the plain lua for now as it is easier to get started with (i think), if needed I could replace it later like you wrote as it's pretty much api compatible.

As for speed I have not jet tested that, the scripts are going to do matrix math etc on per frame/movement basis, but I was planning to move the core matrix stuff to C functions and give the user only access to container handles (lua calls it user data), e.g. matrix.loadID, matrix.mul(matrix2) etc. Or using operator functions (which lua seems to support, but I haven't really looked into it)
Reply
Re: Thoughts on animation scripting language
#12
Hi Roland,

Yep - LuaJIT is more or less API compatible - a later switch-over should be easy.

The only gotcha: for 64-bit ABIs, LuaJIT needs to allocate from the lowest 2 GB of address space. If you start your Lua session early or run only Lua this isn't much of a problem, but if you run your app for a while and then have to allocate a pile of Lua memory, you can run out. There are ways to work around this though - I can send you an email if you ever run into this case.

If you have to make a large number of calls into C that do a relatively small amount of math (e.g. one matrix multiply), LuaJIT might be competitive with C due to the overhead cost.

Cheers
Ben
Reply
Re: Thoughts on animation scripting language
#13
Thanks for the info, but I think basic LUA will do for now.

At the moment I'm trying to set up a global approach for the animation handing, as I have zero experience in LUA and you seem to have some I would appreciate your thoughts regarding the below approach.

Consider the following (pseudo) LUA script

Code:
--global scope part of the script, will be ran upon file load.


--Setup custom group 'methods' for the ldcGroup pseudo class
--  this will determine the way we want to animate the groups
--  simple rotation over the z axis in this example.


function ldcGroup.initLink(grpName)

  result=ldcGroup.link(grpName)
  result.angle=0 --introduce obj var ??
  return result
end

function ldcGroup:getAngle()
  --does not really need a function, but maybe we want to do more in here in the future
  return self.angle
end

function ldcGroup:setAngle(newAngle)

  self.angle=newAngle
  local matrix=self.getCurrentMatrix()
  matrix.loadRotation(newAngle, 0.0, 0.0, 1.0);
end


--make global lua vars for groups we want to manipulate
gearA=ldcGroup.initLink('group1')
gearB=ldcGroup.initLink('group2')


--called by LDCad on 'reset' event
function init()

  gearA:setAngle(0.0);
  gearB:setAngle(0.0);  
end


--called by LDCad on 'frame change' event
function calcFrame()

  angleA=gearA.getAngle() + 15
  gearA:setAngle(angleA)

  angleB=angleA*-2
  gearB:setAngle(angleB)
end

The thing I want to achieve here is setting up a scripting environment which is extremely dynamic. I don't want to restrict users to animate in a certain way. So by using LUA they should be able to animate simple gears, but also e.g. walking mini figs etc.

In the long term you could setup a LUA library containing code for handling gears universally etc. This would also allow for third party written code handling e.g. extremely complex kinetics to be used by others.

So my question is: Does the above approach makes sense, or I'm I thinking in a wrong direction here or are there any LUA limitations spoiling this.

if anybody wants to actively help think out this environment please let me know.

[edit] made minor corrections to the script
Reply
Re: Thoughts on animation scripting language
#14
I haven't used LDCad, so forgive me if any of this misses the point. I haven't used it because I'm very experienced with my existing setup (MLCad -> LDView -> PovRay), because I don't presently have the time to investigate it, and because LDCad looks a little too "heavy" for my aging PC :-)

But it does look interesting, so I wanted to just say a few words.

I've done complex animations before (example: http://www.youtube.com/watch?v=oFR6u9_lnoY). The method I use is to use standalone command-line PHP as a general scripting engine to write a script that modifies the .pov file output by LDView to include all the additional calculations and rotations needed for the animation.

Using this technique not only can I easily manipulate the position of parts and the camera, but I can also programatically generate sequences whereby parts become hidden or unhidden on a frame-by-frame basis thus automatically generating a brick-by-brick build animation of an entire model regardless of whether the model is flattened first or left in a sub-model/structured state (parts are first sorted using MLCad's part sorting feature - example http://www.youtube.com/watch?v=Aj4AUgJApys). I also use this technique to assist in automatically disabling sub-models which are not visible within specific ranges of frames (or still renders) in order to reduce the memory footprint and speed up the render times.

The example script you gave is in fact very similar to the code I inject into the .pov file for cyclic animations, so for someone of my skills I feel you are going about this the right way. The choice of language matters more to the developer than the end user, as long as it has access to stuff like sin/cos/tan/asin/acos/atan/sqrt and preferably also inbuilt functions for splines and beziers. It's clearly too complex for a non-programmer, but in my experience those type of people would only attempt an animation if they had some sort of simple "wizard" to generate the script or animation sequence for them - which is something you could consider later for novices and simpler animations such as the wheels of a car spinning (from recollection SolidWorks provides something similar whereby you select some parts, select a single rotation axis and speed, and you're good to go - all without writing any code).

One thing I would like to say about that example script. Your example uses relative position calculations on each frame. That's fine, for many cases. But I've found that in most of my cases I prefer the ability to perform absolute calculations based upon PovRay's frame_number. I realise it was only an example, and you were probably going to allow something like this anyway, but I'd hate to see you implement an animation system where absolute calculations could not be done - it's much easier to choreograph and splice sequences which have been calculated absolutely with respect to the frame number.

The other thing that is unclear to me is what LDCad would be outputting here. Are you going to output a new unique .mpd for every frame and leave it to the user to convert these to a format suitable for raytracing? Or are you going to output a new .pov file for every frame? If that's the case, someone like myself is more likely to stay with my current system. One php script. One master .mpd file. Possibly one programatically altered .mpd file. One master .pov file. And one programatically altered .pov file. From that last file I can generate 1000s of renders using a batch file.

Ultimately, given the range of functions my scripts provide, I'm probably always going to roll my own anyway, so I'm probably not the best person to offer advice ;-) but I'll certainly be keeping an eye on what you're doing.
Reply
Re: Thoughts on animation scripting language
#15
Stephen Wrote:I haven't used LDCad, so forgive me if any of this misses the point. I haven't used it because I'm very experienced with my existing setup (MLCad -> LDView -> PovRay), because I don't presently have the time to investigate it, and because LDCad looks a little too "heavy" for my aging PC :-)

Don't worry about it.

Stephen Wrote:...Using this technique not only can I easily manipulate the position of parts and the camera, but I can also programatically generate sequences whereby parts become hidden or unhidden on a frame-by-frame basis...

Access to visibility will also be possible, as lua gets full control over the associated group of ldraw parts, I might even let the user manipulate the individual parts inside the group or whole model not sure about that yet.

Stephen Wrote:... thus automatically generating a brick-by-brick build animation of an entire model regardless of whether the model is flattened first or left in a sub-model/structured state...

The current LDCad version supports editing a multi file model at the top level as if it were a single flat model, it's called the nesting mode. While this mode is active you can also create groups out of parts living in different files. It will be those groups you can manipulate (realtime) using LUA scripts during a special animation mode.

Stephen Wrote:... example http://www.youtube.com/watch?v=Aj4AUgJApys). I also use this technique to assist in automatically disabling sub-models which are not visible within specific ranges of frames (or still renders) in order to reduce the memory footprint and speed up the render times.

Great animation

Stephen Wrote:The example script you gave is in fact very similar to the code I inject into the .pov file for cyclic animations, so for someone of my skills I feel you are going about this the right way. The choice of language matters more to the developer than the end user, as long as it has access to stuff like sin/cos/tan/asin/acos/atan/sqrt and preferably also inbuilt functions for splines and beziers.

fun thing about LUA is you can get additional stuff from else where, but I will be supplying built-in functions for most logical LDraw / animation related things. And I could always add things upon request.

Stephen Wrote:It's clearly too complex for a non-programmer, but in my experience those type of people would only attempt an animation if they had some sort of simple "wizard" to generate the script or animation sequence for them

You are right about that, the reason I'm only going to do the scripting route is because my full GUI animation software (LD4DStudio) was still considered to hard by most, so I simply won't even implement the 'easy' way. But supplying wizards at some point is a good idea, I might even be able to make those plugin based so others could add them for me Smile

Stephen Wrote:...One thing I would like to say about that example script. Your example uses relative position calculations on each frame. That's fine, for many cases. But I've found that in most of my cases I prefer the ability to perform absolute calculations based upon PovRay's frame_number.

Yes in the example it's relative, but it won't be limited to that. The two main functions will have no or very little parameters, but things like frame rate and current frame etc will be accessible through global functions/variables. Also the script won't be exclusive for just animation, it will also be possible to use them for 'action response' e.g. the user spins an axle in the model, all the rest moves based on script calculations.

Stephen Wrote:The other thing that is unclear to me is what LDCad would be outputting here. Are you going to output a new unique .mpd for every frame and leave it to the user to convert these to a format suitable for raytracing?

The first goal is realtime animation inside LDCad it self, but later on I want to offer export to multiple mpd's / pov-ray simular to the export functionality of LD4DStudio.



Thanks for you thoughts on the issue.
Reply
Re: Thoughts on animation scripting language
#16
Roland Melkert Wrote:Thanks for you thoughts on the issue.
You're welcome.

Roland Melkert Wrote:it will also be possible to use them for 'action response' e.g. the user spins an axle in the model, all the rest moves based on script calculations.
That sounds good, and based on your obvious programming skills (I watched one of your videos even if I haven't run the software) I would say you're the perfect man for the job.

I wonder, have you ever used SolidWorks or similar? SW has a "mating" feature that allows you to define mating relationships between components via a point-and-click interface and dialog property boxes, so no script needs to be written. You can define for example a concentric relationship for rotational parts, and a coincident planar relationship for sliding parts, and you can further refine scaling (for gear ratios) or constraints in movement range, and so on.

You can then, for example, drag the steering wheel on a car to rotate it and the steering rack will move linearly and the wheels will turn left/right. Of course, you can also drag a wheel and cause the steering wheel to turn. Things do get a bit hairy though when a part has multiple degrees of freedom - when you drag a wheel on a car, are you trying to rotate the wheel on its axle, or are you trying to push the wheel against the suspension. Things can quickly get confusing with complex mating arrangements and the version of SW I've used does struggle at times.

If you managed any usable kind of interface for visually dragging a part (on a 3D view) and its mated parts (scripted or otherwise) then I think people would be impressed, especially in a free CAD application.
Reply
Re: Thoughts on animation scripting language
#17
Thanks

Quote:have you ever used SolidWorks or similar? SW has a "mating" feature that allows you to define mating relationships between components via a point-and-click interface and dialog property boxes

I have never used Solidworks but the concept is familiar, I would love to implement this in LDCad, but I also know I will never be able to hard code every kind of interaction. This is why I chosen to go the scripting route.

The described behavior is something I want to be possible using the scripting environment, but I'm not yet sure how I'm going to handle the interaction. It's ether going to be using extra information on the groups, or maybe some kind of special LDraw meta you can move around like normal parts but will also supply interaction information to the script.

Linking groups (e.g. a robot arm) for relative movement must then be taken care of by the script, it can do so by reading the extra info like freedom of movement and angle etc.

At the moment I'm not even sure if I want things to work with a single script for the top level model (like in my example above) or using a script per group pairing/collection (a bit like the mating you wrote about) or both.
Reply
Re: Thoughts on animation scripting language
#18
Roland Melkert Wrote:While LUA or pearl might be very powerful, it also will be difficult for non programmer users ( I Think) to get started with. A simple custom language on the other hand will be much easier to learn but limited to basic single function formulas etc. Although I could expand the language over time.

In short I find it difficult to decide at the moment, so I was hoping for some additional thoughts.

I made a working proof of concept (called LDA) with focus on easy to understand. It was kind of a modified LDraw syntax combined with some BASIC-like commands. I believe if I have had the tenth of your programming skills, my concept would really have worked. And it would have been user friendly enough to become popular.

I tried LD4D a little, but to be honest I didn't understand anything at all. So I'd suggest you go for a little more limited in "powerfulness" but easier to get over the threshold of getting started. Some wizard to guide the user through the first steps would have been very helpful.

/Tore
Reply
Re: Thoughts on animation scripting language
#19
Currently I'm working with the assumption to create a (very dynamic) LUA scripting environment only. On top of that I could later build wizards or automatic generation to help less experienced users.

API wise iI'm thinking about things like Matrix tools, LDraw group/model access and animation timers. A user then can use those lowlevel tools to write a script which will be able to animate a complete clock based on e.g. the winding tension or make technic figure do a walking sequence. And as LUA is extremly dynamic people could reuse (sub)scripts (aka modules) to reuse certain sequences or math solutions in other animations or build some kind of library of solutions to common problems. I'll be supplying the start of such a collection with things like gear / steering mechanics.

Is your LDA information online somewhere as I'm very open to suggestions.


The biggest problem with LD4D is/was it's interface I guess, it uses a object oriented interface which is very confusing for non programmers I have been told Smile

LDCad is more context and WYSIWYG orientated I'm not yet sure how to tie the scripts to the interface yet though.
Reply
Re: Thoughts on animation scripting language
#20
Roland Melkert Wrote:Is your LDA information online somewhere as I'm very open to suggestions.

No. I'm afraid most of it, like the latest tutorials and examples, were lost when I ended the contract with the ISP who hosted the webpages I stored them at. However, I did store something I called "Animation Start Kit" in a folder, along with what must be the latest version of the executable as recent as April 2011.

Animation Start Kit

If you want to test run the executable, it's a good idea to unpack all content not in a subfolder but directly into your LDraw\Models folder, because that is where LDA will write all its output files, the temporary as well as final ones. And, if you use Dropbox or similar, you need to temporarily pause the updating while LDA "compiles" or it will crash due to file access conflict.

I want to believe that most of the syntax is totally self-explaining. Most lines begin with [object_name].[command] followed by some arguments. From the smpl.txt file, a minifig object namned "Minifig01" is created by the line:

Code:
Minifig01.Load Scene 1  0 0 -10  0 0 1  0 1 0  -1 0 0  mf01.txt
The object Minifig01 is created by loading the file mf01.txt with the object Scene as parent and the LDraw color and matrix applied.

Inside the mf01.txt file, for example the object Minifig01.LeftHand is created on its parent object Minifig01.LeftArm with theis line:
Code:
Self.LeftHand.Create Self.LeftArm 14  5 18 -10  1 0 0  0 0.73 -0.64  0 0.64 0.73  983.dat
where every 'Self' is replaced by the object name from where it is called, in this case 'Minifig01'

Code:
Minifig01.Animation = MFWalk01.txt
tells LDA to apply the animation instructions in MFWalk01.txt on the object Minifig01.

And the walk looks like this:
Five Seconds in Datsville

Please feel free to ask if there is anything you'd like to know about LDA.
/Tore
Reply
Re: Thoughts on animation scripting language
#21
Tore Eriksson Wrote:
Roland Melkert Wrote:Is your LDA information online somewhere as I'm very open to suggestions.

No. I'm afraid most of it, like the latest tutorials and examples, were lost when I ended the contract with the ISP who hosted the webpages I stored them at.

It might be possible to find it in the Wayback Machine (http://archive.org/web/), if you remember the address.
Reply
Re: Thoughts on animation scripting language
#22
Thanks for sharing,

If I understood correctly your animation sequence does interpolation based on start and end angles over subsets of time (similar to the move to action in LD4D).

I think the LUA approach I hinted on in the big example script a few posts above is kinda similar, with one big difference everything can be defined by the user on top of a default set of base objects (e.g. group, matrix and type 1 line -wrappers). This is possible because when you do e.g. a=b, a will inherit all functions and data from b, and you can then create additional functions for a without changing b (standard out of the box LUA). So you could do different things for arms then you would do for legs etc. But all still get the basic API stuff from the group object.

And in the end you use all that to describe the movements based a global timer (like your LDA). But you could also use the custom functions to do e.g. position look-ups (stop animation), or real-time kinetics (no timer, just responses to external actions).

I might be a bit rambling here, because I'm still in the dreaming up stage of it all Smile But again thanks for sharing your thoughts, I'll take a closer look at LDA once I'm ready to start 1.4 for real (I need to fix a couple of bugs in 1.3 first in order to get beta 2 ready).
Reply
Re: Thoughts on animation scripting language
#23
Hi,

there is another face of the problem you have to consider: in most technic models the connections among parts are not so easy to understand so it may be a bit hard to understand wich parts move and wich not if the program itself is not able to recognize at least that.

Furthermore the same parts can move differently depending on the rotation axle or if they are part of quadrilateral structure and so one.
Defining the rotation and scripting of a steering system may be relatively easy, but describing the movement of a deformable quadrilateral structure (or of a Theo Jensen mechanism!) will be really, really hard.

Obviously these considerations are nearly irrilevant for animating a minifig, a simple vehicle or other simple moving structures.

Sergio
Reply
Re: Thoughts on animation scripting language
#24
Yes this is exactly why I want to go the all scripting route. It redirects the problem to the user whom might have way better understanding of the things they want to animate.

I just need to setup a decent environment and api's so they can access all the stuff you would need when hard coding solutions. I know this makes it all a bit user unfriendly but I always targeted LDCad to the more experienced LDraw users anyway.
Reply
Re: Thoughts on animation scripting language
#25
I've been playing around with lua for a couple of weeks now, and managed to set up a decent basic interface with the LDCad internals.

The below lua script is my current test script, everything in it actually works (compile/runtime wise) and I was wondering if it is somewhat 'understandable'. Or do people think it's to lowlevel?

Code:
--Initialization----
function register()

  local myAni=ldc.animation('Test animation 1');
  myAni:setFPS(25);
  myAni:setLength(2); --seconds
  myAni:setEvent('frameChange', 'frameChange');
  myAni:setEvent('play', 'play');

  myAni=ldc.animation('Test animation 2');
  myAni:setFPS(25);
  myAni:setLength(10); --seconds
  myAni:setEvent('frameChange', 'frameChange');
  myAni:setEvent('play', 'play');
end

--ldc.setPrint2Log(true);
--ldc.setPrint2Console(true);
print('apiVersion: ',ldc.getApiVersion());
register();



--Animation functions-----
function play()

  doAltTest=false; --in order to test the matrix class wrapper
  totRotCnt=2; --nr of rotations within the animation length

  --try to bind upto 3 groups
  grp1=ldc.group('Group 1');
  grp2=ldc.group('Group 2');
  grp3=ldc.group('Group 3');

  local ani=ldc.animation.getCurrent();
  print('fps: ', ani:getFPS(), ', frameCnt: ',ani:getFrameCnt());
end

function frameChange()

  local ani=ldc.animation.getCurrent();
  local angle1=ani:getFrameNr()/ani:getFrameCnt()*totRotCnt*360;

  if (grp2:isLinked() and grp3:isLinked()) then

    --full gear rotation test
    local angle2=-0.5*angle1+(360/16/2);
    local angle3=-0.2*angle2+(360/40/2);

    print('frame: ',ani:getFrameNr(),', angle1: ',angle1, ', angle2: ', angle2, ', angle3: ', angle3);

    local ori=ldc.matrix();
    ori:mulRotateAB(angle1, 0, 0, 1);
    grp1:setOri(ori);

    ori:setRotate(angle2, 0, 0, 1);
    grp2:setOri(ori);

    if doAltTest then

      --rel rotation test (excuse to play more with matrix and vector userdata)
      pos=ldc.vector(90, 40, 70);
      mat=ldc.matrix();
      mat:mulTranslateAB(pos);
      mat:mulAB(ori);
      pos:scale(-1);
      mat:mulTranslateAB(pos);
      grp3:setPosOri(mat);
    else
      ori:setRotate(angle3, 0, 0, 1);
      grp3:setOri(ori);
    end

  else

    --single rotating group test
    local ori=ldc.matrix();
    ori:mulRotateAB(angle1, 1, 0, 0);
    grp1:setOri(ori);

  end

end

I'm also thinking to add a matrixstack object, so you could use that similar to the OpenGL intermediate mode.

Anyhow if anyone has additional suggestions for api functions/functionality I'm open to suggestions.
Reply
Re: Thoughts on animation scripting language
#26
Not knowing anything about lua, I think it's quite clear, but I generally like this kind of low-level control.

As for suggestions, it's difficult without having something to play with. Have you planned access/interaction with path data? I mean not only changing control points, etc., but for example measuring path length or setting a position/orientation along a path. Any helping functions you can add for things like the mechanism in the first of these models would be welcome too (ball joints, fixed lengths, sliding axles).
Reply
Re: Thoughts on animation scripting language
#27
Quote:Have you planned access/interaction with path data? I mean not only changing control points, etc., but for example measuring path length or setting a position/orientation along a path.

I'm not sure changing the dynamic parts through script will be in the first version, as it needs some changes to the way they are regenerated at the moment. But they will be scriptable in the long run. Or do you mean a spline like function for plotting e.g. the route of a minifig? If so there are probably already lua libraries for that. I've set up the ldc.matrix object so it also excepts 12 numbers (ldraw style matrix), that way you can link it to any third party lua library doing (more complicated) matrix/quat/etc math.


Quote:Any helping functions you can add for things like the mechanism in the first of these models would be welcome too (ball joints, fixed lengths, sliding axles).

At the moment I'm working with the idea to keep the C++ callback api very basic, so a special lua object for common objects (matrix, group, ldraw ref line, etc). On top of that you could build pure lua libraries which might 'hide' the internal matrix stuff and let people work with just angles / predefined functionality (e.g. steering rack) etc.

That said I do plan to add special (joint) info to groups which would expose e.g. the rotation vector for a gear/minfig arm to the scripting side so you don't have to know the exact placement of stuff to rotate a minifig arm. The additional group info would also allow for interaction with those 'joints', the script could then handle realtime dependency calculations.


Thanks for the input
Reply
Re: Thoughts on animation scripting language
#28
I also hope there will be compatibility between the scripting language and POV-Ray through the use of an exporter or converter. Not sure what extra work that will entail. POV-Ray script is a bit weird about some things (no true functions, no object model...).
Reply
Re: Thoughts on animation scripting language
#29
At the moment I'm not taking POV-Ray into account at all.

But I'm planning to add an POV-Ray export option add some point (based on the one from LD4DStudio), probably in version 1.5.
Reply
Some progress (was re: Thoughts on ani...)
#30
Hi all,

I've been playing around with the scripting functionality this weekend after having taken a break for some time.

So I wanted to show the progress as I'm still open to suggestions on the api / core functions available to to end user.

Short clip of a test animation

This animation uses the new direct LDraw ref line access. This makes it possible to do some mass mutating fun stuff e.g. effecting every brick in a model.

The lua source code for this information is shown at the end of the clip (has clearer highlighting), but I'll give it here too:

Code:
function limit(v, min, max)

  if v<min then
    v=min
  end
  
  if v>max then
    v=max
  end
    
  return v;
end

function register()

  --global defs
  rcktTime=0;  --timespan (seconds) for rocket to get to target
  exTime=3;    --timespan for explosion (seconds)
  totTime=rcktTime+exTime;
  exSpeed=250;
  grav=250;
  
  --create/link animation obj
  local myAni=ldc.animation('Weapons test');
  myAni:setLength(totTime); --seconds
  myAni:setFPS(25); --low fps for screencap
  myAni:setEvent('play', 'preCalcDeps');
  myAni:setEvent('frameChange', 'calcFrame');
end

function preCalcDeps()

  --Link submodels and their main refs
  local sfMain=ldc.subfile();
  local refShack=sfMain:getRef('shack.ldr');
  sfShack=refShack:getSubfile();
  local refDude=sfMain:getRef('dude.ldr');
  local sfDude=refDude:getSubfile();
  local refWeapon=sfDude:getRef('rocketLauncher.ldr');
  
  --Link needed groups
  grpRocket=ldc.group('rocket');  
  local grpTarget=ldc.group('Group 1'); --helper grp so user can drag target around

  --get floor from first tree ref
  floor=sfMain:getRef('3470.dat'):getPos():getY();

  --target
  local impCen=ldc.vector(grpTarget:getPos());
  grpTarget:setVisible(false); --hide helper part(s)
  
  --point dude to target
  -- todo
  local ori=ldc.matrix();
  local angle=45;
  ori:setRotate(angle, 0, -1, 0);
  refDude:setOri(ori);
  
  --Prep the pos and direction vectors for all refs in the shack model
  refPos={}
  refDir={}
  refCnt=sfShack:getRefCount();
  for i=1, refCnt do
    refPos[i]=ldc.vector(sfShack:getRef(i):getPos());
    local tmp=ldc.vector(refPos[i]);
    tmp:sub(impCen);
    tmp:normalize();
    refDir[i]=ldc.vector(tmp);
  end  
end

function calcFrame()

  local curAni=ldc.animation.getCurrent();

  local curTime=curAni:getFrameNr()/curAni:getFrameCnt()*totTime;
  if curTime<rcktTime then
    --Rocket animation
  else
    --explode the shack
    for i=1, refCnt do
      local dx, dy, dz=refDir[i]:get();
      local x, y, z=refPos[i]:get();
      
      x=x + curTime*exSpeed*dx;
      y=y + curTime*exSpeed*dy + 0.5*grav*curTime*curTime;;
      z=z + curTime*exSpeed*dz;
      
      --x=limit(x, -500, 500);
      y=limit(y, -10000, floor);
      --z=limit(z, -500, 500);

      local ref=sfShack:getRef(i);
      ref:setPos(x, y, z);
    end
  end
end

register();
Reply
Re: Some progress (was re: Thoughts on ani...)
#31
Can the animations be exported to POV-Ray? What are your plans in this regard?
Reply
Re: Some progress (was re: Thoughts on ani...)
#32
The upcoming version will probably only have OpenGL export (to bmp's) in the final version.

But I do plan to add Povray export at some point (probably version 1.5). This because I want to establish the basics first, so I won't have to write/adjust the export code multiple times.
Reply
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
Preview of LDCad 1.4 animation scripting api (was re: Thoughts on ani...)
#34
Hi all,

I just finished the API for the upcoming 1.4 version of my LDCad based on the stuff discussed in this thread.

During testing I wrote a basic reference page for the scripting functions and objects (technically lua tables).

I decided to put it online ahead of the actual 1.4 version in the hopes somebody might notice something weird or has additional feedback which I then still could apply to 1.4 beta 1.

The page is at www.melkert.net/LDCad/docs/scriptAPI

I also wrote an (even shorter more basic) page show casing some bare minimum examples, namely:

The page is at www.melkert.net/LDCad/docs/scriptExamples

Any feedback (and or spelling/grammar corrections) are welcome.
Reply
Re: Preview of LDCad 1.4 animation scripting api (was re: Thoughts on ani...)
#35
I just had a quick look at the lua language documentation.
As I am not familar with java or c language it would help a lot to have a sample line for each function/method. Also some results of functions are unclear to me. For example:
Code:
get
Get returns x,y and z in one go.
This function has no additional parameters.
How is the notation of functions that returns something?
In this special case: what is returned? - a string - a vector??

Maybe i am stupid. Hopefully these are good questions Smile
Reply
Re: Preview of LDCad 1.4 animation scripting api (was re: Thoughts on ani...)
#36
The lua reference documentation isn't the best of it's kind imho (nor is mine probably Smile ), so I totally understand things can be a bit confusing.

A fun thing in lua is functions can return multiple values, I make use of that in the mentioned get function so you can fetch the vector object's internal variables in one statement like so:

Code:
local x, y, z=myVec:get()

You can then use the three normal number variables to do some manual (vector) math.

Hope that makes sense, I'll try to add some statement examples to the more off beat functions.

Thanks for the suggestion.
Reply
Re: Preview of LDCad 1.4 animation scripting api (was re: Thoughts on ani...)
#37
Ok, that function makes great sense!

But I think you can imagine that my main concern is the description and help for each function I hope.

The old school description and help files of visual basic I liked a lot. Today you often only get samples, but in most cases there is plenty of room for misunderstanding the underlying logic.
Reply
« Next Oldest | Next Newest »



Forum Jump:


Users browsing this thread: 3 Guest(s)