XMLNodePtr XMLDoc::createNode(const XMLNodePtr &parent, const TCHAR *nodeName, bool force) { DEFINEMETHODNAME; if(parent == NULL) { throwInvalidArgumentException(method, _T("parent=NULL")); } if(nodeName == NULL || _tcsclen(nodeName) == 0) { throwInvalidArgumentException(method, _T("nodeName=%s"), nodeName?nodeName:_T("null")); } StringArray tokens(Tokenizer(nodeName,_T("."))); // Create path if we got any dots XMLNodePtr node = parent; size_t i; for(i = 0; i < tokens.size() - 1; i++) { XMLNodePtr tmp = findChild(node,tokens[i].cstr()); if(tmp == NULL) { tmp = m_doc->createElement(tokens[i].cstr()); node = node->appendChild(tmp); } } XMLNodePtr result = findChild(node,tokens[i].cstr()); if(result != NULL && !force) { throwException(_T("Node %s alredy exist. set force to true, if duplicates are allowed"), nodeName); } else { result = m_doc->createElement(tokens[i].cstr()); result = node->appendChild(result); } return result; }
void loadStatic(XMLNodePtr node) { XMLNodePtr pos = node->getChild("pos"); XMLNodePtr rot = node->getChild("pos"); std::string model_name = (*node->getChild("model")->getChildren().begin())->getCdata(); model_name = trim(model_name); // Find the corresponding model type in the model menu list std::cout << "Looking for model '" << model_name << "'" << std::endl; model mod; for (std::vector<model>::iterator itr = modelsInMenu.begin(); itr != modelsInMenu.end(); ++itr) { model old_model = *itr; if (old_model.name == model_name) { mod = old_model; std::cout << "\tSuccess" << std::endl; } } mod.worldX = pos->getAttribute("x").getValue<float>(); mod.worldZ = pos->getAttribute("y").getValue<float>(); mod.worldY = pos->getAttribute("z").getValue<float>(); mod.name = model_name; std::cout << "Adding model: " << mod.name << std::endl << "low: (" << mod.xlo << ", " << mod.ylo << ")" << std::endl << "high: (" << mod.xhi << ", " << mod.yhi << ")" << std::endl << "pos: (" << mod.worldX << ", " << mod.worldZ << ", " << mod.worldY << ")" << std::endl; modelsInWorld.push_back(mod); }
void setupOutputLevelFile(XMLNodePtr& mNode) { XMLContextPtr mContext = XMLContextPtr(new XMLContext); mNode = XMLNodePtr(new XMLNode(mContext)); mNode->setName("hi"); mNode->setType(xml_nt_node); XMLNodePtr newNode(new XMLNode(mContext)); newNode->setName("josh"); newNode->setType(xml_nt_node); mNode->addChild(newNode); }
void processObjNode(XMLNode &node) { model* mModel = new model(); std::string name = node.getName(); std::cout << "This Node is a: " << name << std::endl; XMLNodePtr cNode = node.getChild(std::string("size")); std::cout << "node: " << cNode->getName() << std::endl; mModel->xhi = cNode->getAttribute("xhi").getValue<float>(); mModel->xlo = cNode->getAttribute("xlo").getValue<float>(); mModel->yhi = cNode->getAttribute("yhi").getValue<float>(); mModel->ylo = cNode->getAttribute("ylo").getValue<float>(); std::cout << "mModel.xlo: " << mModel->xlo << " mModel.ylo: " << mModel->b << std::endl; std::cout << "type: " << cNode->getType() << std::endl; cNode = node.getChild(std::string("color")); mModel->r = cNode->getAttribute(std::string("r")).getValue<float>(); mModel->g = cNode->getAttribute(std::string("g")).getValue<float>(); mModel->b = cNode->getAttribute(std::string("b")).getValue<float>(); cNode = node.getChild(std::string("type")); mModel->name = cNode->getAttribute(std::string("name")).getValue<std::string>(); modelsInMenu.push_back(*mModel); }
void loadGroup(XMLNodePtr node) { XMLNodeList children = node->getChildren(); for (XMLNodeList::iterator itr = children.begin(); itr != children.end(); ++itr) { XMLNodePtr node = *itr; if (node->getName() == "static" || node->getName() == "turret" || node->getName() == "security_droid" || node->getName() == "navNode" ) { loadStatic(node); } } }
Offline::OfflineRenderDeviceCaps LoadPlatformConfig(std::string const & platform) { ResIdentifierPtr plat = ResLoader::Instance().Open("PlatConf/" + platform + ".plat"); KlayGE::XMLDocument doc; XMLNodePtr root = doc.Parse(plat); Offline::OfflineRenderDeviceCaps caps; caps.platform = RetrieveAttrValue(root, "name", ""); caps.major_version = static_cast<uint8_t>(RetrieveAttrValue(root, "major_version", 0)); caps.minor_version = static_cast<uint8_t>(RetrieveAttrValue(root, "minor_version", 0)); caps.requires_flipping = RetrieveNodeValue(root, "requires_flipping", 0) ? true : false; std::string const fourcc_str = RetrieveNodeValue(root, "native_shader_fourcc", ""); caps.native_shader_fourcc = (fourcc_str[0] << 0) + (fourcc_str[1] << 8) + (fourcc_str[2] << 16) + (fourcc_str[3] << 24); caps.native_shader_version = RetrieveNodeValue(root, "native_shader_version", 0); XMLNodePtr max_shader_model_node = root->FirstNode("max_shader_model"); caps.max_shader_model = ShaderModel(static_cast<uint8_t>(RetrieveAttrValue(max_shader_model_node, "major", 0)), static_cast<uint8_t>(RetrieveAttrValue(max_shader_model_node, "minor", 0))); caps.max_texture_depth = RetrieveNodeValue(root, "max_texture_depth", 0); caps.max_texture_array_length = RetrieveNodeValue(root, "max_texture_array_length", 0); caps.max_pixel_texture_units = static_cast<uint8_t>(RetrieveNodeValue(root, "max_pixel_texture_units", 0)); caps.max_simultaneous_rts = static_cast<uint8_t>(RetrieveNodeValue(root, "max_simultaneous_rts", 0)); caps.standard_derivatives_support = RetrieveNodeValue(root, "standard_derivatives_support", 0) ? true : false; caps.shader_texture_lod_support = RetrieveNodeValue(root, "shader_texture_lod_support", 0) ? true : false; caps.fp_color_support = RetrieveNodeValue(root, "fp_color_support", 0) ? true : false; caps.pack_to_rgba_required = RetrieveNodeValue(root, "pack_to_rgba_required", 0) ? true : false; caps.gs_support = RetrieveNodeValue(root, "gs_support", 0) ? true : false; caps.cs_support = RetrieveNodeValue(root, "cs_support", 0) ? true : false; caps.hs_support = RetrieveNodeValue(root, "hs_support", 0) ? true : false; caps.ds_support = RetrieveNodeValue(root, "ds_support", 0) ? true : false; caps.bc4_support = RetrieveNodeValue(root, "bc4_support", 0) ? true : false; caps.bc5_support = RetrieveNodeValue(root, "bc5_support", 0) ? true : false; caps.frag_depth_support = RetrieveNodeValue(root, "frag_depth_support", 0) ? true : false; caps.ubo_support = RetrieveNodeValue(root, "ubo_support", 0) ? true : false; return caps; }
int RetrieveNodeValue(XMLNodePtr root, std::string const & node_name, int default_value) { XMLNodePtr node = root->FirstNode(node_name); if (node) { return RetrieveAttrValue(node, "value", default_value); } return default_value; }
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 XMLDoc::setText(const XMLNodePtr &node, const TCHAR *value) { if(node == NULL) { return; } XMLNodePtr Text = findText(node); if(Text == NULL) { node->appendChild(m_doc->createTextNode(value)); } else { Text->nodeValue = value; } }
void PackJTML(std::string const & jtml_name) { Timer timer; ResIdentifierPtr jtml = ResLoader::Instance().Open(jtml_name); KlayGE::XMLDocument doc; XMLNodePtr root = doc.Parse(jtml); uint32_t n = root->AttribInt("num_tiles", 2048); uint32_t num_tiles = 1; while (num_tiles * 2 <= n) { num_tiles *= 2; } uint32_t tile_size = root->AttribInt("tile_size", 128); std::string fmt_str = root->AttribString("format", ""); ElementFormat format = EF_ARGB8; if ("ARGB8" == fmt_str) { format = EF_ARGB8; } else if ("ABGR8" == fmt_str) { format = EF_ABGR8; } uint32_t pixel_size = NumFormatBytes(format); JudaTexturePtr juda_tex = MakeSharedPtr<JudaTexture>(num_tiles, tile_size, format); uint32_t level = juda_tex->TreeLevels() - 1; RenderFactory& rf = Context::Instance().RenderFactoryInstance(); uint32_t attr = 0; for (XMLNodePtr node = root->FirstNode("image"); node; node = node->NextSibling("image"), ++ attr) { timer.restart(); std::string name = node->AttribString("name", ""); int32_t x = node->AttribInt("x", 0); int32_t y = node->AttribInt("y", 0); std::string address_u_str = node->AttribString("address_u", "wrap"); std::string address_v_str = node->AttribString("address_v", "wrap"); Color border_clr; border_clr.r() = node->AttribFloat("border_r", 0.0f); border_clr.g() = node->AttribFloat("border_g", 0.0f); border_clr.b() = node->AttribFloat("border_b", 0.0f); border_clr.a() = node->AttribFloat("border_a", 0.0f); uint32_t border_clr_u8; switch (format) { case EF_ARGB8: border_clr_u8 = border_clr.ARGB(); break; case EF_ABGR8: border_clr_u8 = border_clr.ABGR(); break; default: border_clr_u8 = 0; break; } TexAddressingMode addr_u, addr_v; std::shared_ptr<address_calculator> calc_u, calc_v; if ("mirror" == address_u_str) { addr_u = TAM_Mirror; calc_u = address_calculators[TAM_Mirror]; } else if ("clamp" == address_u_str) { addr_u = TAM_Clamp; calc_u = address_calculators[TAM_Clamp]; } else if ("border" == address_u_str) { addr_u = TAM_Border; calc_u = address_calculators[TAM_Border]; } else { addr_u = TAM_Wrap; calc_u = address_calculators[TAM_Wrap]; } if ("mirror" == address_v_str) { addr_v = TAM_Mirror; calc_v = address_calculators[TAM_Mirror]; } else if ("clamp" == address_v_str) { addr_v = TAM_Clamp; calc_v = address_calculators[TAM_Clamp]; } else if ("border" == address_v_str) { addr_v = TAM_Border; calc_v = address_calculators[TAM_Border]; } else { addr_v = TAM_Wrap; calc_v = address_calculators[TAM_Wrap]; } cout << "Processing " << name << "... "; TexturePtr src_texture = SyncLoadTexture(name, EAH_CPU_Read | EAH_CPU_Write); if (src_texture->Type() != Texture::TT_2D) { cout << "Texture " << name << "is not 2D texture. Skipped." << endl; continue; } uint32_t in_width = src_texture->Width(0); uint32_t in_height = src_texture->Height(0); TexturePtr texture = rf.MakeTexture2D(in_width, in_height, 1, 1, format, 1, 0, EAH_CPU_Read | EAH_CPU_Write); src_texture->CopyToTexture(*texture); Texture::Mapper mapper(*texture, 0, 0, TMA_Read_Only, 0, 0, in_width, in_height); uint8_t const * in_data_p = mapper.Pointer<uint8_t>(); int32_t in_num_tiles_x = std::min((in_width + tile_size - 1) / tile_size, num_tiles); int32_t in_num_tiles_y = std::min((in_height + tile_size - 1) / tile_size, num_tiles); int32_t beg_tile_x = 0; int32_t end_tile_x = std::min(static_cast<int32_t>(x + in_num_tiles_x), static_cast<int32_t>(num_tiles)) - x; int32_t beg_tile_y = 0; int32_t end_tile_y = std::min(static_cast<int32_t>(y + in_num_tiles_y), static_cast<int32_t>(num_tiles)) - y; juda_tex->AddImageEntry(name, x, y, in_num_tiles_x, in_num_tiles_y, addr_u, addr_v, border_clr); std::vector<std::vector<uint8_t>> tiles; std::vector<uint32_t> tile_ids; std::vector<uint32_t> tile_attrs; for (int32_t by = beg_tile_y; by < end_tile_y; ++ by) { tiles.clear(); tile_ids.clear(); tile_attrs.clear(); for (int32_t bx = beg_tile_x; bx < end_tile_x; ++ bx) { uint32_t xindex = bx - beg_tile_x; tiles.push_back(std::vector<uint8_t>(tile_size * tile_size * pixel_size, 0)); tile_ids.push_back(juda_tex->EncodeTileID(level, bx + x, by + y)); tile_attrs.push_back(attr); for (size_t dy = 0; dy < tile_size; ++ dy) { int32_t tex_y = (*calc_v)(static_cast<int32_t>(by * tile_size + dy), in_height); if (tex_y >= 0) { for (size_t dx = 0; dx < tile_size; ++ dx) { int32_t tex_x = (*calc_u)(static_cast<int32_t>(bx * tile_size + dx), in_width); if (tex_x >= 0) { std::memcpy(&tiles[xindex][(dy * tile_size + dx) * pixel_size], &in_data_p[tex_y * mapper.RowPitch() + tex_x * pixel_size], pixel_size); } else { std::memcpy(&tiles[xindex][(dy * tile_size + dx) * pixel_size], &border_clr_u8, pixel_size); } } } else { for (size_t dx = 0; dx < tile_size; ++ dx) { std::memcpy(&tiles[xindex][(dy * tile_size + dx) * pixel_size], &border_clr_u8, pixel_size); } } } } juda_tex->CommitTiles(tiles, tile_ids, tile_attrs); } cout << "Takes " << timer.elapsed() << "s" << endl; } cout << "Total tiles: " << ((1UL << (juda_tex->TreeLevels() * 2)) - 1) / (4 - 1) << endl; cout << "Non empty tiles: " << juda_tex->NumNonEmptyNodes() << endl; cout << "Tree depth: " << juda_tex->TreeLevels() << endl; std::string base_name = jtml_name.substr(0, jtml_name.find_last_of('.')); cout << "Saving... "; timer.restart(); SaveJudaTexture(juda_tex, base_name + ".jdt"); cout << "Takes " << timer.elapsed() << "s" << endl << endl; }
//------------------------------------------------------------- VCNAnim* VCNAnimLoader::LoadAnimXML( const VCNString& filename ) { // Create the new mesh to be filled! VCNAnim* newAnim = NULL; // Open the XML document XMLElementPtr pRootElem = LoadDocumentRoot( filename ); VCN_ASSERT_MSG( pRootElem != NULL, "Could not load XML Animation!" ); // Go through all the MeshElement nodes XMLNodeListPtr elementNodes; pRootElem->selectNodes( (VCNTChar*)kAttrAnimNode, &elementNodes ); VCNLong animNodeCount; elementNodes->get_length( &animNodeCount ); for( VCNLong i=0; i<animNodeCount; i++ ) { // Create the new mesh to be filled! newAnim = new VCNAnim(); // Get the element's node XMLNodePtr elementNode; elementNodes->get_item( i, &elementNode ); // Load the base properties LoadResourceBaseProperties( elementNode, newAnim ); // Go through all the joints that compose this anims XMLNodeListPtr jointNodes; elementNode->selectNodes( (VCNTChar*)kNodeAnimJoint, &jointNodes ); VCNLong jointNodeCount; jointNodes->get_length( &jointNodeCount ); for( VCNLong i=0; i<jointNodeCount; i++ ) { // Get the mesh's node XMLNodePtr jointNode; jointNodes->get_item( i, &jointNode ); // Load the joint VCNAnimJoint* animJoint = LoadJointXML( jointNode ); // The name of the joint will be the name of the anim + the target joint animJoint->SetName( newAnim->GetName() + VCNTXT("_") + animJoint->GetTargetName() ); // Add it to the resource manager VCNResID jointID = VCNResourceCore::GetInstance()->AddResource( animJoint->GetName(), animJoint ); // Add it to the animation newAnim->AddJoint( jointID ); } // Make sure we aren't loading it twice VCN_ASSERT( !VCNResourceCore::GetInstance()->GetResource<VCNAnim>( newAnim->GetName() ) ); // Add it VCNResourceCore::GetInstance()->AddResource( newAnim->GetName(), newAnim ); } // Free up the doc memory ReleaseDocument(); return newAnim; }
void Context::SaveCfg(std::string const & cfg_file) { XMLDocument cfg_doc; XMLNodePtr root = cfg_doc.AllocNode(XNT_Element, "configure"); cfg_doc.RootNode(root); XMLNodePtr context_node = cfg_doc.AllocNode(XNT_Element, "context"); { XMLNodePtr rf_node = cfg_doc.AllocNode(XNT_Element, "render_factory"); rf_node->AppendAttrib(cfg_doc.AllocAttribString("name", cfg_.render_factory_name)); context_node->AppendNode(rf_node); XMLNodePtr af_node = cfg_doc.AllocNode(XNT_Element, "audio_factory"); af_node->AppendAttrib(cfg_doc.AllocAttribString("name", cfg_.audio_factory_name)); context_node->AppendNode(af_node); XMLNodePtr if_node = cfg_doc.AllocNode(XNT_Element, "input_factory"); if_node->AppendAttrib(cfg_doc.AllocAttribString("name", cfg_.input_factory_name)); context_node->AppendNode(if_node); XMLNodePtr sm_node = cfg_doc.AllocNode(XNT_Element, "scene_manager"); sm_node->AppendAttrib(cfg_doc.AllocAttribString("name", cfg_.scene_manager_name)); context_node->AppendNode(sm_node); XMLNodePtr sf_node = cfg_doc.AllocNode(XNT_Element, "show_factory"); sf_node->AppendAttrib(cfg_doc.AllocAttribString("name", cfg_.show_factory_name)); context_node->AppendNode(sf_node); XMLNodePtr scf_node = cfg_doc.AllocNode(XNT_Element, "script_factory"); scf_node->AppendAttrib(cfg_doc.AllocAttribString("name", cfg_.script_factory_name)); context_node->AppendNode(scf_node); XMLNodePtr adsf_node = cfg_doc.AllocNode(XNT_Element, "audio_data_source_factory"); adsf_node->AppendAttrib(cfg_doc.AllocAttribString("name", cfg_.audio_data_source_factory_name)); context_node->AppendNode(adsf_node); } root->AppendNode(context_node); XMLNodePtr graphics_node = cfg_doc.AllocNode(XNT_Element, "graphics"); { XMLNodePtr frame_node = cfg_doc.AllocNode(XNT_Element, "frame"); frame_node->AppendAttrib(cfg_doc.AllocAttribInt("width", cfg_.graphics_cfg.width)); frame_node->AppendAttrib(cfg_doc.AllocAttribInt("height", cfg_.graphics_cfg.height)); std::string color_fmt_str; switch (cfg_.graphics_cfg.color_fmt) { case EF_ARGB8: color_fmt_str = "ARGB8"; break; case EF_ABGR8: color_fmt_str = "ABGR8"; break; case EF_A2BGR10: color_fmt_str = "A2BGR10"; break; default: color_fmt_str = "ARGB8"; break; } frame_node->AppendAttrib(cfg_doc.AllocAttribString("color_fmt", color_fmt_str)); std::string depth_stencil_fmt_str; switch (cfg_.graphics_cfg.depth_stencil_fmt) { case EF_D16: depth_stencil_fmt_str = "D16"; break; case EF_D24S8: depth_stencil_fmt_str = "D24S8"; break; case EF_D32F: depth_stencil_fmt_str = "D32F"; break; default: depth_stencil_fmt_str = "D16"; break; } frame_node->AppendAttrib(cfg_doc.AllocAttribString("depth_stencil_fmt", depth_stencil_fmt_str)); frame_node->AppendAttrib(cfg_doc.AllocAttribInt("fullscreen", cfg_.graphics_cfg.full_screen)); { XMLNodePtr sample_node = cfg_doc.AllocNode(XNT_Element, "sample"); sample_node->AppendAttrib(cfg_doc.AllocAttribInt("count", cfg_.graphics_cfg.sample_count)); sample_node->AppendAttrib(cfg_doc.AllocAttribInt("quality", cfg_.graphics_cfg.sample_quality)); frame_node->AppendNode(sample_node); } graphics_node->AppendNode(frame_node); XMLNodePtr sync_interval_node = cfg_doc.AllocNode(XNT_Element, "sync_interval"); sync_interval_node->AppendAttrib(cfg_doc.AllocAttribInt("value", cfg_.graphics_cfg.sync_interval)); graphics_node->AppendNode(sync_interval_node); XMLNodePtr motion_blur_node = cfg_doc.AllocNode(XNT_Element, "motion_blur"); motion_blur_node->AppendAttrib(cfg_doc.AllocAttribInt("frames", cfg_.graphics_cfg.motion_frames)); graphics_node->AppendNode(motion_blur_node); XMLNodePtr hdr_node = cfg_doc.AllocNode(XNT_Element, "hdr"); hdr_node->AppendAttrib(cfg_doc.AllocAttribInt("value", cfg_.graphics_cfg.hdr)); graphics_node->AppendNode(hdr_node); XMLNodePtr ppaa_node = cfg_doc.AllocNode(XNT_Element, "ppaa"); ppaa_node->AppendAttrib(cfg_doc.AllocAttribInt("value", cfg_.graphics_cfg.ppaa)); graphics_node->AppendNode(ppaa_node); XMLNodePtr gamma_node = cfg_doc.AllocNode(XNT_Element, "gamma"); gamma_node->AppendAttrib(cfg_doc.AllocAttribInt("value", cfg_.graphics_cfg.gamma)); graphics_node->AppendNode(gamma_node); XMLNodePtr color_grading_node = cfg_doc.AllocNode(XNT_Element, "color_grading"); color_grading_node->AppendAttrib(cfg_doc.AllocAttribInt("value", cfg_.graphics_cfg.color_grading)); graphics_node->AppendNode(color_grading_node); XMLNodePtr stereo_node = cfg_doc.AllocNode(XNT_Element, "stereo"); std::string method_str; switch (cfg_.graphics_cfg.stereo_method) { case STM_None: method_str = "none"; break; case STM_ColorAnaglyph_RedCyan: method_str = "red_cyan"; break; case STM_ColorAnaglyph_YellowBlue: method_str = "yellow_blue"; break; case STM_ColorAnaglyph_GreenRed: method_str = "green_red"; break; case STM_LCDShutter: method_str = "lcd_shutter"; break; case STM_HorizontalInterlacing: method_str = "hor_interlacing"; break; case STM_VerticalInterlacing: method_str = "ver_interlacing"; break; case STM_Horizontal: method_str = "horizontal"; break; case STM_Vertical: method_str = "vertical"; break; } stereo_node->AppendAttrib(cfg_doc.AllocAttribString("method", method_str)); std::ostringstream oss; oss.precision(2); oss << std::fixed << cfg_.graphics_cfg.stereo_separation; stereo_node->AppendAttrib(cfg_doc.AllocAttribString("separation", oss.str())); graphics_node->AppendNode(stereo_node); } root->AppendNode(graphics_node); std::ofstream ofs(cfg_file.c_str()); cfg_doc.Print(ofs); }
//------------------------------------------------------------- /// A lighting array is composed of normals and colors //------------------------------------------------------------- VCNResID VCNMeshLoader::LoadMeshElementLightingXML( XMLNodePtr elementNode ) { // Fetch the normals from the element node XMLNodePtr normals = 0; elementNode->selectSingleNode( (VCNTChar*)kNodeVertexNormals, &normals ); bool hasNormals = (normals != NULL); // Fetch the colors from the element node XMLNodePtr colors = 0; elementNode->selectSingleNode( (VCNTChar*)kNodeVertexColors, &colors ); bool hasColors = (colors != NULL); // Get the expected size of the normals VCNUInt normalSize = 0; if( hasNormals ) { GetAttributeUInt( normals, kAttrVertexNormalsSize, normalSize ); if( normalSize == 0 ) hasNormals = false; } // Get the expected size of the colors VCNUInt colorSize = 0; if( hasColors ) { GetAttributeUInt( colors, kAttrVertexColorsSize, colorSize ); if( colorSize == 0 ) hasColors = false; } // If we have neither, then no lighting information at all if( !hasColors && !hasNormals ) return kInvalidResID; // If we have both, they MUST be of same size! if( hasColors && hasNormals && (normalSize != colorSize) ) { VCN_ASSERT_FAIL( "LIGHTING REJECTED!" ); return kInvalidResID; } // Now just retain one of the sizes VCNLong size = (VCNLong)(hasNormals?normalSize:colorSize); // Create an array to contain all of this (6 floats per vertex) VCNUInt stride = size * (kNormalFloats+kColorFloats); VCNFloat* buffer = new VCNFloat[ stride ]; // Create some tools... VCNFloat* ptrFloat = buffer; VCNInt safety = 0; // Pick out the nodes of every normal (if we have them) XMLNodeListPtr normalElements; if( hasNormals ) { normalElements = 0; normals->selectNodes( (VCNTChar*)kNodeVertexNormal, &normalElements ); VCNLong normalElementsLength = 0; normalElements->get_length( &normalElementsLength ); VCN_ASSERT( normalElementsLength == size && "FILE IS CORRUPTED!" ); } // Pick out the nodes of every color (if we have them) XMLNodeListPtr colorsElements; if( hasColors ) { colorsElements = 0; colors->selectNodes( (VCNTChar*)kNodeVertexColor, &colorsElements ); VCNLong colorElementsLength = 0; normalElements->get_length( &colorElementsLength ); VCN_ASSERT( colorElementsLength == size && "FILE IS CORRUPTED!" ); } // Now read it in! for( VCNLong i=0; i<size; i++ ) { // Normals if( hasNormals ) { // Get the element's node XMLNodePtr normalNode = 0; normalElements->get_item( i, &normalNode ); // Read the X GetAttributeFloat( normalNode, kAttrVertexNormalX, *ptrFloat ); ptrFloat++; // Read the Y GetAttributeFloat( normalNode, kAttrVertexNormalY, *ptrFloat ); ptrFloat++; // Read the Z GetAttributeFloat( normalNode, kAttrVertexNormalZ, *ptrFloat ); ptrFloat++; // Verify the safety to make sure we're reading in the right order GetAttributeInt( normalNode, kAttrVertexNormalID, safety ); VCN_ASSERT( safety==i && "VERTEX AREN'T READ IN ORDER!" ); } else { // Put three zeros instead *ptrFloat = 0.0f; ptrFloat++; *ptrFloat = 0.0f; ptrFloat++; *ptrFloat = 0.0f; ptrFloat++; } // Then colors if( hasColors ) { // Get the element's node XMLNodePtr colorNode = 0; colorsElements->get_item( i, &colorNode ); // Read the X GetAttributeFloat( colorNode, kAttrVertexColorR, *ptrFloat ); ptrFloat++; // Read the Y GetAttributeFloat( colorNode, kAttrVertexColorG, *ptrFloat ); ptrFloat++; // Read the Z GetAttributeFloat( colorNode, kAttrVertexColorB, *ptrFloat ); ptrFloat++; // Verify the safety to make sure we're reading in the right order GetAttributeInt( colorNode, kAttrVertexColorID, safety ); VCN_ASSERT( safety==i && "VERTEX AREN'T READ IN ORDER!" ); } else { // Put three ones instead (white) *ptrFloat = 1.0f; ptrFloat++; *ptrFloat = 1.0f; ptrFloat++; *ptrFloat = 1.0f; ptrFloat++; } } // Now give the information to the cache manager // (he'll take care of making this data API specific) VCNResID cacheID = VCNRenderCore::GetInstance()->CreateCache( VT_LIGHTING, buffer, stride*sizeof(VCNFloat) ); // Clear the buffer delete [] buffer; // Return the cache ID return cacheID; }
void SaveRenderMaterial(RenderMaterialPtr const & mtl, std::string const & mtlml_name) { KlayGE::XMLDocument doc; XMLNodePtr root = doc.AllocNode(XNT_Element, "material"); doc.RootNode(root); { XMLNodePtr albedo_node = doc.AllocNode(XNT_Element, "albedo"); std::string color_str = boost::lexical_cast<std::string>(mtl->albedo.x()) + ' ' + boost::lexical_cast<std::string>(mtl->albedo.y()) + ' ' + boost::lexical_cast<std::string>(mtl->albedo.z()) + ' ' + boost::lexical_cast<std::string>(mtl->albedo.w()); albedo_node->AppendAttrib(doc.AllocAttribString("color", color_str)); if (!mtl->tex_names[RenderMaterial::TS_Albedo].empty()) { albedo_node->AppendAttrib(doc.AllocAttribString("texture", mtl->tex_names[RenderMaterial::TS_Albedo])); } root->AppendNode(albedo_node); } if ((mtl->metalness > 0) || !mtl->tex_names[RenderMaterial::TS_Metalness].empty()) { XMLNodePtr metalness_node = doc.AllocNode(XNT_Element, "metalness"); if (mtl->metalness > 0) { metalness_node->AppendAttrib(doc.AllocAttribFloat("value", mtl->metalness)); } if (!mtl->tex_names[RenderMaterial::TS_Metalness].empty()) { metalness_node->AppendAttrib(doc.AllocAttribString("texture", mtl->tex_names[RenderMaterial::TS_Metalness])); } root->AppendNode(metalness_node); } if ((mtl->glossiness > 0) || !mtl->tex_names[RenderMaterial::TS_Glossiness].empty()) { XMLNodePtr glossiness_node = doc.AllocNode(XNT_Element, "glossiness"); if (mtl->glossiness > 0) { glossiness_node->AppendAttrib(doc.AllocAttribFloat("value", mtl->glossiness)); } if (!mtl->tex_names[RenderMaterial::TS_Glossiness].empty()) { glossiness_node->AppendAttrib(doc.AllocAttribString("texture", mtl->tex_names[RenderMaterial::TS_Glossiness])); } root->AppendNode(glossiness_node); } if ((mtl->emissive.x() > 0) || (mtl->emissive.y() > 0) || (mtl->emissive.z() > 0) || (!mtl->tex_names[RenderMaterial::TS_Emissive].empty())) { XMLNodePtr emissive_node = doc.AllocNode(XNT_Element, "emissive"); if ((mtl->emissive.x() > 0) || (mtl->emissive.y() > 0) || (mtl->emissive.z() > 0)) { std::string color_str = boost::lexical_cast<std::string>(mtl->emissive.x()) + ' ' + boost::lexical_cast<std::string>(mtl->emissive.y()) + ' ' + boost::lexical_cast<std::string>(mtl->emissive.z()); emissive_node->AppendAttrib(doc.AllocAttribString("color", color_str)); } if (!mtl->tex_names[RenderMaterial::TS_Emissive].empty()) { emissive_node->AppendAttrib(doc.AllocAttribString("texture", mtl->tex_names[RenderMaterial::TS_Emissive])); } root->AppendNode(emissive_node); } if (!mtl->tex_names[RenderMaterial::TS_Normal].empty()) { XMLNodePtr normal_node = doc.AllocNode(XNT_Element, "normal"); normal_node->AppendAttrib(doc.AllocAttribString("texture", mtl->tex_names[RenderMaterial::TS_Normal])); root->AppendNode(normal_node); } if (!mtl->tex_names[RenderMaterial::TS_Height].empty()) { XMLNodePtr height_node = doc.AllocNode(XNT_Element, "height"); height_node->AppendAttrib(doc.AllocAttribString("texture", mtl->tex_names[RenderMaterial::TS_Height])); height_node->AppendAttrib(doc.AllocAttribFloat("offset", mtl->height_offset_scale.x())); height_node->AppendAttrib(doc.AllocAttribFloat("scale", mtl->height_offset_scale.y())); root->AppendNode(height_node); } if (mtl->detail_mode != RenderMaterial::SDM_Parallax) { XMLNodePtr detail_node = doc.AllocNode(XNT_Element, "detail"); std::string detail_mode_str; switch (mtl->detail_mode) { case RenderMaterial::SDM_FlatTessellation: detail_mode_str = "Flat Tessellation"; break; case RenderMaterial::SDM_SmoothTessellation: detail_mode_str = "Smooth Tessellation"; break; default: KFL_UNREACHABLE("Invalid surface detail mode"); } detail_node->AppendAttrib(doc.AllocAttribString("mode", detail_mode_str)); { XMLNodePtr tess_node = doc.AllocNode(XNT_Element, "tess"); tess_node->AppendAttrib(doc.AllocAttribFloat("edge_hint", mtl->tess_factors.x())); tess_node->AppendAttrib(doc.AllocAttribFloat("inside_hint", mtl->tess_factors.y())); tess_node->AppendAttrib(doc.AllocAttribFloat("min", mtl->tess_factors.z())); tess_node->AppendAttrib(doc.AllocAttribFloat("max", mtl->tess_factors.w())); detail_node->AppendNode(tess_node); } root->AppendNode(detail_node); } if (mtl->transparent) { XMLNodePtr transparent_node = doc.AllocNode(XNT_Element, "transparent"); transparent_node->AppendAttrib(doc.AllocAttribString("value", "1")); root->AppendNode(transparent_node); } if (mtl->alpha_test > 0) { XMLNodePtr alpha_test_node = doc.AllocNode(XNT_Element, "alpha_test"); alpha_test_node->AppendAttrib(doc.AllocAttribFloat("value", mtl->alpha_test)); root->AppendNode(alpha_test_node); } if (mtl->sss) { XMLNodePtr sss_node = doc.AllocNode(XNT_Element, "sss"); sss_node->AppendAttrib(doc.AllocAttribString("value", "1")); root->AppendNode(sss_node); } if (mtl->two_sided) { XMLNodePtr two_sided_node = doc.AllocNode(XNT_Element, "two_sided"); two_sided_node->AppendAttrib(doc.AllocAttribString("value", "1")); root->AppendNode(two_sided_node); } std::ofstream ofs(mtlml_name.c_str()); if (!ofs) { ofs.open((ResLoader::Instance().LocalFolder() + mtlml_name).c_str()); } doc.Print(ofs); }
//------------------------------------------------------------- VCNResID VCNMeshLoader::LoadMeshElementFaceXML( XMLNodePtr elementNode ) { // Fetch the node we need from the element node XMLNodePtr node = 0; elementNode->selectSingleNode( (VCNTChar*)kNodeFaces, &node ); // It might very well be that we aren't using indexes if( node == NULL ) return kInvalidResID; // Get the expected size of the array VCNUInt size = 0; GetAttributeUInt( node, kAttrFacesSize, size ); // If we don't have any, leave. if( size == 0 ) return kInvalidResID; // Create an array to contain all of this (3 indexes per face) VCNUInt stride = kFaceUShorts * kCacheStrides[VT_INDEX]; VCNUInt numBytes = size * stride; VCNByte* buffer = new VCNByte[numBytes]; // Create some tools... VCNUShort* ptrFaces = (VCNUShort*)buffer; VCNInt safety = 0; // Read the XML and fill the array! XMLNodeListPtr faces = 0; node->selectNodes( (VCNTChar*)kNodeFace, &faces ); VCNLong facesLength = 0; faces->get_length( &facesLength ); VCN_ASSERT( facesLength == size && "FILE IS CORRUPTED!" ); for( VCNLong i=0; i<facesLength; i++ ) { // Get the element's node XMLNodePtr faceNode = 0; faces->get_item( i, &faceNode ); // Read the X GetAttributeUShort( faceNode, kAttrFace1, *ptrFaces ); ptrFaces++; // Read the Y GetAttributeUShort( faceNode, kAttrFace2, *ptrFaces ); ptrFaces++; // Read the Z GetAttributeUShort( faceNode, kAttrFace3, *ptrFaces ); ptrFaces++; // Verify the safety to make sure we're reading in the right order GetAttributeInt( faceNode, kAttrVertexPositionID, safety ); VCN_ASSERT( safety==i && "VERTEX AREN'T READ IN ORDER!" ); } // Now give the information to the cache manager // (he'll take care of making this data API specific) VCNResID cacheID = VCNRenderCore::GetInstance()->CreateCache( VT_INDEX, buffer, numBytes ); // Clear the buffer delete [] buffer; // Return the cache ID return cacheID; }
//------------------------------------------------------------- VCNResID VCNMeshLoader::LoadMeshElementPositionXML( XMLNodePtr elementNode, VCNSphere* bounding, VCNAabb* aabb /*= NULL*/ ) { // Fetch the node we need from the element node XMLNodePtr node = 0; elementNode->selectSingleNode( (VCNTChar*)kNodeVertexPositions, &node ); VCN_ASSERT( node != NULL && "No positions in mesh!" ); // Get the expected size of the array VCNUInt size = 0; GetAttributeUInt( node, kAttrVertexPositionsSize, size ); // If we don't have any, leave. if( size == 0 ) return kInvalidResID; // Create an array to contain all of this (3 floats per position) VCNUInt stride = size * kPositionFloats; VCNFloat* buffer = new VCNFloat[ stride ]; // Create some tools... VCNFloat* ptrFloat = buffer; VCNInt safety = 0; // Keep track of the min and max VCNFloat minX, maxX; VCNFloat minY, maxY; VCNFloat minZ, maxZ; minX = minY = minZ = kMaxFloat; maxX = maxY = maxZ = kMinFloat; // Read the XML and fill the array! XMLNodeListPtr positions = 0; node->selectNodes( (VCNTChar*)kNodeVertexPosition, &positions ); VCN_ASSERT( positions != 0 && "FILE IS CORRUPTED!" ); VCNLong positionsLength = 0; positions->get_length( &positionsLength ); VCN_ASSERT( positionsLength == size && "FILE IS CORRUPTED!" ); for( VCNLong i=0; i<positionsLength; i++ ) { // Get the element's node XMLNodePtr positionNode = 0; positions->get_item( i, &positionNode ); // Read the X GetAttributeFloat( positionNode, kAttrVertexPositionX, *ptrFloat ); if( *ptrFloat < minX ) minX = *ptrFloat; if( *ptrFloat > maxX ) maxX = *ptrFloat; ptrFloat++; // Read the Y GetAttributeFloat( positionNode, kAttrVertexPositionY, *ptrFloat ); if( *ptrFloat < minY ) minY = *ptrFloat; if( *ptrFloat > maxY ) maxY = *ptrFloat; ptrFloat++; // Read the Z GetAttributeFloat( positionNode, kAttrVertexPositionZ, *ptrFloat ); if( *ptrFloat < minZ ) minZ = *ptrFloat; if( *ptrFloat > maxZ ) maxZ = *ptrFloat; ptrFloat++; // Verify the safety to make sure we're reading in the right order GetAttributeInt( positionNode, kAttrVertexPositionID, safety ); VCN_ASSERT( safety==i && "VERTEX AREN'T READ IN ORDER!" ); } // Now give the information to the cache manager // (he'll take care of making this data API specific) VCNResID cacheID = VCNRenderCore::GetInstance()->CreateCache( VT_POSITION, buffer, stride*sizeof(VCNFloat) ); // Clear the buffer delete [] buffer; Vector3 minVect ( minX, minY, minZ ); Vector3 maxVect ( maxX, maxY, maxZ ); Vector3 diagonal = (maxVect - minVect) / 2.0f; // If he wants us to fill the AABB, we'll do it for him if( bounding ) { VCNSphere tmpSphere( diagonal.Length(), minVect + diagonal ); *bounding = tmpSphere; } if (aabb) { VCNAabb tempAabb(minVect, maxVect); *aabb = tempAabb; } // Return the cache ID return cacheID; }
void NowWeCanReallyAddTheLevel(XMLNodePtr& levelNode, XMLContextPtr& context) { std::string temp; char namePostFix = 'A'; // a postfix character to add as a name so we can distinguish between different navNodes. -- this is an ugly hack. std::cout << "writing out models..." << std::endl; for(unsigned int i=0;i<modelsInWorld.size();i++) { XMLNodePtr staticNode(new XMLNode(context)); XMLNodePtr posNode(new XMLNode(context)); XMLNodePtr rotNode(new XMLNode(context)); XMLNodePtr nameNode(new XMLNode(context)); XMLNodePtr realNameNode(new XMLNode(context)); staticNode->setName("static"); posNode->setName("pos"); rotNode->setName("rot"); nameNode->setName("model"); staticNode->setType(xml_nt_node); posNode->setType(xml_nt_leaf); nameNode->setType(xml_nt_node); rotNode->setType(xml_nt_leaf); realNameNode->setType(xml_nt_cdata); levelNode->addChild(staticNode); posNode->setAttribute("x", modelsInWorld[i].worldX); posNode->setAttribute("y", modelsInWorld[i].worldZ); posNode->setAttribute("z", modelsInWorld[i].worldY); staticNode->addChild(posNode); rotNode->setAttribute("x", 0.0f); rotNode->setAttribute("y", 0.0f); rotNode->setAttribute("z", 0.0f); staticNode->addChild(rotNode); realNameNode->setCdata(modelsInWorld[i].name); nameNode->addChild(realNameNode); staticNode->addChild(nameNode); if(modelsInWorld[i].name==std::string("turret")) { std::cout << "adding turret info to xml node" << std::endl; staticNode->setName("turret"); XMLNodePtr turretNameNode(new XMLNode(context)); XMLNodePtr maxChildNode(new XMLNode(context)); XMLNodePtr aiLevelNode(new XMLNode(context)); XMLNodePtr parentNode(new XMLNode(context)); XMLNodePtr realParentNode(new XMLNode(context)); XMLNodePtr realTurretNameNode(new XMLNode(context)); turretNameNode->setType(xml_nt_node); realTurretNameNode->setType(xml_nt_cdata); parentNode->setType(xml_nt_node); realParentNode->setType(xml_nt_cdata); aiLevelNode->setType(xml_nt_leaf); maxChildNode->setType(xml_nt_leaf); turretNameNode->setName("name"); parentNode->setName("parent"); aiLevelNode->setName("level"); maxChildNode->setName("maxChildren"); realParentNode->setCdata("null"); realTurretNameNode->setCdata("turret"); aiLevelNode->setAttribute("nu", -1); maxChildNode->setAttribute("num", 0); parentNode->addChild(realParentNode); turretNameNode->addChild(realTurretNameNode); staticNode->addChild(aiLevelNode); staticNode->addChild(parentNode); staticNode->addChild(turretNameNode); staticNode->addChild(maxChildNode); } else if(modelsInWorld[i].name==std::string("security_droid")) { std::cout << "adding droid info to xml node" << std::endl; staticNode->setName("security_droid"); XMLNodePtr droidNameNode(new XMLNode(context)); XMLNodePtr maxChildNode(new XMLNode(context)); XMLNodePtr aiLevelNode(new XMLNode(context)); XMLNodePtr parentNode(new XMLNode(context)); XMLNodePtr realParentNode(new XMLNode(context)); XMLNodePtr realDroidNameNode(new XMLNode(context)); droidNameNode->setType(xml_nt_node); realDroidNameNode->setType(xml_nt_cdata); parentNode->setType(xml_nt_node); realParentNode->setType(xml_nt_cdata); aiLevelNode->setType(xml_nt_leaf); maxChildNode->setType(xml_nt_leaf); droidNameNode->setName("name"); parentNode->setName("parent"); aiLevelNode->setName("level"); maxChildNode->setName("maxChildren"); realParentNode->setCdata("null"); realDroidNameNode->setCdata("droid"); aiLevelNode->setAttribute("nu", -1); maxChildNode->setAttribute("num", 0); parentNode->addChild(realParentNode); droidNameNode->addChild(realDroidNameNode); staticNode->addChild(aiLevelNode); staticNode->addChild(parentNode); staticNode->addChild(droidNameNode); staticNode->addChild(maxChildNode); } } std::cout << "writing out navNodes ..." << std::endl; for(std::vector<navNodeId*>::iterator itr=navNodes.begin();itr!=navNodes.end();itr++) { XMLNodePtr staticNode(new XMLNode(context)); XMLNodePtr posNode(new XMLNode(context)); XMLNodePtr rotNode(new XMLNode(context)); XMLNodePtr nameNode(new XMLNode(context)); XMLNodePtr realNameNode(new XMLNode(context)); staticNode->setName("navNode"); posNode->setName("pos"); rotNode->setName("rot"); nameNode->setName("name"); staticNode->setType(xml_nt_node); posNode->setType(xml_nt_leaf); nameNode->setType(xml_nt_node); rotNode->setType(xml_nt_leaf); realNameNode->setType(xml_nt_cdata); levelNode->addChild(staticNode); posNode->setAttribute("x", (*itr)->worldX); posNode->setAttribute("y", (*itr)->worldZ); posNode->setAttribute("z", (*itr)->worldY); staticNode->addChild(posNode); rotNode->setAttribute("x", 0.0f); rotNode->setAttribute("y", 0.0f); rotNode->setAttribute("z", 0.0f); staticNode->addChild(rotNode); std::ostringstream s; s << (*itr)->id; realNameNode->setCdata(s.str()); nameNode->addChild(realNameNode); staticNode->addChild(nameNode); } std::cout << "writing out NavNodeLinks ... " << std::endl; for(std::vector<pair>::iterator itr=navNodeLinks.begin();itr!=navNodeLinks.end();itr++) { XMLNodePtr staticNode(new XMLNode(context)); staticNode->setName("navNodeLink"); staticNode->setType(xml_nt_node); XMLNodePtr navNode1(new XMLNode(context)); XMLNodePtr navNode2(new XMLNode(context)); navNode1->setType(xml_nt_node); navNode2->setType(xml_nt_node); navNode1->setName("navNode1"); navNode2->setName("navNode2"); XMLNodePtr nameNavNode1(new XMLNode(context)); XMLNodePtr nameNavNode2(new XMLNode(context)); nameNavNode1->setType(xml_nt_cdata); nameNavNode2->setType(xml_nt_cdata); std::ostringstream s1, s2; s1 << (*itr).model1->id; s2 << (*itr).model2->id; nameNavNode1->setCdata(s1.str()); nameNavNode2->setCdata(s2.str()); levelNode->addChild(staticNode); staticNode->addChild(navNode1); staticNode->addChild(navNode2); navNode1->addChild(nameNavNode1); navNode2->addChild(nameNavNode2); } }
//------------------------------------------------------------- VCNResID VCNMeshLoader::LoadMeshElementTextureCoordXML( XMLNodePtr elementNode, VCNCacheType coordType ) { XMLNodePtr node = NULL; // Fetch the node we need from the element node switch( coordType ) { case VT_DIFFUSE_TEX_COORDS: elementNode->selectSingleNode( (VCNTChar*)kNodeDiffuseTexCoords, &node ); break; case VT_NORMAL_TEX_COORDS: elementNode->selectSingleNode( (VCNTChar*)kNodeNormalTexCoords, &node ); break; default: VCN_ASSERT( false && "Trying to load unrecognized coord type!" ); } // If we didn't find it, we don't have it if( node == NULL ) return kInvalidResID; // Get the expected size of the array VCNUInt size = 0; GetAttributeUInt( node, kAttrVertexTexCoordsSize, size ); // If we don't have any, leave. if( size == 0 ) return kInvalidResID; // Create an array to contain all of this (2 floats per position) VCNUInt stride = size * kTexCoordFloats; VCNFloat* buffer = new VCNFloat[ stride ]; // Create some tools... VCNFloat* ptrFloat = buffer; VCNInt safety = 0; // Read the XML and fill the array! XMLNodeListPtr textureCoords = 0; node->selectNodes( (VCNTChar*)kNodeVertexTexCoord, &textureCoords ); VCNLong textureCoordsLength = 0; textureCoords->get_length( &textureCoordsLength ); VCN_ASSERT( textureCoordsLength == size && "FILE IS CORRUPTED!" ); for( VCNLong i=0; i<textureCoordsLength; i++ ) { // Get the first one XMLNodePtr textureCoordNode = 0; textureCoords->get_item( i, &textureCoordNode ); // Read the U GetAttributeFloat( textureCoordNode, kAttrVertexTexCoordU, *ptrFloat ); ptrFloat++; // Read the V GetAttributeFloat( textureCoordNode, kAttrVertexTexCoordV, *ptrFloat ); ptrFloat++; // Verify the safety to make sure we're reading in the right order GetAttributeInt( textureCoordNode, kAttrVertexTexCoordID, safety ); VCN_ASSERT( safety==i && "VERTEX AREN'T READ IN ORDER!" ); } // Now give the information to the cache manager // (he'll take care of making this data API specific) VCNResID cacheID = VCNRenderCore::GetInstance()->CreateCache( coordType, buffer, stride*sizeof(VCNFloat) ); // Clear the buffer delete [] buffer; // Return the cache ID return cacheID; }
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(); } }