Jump to content

Animation for specific bones


photo

Recommended Posts

Hello

I have skeleton set by Inverse Kinematics

and animation where only some bones(not affected by IK) need to be animated,

how to apply animation only to list of specific bones?

reading  https://developer.unigine.com/en/docs/2.7.2/api/library/objects/class.objectmeshskinned

tried enable/disable some - with no difference by setLayerBoneTransformEnabled

and setLayerEnabled must be disabled or enabled in this case?

//setup animation layer
for (int i = 0; i < smesh.getNumBones(); i++)
   smesh.setLayerBoneTransformEnabled(layer, i, i >= 31 && i <= 47 ? 1 : 0);
smesh.setLayer(layer, 1, 1);

int animIndex = smesh.addAnimation(animPathNameExt);
smesh.setAnimation(layer, animIndex);

//...
// in loop
// IK setup bones
//...
// play animation
smesh.setFrame(layer, (float)Time * (Frames - 1));

 

Link to comment

Hi lightmap,

At first glance it looks like a bug in the engine's method setLayerBoneTransformEnabled(). Thank you for this.
Workaround:
1. Save all IK bone transforms
2. Call setFrame()
3. Restore all IK bone transforms

Best regards,
Alexander

  • Like 1
Link to comment

Hello,

let me know if it is bug, maybe it is not, probably I'm using it wrong

setLayerBoneTransformEnabled() meant to be used only with setLayerBoneTransform? or it also must affect animation in that layer?

 

Link to comment

does that mean Unigine can't apply animation from *.anim only for list of some bones ?

(animation must apply from some hierarchy branch till end leafs, not random bones)

or there options?

Link to comment

in case where I need to combine two animations, for left and right parts of model (single skinned mesh)

I have two animations - Left.anim and Right.anim, separately each must have weight 1.0f

for Left.anim only left side animated, right side 0 and same as bind pose

if both animation triggered - each layer blended as result in mid state <- I need a final state for both left and right

so I need to exclude some bones from blending

Link to comment

Hi lightmap,

Look at our animation samples (SDK Browser -> Samples -> UnigineScript -> Animation). They are difficult to understand, but this is what you need. You need to use inverseLayer() and mulLayer() functions to mix your animations:

// ObjectMeshSkinnedPtr mesh;

void init()
{
	mesh->setNumLayers(3); // 2 animations + 1 temporary
	mesh->setAnimation(0, "Left.anim");
	mesh->setAnimation(1, "Right.anim");

	// create a temporary reference layer 2 to calculate the mixed animation
	mesh->setFrame(1, 0.0f);
	mesh->inverseLayer(2, 1);
}

void update()
{
	// play animation
	float time = engine.game.getTime();
	mesh->setFrame(0, time);
	mesh->setFrame(1, time);
	
	// combine two animations:
	// 1) find local transformations of all bones relative to the frame 0 of the "Right.anim" animation
	//    and put result to the layer 1
	mesh->mulLayer(1,2,1);
	// 2) add local transformations of "Right.anim" animation bones to the "Left.anim" and put result to
	//    the layer 0
	mesh->mulLayer(0,0,1);
}


Best regards,
Alexander

  • Like 1
Link to comment
×
×
  • Create New...