Jump to content

Cloning Skeleton along with Meshes


royibernthal
 Share

Recommended Posts

I have a model loaded from a .babylon file, which consists of several meshes, a matching skeleton with animations is also loaded from that same file.

I'd like to create a clone of the whole model (meshes + skeleton), and be able to animate each clone separately.

 

I iterate over the meshes with a simple FOR loop and clone them, so far everything works as expected.

I clone the skeleton, however when I try to animate the clone using scene.beginAnimation(skeleton...) neither the cloned meshes nor the original meshes are animated.

When I try to animate the original skeleton, the original meshes are animated successfully.

Since my skeleton cloning is completely separate from the meshes cloning, I guess it makes sense, as they don't have references of each other.

 

1) Is there a way to pass the skeleton which meshes it should be attached to after cloning? (or the other way around - pass the cloned skeleton to the cloned meshes)

Alternatively - Is there some way to clone the meshes and skeleton in a way that keeps the newly cloned meshes synced to the newly cloned skeleton?

2) Is it even necessary to clone the skeletons if I want different clones of the same model to be animated separately?

3) Does a skeleton have a function similar to mesh.createInstance()? For instance, if I call mesh.createInstance(), should I still call skeleton.clone() or does skeleton have a function similar to createInstance() for improved performance?

Link to comment
Share on other sites

@gryff Yup, both of them.

 

If I understand things correctly, the example in the tutorial is for 1 mesh per skeleton (e.g. the rabbit). What if I have multiple meshes per skeleton? How would that look like?

 

Let's say I'm loading a human model from a .babylon file.

-Multiple meshes are loaded: head, hands, legs, etc...

-Only one skeleton is loaded

 

Each mesh has a mesh.skeleton reference, which I can only assume references the same skeleton object, correct me if I'm wrong.

The picture I have in my head of how things are connected to each other is probably wrong, would you help me understand how it actually works?

 

btw - Is there a way to see the source of the demo you linked to?

Link to comment
Share on other sites

Hey, its rabbit and dude... our good buddies.  royi, playground search for "dude" or "rabbit"... you'll get a bucket of slop to dig-in.  :)

Are you really good at using your object inspector... in your browser f12 dev tools?  console.log the mesh, click on the word object in the console, and the object inspector should open.  You can drill right into the bone matrices and do real-time value changes... twist the rabbit's head backwards and stuff.  :) Debug layer and .showBones is handy/hot, too.

Link to comment
Share on other sites

Hey Wingnut, found a similar source in a playground search as you suggested:

http://www.babylonjs-playground.com/#1NSCXV#4

However it clones only the rabbit which consists of 1 mesh per skeleton, I have no idea how to do it for multiple meshes per skeleton.

 

I'm familiar with dev tools :) My guess is the skeleton is properly animated since I called scene.beginAnimation, but my cloned skeleton is simply not linked to the model's cloned meshes, and so the animation isn't rendered.

Link to comment
Share on other sites

@aWeirdo 

Hey,

1) I tried setting manually the skeleton property of all the cloned meshes to reference the cloned skeleton, which I think is what you did in your example (correct me if I'm wrong).

I'm trying to set the skeleton of cloned meshes created by originalMesh.createInstance() or originalMesh.clone().

However, when I try to set mesh.skeleton = skeleton, the following error is thrown in the console:

Quote

TypeError: setting a property that has only a getter

What am I missing? Aren't you also setting the skeleton property of a cloned mesh to the cloned skeleton in your example?

 

2) Is the first mesh in the array of loaded meshes (newMeshes) set to be the parent of all other meshes via blender? (or any other software)

dude = newMeshes[0] seems to be enough to represent the whole model, without needing to manually clone any of the other loaded meshes in the newMeshes array.

Link to comment
Share on other sites

@royibernthal 
If possible, please create a PG, it makes everything much easier :) 

When importing a mesh and setting "dude = newMeshes[0];" the imported mesh's skeletons aswell as its protential children's skeletons are automaticly applied to dude.

Cloning a mesh doesn't do that, 

