Page 1 of 1

Animation Scripting

Posted: 26 Nov 2012, 07:34
by emilio_l_cruz
Hello. Newb alert… again.

After figuring out that Spring does not support bones animation per se, I am now trying to wrap my head around scripting the animations.

In fact, I have built up a library of bones-based animations over the years that I really want to use for my pet project in Spring. I can convert these animations to plain numeric values using the SMD (i.e., Half-Life) format as below:

<ID> <PosX> <PosY> <PosZ> <RotX> <RotY> <RotZ>

Where

<ID> is the bone
<PosX> <PosY> and <PosZ> are the X Y Z coordinates / position in world units
<RotX> <RotY> and <RotZ> are local Euler rotations in radians

Ofcourse, for a complete animation sequence involving several bones and key frames, there will be hundreds (if not thousands) of lines. I know THAT … and that is really not a problem as I have some helper programs / tools to “parse” the code. What I am not sure is the approach to take.

So finally, here are my questions

Question 1 – I am thinking that I can use the SMD information to hard-code / script the animation. Is this right?

Question 2 – Assuming, the answer above is yes and bearing in mind the hierarchical structure of .s3o files, do I still need to bother / script the <PosX> <PosY> and <PosZ> coordinates in the script or do I just mess with the rotations? I am guessing that unless there is something funky meant to happen to the model animation (e.g., it gets cut into several pieces), I only ever need to bother with <PosX> <PosY> and <PosZ> in Upspring during the model setup with the lua script being only concerned with the rotations <RotX> <RotY> and <RotZ>. Is this right?

Question 3 – Can anyone be kind enough to show me some sample code to convert the SMD information (<PosX> <PosY> <PosZ> <RotX> <RotY> <RotZ>) to lua script?

Thanks a lot in advance and more power!

Re: Animation Scripting

Posted: 26 Nov 2012, 08:18
by PicassoCT
1) Thats correct, grisha!

2) True.

3) you got the rotation x,y, z
So it converts to

Turn(Piecename, axis, math.rad(x), speedForThisMovement)

Thats the actuall problem, you need to synchronize movements, therefore you need the speed too. Precise Speed, so it runs smoth.

Next thing is animations that are aborted midways. So you do start the next step with the leg behind, meaning it will take longer for the leg to go forward, so just WaitForTurn is not enough.

Re: Animation Scripting

Posted: 26 Nov 2012, 08:49
by emilio_l_cruz
That was fast. Thanks PicassoCT.

Just to cement my understanding, my basic coding for each bone and sequence should therefore look something like this:

Turn(<ID>,x_axis, math.rad(<RotX>), speedForThisMovement)
Turn(<ID>,y_axis, math.rad(<RotY>), speedForThisMovement)
Turn(<ID>,z_axis, math.rad(<RotZ>), speedForThisMovement)

Where <ID> becomes the .s3o piece name instead of bone.

Thanks a lot

Re: Animation Scripting

Posted: 26 Nov 2012, 10:11
by PicassoCT
yes, but you have to calculate the speed depending on the time you want the animation to end, and where the piece is currently.

Also some animations are not linear when it comes to speed.

So you need to break it down into steps.
fast movement- slower movement- slow approach to target

Re: Animation Scripting

Posted: 26 Nov 2012, 12:38
by Beherith
Kinda useful thing here:

I see that you dont have any movement speeds, just the positions of the pieces at the keyframes. This is not an issue. I wrote a script that calculates the speeds based on the last known position of the piece.
http://imolarpg.dyndns.org/trac/balates ... othanim.py

What does this do and how to use it? Just input your keyframes with NOW instead of speeds into the .bos file. Run the script and it will replace the NOW tags with the ideal speeds.

Input:

Code: Select all

	        if( bMoving )
20	        {
21	                move pelvis to y-axis [-0.500000] now;
22	                move lcannon to y-axis [0.000000] now;
23	                move lcannon to z-axis [0.000000] now;
24	                move rcannon to y-axis [0.000000] now;
25	                move rcannon to z-axis [0.000000] now;
26	                move locase to y-axis [0.000000] now;
27	                move rfirept to y-axis [-0.300000] now;
28	                move rfirept to z-axis [0.209998] now;
29	                move lfirept to y-axis [-0.300000] now;
30	                move lfirept to z-axis [0.209998] now;
31	                turn lthigh to x-axis <-62.934066> now;
32	                turn rthigh to x-axis <3.505495> now;
33	                turn torso to z-axis <-4.560440> now;
34	                turn rleg to x-axis <82.978022> now;
35	                turn rfoot to x-axis <-36.901099> now;
36	                turn lleg to x-axis <57.302198> now;
37	                turn lfoot to x-axis <5.258242> now;
38	                sleep 7000 / currentSpeed;
39	        } 
Output:

