Jump to content

Blender Exporter with Multiple Actions


port9001
 Share

Recommended Posts

Hello all. I need some help figuring out why my animations won't play. I am a JavaScript developer delving into the world of Blender so I'm sure I'm missing something obvious. 

Versions:

  • Blender 2.79
  • BabylonJS Blender Exporter 5.5.0
  • BabylonJS 3.2.0-alpha4

First off I have created a simple mesh in Blender with an Armature. I attached the Armature, weight painted it, and use Pose Mode + the Action Editor to create an Action. This part worked fine, beyond the pains of learning a new skill.

My mesh has 3 total Actions that I can see:

  • Action (which I did not create, it was there by default and I don't know how to remove it)
  • character-walk (my final walk action)
  • character-walkblock (a blockier version of the walk animation that I left for the purposes of testing use of multiple actions in BabylonJS)

yGEbLlx.png

 

The walk and walkblock animations both play and render fine in Blender. The Action has no frames so does nothing. I'm not sure if Action is significant or not but I'm at a loss of how to remove it. I used the BabylonJS Exporter to create a .babylon file of my scene. Here is the log output:

Exporter version: 5.5.0, Blender version: 2.79 (sub 0)
========= Conversion from Blender to Babylon.js =========
	Scene settings used:
		selected layers only:  false
		flat shading entire scene:  false
		inline textures:  false
		texture directory:  C:\source\omnispace\assets\babylon\
	Python World class constructor completed
	processing begun of skeleton:  Armature, id:  0
		processing begun of bone:  Body, index:  0
		processing begun of bone:  Torso, index:  1
		processing begun of bone:  Head, index:  2
		processing begun of bone:  Arm_L, index:  3
		processing begun of bone:  Forearm_L, index:  4
		processing begun of bone:  Hand_L, index:  5
		processing begun of bone:  Arm_R, index:  6
		processing begun of bone:  Forearm_R, index:  7
		processing begun of bone:  Hand_R, index:  8
		processing begun of bone:  Leg_L, index:  9
		processing begun of bone:  Foot_L, index:  10
		processing begun of bone:  Leg_R, index:  11
		processing begun of bone:  Foot_R, index:  12
		processing action Action:  in[0 - 1], out[0 - 1]
	processing begun of mesh:  character
		animation processing begun
			WARNING: action Action has no frames, ignored.
			processing action walk:  in[1 - 33], out[0 - 33]
			processing action walkblock:  in[1 - 33], out[40 - 73]
		processing begun of Standard material:  Material
		num positions      :  82
		num normals        :  82
		num uvs            :  0
		num uvs2           :  0
		num colors         :  328
		num indices        :  444
		Skeleton stats:  
			Total Influencers:  286
			Avg # of influencers per vertex:  3.4878
			Highest # of influencers observed:  8, num vertices with this:  1
			exported as 8 influencers
			num skeletonWeights and skeletonIndices:  656
	processing begun of camera (UniversalCamera):  Camera
	processing begun of light (POINT):  Lamp
========= Writing of scene file started =========
========= Writing of scene file completed =========
========= end of processing =========
elapsed time:  0 min, 0.1393 secs

Which looks fine, beyond the warning about Action not having frames. Finally I import the mesh in my project. Here's the code for how I do that:

scene.executeWhenReady(function () {
	let loadedMeshes, loadedSkeletons;

	return new Promise(resolve => {
		BABYLON.SceneLoader.ImportMesh("", "dist/babylon/", "character.babylon", scene, (meshes, particleSystems, skeletons) => {
			loadedMeshes = meshes;
			loadedSkeletons = skeletons;
			// None of these work (note I tried each of them by itself, not all at once)
			// scene.beginAnimation(meshes[0], 1, 20, true, 0.5);
			// scene.beginAnimation(meshes[0].skeleton, 1, 20, true, 0.5);
			// scene.beginAnimation(skeletons[0], 1, 20, true, 0.5);
			// skeletons[0].beginAnimation("Action", true, 0.5);
			// skeletons[0].beginAnimation("walk", true);
			// skeletons[0].beginAnimation("character-walk", true);
			resolve();
		});
	})
		.then(() => {
			const light = new BABYLON.HemisphericLight("ambient", new BABYLON.Vector3(0, 1, 0), scene);
			light.specular = new BABYLON.Color3(0, 0, 0); // Turn off reflections from this light

			const unitsAway = 30;
			camera = new BABYLON.FollowCamera("camera", new BABYLON.Vector3(unitsAway, unitsAway, -unitsAway), scene);
			camera.mode = BABYLON.Camera.ORTHOGRAPHIC_CAMERA;

			// Here we make height 1/2 of width, a typical isometric style
			camera.orthoTop = unitsAway / 2;
			camera.orthoBottom = -unitsAway / 2;
			camera.orthoLeft = -unitsAway;
			camera.orthoRight = unitsAway;

			// target the camera to scene origin
			camera.setTarget(BABYLON.Vector3.Zero());

			// attach the camera to the canvas
			camera.attachControl(this.canvas, false);

			engine.runRenderLoop(function () { // Register a render loop to repeatedly render the scene
				scene.render();
			});
		})
		.then(() => {
			// They don't work here either (note I tried each of them by itself, not all at once)
			// scene.beginAnimation(loadedMeshes[0], 1, 20, true, 0.5);
			// scene.beginAnimation(loadedMeshes[0].skeleton, 1, 20, true, 0.5);
			// scene.beginAnimation(loadedSkeletons[0], 1, 20, true, 0.5);
			// loadedSkeletons[0].beginAnimation("Action", true, 0.5);
			// loadedSkeletons[0].beginAnimation("walk", true);
			// loadedSkeletons[0].beginAnimation("character-walk", true);
		});
});

The mesh loads and there are no errors. But none of the animation statements cause it to use any of the actions.

There are some interesting things I noted in the .babylon file JSON:

PeRQ9YI.png

Link to comment
Share on other sites

First, to delete an action, change to it in action editor, then click the'F' toggle button & 'X' button.  When saved & reloaded should be gone.  There are no frames, so it being ignored as you noted.

I am not in expert in the action editor (I use pose libraries for my own animation system), but the area in the log file showing animation processing is in the wrong place.  It should be with the armature not the mesh.  In your screen shot, You have the "Character" mesh set as active object.  Change to / click "Armature".  You will probably have not current action assigned.  Assign one.

As far as getting the animations from being assigned to the mesh, hit the 'F' toggle button & 'X' button to all of them. 

If this goes not work, get someone to look at your '.blend'.

Your javascript looks tortured.  You have a promise inside a executeWhenReady.  Nuke the promise.  This way more complicated than it needs to be.  Something like the pseudo code below is all that is required. Get stuff working before getting tricky.

var scene = engine.create();
// add lights & camera
// import mesh, callbacks not need here

scene.executeWhenReady(function() {
     mesh = scene.getMeshByName("Character");
     // set mesh as target for camera
     mesh.skeleton.startAnimationRange("walk");
});

 

Link to comment
Share on other sites

@JCPalmer I appreciate the help! I apologize for the Promises. I've been working with them for years now and they come pretty naturally to me. The code is cleaner without them though so thanks for the tip.

I was able to remove the default 'Action' using the NLA Editor (a feature I'm not familiar with but Google recommended). It's gone finally. I'm not sure that matters much but it clears up that aspect of this problem. I then cleared the actions from the mesh. Finally I selected the Amature and set it's action (right click > Set Action) to "character-walk". Here is my new log output 

Exporter version: 5.5.0, Blender version: 2.79 (sub 0)
========= Conversion from Blender to Babylon.js =========
	Scene settings used:
		selected layers only:  false
		flat shading entire scene:  false
		inline textures:  false
		texture directory:  C:\source\omnispace\assets\babylon\
	Python World class constructor completed
	processing begun of skeleton:  Armature, id:  0
		processing begun of bone:  Body, index:  0
		processing begun of bone:  Torso, index:  1
		processing begun of bone:  Head, index:  2
		processing begun of bone:  Arm_L, index:  3
		processing begun of bone:  Forearm_L, index:  4
		processing begun of bone:  Hand_L, index:  5
		processing begun of bone:  Arm_R, index:  6
		processing begun of bone:  Forearm_R, index:  7
		processing begun of bone:  Hand_R, index:  8
		processing begun of bone:  Leg_L, index:  9
		processing begun of bone:  Foot_L, index:  10
		processing begun of bone:  Leg_R, index:  11
		processing begun of bone:  Foot_R, index:  12
	processing begun of mesh:  character
		processing begun of Standard material:  Material
		num positions      :  82
		num normals        :  82
		num uvs            :  0
		num uvs2           :  0
		num colors         :  328
		num indices        :  444
		Skeleton stats:  
			Total Influencers:  286
			Avg # of influencers per vertex:  3.4878
			Highest # of influencers observed:  8, num vertices with this:  1
			exported as 8 influencers
			num skeletonWeights and skeletonIndices:  656
	processing begun of camera (UniversalCamera):  Camera
	processing begun of light (POINT):  Lamp
========= Writing of scene file started =========
========= Writing of scene file completed =========
========= end of processing =========
elapsed time:  0 min, 0.0671 secs

 

As you can see the blank Action is now gone. Unfortunately so is all of the animation processing. And the animations array is now empty and there's no ranges in the JSON. It seems the animations are not linked to the Armature although they seem to be in Blender?PIoyA1o.png

Link to comment
Share on other sites

Yeah, understood. I've attached the .blend file I'm working with.

I spent some time trying various ways of adding and setting animations to the armature. Nothing I tried got picked up by the exporter. The only time I've seen it process animations is when the animations were attached to the mesh itself (as in first post). I'm probably just not attaching/adding/assigning the actions correctly? 

dude5_anim2.blend

Link to comment
Share on other sites

@mecanicus Hey thanks for the link! This gave me a clue as to why my animation was not being exported. 

In my .blend file my mesh was named "character" but my armature had the default name of "Armature". I had originally named my actions with the hyphen format so they were named "character-walk" and "character-walkblock". Turns out I needed to use the armature/skeleton name, not the mesh name. I renamed my actions to "Armature-walk" (also could have renamed the armature) and it exported correctly. 

So for future readers/reference: in order for the Exporter to know that your actions belong to your armature, name them with the format of <ArmatureName>-<ActionName>.

 

Link to comment
Share on other sites

Also, you do not actually even need to show the object in the action name in your case.  Your blend only has one object with animation.

By the way, you are exporting 8 matrix weights per vertex, because 1 vertex uses that many, see log file.  This doubles your export size in this area.  You can probably reduce this to 4.  This is a custom data property on the MESH, because that is part of the geo for a mesh, not the armature & you can have multiple meshes per armature.

influencers.jpg.79fa1d148ad39dc24ac9b7f0b2754ba5.jpg

Link to comment
Share on other sites

1 hour ago, JCPalmer said:

Yes, I just found that myself.  Please mark this as solved by adding 'solved' as a tag to the first pose, make it appear on title.  Also close github issue, if that was you.

GitHub issue isn't me. I marked this topic as done. Thanks for the earlier help getting the actions assigned correctly. 

 

1 hour ago, JCPalmer said:

Also, you do not actually even need to show the object in the action name in your case.  Your blend only has one object with animation.

By the way, you are exporting 8 matrix weights per vertex, because 1 vertex uses that many, see log file.  This doubles your export size in this area.  You can probably reduce this to 4.  This is a custom data property on the MESH, because that is part of the geo for a mesh, not the armature & you can have multiple meshes per armature.

Yeah, that's interesting. If I change my actions to names without hyphens they link up with the armature. I assume this because there's only one mesh/armature present in the .blend? I've been doing a 1 .blend per model/mesh approach up until now. Is it more typical to have all of the needed meshes in one file?

Link to comment
Share on other sites

Yes, this is because actions are not really owned by objects.  They are a sets of values of properties  across time.  If another object had the same structure, it could also use the action.  The exporter detects an object has animation if it has a current action assigned.

I do not what is typical, but some people have had actions for different meshes, which are supposed to run at the same type to be in-sync.  In that case you either have to give exporter names, so it knows who gets what, or use the switch where each object only gets the animation currently assigned.  See 5.5 version post for more.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...