If you look closely in my code, you'll notise that in the import code, i make a dude.skeletons array and add all imported skeletons, which i use later in the cloning.
 

       dude.skeletons = [];
		
		for (var i = 0; i < skeletons.length; i+=1){
			dude.skeletons[i] = skeletons[i];
			scene.beginAnimation(dude.skeletons[i], 0, 120, 1.0, true);
		}



Then when cloning,

I start by doing the mesh cloning itself, followed by cloning the dude.skeletons array into a clone.skeletons array,

and then at the end, i set the proper connections between the clone.skeleton variable and the clone.skeletons array index.

 

Link to comment
Share on other sites

@aWeirdo I just understood the problem, I was trying to set the skeleton of an InstancedMesh created by Mesh/createInstance(), it seems skeleton only has a getter and no setter on InstancedMesh.

Is InstancedMesh not supposed to support cloning skeletons or is there some other way to do it?

 

I created a rough PG of what I'm trying to do, it works when I clone with Mesh/clone():

http://www.babylonjs-playground.com/#1SVN3I#13

Link to comment
Share on other sites

  • 3 weeks later...

Hello,

I'm also attempting to use this.createInstance() of an imported mesh with no skeleton, only a single mesh. Is this supported for a single imported mesh? Or is this.createInstance() only to use for native objects created in babylon? I would like to use this.createInstance() as I already have my scene completed, and the client decided at the very last moment that they wanted an imported mesh instead of a native babylon sphere in a physics simulation. If this is supported, then how do I access the variable that represents newmeshes[0] on an imported mesh?

Thanks,

DB

I tried modifying the following PG scene to instance an imported mesh in place of the shperes, but have had no luck. The basic PG scene minus my messy code trying to work with the attached mesh is below:

http://www.babylonjs-playground.com/#1MJ09V#5

I left out the importing of the mesh, but the .babylon file is attached if anyone believes they can instance the low poly mesh after import. It appears I might need to clone, but then would need to make many other modifications to my scene. Either way, if anyone might assist with an example of eith instancing or cloning (instancing preferred), I would be very grateful.

The only mesh in the scene is named "Cell_05".

Thanks much,

DB

Cell_05.babylon

Link to comment
Share on other sites

@dbawel Hi, I don't see in your PG any attempt to import the .babylon file.

 

Here's how the import should look like, task.loadmeshes is the "newmeshes" you're looking for:

var assetsManager = new BABYLON.AssetsManager(scene);
	
assetsManager.addMeshTask("cell", "", "http://www.html5gamedevs.com/applications/core/interface/file/", "attachment.php?id=9871");
	
assetsManager.onTaskSuccess = function (task) {
	//task.loadedMeshes
};

assetsManager.load();

 

You won't be able to load the .babylon file though from that URL, you'll get a cross-origin error. Try to load it within your own environment and it should work. Otherwise, you can attempt to load it from a server which will support cross-origin requests from the PG.

Link to comment
Share on other sites

@royibernthal - MY apologies that I wasn't clear in my last post. I'm using the code above - but unable to generate the code for instancing - only cloning a single mesh. Is instancing supported for imported meshes, and if so, what is the method to identify the imported mesh as meshes[]; returns a null object on instancing. I need to use the meshes in a physics simulation with hundreds of instances.

Thanks,

DB

Link to comment
Share on other sites

@dbawel a .babylon file contains data from which bjs can create "native" babylon meshes (along with other scene info which is irrelevant to your question), so it's all the same, it doesn't matter that the meshes are imported.

task.loadedmeshes is an array of meshes on which you can call createInstance(). e.g. task.loadedmeshes[0].createInstance() should work for you.

Depending on the amount of meshes you load from a .babylon file, you might want to loop over task.loadedmeshes and bundle the instances created with some extra logic.

Assuming your .babylon file contains only 1 mesh like you say, this case should be fairly easy, just create as many instances of task.loadedmeshes[0] as you need.

If you still have problems or encounter errors, feel free to upload a PG and I'll try my best to help you identify the issue.

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...