Game::HeroInfo::HeroInfo(const PTree& root) : name(root.get<std::string>("name")), user_id(root.get("userId", "")), elo(root.get("elo", -1)), crashed(root.get("crashed",false)) { }
bool LoadDrawable::operator()( const PTree & cfg, SCENENODE & topnode, keyed_container<SCENENODE>::handle * nodehandle, keyed_container<DRAWABLE>::handle * drawhandle) { std::vector<std::string> texname; if (!cfg.get("texture", texname)) return true; std::string meshname; if (!cfg.get("mesh", meshname, error)) return false; return operator()(meshname, texname, cfg, topnode, nodehandle, drawhandle); }
static bool LoadCoilover( const PTree & cfg, CarSuspensionInfo & info, std::ostream & error_output) { if (!cfg.get("spring-constant", info.spring_constant, error_output)) return false; if (!cfg.get("bounce", info.bounce, error_output)) return false; if (!cfg.get("rebound", info.rebound, error_output)) return false; if (!cfg.get("travel", info.travel, error_output)) return false; if (!cfg.get("anti-roll", info.anti_roll, error_output)) return false; LoadPoints(cfg, "damper-factor-", info.damper_factors); LoadPoints(cfg, "spring-factor-", info.spring_factors); return true; }
bool CarGraphics::LoadCameras( const PTree & cfg, const float cambounce, std::ostream & error_output) { 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, cambounce, error_output); if (!cam) { ClearCameras(); return false; } cameras.push_back(cam); } return true; }
bool CAR::LoadPhysics( const PTree & cfg, const std::string & carpath, const MATHVECTOR <float, 3> & initial_position, const QUATERNION <float> & initial_orientation, const bool defaultabs, const bool defaulttcs, const bool damage, ContentManager & content, DynamicsWorld & world, std::ostream & error_output) { std::string carmodel; std::tr1::shared_ptr<MODEL> modelptr; if (!cfg.get("body.mesh", carmodel, error_output)) return false; if (!content.load(carpath, carmodel, modelptr)) return false; btVector3 size = ToBulletVector(modelptr->GetSize()); btVector3 center = ToBulletVector(modelptr->GetCenter()); btVector3 position = ToBulletVector(initial_position); btQuaternion rotation = ToBulletQuaternion(initial_orientation); if (!dynamics.Load(cfg, size, center, position, rotation, damage, world, error_output)) return false; dynamics.SetABS(defaultabs); dynamics.SetTCS(defaulttcs); mz_nominalmax = (GetTireMaxMz(FRONT_LEFT) + GetTireMaxMz(FRONT_RIGHT)) * 0.5; return true; }
void read(PTree & node) { std::string line, name; while (in.good()) { std::getline(in, line, '\n'); if (line.empty()) { continue; } size_t begin = line.find_first_not_of(" \t["); size_t end = line.find_first_of(";#]\r", begin); if (begin >= end) { continue; } size_t next = line.find("=", begin); if (next >= end) { // New node. next = line.find_last_not_of(" \t\r]", end); name = line.substr(begin, next); read(root.set(name, PTree())); continue; } size_t next2 = line.find_first_not_of(" \t\r", next+1); next = line.find_last_not_of(" \t", next-1); if (next2 >= end) continue; name = line.substr(begin, next+1); if (!fopen || line.at(next2) != '&') { // New property. std::string value = line.substr(next2, end-next2); node.set(name, value); continue; } // Value is a reference. std::string value = line.substr(next2+1, end-next2-1); const PTree * ref_ptr; if (root.get(value, ref_ptr) || cache.get(value, ref_ptr)) { node.set(name, *ref_ptr); continue; } // Load external reference. PTree ref; read_ini(value, *fopen, ref); cache.set(value, ref); node.set(name, ref); } }
bool CarGraphics::LoadLight( const PTree & cfg, ContentManager & content, std::ostream & error_output) { float radius; std::string radiusstr; Vec3 pos(0), col(0); if (!cfg.get("position", pos, error_output)) return false; if (!cfg.get("color", col, error_output)) return false; if (!cfg.get("radius", radius, error_output)) return false; cfg.get("radius", radiusstr); lights.push_back(Light()); SceneNode & bodynoderef = topnode.GetNode(bodynode); lights.back().node = bodynoderef.AddNode(); SceneNode & node = bodynoderef.GetNode(lights.back().node); node.GetTransform().SetTranslation(Vec3(pos[0], pos[1], pos[2])); std::shared_ptr<Model> mesh; if (!content.get(mesh, "", "cube" + radiusstr)) { VertexArray varray; varray.SetToUnitCube(); varray.Scale(radius, radius, radius); content.load(mesh, "", "cube" + radiusstr, varray); } models.insert(mesh); keyed_container <Drawable> & dlist = node.GetDrawList().lights_omni; lights.back().draw = dlist.insert(Drawable()); Drawable & draw = dlist.get(lights.back().draw); draw.SetColor(col[0], col[1], col[2]); draw.SetModel(*mesh); draw.SetCull(true); draw.SetDrawEnable(false); return true; }
bool CAR::LoadLight( const PTree & cfg, ContentManager & content, std::ostream & error_output) { float radius; std::string radiusstr; MATHVECTOR<float, 3> pos(0), col(0); if (!cfg.get("position", pos, error_output)) return false; if (!cfg.get("color", col, error_output)) return false; if (!cfg.get("radius", radius, error_output)) return false; cfg.get("radius", radiusstr); lights.push_back(LIGHT()); SCENENODE & bodynoderef = topnode.GetNode(bodynode); lights.back().node = bodynoderef.AddNode(); SCENENODE & node = bodynoderef.GetNode(lights.back().node); node.GetTransform().SetTranslation(MATHVECTOR<float,3>(pos[0], pos[1], pos[2])); std::tr1::shared_ptr<MODEL> mesh; if (!content.get("", "cube"+radiusstr, mesh)) { VERTEXARRAY varray; varray.SetToUnitCube(); varray.Scale(radius, radius, radius); content.load("", "cube"+radiusstr, varray, mesh); } models.push_back(mesh); keyed_container <DRAWABLE> & dlist = GetDrawlist(node, OMNI); lights.back().draw = dlist.insert(DRAWABLE()); DRAWABLE & draw = dlist.get(lights.back().draw); draw.SetColor(col[0], col[1], col[2]); draw.SetModel(*mesh); draw.SetCull(true, true); draw.SetDrawEnable(false); return true; }
bool LoadDrawable::operator()( const std::string & meshname, const std::vector<std::string> & texname, const PTree & cfg, SCENENODE & topnode, keyed_container<SCENENODE>::handle * nodeptr, keyed_container<DRAWABLE>::handle * drawptr) { DRAWABLE drawable; // set textures TEXTUREINFO texinfo; texinfo.mipmap = true; texinfo.anisotropy = anisotropy; std::tr1::shared_ptr<TEXTURE> tex; if (texname.size() == 0) { error << "No texture defined" << std::endl; return false; } if (texname.size() > 0) { if (!content.load(path, texname[0], texinfo, tex)) return false; drawable.SetDiffuseMap(tex); } if (texname.size() > 1) { if (!content.load(path, texname[1], texinfo, tex)) return false; drawable.SetMiscMap1(tex); } if (texname.size() > 2) { if (!content.load(path, texname[2], texinfo, tex)) return false; drawable.SetMiscMap2(tex); } // set mesh std::tr1::shared_ptr<MODEL> mesh; if (!content.load(path, meshname, mesh)) return false; std::string scalestr; if (cfg.get("scale", scalestr) && !content.get(path, meshname + scalestr, mesh)) { MATHVECTOR<float, 3> scale; std::stringstream s(scalestr); s >> scale; VERTEXARRAY meshva = mesh->GetVertexArray(); meshva.Scale(scale[0], scale[1], scale[2]); content.load(path, meshname + scalestr, meshva, mesh); }
// 1-9 points static void LoadPoints(const PTree & cfg, const std::string & name, LinearInterp<btScalar> & points) { int i = 1; std::stringstream s; s << std::setw(1) << i; std::vector<btScalar> point(2); while (cfg.get(name+s.str(), point) && i < 10) { s.clear(); s << std::setw(1) << ++i; points.AddPoint(point[0], point[1]); } }
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; }
bool CARENGINEINFO::Load(const PTree & cfg, std::ostream & error_output) { std::vector<std::pair<btScalar, btScalar> > torque; std::vector<btScalar> pos(3); if (!cfg.get("peak-engine-rpm", redline, error_output)) return false; //used only for the redline graphics if (!cfg.get("rpm-limit", rpm_limit, error_output)) return false; if (!cfg.get("inertia", inertia, error_output)) return false; if (!cfg.get("start-rpm", start_rpm, error_output)) return false; if (!cfg.get("stall-rpm", stall_rpm, error_output)) return false; if (!cfg.get("fuel-consumption", fuel_consumption, error_output)) return false; if (!cfg.get("mass", mass, error_output)) return false; if (!cfg.get("position", pos, error_output)) return false; position.setValue(pos[0], pos[1], pos[2]); int curve_num = 0; std::vector<btScalar> torque_point(2); std::string torque_str("torque-curve-00"); while (cfg.get(torque_str, torque_point)) { torque.push_back(std::pair<btScalar, btScalar>(torque_point[0], torque_point[1])); curve_num++; std::stringstream str; str << "torque-curve-"; str.width(2); str.fill('0'); str << curve_num; torque_str = str.str(); } if (torque.size() <= 1) { error_output << "You must define at least 2 torque curve points." << std::endl; return false; } SetTorqueCurve(redline, torque); 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; }
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; }
bool CarSuspension::Load( const PTree & cfg_wheel, CarSuspension *& suspension, std::ostream & error_output) { CarSuspensionInfo info; std::vector<btScalar> p(3); if (!cfg_wheel.get("position", p, error_output)) return false; if (!cfg_wheel.get("camber", info.camber, error_output)) return false; if (!cfg_wheel.get("caster", info.caster, error_output)) return false; if (!cfg_wheel.get("toe", info.toe, error_output)) return false; cfg_wheel.get("steering", info.steering_angle); cfg_wheel.get("ackermann", info.ackermann); info.position.setValue(p[0], p[1], p[2]); const PTree * cfg_coil; if (!cfg_wheel.get("coilover", cfg_coil, error_output)) return false; if (!LoadCoilover(*cfg_coil, info, error_output)) return false; const PTree * cfg_susp; if (cfg_wheel.get("macpherson-strut", cfg_susp)) { std::vector<btScalar> strut_top(3), strut_end(3), hinge(3); if (!cfg_susp->get("hinge", hinge, error_output)) return false; if (!cfg_susp->get("strut-top", strut_top, error_output)) return false; if (!cfg_susp->get("strut-end", strut_end, error_output)) return false; MacPhersonSuspension * mps = new MacPhersonSuspension(); mps->Init(info, strut_top, strut_end, hinge); suspension = mps; } /* else if (cfg_wheel.get("double-wishbone", cfg_susp)) { std::vector<btScalar> up_ch0(3), up_ch1(3), lo_ch0(3), lo_ch1(3), up_hub(3), lo_hub(3); if (!cfg_susp->get("upper-chassis-front", up_ch0, error_output)) return false; if (!cfg_susp->get("upper-chassis-rear", up_ch1, error_output)) return false; if (!cfg_susp->get("lower-chassis-front", lo_ch0, error_output)) return false; if (!cfg_susp->get("lower-chassis-rear", lo_ch1, error_output)) return false; if (!cfg_susp->get("upper-hub", up_hub, error_output)) return false; if (!cfg_susp->get("lower-hub", lo_hub, error_output)) return false; WishboneSuspension * wbs = new WishboneSuspension(); wbs->Init(info, up_ch0, up_ch1, lo_ch0, lo_ch1, up_hub, lo_hub); suspension = wbs; }*/ else { std::vector<btScalar> ch(3, 0), wh(3, 0); if (!cfg_wheel.get("hinge", cfg_susp, error_output)) return false; if (!cfg_susp->get("chassis", ch, error_output)) return false; if (!cfg_susp->get("wheel", wh, error_output)) return false; BasicSuspension * bs = new BasicSuspension(); bs->Init(info, ch, wh); suspension = bs; } return true; }
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 CarEngineInfo::Load(const PTree & cfg, std::ostream & error_output) { std::vector<btScalar> pos(3, 0.0f); if (!cfg.get("displacement", displacement, error_output)) return false; if (!cfg.get("max-power", maxpower, error_output)) return false; if (!cfg.get("peak-engine-rpm", redline, error_output)) return false; if (!cfg.get("rpm-limit", rpm_limit, error_output)) return false; if (!cfg.get("inertia", inertia, error_output)) return false; if (!cfg.get("start-rpm", start_rpm, error_output)) return false; if (!cfg.get("stall-rpm", stall_rpm, error_output)) return false; if (!cfg.get("position", pos, error_output)) return false; if (!cfg.get("mass", mass, error_output)) return false; position.setValue(pos[0], pos[1], pos[2]); // fuel consumption btScalar fuel_heating_value = 4.5E7; // Ws/kg btScalar engine_efficiency = 0.35; cfg.get("fuel-heating-value", fuel_heating_value); cfg.get("efficiency", engine_efficiency); fuel_rate = 1 / (engine_efficiency * fuel_heating_value); // nos parameters cfg.get("nos-mass", nos_mass); cfg.get("nos-boost", nos_boost); cfg.get("nos-ratio", nos_fuel_ratio); // friction (Heywood 1988 tfmep) friction[0] = btScalar(97000 / (4 * M_PI)) * displacement; friction[1] = btScalar(15000 / (4 * M_PI)) * displacement; friction[2] = btScalar(5000 / (4 * M_PI)) * displacement; std::vector<btScalar> f(3, 0); if (cfg.get("torque-friction", f)) { friction[0] = f[0]; friction[1] = f[1]; friction[2] = f[2]; } // torque int curve_num = 0; std::vector<btScalar> torque_point(2); std::string torque_str("torque-curve-00"); std::vector<std::pair<btScalar, btScalar> > torque; while (cfg.get(torque_str, torque_point)) { torque.push_back(std::pair<btScalar, btScalar>(torque_point[0], torque_point[1])); curve_num++; std::ostringstream s; s << "torque-curve-"; s.width(2); s.fill('0'); s << curve_num; torque_str = s.str(); } if (torque.size() <= 1) { error_output << "You must define at least 2 torque curve points." << std::endl; return false; } // set torque curve torque_curve.Clear(); if (torque[0].first > stall_rpm) { btScalar dx = torque[1].first - torque[0].first; btScalar dy = torque[1].second - torque[0].second; btScalar stall_torque = dy / dx * (stall_rpm - torque[0].first) + torque[0].second; torque_curve.AddPoint(stall_rpm, stall_torque); error_output << "Torque curve begins above stall rpm.\n" << "Extrapolating to " << stall_rpm << ", " << stall_torque << std::endl; } for (const auto & tp : torque) { torque_curve.AddPoint(tp.first, tp.second); } if (torque[torque.size() - 1].first < rpm_limit) { btScalar r = torque[torque.size() - 1].first + 10000.0f; btScalar t = 0.0f; torque_curve.AddPoint(r , t); error_output << "Torque curve ends below rpm limit.\n" << "Extrapolating to " << r << ", " << t << std::endl; } // calculate idle throttle position for (idle_throttle = 0.0f; idle_throttle < 1.0f; idle_throttle += 0.01f) { if (GetTorque(idle_throttle, start_rpm) > -GetFrictionTorque(idle_throttle, start_rpm)) break; } // calculate idle throttle slope btScalar stall_throttle; for (stall_throttle = idle_throttle; stall_throttle < 1.0f; stall_throttle += 0.01f) { if (GetTorque(stall_throttle, stall_rpm) > -GetFrictionTorque(stall_throttle, stall_rpm)) break; } idle_throttle_slope = 1.5f * (idle_throttle - stall_throttle) / (start_rpm - stall_rpm); 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; }
int main() { PTree<string> pt; // normal get string name("Alice"); pt.put("person.name", name); string nameOut = pt.get("person.name"); // assignment syntax assert(name == nameOut); string nameEx(pt.get<string>("person.name")); // explicit syntax, need convert explicitly assert(name == nameEx); assert(pt.isValidPath("person.name")); // const get const PTree<string>& cpt = pt; string nameOutC = cpt.get("person.name"); assert(name == nameOutC); string nameExC; nameExC = cpt.get<string>("person.name"); assert(name == nameExC); const string& nameRefC = cpt.get("person.name"); assert(name == nameRefC); // ref get string& nameRef = pt.get("person.name"); nameRef = "Bob"; nameOut = pt.get<string>("person.name"); assert(nameRef == nameOut); // other types int age = 25; pt.put("person.age", age); int ageOut(pt.get("person.age")); assert(age == ageOut); float height = 1.65; pt.put("person.height", height); float heightOut(pt.get("person.height")); assert(height == heightOut); Car car; car.color = "black"; car.price = 50000; pt.put("person.car", car); Car carOut(pt.get("person.car")); assert(car.color == carOut.color); assert(car.price == carOut.price); // push as vector int income = 100; pt.push("person.deposit", income++); pt.push("person.deposit", income++); pt.push("person.deposit", income++); const std::vector<int>& sum = pt.get("person.deposit"); assert(sum.size() == 3); // del string error; pt.del("person.name"); try { pt.get("person.name"); } catch (const PTreeError& e) { error = e.what(); cout << "catched PTreeError: " << error << endl; } assert(!error.empty()); assert(!pt.isValidPath("person.name")); cout << "all test passed" << endl; return 0; }