X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Flibr2c2%2Fvehicletype.cpp;h=58ef1d468cb4946294a166f85cf020a862ac8748;hb=7ecefa673473c6d6ef9505ca415d5b0e4dbc3944;hp=3d695f82622ada1cf4e269ef6cb78dbfb10331ef;hpb=1ff06c5bc46a677fa389ef86c6b26664368f1653;p=r2c2.git diff --git a/source/libr2c2/vehicletype.cpp b/source/libr2c2/vehicletype.cpp index 3d695f8..58ef1d4 100644 --- a/source/libr2c2/vehicletype.cpp +++ b/source/libr2c2/vehicletype.cpp @@ -1,10 +1,8 @@ -/* $Id$ - -This file is part of R²C² -Copyright © 2010 Mikkosoft Productions, Mikko Rasa -Distributed under the GPL -*/ - +#include +#include +#include +#include +#include #include "vehicletype.h" using namespace std; @@ -13,11 +11,15 @@ using namespace Msp; namespace R2C2 { VehicleType::VehicleType(const ArticleNumber &an): - art_nr(an), + ObjectType(an), locomotive(false), + swap_direction(false), + gauge(1.524), length(0), width(0), - height(0) + height(0), + rotate_object(false), + max_speed(0) { } unsigned VehicleType::get_max_function() const @@ -27,34 +29,62 @@ unsigned VehicleType::get_max_function() const return (--functions.end())->first; } +const VehicleType::Axle &VehicleType::get_axle(unsigned i) const +{ + if(i>=axles.size()) + throw out_of_range("VehicleType::get_axle"); + return axles[i]; +} + +const VehicleType::Axle &VehicleType::get_fixed_axle(unsigned i) const +{ + if(i>=fixed_axles.size()) + throw out_of_range("VehicleType::get_fixed_axle"); + return *fixed_axles[i]; +} + +const VehicleType::Bogie &VehicleType::get_bogie(unsigned i) const +{ + if(i>=bogies.size()) + throw out_of_range("VehicleType::get_bogie"); + return bogies[i]; +} + +const VehicleType::Axle &VehicleType::get_bogie_axle(unsigned i, unsigned j) const +{ + if(i>=bogies.size()) + throw out_of_range("VehicleType::get_bogie_axle"); + if(j>=bogies[i].axles.size()) + throw out_of_range("VehicleType::get_bogie_axle"); + return *bogies[i].axles[j]; +} + +const VehicleType::Rod &VehicleType::get_rod(unsigned i) const +{ + if(i>=rods.size()) + throw out_of_range("VehicleType::get_rod"); + return rods[i]; +} + float VehicleType::get_front_axle_offset() const { - float front = length/2; if(!axles.empty()) - front = axles.front().position; - if(!bogies.empty()) - { - const Bogie &bogie = bogies.front(); - front = max(front, bogie.position+bogie.axles.front().position); - } - return front; + return axles.front().position; + return length/2; } float VehicleType::get_back_axle_offset() const { - float back = -length/2; if(!axles.empty()) - back = axles.back().position; - if(!bogies.empty()) - { - const Bogie &bogie = bogies.back(); - back = min(back, bogie.position+bogie.axles.back().position); - } - return back; + return axles.back().position; + return -length/2; } VehicleType::Axle::Axle(): + index(0), + bogie(0), + local_position(0), position(0), wheel_dia(0), powered(false) @@ -67,20 +97,59 @@ VehicleType::Bogie::Bogie(): { } +VehicleType::Rod::Rod(): + mirror_object(false) +{ } + + VehicleType::Loader::Loader(VehicleType &vt): - DataFile::ObjectLoader(vt) + DataFile::DerivedObjectLoader(vt) { add("axle", &Loader::axle); add("bogie", &Loader::bogie); add("function", &Loader::function); + add("gauge", &Loader::gauge); add("height", &Loader::height); add("length", &Loader::length); add("locomotive", &VehicleType::locomotive); + add("maximum_speed", &VehicleType::max_speed); + add("mirror_rods", &Loader::mirror_rods); add("object", &VehicleType::object); - add("name", &VehicleType::name); + add("rod", &Loader::rod); + add("rotate_object", &VehicleType::rotate_object); + add("swap_direction", &VehicleType::swap_direction); add("width", &Loader::width); } +void VehicleType::Loader::finish() +{ + for(unsigned i=0; ibogie = &obj.bogies[i]; + obj.bogies[i].axles[j]->position += obj.bogies[i].position; + } + } + + for(unsigned i=0; isecond>=0x10000) + throw runtime_error(format("unresolved reference to %s\n", i->first)); + + obj.shape = new Geometry::TransformedShape( + Geometry::Box(obj.length, obj.width, obj.height), + Transform::translation(Vector(0, 0, obj.height/2))); +} + void VehicleType::Loader::axle() { Axle axl; @@ -91,7 +160,8 @@ void VehicleType::Loader::axle() void VehicleType::Loader::bogie() { Bogie bog; - load_sub(bog); + Bogie::Loader ldr(obj, bog); + load_sub_with(ldr); obj.bogies.push_back(bog); } @@ -100,6 +170,11 @@ void VehicleType::Loader::function(unsigned i, const string &f) obj.functions[i] = f; } +void VehicleType::Loader::gauge(float g) +{ + obj.gauge = g/1000; +} + void VehicleType::Loader::height(float h) { obj.height = h/1000; @@ -110,6 +185,65 @@ void VehicleType::Loader::length(float l) obj.length = l/1000; } +void VehicleType::Loader::mirror_rods() +{ + MirrorParametersLoader params; + load_sub_with(params); + Regex r_filter(params.filter); + + vector mirror_indices(obj.rods.size(), 0); + for(TagMap::const_iterator i=rod_tags.begin(); i!=rod_tags.end(); ++i) + if(i->second<0x10000 && r_filter.match(i->first)) + mirror_indices[i->second] = 1; + + for(unsigned i=0, j=obj.rods.size(); i::iterator j=mr.constraints.begin(); j!=mr.constraints.end(); ++j) + { + j->target_position.y = -j->target_position.y; + j->local_position.y = -j->local_position.y; + j->axis.y = -j->axis.y; + if(j->target==RodConstraint::ROD && mirror_indices[j->target_index]) + j->target_index = mirror_indices[j->target_index]; + else if(j->target==RodConstraint::AXLE) + j->target_position = axle_trans.transform(j->target_position); + } + + obj.rods.push_back(mr); + } +} + +void VehicleType::Loader::rod(const string &t) +{ + Rod rd; + Rod::Loader ldr(rd, rod_tags); + load_sub_with(ldr); + + unsigned n = obj.rods.size(); + if(rod_tags.count(t)) + { + unsigned p = rod_tags[t]; + for(vector::iterator i=obj.rods.begin(); i!=obj.rods.end(); ++i) + for(vector::iterator j=i->constraints.begin(); j!=i->constraints.end(); ++j) + if(j->target_index==p) + j->target_index = n; + } + rod_tags[t] = n; + obj.rods.push_back(rd); +} + void VehicleType::Loader::width(float w) { obj.width = w/1000; @@ -127,7 +261,8 @@ VehicleType::Axle::Loader::Loader(Axle &a): void VehicleType::Axle::Loader::position(float p) { - obj.position = p/1000; + obj.local_position = p/1000; + obj.position = obj.local_position; } void VehicleType::Axle::Loader::wheel_diameter(float d) @@ -136,8 +271,9 @@ void VehicleType::Axle::Loader::wheel_diameter(float d) } -VehicleType::Bogie::Loader::Loader(Bogie &b): - DataFile::ObjectLoader(b) +VehicleType::Bogie::Loader::Loader(VehicleType &t, Bogie &b): + DataFile::ObjectLoader(b), + parent(t) { add("axle", &Loader::axle); add("object", &Bogie::object); @@ -149,7 +285,11 @@ void VehicleType::Bogie::Loader::axle() { Axle axl; load_sub(axl); - obj.axles.push_back(axl); + if(obj.axles.empty()) + obj.first_axle = parent.axles.size(); + parent.axles.push_back(axl); + // Actual pointers will be filled after everything is loaded + obj.axles.push_back(0); } void VehicleType::Bogie::Loader::position(float p) @@ -157,4 +297,103 @@ void VehicleType::Bogie::Loader::position(float p) obj.position = p/1000; } + +VehicleType::RodConstraint::RodConstraint(): + type(MOVE), + target(BODY), + target_index(0) +{ } + + +VehicleType::RodConstraint::Loader::Loader(RodConstraint &c, TagMap &t): + DataFile::ObjectLoader(c), + tags(t) +{ + add("axis", &Loader::axis); + add("local_position", &Loader::local_position); + add("target_axle", &Loader::target_axle); + add("target_position", &Loader::target_position); + add("target_rod", &Loader::target_rod); +} + +void VehicleType::RodConstraint::Loader::axis(float x, float y, float z) +{ + obj.axis = Vector(x, y, z); + obj.axis.normalize(); +} + +void VehicleType::RodConstraint::Loader::local_position(float x, float y, float z) +{ + obj.local_position = Vector(x/1000, y/1000, z/1000); +} + +void VehicleType::RodConstraint::Loader::target_axle(unsigned i) +{ + obj.target = AXLE; + obj.target_index = i; + // TODO check range +} + +void VehicleType::RodConstraint::Loader::target_position(float x, float y, float z) +{ + obj.target_position = Vector(x/1000, y/1000, z/1000); +} + +void VehicleType::RodConstraint::Loader::target_rod(const string &n) +{ + obj.target = ROD; + TagMap::iterator i = tags.find(n); + if(i!=tags.end()) + obj.target_index = i->second; + else + { + obj.target_index = 0x10000+tags.size(); + tags[n] = obj.target_index; + } +} + + +VehicleType::Rod::Loader::Loader(Rod &r, TagMap &t): + DataFile::ObjectLoader(r), + tags(t) +{ + add("initial_position", &Loader::initial_position); + add("mirror_object", &Rod::mirror_object); + add("move", &Loader::constraint); + add("object", &Rod::object); + add("rotate", &Loader::constraint); + add("slide", &Loader::constraint); +} + +template +void VehicleType::Rod::Loader::constraint() +{ + RodConstraint cns; + cns.type = t; + load_sub(cns, tags); + obj.constraints.push_back(cns); +} + +void VehicleType::Rod::Loader::initial_position(float x, float y, float z) +{ + obj.initial_position = Vector(x/1000, y/1000, z/1000); +} + + +VehicleType::MirrorParametersLoader::MirrorParametersLoader() +{ + add("filter", &MirrorParametersLoader::filt); + add("phase_offset", &MirrorParametersLoader::phase_offs); +} + +void VehicleType::MirrorParametersLoader::filt(const string &f) +{ + filter = f; +} + +void VehicleType::MirrorParametersLoader::phase_offs(float o) +{ + phase_offset = Angle::from_degrees(o); +} + } // namespace R2C2