Yes, that is the suggested method. And yes, you should be concerned with performance doing it this way because for a n number of animated models you have with a m number of bones, you’re articulating n x m matrix multiplications per frame. You can circumvent this by creating place-holder geometries (simple quads for example) in your main animated character model and swap in/out your armor at runtime.
Hmm got it… have some great advantage using a model with all armors, and this way just set the desired armor at runtime? (I believe that u made something like this, but instead of armors, parts of armor).
Do u know if Urho3D have some cache system or instance to make this system better? Because if have two characters using same armor, the skinning is the same, so I dont know if Urho3D instance this to gain performance.
Combined skinned models
To create a combined skinned model from many parts (for example body + clothes), several AnimatedModel components can be created to the same scene node. These will then share the same bone nodes. The component that was first created will be the “master” model which drives the animations; the rest of the models will just skin themselves using the same bones. For this to work, all parts must have been authored from a compatible skeleton, with the same bone names. The master model should have all the bones required by the combined whole (for example a full biped), while the other models may omit unnecessary bones. Note that if the parts contain compatible vertex morphs (matching names), the vertex morph weights will also be controlled by the master model and copied to the rest.
Also, GPU skinning is a thing and bones * nodes is pretty much irrelevant - it’s the vertex count that matters in skinning … a weighted blend of matrices and a mult for every vertex. Thus, GPU skinning.
// Note: the model's world transform will be baked in the skin matrices
const Vector<Bone>& bones = skeleton_.GetBones();
// Use model's world transform in case a bone is missing
const Matrix3x4& worldTransform = node_->GetWorldTransform();
// Skinning with global matrices only
for (unsigned i = 0; i < bones.Size(); ++i)
const Bone& bone = bones[i];
skinMatrices_[i] = bone.node_->GetWorldTransform() * bone.offsetMatrix_;
skinMatrices_[i] = worldTransform;
This line in particular: skinMatrices_[i] = bone.node_->GetWorldTransform() * bone.offsetMatrix_;
is the m x n matrix multiplications per frame. GPU skinning still requires skinMatrices_ to be computed by the CPU (edit, added the CPU part).