Code: Select all

19	        if( bMoving )
20	        {
21	                move pelvis to y-axis [-0.500000] speed [4.267241] *  currentSpeed / 100;
22	                move lcannon to y-axis [0.000000] now;
23	                move lcannon to z-axis [0.000000] now;
24	                move rcannon to y-axis [0.000000] now;
25	                move rcannon to z-axis [0.000000] now;
26	                move locase to y-axis [0.000000] now;
27	                move rfirept to y-axis [-0.300000] speed [2.560345] *  currentSpeed / 100;
28	                move rfirept to z-axis [0.209998] speed [1.792224] *  currentSpeed / 100;
29	                move lfirept to y-axis [-0.300000] speed [2.560345] *  currentSpeed / 100;
30	                move lfirept to z-axis [0.209998] speed [1.792224] *  currentSpeed / 100;
31	                turn lthigh to x-axis <-62.934066> speed <537.109701> *  currentSpeed / 100;
32	                turn rthigh to x-axis <3.505495> speed <29.917587> *  currentSpeed / 100;
33	                turn torso to z-axis <-4.560440> speed <38.920997> *  currentSpeed / 100;
34	                turn rleg to x-axis <82.978022> speed <708.174498> *  currentSpeed / 100;
35	                turn rfoot to x-axis <-36.901099> speed <314.931793> *  currentSpeed / 100;
36	                turn lleg to x-axis <57.302198> speed <489.044621> *  currentSpeed / 100;
37	                turn lfoot to x-axis <5.258242> speed <44.876376> *  currentSpeed / 100;
38	                sleep 7000 / currentSpeed;
39	        } 
Edit: Im gonna get yelled at for using BOS instead of Lua scripts, right?

Re: Animation Scripting

Posted: 26 Nov 2012, 12:43
by PicassoCT
The Tardition demands it. Yells Bells! Everyone hate him for beeing faster

Would be cool if there was a callin for keyframes - basically till time x- get these movements handed over done..

Re: Animation Scripting

Posted: 26 Nov 2012, 13:13
by knorke
I only ever need to bother with <PosX> <PosY> and <PosZ> in Upspring during the model setup with the lua script being only concerned with the rotations <RotX> <RotY> and <RotZ>. Is this right?
depends on the model?
wall-e has linear pistons for stretching his arms:
Image

For a human in theory all the joints can only rotate but in praxis there will probally still be some linear movements. example:
Image
I tried BVH animations and they resulted in some linear movements, too.
http://springrts.com/phpbb/viewtopic.php?f=14&t=28790
(didnt work out 100% because i did not have the original model and mine was maybe a bit off)

Btw yes, the generated scripts were thousands of lines of Turn & Move commands, imo only useable for testing.
Most of the existing scripts use this style but imo it is a bit stupid and mostly done because with bos not much else was possible. (no arrays etc)
For real use better save it in some datafile and the script reads the steps or something.
Edit: Im gonna get yelled at for using BOS instead of Lua scripts, right?
srsly :/

Re: Animation Scripting

Posted: 26 Nov 2012, 17:41
by FLOZi
Protip: Don't turn a piece in multiple axes at once

Re: Animation Scripting

Posted: 26 Nov 2012, 19:08
by zwzsg
FLOZi wrote:Protip: Don't turn a piece in multiple axes at once
It's certainly possible, the trouble is, the rotation will never be in the order you wanted them to be. And two programs, let's say Spring and UpSpring, will likely use different order.

Re: Animation Scripting

Posted: 28 Nov 2012, 01:42
by emilio_l_cruz
Thanks all for the inputs.
knorke wrote:For a human in theory all the joints can only rotate but in praxis there will probally still be some linear movements.
knorke, you are right.

I do need translation movements like when the infantry dies or otherwise go prone flat to the ground. The base piece of the model in either example will have to be translated in XYZ coordinates.

So my lua coding should be like the following:

Move(<ID>, x_axis, <PosX>, speedForThisMovement)
Move(<ID>, y_axis, <PosY>, speedForThisMovement)
Move(<ID>, z_axis, <PosZ>, speedForThisMovement)
Turn(<ID>, x_axis, math.rad(<RotX>), speedForThisMovement)
Turn(<ID>, y_axis, math.rad(<RotY>), speedForThisMovement)
Turn(<ID>, z_axis, math.rad(<RotZ>), speedForThisMovement)

I do not need the math.rad function for the <PosX> <PosY> and <PosZ> coordinates as these are translation movements and not rotations? Is this right?

Again, thanks alot!