Character animation in Babylon.js

blender

#1

I’m new in this world so don’t judge strictly. I have implemented skinning in blender for my character added bones following this tutorial rigging and now i want to animate it purely in babylon.js (walk, idle, run ). There are a lot of tutorials about how to animate character in blender and then export it into babylon.js but i need it to be purely animated (coded) in babylon.js. I searched a lot these days and didn’t find any tutorial about this. Anyone can help? Thanks in Advance.


#2

What you’re asking is extremely difficult to do unfortunately. Skeletal animation has a lot of nuances that you will have a very hard time replicating using only code, which is why 3d package’s exist in the first place. Whatever you are trying to do it is guaranteed to be easier to do with a Blender to Babylon workflow.

Babylonjs has the ability to do simple animations with static meshes, and I’m pretty sure bone rotation for procedural animations, but the latter would absolutely be better off with some kind of base animation to work with from Blender.

What is it exactly you’re trying to do?


#3

Hello guys, I am pretty new in 3D but I have implemented procedural animations that are quite good enough for me. I dont know how “fine” animations author wants to achieve but something basic that looks “good” until you come too close is simple with pure procedural programming.

Look at here Babylon

There you can see character (poceduraly generated) that can walk around (use right mouse button) and he can also attack (button on top left side of screen). It might look kinda primitive so far, but all that animations are written on like 15 lines of code.

I can describe principles that I have used if you´d be interested.

No 3d program used, everything just procedural (except for textures).


#4

Thank you for your reply Milan. That’s actually what i need. Well the movement not so natural but it’s good to start. Can you explain how did you do that? Source code in addition would be great also.


#5

Thank you for your reply Justin. I agree that it’s going to be easier to make animation in Blender, but i want to learn how to do it by myself with code first, even if the movement will be not so smooth and real as it would be in Blender or any other 3d software. That’s what i exactly try to do - to learn how to do it.


