std::string RetrieveAttrValue(XMLNodePtr node, std::string const & attr_name, std::string const & default_value) { XMLAttributePtr attr = node->Attrib(attr_name); if (attr) { return attr->ValueString(); } return default_value; }
void SubThreadStage() { ResIdentifierPtr psmm_input = ResLoader::Instance().Open(ps_desc_.res_name); KlayGE::XMLDocument doc; XMLNodePtr root = doc.Parse(psmm_input); { XMLNodePtr particle_node = root->FirstNode("particle"); { XMLNodePtr alpha_node = particle_node->FirstNode("alpha"); ps_desc_.ps_data->particle_alpha_from_tex = alpha_node->Attrib("from")->ValueString(); ps_desc_.ps_data->particle_alpha_to_tex = alpha_node->Attrib("to")->ValueString(); } { XMLNodePtr color_node = particle_node->FirstNode("color"); { Color from; XMLAttributePtr attr = color_node->Attrib("from"); if (attr) { std::vector<std::string> strs; boost::algorithm::split(strs, attr->ValueString(), boost::is_any_of(" ")); for (size_t i = 0; i < 3; ++ i) { if (i < strs.size()) { boost::algorithm::trim(strs[i]); from[i] = static_cast<float>(atof(strs[i].c_str())); } else { from[i] = 0; } } } from.a() = 1; ps_desc_.ps_data->particle_color_from = from; Color to; attr = color_node->Attrib("to"); if (attr) { std::vector<std::string> strs; boost::algorithm::split(strs, attr->ValueString(), boost::is_any_of(" ")); for (size_t i = 0; i < 3; ++ i) { if (i < strs.size()) { boost::algorithm::trim(strs[i]); to[i] = static_cast<float>(atof(strs[i].c_str())); } else { to[i] = 0; } } } to.a() = 1; ps_desc_.ps_data->particle_color_to = to; } } } { XMLNodePtr emitter_node = root->FirstNode("emitter"); XMLAttributePtr type_attr = emitter_node->Attrib("type"); if (type_attr) { ps_desc_.ps_data->emitter_type = type_attr->ValueString(); } else { ps_desc_.ps_data->emitter_type = "point"; } XMLNodePtr freq_node = emitter_node->FirstNode("frequency"); if (freq_node) { XMLAttributePtr attr = freq_node->Attrib("value"); ps_desc_.ps_data->frequency = attr->ValueFloat(); } XMLNodePtr angle_node = emitter_node->FirstNode("angle"); if (angle_node) { XMLAttributePtr attr = angle_node->Attrib("value"); ps_desc_.ps_data->angle = attr->ValueInt() * DEG2RAD; } XMLNodePtr pos_node = emitter_node->FirstNode("pos"); if (pos_node) { float3 min_pos(0, 0, 0); XMLAttributePtr attr = pos_node->Attrib("min"); if (attr) { std::vector<std::string> strs; boost::algorithm::split(strs, attr->ValueString(), boost::is_any_of(" ")); for (size_t i = 0; i < 3; ++ i) { if (i < strs.size()) { boost::algorithm::trim(strs[i]); min_pos[i] = static_cast<float>(atof(strs[i].c_str())); } else { min_pos[i] = 0; } } } ps_desc_.ps_data->min_pos = min_pos; float3 max_pos(0, 0, 0); attr = pos_node->Attrib("max"); if (attr) { std::vector<std::string> strs; boost::algorithm::split(strs, attr->ValueString(), boost::is_any_of(" ")); for (size_t i = 0; i < 3; ++ i) { if (i < strs.size()) { boost::algorithm::trim(strs[i]); max_pos[i] = static_cast<float>(atof(strs[i].c_str())); } else { max_pos[i] = 0; } } } ps_desc_.ps_data->max_pos = max_pos; } XMLNodePtr vel_node = emitter_node->FirstNode("vel"); if (vel_node) { XMLAttributePtr attr = vel_node->Attrib("min"); ps_desc_.ps_data->min_vel = attr->ValueFloat(); attr = vel_node->Attrib("max"); ps_desc_.ps_data->max_vel = attr->ValueFloat(); } XMLNodePtr life_node = emitter_node->FirstNode("life"); if (life_node) { XMLAttributePtr attr = life_node->Attrib("min"); ps_desc_.ps_data->min_life = attr->ValueFloat(); attr = life_node->Attrib("max"); ps_desc_.ps_data->max_life = attr->ValueFloat(); } } { XMLNodePtr updater_node = root->FirstNode("updater"); XMLAttributePtr type_attr = updater_node->Attrib("type"); if (type_attr) { ps_desc_.ps_data->updater_type = type_attr->ValueString(); } else { ps_desc_.ps_data->updater_type = "polyline"; } if ("polyline" == ps_desc_.ps_data->updater_type) { for (XMLNodePtr node = updater_node->FirstNode("curve"); node; node = node->NextSibling("curve")) { std::vector<float2> xys; for (XMLNodePtr ctrl_point_node = node->FirstNode("ctrl_point"); ctrl_point_node; ctrl_point_node = ctrl_point_node->NextSibling("ctrl_point")) { XMLAttributePtr attr_x = ctrl_point_node->Attrib("x"); XMLAttributePtr attr_y = ctrl_point_node->Attrib("y"); xys.push_back(float2(attr_x->ValueFloat(), attr_y->ValueFloat())); } XMLAttributePtr attr = node->Attrib("name"); size_t const name_hash = RT_HASH(attr->ValueString().c_str()); if (CT_HASH("size_over_life") == name_hash) { ps_desc_.ps_data->size_over_life_ctrl_pts = xys; } else if (CT_HASH("mass_over_life") == name_hash) { ps_desc_.ps_data->mass_over_life_ctrl_pts = xys; } else if (CT_HASH("opacity_over_life") == name_hash) { ps_desc_.ps_data->opacity_over_life_ctrl_pts = xys; } } } } RenderFactory& rf = Context::Instance().RenderFactoryInstance(); RenderDeviceCaps const & caps = rf.RenderEngineInstance().DeviceCaps(); if (caps.multithread_res_creating_support) { this->MainThreadStage(); } }