bool operator()(const PTree & cfg) { const PTree * link; if (cfg.get("link", link)) { // load breakable body drawables if (!loadDrawable(cfg, topnode)) return false; } else { // load fixed body drawables if (!loadDrawable(cfg, topnode.GetNode(bodynode))) return false; } return true; }
static bool LoadWheel( const PTree & cfg_wheel, struct LoadDrawable & loadDrawable, SCENENODE & topnode, std::ostream & error_output) { keyed_container<SCENENODE>::handle wheelnode = topnode.AddNode(); ContentManager & content = loadDrawable.content; const std::string& path = loadDrawable.path; std::string meshname; std::vector<std::string> texname; if (!cfg_wheel.get("mesh", meshname, error_output)) return false; if (!cfg_wheel.get("texture", texname, error_output)) return false; std::string tiredim; const PTree * cfg_tire; if (!cfg_wheel.get("tire", cfg_tire, error_output)) return false; if (!cfg_tire->get("size", tiredim, error_output)) return false; MATHVECTOR<float, 3> size(0); cfg_tire->get("size", size); float width = size[0] * 0.001; float diameter = size[2] * 0.0254; // get wheel disk mesh std::tr1::shared_ptr<MODEL> mesh; if (!content.load(path, meshname, mesh)) return false; // gen wheel mesh if (!content.get(path, meshname+tiredim, mesh)) { VERTEXARRAY rimva, diskva; MESHGEN::mg_rim(rimva, size[0], size[1], size[2], 10); diskva = mesh->GetVertexArray(); diskva.Translate(-0.75 * 0.5, 0, 0); diskva.Scale(width, diameter, diameter); content.load(path, meshname+tiredim, rimva + diskva, mesh); } // load wheel if (!loadDrawable(meshname+tiredim, texname, cfg_wheel, topnode, &wheelnode)) { return false; } // tire (optional) texname.clear(); if (!cfg_tire->get("texture", texname, error_output)) return true; // gen tire mesh if (!content.get(path, "tire"+tiredim, mesh)) { VERTEXARRAY tireva; MESHGEN::mg_tire(tireva, size[0], size[1], size[2]); content.load(path, "tire"+tiredim, tireva, mesh); } // load tire if (!loadDrawable("tire"+tiredim, texname, *cfg_tire, topnode.GetNode(wheelnode))) { return false; } // brake (optional) texname.clear(); std::string brakename; const PTree * cfg_brake; if (!cfg_wheel.get("brake", cfg_brake, error_output)) return true; if (!cfg_brake->get("texture", texname)) return true; float radius; std::string radiusstr; cfg_brake->get("radius", radius); cfg_brake->get("radius", radiusstr); // gen brake disk mesh if (!content.get(path, "brake"+radiusstr, mesh)) { float diameter_mm = radius * 2 * 1000; float thickness_mm = 0.025 * 1000; VERTEXARRAY brakeva; MESHGEN::mg_brake_rotor(brakeva, diameter_mm, thickness_mm); content.load(path, "brake"+radiusstr, brakeva, mesh); } // load brake disk if (!loadDrawable("brake"+radiusstr, texname, *cfg_brake, topnode.GetNode(wheelnode))) { return false; } return true; }
bool CAR::LoadGraphics( const PTree & cfg, const std::string & partspath, const std::string & carpath, const std::string & carname, const std::string & carpaint, const MATHVECTOR <float, 3> & carcolor, const int anisotropy, const float camerabounce, const bool damage, const bool debugmode, ContentManager & content, std::ostream & info_output, std::ostream & error_output) { //write_inf(cfg, std::cerr); cartype = carname; LoadDrawable loadDrawable(carpath, anisotropy, content, models, error_output); // load body first const PTree * cfg_body; std::string meshname; std::vector<std::string> texname; if (!cfg.get("body", cfg_body, error_output)) { error_output << "there is a problem with the .car file" << std::endl; return false; } if (!cfg_body->get("mesh", meshname, error_output)) return false; if (!cfg_body->get("texture", texname, error_output)) return false; if (carpaint != "default") texname[0] = carpaint; if (!loadDrawable(meshname, texname, *cfg_body, topnode, &bodynode)) return false; // load wheels const PTree * cfg_wheel; if (!cfg.get("wheel", cfg_wheel, error_output)) return false; for (PTree::const_iterator i = cfg_wheel->begin(); i != cfg_wheel->end(); ++i) { if (!LoadWheel(i->second, loadDrawable, topnode, error_output)) { error_output << "Failed to load wheels." << std::endl; return false; } } // load drawables LoadBody loadBody(topnode, bodynode, loadDrawable); for (PTree::const_iterator i = cfg.begin(); i != cfg.end(); ++i) { if (i->first != "body" && i->first != "steering" && i->first != "light-brake" && i->first != "light-reverse") { loadBody(i->second); } } // load steering wheel const PTree * cfg_steer; if (cfg.get("steering", cfg_steer)) { SCENENODE & bodynoderef = topnode.GetNode(bodynode); if (!loadDrawable(*cfg_steer, bodynoderef, &steernode, 0)) { error_output << "Failed to load steering wheel." << std::endl; return false; } cfg_steer->get("max-angle", steer_angle_max); steer_angle_max = steer_angle_max / 180.0 * M_PI; SCENENODE & steernoderef = bodynoderef.GetNode(steernode); steer_orientation = steernoderef.GetTransform().GetRotation(); } // load brake/reverse light point light sources (optional) int i = 0; std::string istr = "0"; const PTree * cfg_light; while (cfg.get("light-brake-"+istr, cfg_light)) { if (!LoadLight(*cfg_light, content, error_output)) { error_output << "Failed to load lights." << std::endl; return false; } std::stringstream sstr; sstr << ++i; istr = sstr.str(); } i = 0; istr = "0"; while (cfg.get("light-reverse-"+istr, cfg_light)) { if (!LoadLight(*cfg_light, content, error_output)) { error_output << "Failed to load lights." << std::endl; return false; } std::stringstream sstr; sstr << ++i; istr = sstr.str(); } // load car brake/reverse graphics (optional) if (cfg.get("light-brake", cfg_light)) { SCENENODE & bodynoderef = topnode.GetNode(bodynode); if (!loadDrawable(*cfg_light, bodynoderef, 0, &brakelights)) { error_output << "Failed to load lights." << std::endl; return false; } } if (cfg.get("light-reverse", cfg_light)) { SCENENODE & bodynoderef = topnode.GetNode(bodynode); if (!loadDrawable(*cfg_light, bodynoderef, 0, &reverselights)) { error_output << "Failed to load lights." << std::endl; return false; } } const PTree * cfg_cams; if (!cfg.get("camera", cfg_cams)) { return false; } if (!cfg_cams->size()) { error_output << "No cameras defined." << std::endl; return false; } cameras.reserve(cfg_cams->size()); for (PTree::const_iterator i = cfg_cams->begin(); i != cfg_cams->end(); ++i) { CAMERA * cam = LoadCamera(i->second, camerabounce, error_output); if (!cam) return false; cameras.push_back(cam); } SetColor(carcolor[0], carcolor[1], carcolor[2]); return true; }
PHDrawable * IGObject::getDrawable() { if (!drawable) drawable = loadDrawable(); return drawable; }
static bool LoadWheel( const PTree & cfg_wheel, struct LoadDrawable & loadDrawable, SceneNode & topnode, std::ostream & error_output) { SceneNode::Handle wheelnode = topnode.AddNode(); ContentManager & content = loadDrawable.content; const std::string& path = loadDrawable.path; std::string meshname; std::vector<std::string> texname; std::shared_ptr<Model> mesh; const PTree * cfg_tire; Vec3 size(0); std::string sizestr; if (!cfg_wheel.get("mesh", meshname, error_output)) return false; if (!cfg_wheel.get("texture", texname, error_output)) return false; if (!cfg_wheel.get("tire", cfg_tire, error_output)) return false; if (!cfg_tire->get("size", sizestr, error_output)) return false; if (!cfg_tire->get("size", size, error_output)) return false; // load wheel bool genrim = true; cfg_wheel.get("genrim", genrim); if (genrim) { // get wheel disk mesh content.load(mesh, path, meshname); // gen wheel mesh meshname = meshname + sizestr; if (!content.get(mesh, path, meshname)) { float width = size[0] * 0.001; float diameter = size[2] * 0.0254; VertexArray rimva, diskva; MeshGen::mg_rim(rimva, size[0], size[1], size[2], 10); diskva = mesh->GetVertexArray(); diskva.Translate(-0.75 * 0.5, 0, 0); diskva.Scale(width, diameter, diameter); content.load(mesh, path, meshname, rimva + diskva); } } if (!loadDrawable(meshname, texname, cfg_wheel, topnode, &wheelnode)) { return false; } // load tire (optional) texname.clear(); if (cfg_tire->get("texture", texname)) { meshname.clear(); if (!cfg_tire->get("mesh", meshname)) { // gen tire mesh meshname = "tire" + sizestr; if (!content.get(mesh, path, meshname)) { VertexArray tireva; MeshGen::mg_tire(tireva, size[0], size[1], size[2]); content.load(mesh, path, meshname, tireva); } } if (!loadDrawable(meshname, texname, *cfg_tire, topnode.GetNode(wheelnode))) { return false; } } // load brake (optional) texname.clear(); const PTree * cfg_brake; if (cfg_wheel.get("brake", cfg_brake, error_output) && cfg_brake->get("texture", texname)) { float radius; std::string radiusstr; cfg_brake->get("radius", radius); cfg_brake->get("radius", radiusstr); meshname.clear(); if (!cfg_brake->get("mesh", meshname)) { // gen brake disk mesh meshname = "brake" + radiusstr; if (!content.get(mesh, path, meshname)) { float diameter_mm = radius * 2 * 1000; float thickness_mm = 0.025 * 1000; VertexArray brakeva; MeshGen::mg_brake_rotor(brakeva, diameter_mm, thickness_mm); content.load(mesh, path, meshname, brakeva); } } if (!loadDrawable(meshname, texname, *cfg_brake, topnode.GetNode(wheelnode))) { return false; } } return true; }
bool CarGraphics::Load( const PTree & cfg, const std::string & carpath, const std::string & /*carname*/, const std::string & carwheel, const std::string & carpaint, const Vec3 & carcolor, const int anisotropy, const float camerabounce, ContentManager & content, std::ostream & error_output) { assert(!loaded); // init drawable load functor LoadDrawable loadDrawable(carpath, anisotropy, content, models, textures, error_output); // load body first const PTree * cfg_body; std::string meshname; std::vector<std::string> texname; if (!cfg.get("body", cfg_body, error_output)) return false; if (!cfg_body->get("mesh", meshname, error_output)) return false; if (!cfg_body->get("texture", texname, error_output)) return false; if (carpaint != "default") texname[0] = carpaint; if (!loadDrawable(meshname, texname, *cfg_body, topnode, &bodynode)) return false; // load wheels const PTree * cfg_wheels; if (!cfg.get("wheel", cfg_wheels, error_output)) return false; std::shared_ptr<PTree> sel_wheel; if (carwheel != "default" && !content.load(sel_wheel, carpath, carwheel)) return false; for (PTree::const_iterator i = cfg_wheels->begin(); i != cfg_wheels->end(); ++i) { const PTree * cfg_wheel = &i->second; // override default wheel with selected, not very efficient, fixme PTree opt_wheel; if (sel_wheel.get()) { opt_wheel.set(*sel_wheel); opt_wheel.merge(*cfg_wheel); cfg_wheel = &opt_wheel; } if (!LoadWheel(*cfg_wheel, loadDrawable, topnode, error_output)) { error_output << "Failed to load wheels." << std::endl; return false; } } // load drawables LoadBody loadBody(topnode, bodynode, loadDrawable); for (PTree::const_iterator i = cfg.begin(); i != cfg.end(); ++i) { if (i->first != "body" && i->first != "steering" && i->first != "light-brake" && i->first != "light-reverse") { loadBody(i->second); } } // load steering wheel const PTree * cfg_steer; if (cfg.get("steering", cfg_steer)) { SceneNode & bodynoderef = topnode.GetNode(bodynode); if (!loadDrawable(*cfg_steer, bodynoderef, &steernode, 0)) { error_output << "Failed to load steering wheel." << std::endl; return false; } cfg_steer->get("max-angle", steer_angle_max); steer_angle_max = steer_angle_max / 180.0 * M_PI; SceneNode & steernoderef = bodynoderef.GetNode(steernode); steer_orientation = steernoderef.GetTransform().GetRotation(); steer_rotation = steer_orientation; } // load brake/reverse light point light sources (optional) int i = 0; std::string istr = "0"; const PTree * cfg_light; while (cfg.get("light-brake-"+istr, cfg_light)) { if (!LoadLight(*cfg_light, content, error_output)) { error_output << "Failed to load lights." << std::endl; return false; } std::ostringstream sstr; sstr << ++i; istr = sstr.str(); } i = 0; istr = "0"; while (cfg.get("light-reverse-"+istr, cfg_light)) { if (!LoadLight(*cfg_light, content, error_output)) { error_output << "Failed to load lights." << std::endl; return false; } std::ostringstream sstr; sstr << ++i; istr = sstr.str(); } // load car brake/reverse graphics (optional) if (cfg.get("light-brake", cfg_light)) { SceneNode & bodynoderef = topnode.GetNode(bodynode); if (!loadDrawable(*cfg_light, bodynoderef, 0, &brakelights)) { error_output << "Failed to load lights." << std::endl; return false; } } if (cfg.get("light-reverse", cfg_light)) { SceneNode & bodynoderef = topnode.GetNode(bodynode); if (!loadDrawable(*cfg_light, bodynoderef, 0, &reverselights)) { error_output << "Failed to load lights." << std::endl; return false; } } if (!LoadCameras(cfg, camerabounce, error_output)) { return false; } SetColor(carcolor[0], carcolor[1], carcolor[2]); loaded = true; return true; }