#6
>     {"name":"Bone.004","index":3,"matrix":[0.996,-0.0155,0.0882,0,0.0505,0.9107,-0.41,0,-0.074,0.4128,0.9078,0,0,0.07,0,1],"rest":[0.996,-0.0155,0.0882,0,0.0505,0.9107,-0.41,0,-0.074,0.4128,0.9078,0,0,0.07,0,1],"parentBoneIndex":2,"length":0.0417
>     ,"animation":{"dataType":3,"framePerSecond":24,"keys":[
>     {"frame":1,"values":[0.996,-0.0155,0.0882,0,0.0505,0.9107,-0.41,0,-0.074,0.4128,0.9078,0,0,0.07,0,1]},
>     {"frame":14,"values":[0.9944,0.076,0.0727,0,-0.0405,0.9145,-0.4026,0,-0.0971,0.3974,0.9125,0,0,0.07,0,1]},
>     {"frame":15,"values":[0.9405,0.3382,0.0329,0,-0.3024,0.8772,-0.373,0,-0.155,0.3409,0.9272,0,0,0.07,0,1]},
>     {"frame":16,"values":[0.7645,0.6447,-0.0037,0,-0.6118,0.7236,-0.3195,0,-0.2033,0.2465,0.9476,0,0,0.07,0,1]},
>     {"frame":17,"values":[0.5638,0.8258,-0.0168,0,-0.7974,0.5389,-0.2716,0,-0.2152,0.1665,0.9623,0,0,0.07,0,1]},
>     {"frame":18,"values":[0.4848,0.8745,-0.0181,0,-0.848,0.4648,-0.2545,0,-0.2141,0.1387,0.9669,0,0,0.07,0,1]},
>     {"frame":38,"values":[0.4949,0.8688,-0.018,0,-0.8421,0.4744,-0.2566,0,-0.2144,0.1422,0.9663,0,0,0.07,0,1]},
>     {"frame":39,"values":[0.5254,0.8507,-0.0176,0,-0.8232,0.503,-0.2632,0,-0.215,0.1528,0.9646,0,0,0.07,0,1]},
>     {"frame":40,"values":[0.5752,0.8179,-0.0164,0,-0.7892,0.5495,-0.2741,0,-0.2152,0.1706,0.9616,0,0,0.07,0,1]},
>     {"frame":41,"values":[0.641,0.7674,-0.0137,0,-0.7372,0.6106,-0.2891,0,-0.2135,0.1954,0.9572,0,0,0.07,0,1]},
>     {"frame":42,"values":[0.7172,0.6968,-0.0084,0,-0.665,0.6807,-0.3075,0,-0.2085,0.2261,0.9515,0,0,0.07,0,1]},
>     {"frame":43,"values":[0.7954,0.6061,0.0001,0,-0.5726,0.7515,-0.3277,0,-0.1987,0.2606,0.9448,0,0,0.07,0,1]},
>     {"frame":44,"values":[0.8664,0.4991,0.012,0,-0.4643,0.8144,-0.348,0,-0.1835,0.2959,0.9374,0,0,0.07,0,1]},
>     {"frame":45,"values":[0.9229,0.3841,0.0266,0,-0.3485,0.8627,-0.3665,0,-0.1637,0.3289,0.93,0,0,0.07,0,1]},
>     {"frame":46,"values":[0.9615,0.2715,0.0424,0,-0.2356,0.8937,-0.3818,0,-0.1415,0.3571,0.9233,0,0,0.07,0,1]},
>     {"frame":47,"values":[0.9836,0.171,0.0575,0,-0.1351,0.9094,-0.3933,0,-0.1196,0.3791,0.9176,0,0,0.07,0,1]},
>     {"frame":48,"values":[0.9935,0.0896,0.0705,0,-0.054,0.9143,-0.4014,0,-0.1004,0.3949,0.9132,0,0,0.07,0,1]},
>     {"frame":49,"values":[0.9963,0.0309,0.0803,0,0.0044,0.9137,-0.4064,0,-0.0859,0.4053,0.9102,0,0,0.07,0,1]},
>     {"frame":50,"values":[0.9963,-0.004,0.0862,0,0.0391,0.9116,-0.4091,0,-0.0769,0.411,0.9084,0,0,0.07,0,1]},
>     {"frame":51,"values":[0.996,-0.0155,0.0882,0,0.0505,0.9107,-0.41,0,-0.074,0.4128,0.9078,0,0,0.07,0,1]}],"loopBehavior":1,"name":"anim","property":"_matrix"}},

Hi Alissa this is the raw code from blender animation… its one bone of maybe 18 and its just a hand making a fist…
So its absolutely doable… but its a question of time resources etx imho


#7

Hello I will try to describe basic principle of what I am doing to animate my objects.

1. Create “connected” meshes

I have created “wrapper” around mesh that can be connected to each other - upper leg is connected to body, lower leg is connected to upper leg and foot is connected to lower leg (similar for arms).

My “engine” supports 6 sides - thus I can connect leg to the “bottom side of body” and head to the “upper side of body”, arms to the left and right (also more than one child can be attached to one side of parent).

That wrapper objects contains info about their children (what is connected to them and on which side)

2. Update object positions

Then I have written function that is keeping meshes connected to each other depending on their parent/child relationship.

Example: I rotate upper leg forward -> its bottom side is moved -> lower leg is automatically moved accordingly to stay connected to upper leg

In these 2 steps I created model, that “holds together” no matter how I rotate each of body parts - but it is not animated yet.

3. Animation

Basic philosophy of my animations is similar to what would I do in 3D program. I just need to specify rotations for all the meshes in some “keyframes” and then extrapolate its curent position each frame.

My animation objects consist of “steps” - each step represents one “keyframe” (body part rotations). Each step has also specified time (how long will it take to reach specified coordinates).

Animation object then run step by step (once or in loop) and it calculates rotation of body parts accordingly to elapsed time and final predefined positon while my model is keeping all parts connected (as described in point 1 and 2).

