bool LegacyAvatarSerializer::ReadBoneModifierSet(BoneModifierSetVector& dest, const QDomElement& source) { BoneModifierSet modifier_set; modifier_set.name_ = source.attribute("name").toStdString(); unsigned num_bones = 0; QDomElement bones = source.firstChildElement("bones"); if (!bones.isNull()) { QDomElement bone = bones.firstChildElement("bone"); while (!bone.isNull()) { BoneModifier modifier; modifier.bone_name_ = bone.attribute("name").toStdString(); QDomElement rotation = bone.firstChildElement("rotation"); QDomElement translation = bone.firstChildElement("translation"); QDomElement scale = bone.firstChildElement("scale"); modifier.start_.position_ = ParseVector3(translation.attribute("start").toStdString()); modifier.start_.orientation_ = ParseEulerAngles(rotation.attribute("start").toStdString()); modifier.start_.scale_ = ParseVector3(scale.attribute("start").toStdString()); modifier.end_.position_ = ParseVector3(translation.attribute("end").toStdString()); modifier.end_.orientation_ = ParseEulerAngles(rotation.attribute("end").toStdString()); modifier.end_.scale_ = ParseVector3(scale.attribute("end").toStdString()); std::string trans_mode = translation.attribute("mode").toStdString(); std::string rot_mode = rotation.attribute("mode").toStdString(); if (trans_mode == "absolute") modifier.position_mode_ = BoneModifier::Absolute; if (trans_mode == "relative") modifier.position_mode_ = BoneModifier::Relative; if (rot_mode == "absolute") modifier.orientation_mode_ = BoneModifier::Absolute; if (rot_mode == "relative") modifier.orientation_mode_ = BoneModifier::Relative; if (rot_mode == "cumulative") modifier.orientation_mode_ = BoneModifier::Cumulative; modifier_set.modifiers_.push_back(modifier); bone = bone.nextSiblingElement("bone"); ++num_bones; } } if (num_bones) dest.push_back(modifier_set); return true; }
//-------------------------------------------------- //-------------------------------------------------- template <> Vector3 GetAttributeValue<Vector3>(const XML::Node* in_node, const std::string& in_attributeName, const Vector3& in_defaultValue) { for(rapidxml::xml_attribute<>* attribute = in_node->first_attribute(); attribute != nullptr; attribute = attribute->next_attribute()) { if (GetName(attribute) == in_attributeName) { return ParseVector3(GetValue(attribute)); } } return in_defaultValue; }
void ParseVertexAttrib(const std::string& line, std::vector<Vector3>& positions, std::vector<Vector3>& normals, std::vector<Vector2>& texcoords) { if (line.size() > 1) { const char next = line[1]; if (isSpaceOrTab(next)) // "v ": parse vertex position { const Vector3 position = ParseVector3(line); positions.push_back(position); } else if (next == 'n') // "v ": parse vertex normal { const Vector3 normal = ParseVector3(line); normals.push_back(normal); } else if (next == 't') // "v ": parse vertex texcoord { const Vector2 texcoord = ParseVector2(line); texcoords.push_back(texcoord); } } }
bool ParseVN (std::wifstream& in, ObjectData& o) { int total = (int)o.vertex->size(); int i = 0; while (i < total) { (*o.vertex)[i].normal.w = 0.0f; if(!ParseVector3(in, (*o.vertex)[i++].normal)) return false; } return true; }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------ template <> Vector3 ParseValue(const std::string& in_value) { return ParseVector3(in_value); }
// ------------------------------------------------------------------------------------------------ void ColladaModelFactory::GetTransform(xml_node* node, Matrix * out ) { Matrix rotateX,rotateY,rotateZ,translate,scale; rotateX.MakeIdentity(); rotateY.MakeIdentity(); rotateZ.MakeIdentity(); translate.MakeIdentity(); scale.MakeIdentity(); for(xml_node* child = GetChildEle(node); child != NULL; child=GetNextEle(child)) { const char * name = (const char*)child->name(); const char * sid = GetAttributeText(child, "sid", false); if (!name) { continue; } if (!sid) { continue; } if(strcmp(name, "rotate")==0) { if(strcmp(sid, "rotateX")==0) { float4 temp; if (!ParseVector4(child, &temp)) { ParseError("Failed to parse '%s' transform (expected 4 floats)'\n", sid); } else { rotateX = Matrix::CreateRotationX(temp.w); } } else if(strcmp(sid, "rotateY")==0) { float4 temp; if (!ParseVector4(child, &temp)) { ParseError("Failed to parse '%s' transform (expected 4 floats)'\n", sid); } else { rotateY = Matrix::CreateRotationY(temp.w); } } else if(strcmp(sid, "rotateZ")==0) { float4 temp; if (!ParseVector4(child, &temp)) { ParseError("Failed to parse '%s' transform (expected 4 floats)'\n", sid); } else { rotateZ = Matrix::CreateRotationZ(temp.w); } } } else if(strcmp(name, "translate")==0) { float3 temp; if (!ParseVector3(child, &temp)) { ParseError("Failed to parse '%s' transform (expected 3 floats)'\n", name); } else { translate = Matrix::CreateTranslation(temp); } } else if(strcmp(name, "scale")==0) { float3 temp; if (!ParseVector3(child, &temp)) { ParseError("Failed to parse '%s' transform (expected 3 floats)'\n", name); } else { scale = Matrix::CreateScale(temp); } } // unhandled transform node else { Logger::Log(OutputMessageType::Warning, "Unexpected transform node, '%s'\n", name); } } Matrix tmp = scale * rotateX; tmp = tmp * rotateY; tmp = tmp * rotateZ; tmp = tmp * translate; *out = tmp; }
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::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::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; }