Hi @gbz,
Thanks for mentioning the scaling. I set the model back to scale (1,1,1) and the weapon is closer but still not quite right. I also tried to use a cube instead of the mace for testing.
Initially, I set the cube’s location as follows. The cube weapons do show up at the right place. I also tried to visualize the bones of the default pose on the side. The bone I want to attach weapon is highlighted with a larger sphere.
if (bone.id === 'cave_troll_RArmPalm_052') {
targetBoneMatrix = bone.getAbsoluteTransform();
}
const weaponTemplate = BABYLON.MeshBuilder.CreateBox('weapon', { size: 50 }, scene);
targetBoneMatrix.decompose(weaponTemplate.scaling, weaponTemplate.rotationQuaternion, weaponTemplate.position);
The skin animation is driven by ‘#include’ in pbr vertex shader code. For GPU instanced animation, I replaced the default bonesVertex with a customized implementation that can accept baked animation as a uniform. And depending on the offset of the current frame and the influence bone, the corresponding transformation matrix is retrieved to calculate influence and execute:
finalWorld = finalWorld * influence;
I was thinking since I successfully applied the transformation matrix of the target bone to the skins around the bone. The same transformation can also be applied to animate the weapon. So I attached the material for the mace to the box weapon. And I have an instanced buffer mycontrol of type vec4. If mycontrol.y == 1.0, the following transformation is used instead of the default finalWorld * influence.
This code basically retrieves the boneSampler of the target bone for the current frame. And assuming all the vertices on the weapon are only influenced by the target bone. The result is the correct animation of the weapon. bakedAnimMatrices is the texture that store all the transformation matrix for all the bones and all the frames, bakedAnimFrames is total number of frames, animIndex is current frame.
But the position of the weapon is shifted away from the target bone position, as shown in the screenshot in my original question. I think there could be some gaps in my knowledge and my assumption to transform weapon the same way as transform skins influenced by the target bone is not correct.
if (mycontrol.y == 1.0) {
float animIndex = mycontrol.x;
// num of bones + 1 is used to store the transform matrix for the target bone
float indexMace = 123.0;
float numOfBones = 123.0;
float myBoneTextureWidth = (numOfBones + 1.0) * 4.0;
float dx = 1.0 / myBoneTextureWidth;
float offsetY = animIndex / bakedAnimFrames;
float offsetMace = indexMace * 4.0;
vec4 mace0 = texture2D(bakedAnimMatrices, vec2(dx * (offsetMace + 0.5), offsetY));
vec4 mace1 = texture2D(bakedAnimMatrices, vec2(dx * (offsetMace + 1.5), offsetY));
vec4 mace2 = texture2D(bakedAnimMatrices, vec2(dx * (offsetMace + 2.5), offsetY));
vec4 mace3 = texture2D(bakedAnimMatrices, vec2(dx * (offsetMace + 3.5), offsetY));
mat4 maceMatrix = mat4(mace0, mace1, mace2, mace3);
finalWorld = finalWorld * maceMatrix;
}