diff --git a/src/user/user_model.cc b/src/user/user_model.cc index ad7af6ddcf..75da5ed2df 100644 --- a/src/user/user_model.cc +++ b/src/user/user_model.cc @@ -447,7 +447,20 @@ mjCModel& mjCModel::operator+=(const mjCModel& other) { // do not copy assets for self-attach // TODO: asset should be copied only when referenced CopyList(meshes_, other.meshes_); + int old_nskin = skins_.size(); CopyList(skins_, other.skins_); + int new_nskin = skins_.size(); + + // Iterate ONLY over the newly added skins + for (int i = old_nskin; i < new_nskin; ++i) { + mjCSkin* skin = skins_[i]; + for (std::string& bodyname : skin->bodyname_) { + if (!bodyname.empty()) { + bodyname = prefix + bodyname; + } + } + } + CopyList(hfields_, other.hfields_); CopyList(textures_, other.textures_); CopyList(materials_, other.materials_); @@ -1921,6 +1934,7 @@ void mjCModel::IndexAssets(bool discard) { throw mjCError(skin, "material '%s' not found in skin %d", skin->material_.c_str(), i); } } + skin->ResolveReferences(this); } // materials referenced in sites diff --git a/src/user/user_objects.cc b/src/user/user_objects.cc index 758783e4d5..a582cf260f 100644 --- a/src/user/user_objects.cc +++ b/src/user/user_objects.cc @@ -2598,7 +2598,28 @@ void mjCBody::Compile(void) { } - +// skin attach issue fix--------- +void mjCSkin::ResolveReferences(const mjCModel* m) { + // Resize the bodyid list to match the bodyname list + bodyid.resize(bodyname_.size()); + + for (int i = 0; i < bodyname_.size(); ++i) { + if (!bodyname_[i].empty()) { + // Find the body object using the (now prefixed) name + mjCBody* b = (mjCBody*)m->FindObject(mjOBJ_BODY, bodyname_[i]); + if (b) { + // Success! Store the numerical ID. + bodyid[i] = b->id; + } else { + // This is the error we are fixing! + throw mjCError(this, "unknown body '%s' in skin", bodyname_[i].c_str()); + } + } else { + // This bone doesn't reference a body. + bodyid[i] = -1; + } + } +} //------------------ class mjCFrame implementation ------------------------------------------------- // initialize frame