From 7f90e3618139465c533aec37e8d1d76c66eb8514 Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Wed, 30 Jun 2010 21:24:47 +0100 Subject: [PATCH] Train moving along GenTrack --- include/Maths.hpp | 5 ++ maps/gen_track/gen_track.xml | 33 +++++++++--- src/GenTrack.cpp | 97 ++++++++++++++++++++++++++++++++---- src/Map.cpp | 4 +- src/Train.cpp | 4 +- 5 files changed, 122 insertions(+), 21 deletions(-) diff --git a/include/Maths.hpp b/include/Maths.hpp index 4b4800b..29ea33c 100644 --- a/include/Maths.hpp +++ b/include/Maths.hpp @@ -193,6 +193,11 @@ struct Point { return *this; } + Point operator-() const + { + return make_point(-x, -y); + } + bool operator<(const Point& rhs) const { return x < rhs.x diff --git a/maps/gen_track/gen_track.xml b/maps/gen_track/gen_track.xml index 8449624..8e232d1 100644 --- a/maps/gen_track/gen_track.xml +++ b/maps/gen_track/gen_track.xml @@ -2,19 +2,25 @@ No Name - + gen_track.bin + + + + + + + + - + - - + @@ -22,8 +28,21 @@ + exit-dir-x="-1" exit-dir-y="1"/> + + + + + + + + + diff --git a/src/GenTrack.cpp b/src/GenTrack.cpp index 3adcc23..850169f 100644 --- a/src/GenTrack.cpp +++ b/src/GenTrack.cpp @@ -18,6 +18,8 @@ #include "ITrackSegment.hpp" #include "TrackCommon.hpp" #include "XMLBuilder.hpp" +#include "OpenGLHelper.hpp" +#include "ILogger.hpp" #include @@ -52,6 +54,9 @@ public: private: float extend_from_center(track::Direction dir) const; + void ensure_valid_direction(track::Direction dir) const; + void transform(const track::TravelToken& token, float delta) const; + float rotation_at(float delta) const; BezierCurve curve; IMeshBufferPtr rail_buf; @@ -59,6 +64,7 @@ private: Point origin; float height; Vector delta; + track::Direction entry_dir, exit_dir; typedef tuple, track::Direction, @@ -72,7 +78,9 @@ GenTrack::MeshCache GenTrack::mesh_cache; GenTrack::GenTrack(Vector delta, track::Direction entry_dir, track::Direction exit_dir) - : delta(delta) + : delta(delta), + entry_dir(entry_dir), + exit_dir(exit_dir) { Vector delta_f = make_vector( static_cast(delta.x), @@ -82,12 +90,12 @@ GenTrack::GenTrack(Vector delta, Vector entry_dir_norm = make_vector( static_cast(entry_dir.x), 0.0f, - static_cast(entry_dir.y)).normalise(); + static_cast(entry_dir.z)).normalise(); Vector exit_dir_norm = make_vector( static_cast(exit_dir.x), 0.0f, - static_cast(exit_dir.y)).normalise(); + static_cast(exit_dir.z)).normalise(); float pinch_length = (delta_f.length() + 1.0f) / 3.0f; @@ -115,15 +123,14 @@ float GenTrack::extend_from_center(track::Direction dir) const { // Track must extend from the centre to the edge of a tile const float x_sq = static_cast(dir.x * dir.x); - const float y_sq = static_cast(dir.y * dir.y); + const float y_sq = static_cast(dir.z * dir.z); - if (dir.x == dir.y) + if (dir.x == dir.z) return sqrtf(2.0f) * 0.5f; - else if (dir.x < dir.y) + else if (dir.x < dir.z) return sqrtf(x_sq / y_sq + 1) * 0.5f; else return sqrtf(y_sq / x_sq + 1) * 0.5f; - } void GenTrack::merge(IMeshBufferPtr buf) const @@ -149,12 +156,33 @@ float GenTrack::segment_length(const track::TravelToken& token) const bool GenTrack::is_valid_direction(const track::Direction& dir) const { - return false; + return dir == entry_dir || dir == -exit_dir; +} + +void GenTrack::ensure_valid_direction(track::Direction dir) const +{ + if (!is_valid_direction(dir)) + throw runtime_error( + "Invalid direction on gen-track: " + + boost::lexical_cast(dir) + + " (should be " + + boost::lexical_cast(entry_dir) + + " or " + boost::lexical_cast(-exit_dir) + ")"); } track::Connection GenTrack::next_position(const track::TravelToken& token) const { - throw runtime_error("next_position not implemented"); + ensure_valid_direction(token.direction); + + if (token.direction == entry_dir) { + Point off = + make_point(exit_dir.x, exit_dir.z) + make_point(delta.x, delta.y); + return make_pair(origin + off, exit_dir); + } + else { + Point off = -make_point(exit_dir.x, exit_dir.z); + return make_pair(origin + off, exit_dir); + } } void GenTrack::get_endpoints(vector >& output) const @@ -176,10 +204,59 @@ ITrackSegmentPtr GenTrack::merge_exit(Point where, track::Direction dir) return ITrackSegmentPtr(); } +float GenTrack::rotation_at(float curve_delta) const +{ + assert(curve_delta >= 0.0f && curve_delta <= 1.0f); + + const Vector deriv = curve.deriv(curve_delta); + + // Derivation of angle depends on quadrant + if (deriv.z >= 0 && deriv.x > 0) + return rad_to_deg(atanf(deriv.z / deriv.x)); + else if (deriv.z > 0 && deriv.x <= 0) + return 90 - rad_to_deg(atanf(deriv.x / deriv.z)); + else if (deriv.z < 0 && deriv.x <= 0) + return 270 - rad_to_deg(atanf(deriv.x / deriv.z)); + else if (deriv.z <= 0 && deriv.x > 0) + return rad_to_deg(atanf(deriv.z / deriv.x)); + else + assert(false); +} + +void GenTrack::transform(const track::TravelToken& token, float delta) const +{ + assert(delta < curve.length); + + const float curve_delta = delta / curve.length; + + Vector curve_value = curve(curve_delta); + + const float angle = rotation_at(curve_delta); + + glTranslatef( + static_cast(origin.x) + curve_value.x, + height, + static_cast(origin.y) + curve_value.z); + + glRotatef(-angle, 0.0f, 1.0f, 0.0f); + +} + track::TravelToken GenTrack::get_travel_token(track::Position pos, track::Direction dir) const { - throw runtime_error("get_travel_token not implemented"); + using namespace placeholders; + + ensure_valid_direction(dir); + + track::TravelToken tok = { + dir, + pos, + bind(&GenTrack::transform, this, _1, _2), + track::flat_gradient_func, + 1 + }; + return tok; } xml::element GenTrack::to_xml() const diff --git a/src/Map.cpp b/src/Map.cpp index 380d828..5832a8f 100644 --- a/src/Map.cpp +++ b/src/Map.cpp @@ -1727,10 +1727,10 @@ void MapLoader::handle_gen_track(const AttributeSet& attrs) attrs.get("delta-y", delta.y); attrs.get("entry-dir-x", entry_dir.x); - attrs.get("entry-dir-y", entry_dir.y); + attrs.get("entry-dir-y", entry_dir.z); attrs.get("exit-dir-x", exit_dir.x); - attrs.get("exit-dir-y", exit_dir.y); + attrs.get("exit-dir-y", exit_dir.z); my_map->set_track_at(tile, make_gen_track(delta, entry_dir, exit_dir)); } diff --git a/src/Train.cpp b/src/Train.cpp index e9d7fd3..3ae3679 100644 --- a/src/Train.cpp +++ b/src/Train.cpp @@ -108,7 +108,7 @@ Train::Train(IMapPtr a_map) // Bit of a hack to put the engine in the right place move(0.275); -#if 1 +#if 0 for (int i = 1; i <= 4; i++) add_part(load_waggon("coal_truck")); #endif @@ -253,7 +253,7 @@ void Train::enter_segment(Part& a_part, const track::Connection& a_connection) Point pos; tie(pos, a_part.direction) = a_connection; -#if 0 +#if 1 debug() << "Train part entered segment at " << pos << " moving " << a_part.direction; #endif -- 2.39.2