How is attack animation defined ? It is pretty simple, look at following code - there are just two steps and thats it (preparation and slash itself).

As you can see, I dont use any mesh deformations, just rotations, thats why it is only useful for “zoomed out view” but for smaller things it works and it take just several minutes to create another animation like that.

var anim = new Animation(this);
var step = new AnimationStep(anim, 225);

// Sword arm prepare
step.addVector(this.body, new BABYLON.Vector3(0, -0.4, 0));
step.addVector(this.arm2, new BABYLON.Vector3(1.5, -0.4, 1.5));
step.addVector(this.hand2, new BABYLON.Vector3(2.5, -1, 2.5));

// Shield arm defensive stance
step.addVector(this.arm1, new BABYLON.Vector3(0, 0.8, -1.2));
step.addVector(this.hand1, new BABYLON.Vector3(1.2, 0.8, -1.2));

// Slash
step = new AnimationStep(anim, 200);
step.addVector(this.arm2, new BABYLON.Vector3(-0.8, -0.5, 0.8));
step.addVector(this.hand2, new BABYLON.Vector3(-0.8, -0.5, 0.8));

step.addVector(this.body, new BABYLON.Vector3(-0.05, 0.4, 0));
step.addVectorMulti([ this.uleg2 ], new BABYLON.Vector3(0.3, 0, -0.2));
step.addVectorMulti([ this.uleg1 ], new BABYLON.Vector3(-0.2, 0, 0.2));

At the end of the day I am pretty lame and only for 2 weeks in Babylon.js so take this as an advice from absolute novice noob. Maybe I am doing that all wrong, but it works for my needs so far.


#8

I think its interesting… i too used babylonjs internal system to swing a sword…
just learned quaternion, and inserted 3 keyframes
start " end" start
but doing it in blender is so much more control of the rotation…
So as long as you dont have tons of bones to animate go for it…


#9

Oh, I see! Well if your goal is simply to learn to do it that way then I suppose that’s perfectly fine! I’m glad there are people here with experience doing it that way.

I agree with droggam that it’s impractical to do for complex animations, but I’m sure you will learn a lot coding it!

Good luck and I look forward to seeing more from you!


#10

For example: i have a 3d character and it has like 42 bones (head, neck, collars (right, left) etc) how can i have an access to those bones? How to do this? Any example on that would be great. Thank you.


#11

You might look into IK bone controllers. I had a topic from the old site.

One PG from there does not work in 4.0, so you must run it from the stable BJS.

If you wish to move the character at the same time, it is simply going to look bad, unless you do it through the translation of the root bone, not position of the mesh.


#12

Thank you for your reply. I’ll go through it and see what happens. Thank you again.


#13

Thank you. I will need luck :slight_smile:


#14

Hi Erk. I didn’t follow the code but thank you. I will take a look.


#15

Hi again Milan. May i ask you to provide full source of your code? With the object and so on if it’s not a secret project :slightly_smiling_face:. It would help to understand more deeply the concept. Thank you in advance.


#16

Hi again JCPalmer. I have some issues with IK-controllers use. They work simply fine in blender but in babylon they don’t have any effect. What could be the problem? Also i couldn’t load my own model in your code. your code .


#17

You should look at the IK docs for implementing IK in BJS. My code, as you call it, is for exporting as JS not a .babylon /JSON file.

I have made the PG work for BJS 4.0. (aside, anyone know where BoneAxesViewer is if not in BABYLON.Debug?)

You should just rip out the 2 library loads & probably just put the runWhenReady part in the Append or importMesh callback.

For IK in Blender, this is not directly exportable. You need to append your poses to an action. Probably not every frame, since Blender will interpolate. When exported, the resulting interpolation will generate every frame. I do not know a lot about doing that as I have my own animation system.

One thing the exporter does allow the IK bones is to be ignored, to conserve resources for mobile. They have no use in BJS. Just name them with a .ik in bone name, & select the Ignore IK bones, on the World tab for Blender 2.80, scene tab for 2.79. I will not longer post images for 2.79