//-------------------------------------------------- //-------------------------------------------------- template <> Quaternion GetAttributeValue<Quaternion>(const XML::Node* in_node, const std::string& in_attributeName, const Quaternion& in_defaultValue) { for(rapidxml::xml_attribute<>* attribute = in_node->first_attribute(); attribute != nullptr; attribute = attribute->next_attribute()) { if (GetName(attribute) == in_attributeName) { return ParseQuaternion(GetValue(attribute)); } } return in_defaultValue; }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------ template <> Quaternion ParseValue(const std::string& in_value) { return ParseQuaternion(in_value); }
bool LegacyAvatarSerializer::ReadAttachment(AvatarAttachmentVector& dest, const QDomElement& elem) { AvatarAttachment attachment; QDomElement name = elem.firstChildElement("name"); if (!name.isNull()) { attachment.name_ = name.attribute("value").toStdString(); } else { RexLogicModule::LogError("Attachment without name element"); return false; } QDomElement category = elem.firstChildElement("category"); if (!category.isNull()) { attachment.category_ = category.attribute("name").toStdString(); } QDomElement mesh = elem.firstChildElement("mesh"); if (!mesh.isNull()) { attachment.mesh_.name_ = mesh.attribute("name").toStdString(); attachment.link_skeleton_ = ParseBool(mesh.attribute("linkskeleton").toStdString()); } else { RexLogicModule::LogError("Attachment without mesh element"); return false; } QDomElement avatar = elem.firstChildElement("avatar"); if (!avatar.isNull()) { QDomElement bone = avatar.firstChildElement("bone"); if (!bone.isNull()) { attachment.bone_name_ = bone.attribute("name").toStdString(); if (attachment.bone_name_ == "None") attachment.bone_name_ = std::string(); attachment.transform_.position_ = ParseVector3(bone.attribute("offset").toStdString()); attachment.transform_.orientation_ = ParseQuaternion(bone.attribute("rotation").toStdString()); attachment.transform_.scale_ = ParseVector3(bone.attribute("scale").toStdString()); } QDomElement polygon = avatar.firstChildElement("avatar_polygon"); while (!polygon.isNull()) { uint idx = ParseInt(polygon.attribute("idx").toStdString()); attachment.vertices_to_hide_.push_back(idx); polygon = polygon.nextSiblingElement("avatar_polygon"); } } else { RexLogicModule::LogError("Attachment without avatar element"); return false; } dest.push_back(attachment); return true; }
bool LegacyAvatarSerializer::ReadAttachment(AvatarAttachment& dest, const QDomDocument source, const EC_AvatarAppearance& appearance, const std::string& attachment_name) { QDomElement attachment_elem = source.firstChildElement("attachment"); if (attachment_elem.isNull()) { RexLogicModule::LogError("Attachment without attachment element"); return false; } dest.name_ = attachment_name; std::string meshname = appearance.GetMesh().name_; std::string basemeshname = appearance.GetProperty("basemesh"); bool found = false; QDomElement avatar_elem = attachment_elem.firstChildElement("avatar"); while (!avatar_elem.isNull()) { std::string name = avatar_elem.attribute("name").toStdString(); if ((name == meshname) || (name == basemeshname)) { found = true; break; } avatar_elem = avatar_elem.nextSiblingElement("avatar"); } if (!found) { RexLogicModule::LogError("No matching avatar mesh found in attachment. This attachment cannot be used for this avatar mesh"); return false; } QDomElement mesh_elem = attachment_elem.firstChildElement("mesh"); if (!mesh_elem.isNull()) { dest.mesh_.name_ = mesh_elem.attribute("name").toStdString(); dest.link_skeleton_ = ParseBool(mesh_elem.attribute("linkskeleton").toStdString()); } else { RexLogicModule::LogError("Attachment without mesh element"); return false; } QDomElement bone = avatar_elem.firstChildElement("bone"); if (!bone.isNull()) { dest.bone_name_ = bone.attribute("name").toStdString(); if (dest.bone_name_ == "None") dest.bone_name_ = std::string(); dest.transform_.position_ = ParseVector3(bone.attribute("offset").toStdString()); dest.transform_.orientation_ = ParseQuaternion(bone.attribute("rotation").toStdString()); dest.transform_.scale_ = ParseVector3(bone.attribute("scale").toStdString()); } QDomElement polygon = avatar_elem.firstChildElement("avatar_polygon"); while (!polygon.isNull()) { uint idx = ParseInt(polygon.attribute("idx").toStdString()); dest.vertices_to_hide_.push_back(idx); polygon = polygon.nextSiblingElement("avatar_polygon"); } QDomElement category_elem = attachment_elem.firstChildElement("category"); if (!category_elem.isNull()) { dest.category_ = category_elem.attribute("name").toStdString(); } return true; }
bool LegacyAvatarSerializer::ReadAvatarAppearance(RexLogic::EC_AvatarAppearance& dest, const QDomDocument& source, bool read_mesh) { PROFILE(Avatar_ReadAvatarAppearance); QDomElement avatar = source.firstChildElement("avatar"); if (avatar.isNull()) { RexLogicModule::LogError("No avatar element"); return false; } // Get mesh & skeleton if (read_mesh) { dest.Clear(); QDomElement base_elem = avatar.firstChildElement("base"); if (!base_elem.isNull()) { AvatarAsset mesh; mesh.name_ = base_elem.attribute("mesh").toStdString(); dest.SetMesh(mesh); } // Get skeleton QDomElement skeleton_elem = avatar.firstChildElement("skeleton"); if (!skeleton_elem.isNull()) { AvatarAsset skeleton; skeleton.name_ = skeleton_elem.attribute("name").toStdString(); dest.SetSkeleton(skeleton); } } // Get materials, should be 2 of them uint mat_index = 0; QDomElement material_elem = avatar.firstChildElement("material"); AvatarMaterialVector materials; while (!material_elem.isNull()) { AvatarMaterial material; material.asset_.name_ = material_elem.attribute("name").toStdString(); // Check for texture override QDomElement texture_elem; switch (mat_index) { case 0: texture_elem = avatar.firstChildElement("texture_body"); break; case 1: texture_elem = avatar.firstChildElement("texture_face"); break; } if (!texture_elem.isNull()) { std::string tex_name = texture_elem.attribute("name").toStdString(); if (!tex_name.empty()) { AvatarAsset texture; texture.name_ = tex_name; material.textures_.push_back(texture); } } materials.push_back(material); material_elem = material_elem.nextSiblingElement("material"); ++mat_index; } dest.SetMaterials(materials); // Get main transform QDomElement transform_elem = avatar.firstChildElement("transformation"); if (!transform_elem.isNull()) { Transform trans; trans.position_ = ParseVector3(transform_elem.attribute("position").toStdString()); trans.orientation_ = ParseQuaternion(transform_elem.attribute("rotation").toStdString()); trans.scale_ = ParseVector3(transform_elem.attribute("scale").toStdString()); dest.SetTransform(trans); } // Get attachments QDomElement attachment_elem = avatar.firstChildElement("attachment"); AvatarAttachmentVector attachments; while (!attachment_elem.isNull()) { ReadAttachment(attachments, attachment_elem); attachment_elem = attachment_elem.nextSiblingElement("attachment"); } dest.SetAttachments(attachments); // Get bone modifiers QDomElement bonemodifier_elem = avatar.firstChildElement("dynamic_animation"); BoneModifierSetVector bonemodifiers; while (!bonemodifier_elem.isNull()) { ReadBoneModifierSet(bonemodifiers, bonemodifier_elem); bonemodifier_elem = bonemodifier_elem.nextSiblingElement("dynamic_animation"); } // Get bone modifier parameters QDomElement bonemodifierparam_elem = avatar.firstChildElement("dynamic_animation_parameter"); while (!bonemodifierparam_elem.isNull()) { ReadBoneModifierParameter(bonemodifiers, bonemodifierparam_elem); bonemodifierparam_elem = bonemodifierparam_elem.nextSiblingElement("dynamic_animation_parameter"); } dest.SetBoneModifiers(bonemodifiers); // Get morph modifiers QDomElement morphmodifier_elem = avatar.firstChildElement("morph_modifier"); MorphModifierVector morphmodifiers; while (!morphmodifier_elem.isNull()) { ReadMorphModifier(morphmodifiers, morphmodifier_elem); morphmodifier_elem = morphmodifier_elem.nextSiblingElement("morph_modifier"); } dest.SetMorphModifiers(morphmodifiers); // Get master modifiers QDomElement mastermodifier_elem = avatar.firstChildElement("master_modifier"); MasterModifierVector mastermodifiers; while (!mastermodifier_elem.isNull()) { ReadMasterModifier(mastermodifiers, mastermodifier_elem); mastermodifier_elem = mastermodifier_elem.nextSiblingElement("master_modifier"); } dest.SetMasterModifiers(mastermodifiers); // Get animations QDomElement animation_elem = avatar.firstChildElement("animation"); AnimationDefinitionMap animations; while (!animation_elem.isNull()) { ReadAnimationDefinition(animations, animation_elem); animation_elem = animation_elem.nextSiblingElement("animation"); } dest.SetAnimations(animations); // Get properties QDomElement property_elem = avatar.firstChildElement("property"); while (!property_elem.isNull()) { std::string name = property_elem.attribute("name").toStdString(); std::string value = property_elem.attribute("value").toStdString(); if ((!name.empty()) && (!value.empty())) dest.SetProperty(name, value); property_elem = property_elem.nextSiblingElement("property"); } // Get assetmap (optional, inventory based avatars only) QDomElement assetmap_elem = avatar.firstChildElement("assetmap"); if (!assetmap_elem.isNull()) { AvatarAssetMap new_map; QDomElement asset_elem = assetmap_elem.firstChildElement("asset"); while (!asset_elem.isNull()) { std::string name = asset_elem.attribute("name").toStdString(); std::string id = asset_elem.attribute("id").toStdString(); new_map[name] = id; asset_elem = asset_elem.nextSiblingElement("asset"); } dest.SetAssetMap(new_map); } return true; }