From 113289dc170e1cd463d47cc8bd9a41908c701332 Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Sat, 27 Mar 2010 20:35:45 +0000 Subject: [PATCH] Add transform function for S-bends --- src/Editor.cpp | 2 +- src/Map.cpp | 2 +- src/Points.cpp | 2 +- src/SBend.cpp | 78 +++++++++++++++++++++++++++++++++++++++++++------- 4 files changed, 71 insertions(+), 13 deletions(-) diff --git a/src/Editor.cpp b/src/Editor.cpp index bba6bd6..a415d0a 100644 --- a/src/Editor.cpp +++ b/src/Editor.cpp @@ -307,7 +307,7 @@ bool Editor::canPlaceTrack(ITrackSegmentPtr track) for (vector >::iterator it = covered.begin(); it != covered.end(); ++it) { if (map->isValidTrack(*it)) { - warn() << "Cannot place curve here"; + warn() << "Cannot place track here"; return false; } } diff --git a/src/Map.cpp b/src/Map.cpp index 19a53e1..0c80e20 100644 --- a/src/Map.cpp +++ b/src/Map.cpp @@ -765,7 +765,7 @@ void Map::renderSector(IGraphicsPtr aContext, int id, tile.track->renderedOn(frameNum); -#if 0 +#if 1 // Draw the endpoints for debugging vector > tiles; tile.track->get()->getEndpoints(tiles); diff --git a/src/Points.cpp b/src/Points.cpp index e310c7e..913a009 100644 --- a/src/Points.cpp +++ b/src/Points.cpp @@ -364,7 +364,7 @@ void Points::transform(const track::TravelToken& aToken, float delta) const glTranslatef( static_cast(myX) + xTrans, - 0.0f, + height, static_cast(myY) + yTrans); if (myAxis == axis::Y || myAxis == -axis::Y) diff --git a/src/SBend.cpp b/src/SBend.cpp index e1021b7..6880f55 100644 --- a/src/SBend.cpp +++ b/src/SBend.cpp @@ -72,7 +72,7 @@ SBend::SBend(track::Direction dir, int straight, int off) assert(straight > 0); - static const float PINCH = 1.0f; + const float pinch = static_cast(straight) / 3.0f; const int reflect = (axis == axis::Y ? -1 : 1); @@ -80,8 +80,8 @@ SBend::SBend(track::Direction dir, int straight, int off) const float straightF = static_cast(straight); Vector p1 = makeVector(0.0f, 0.0f, 0.0f); - Vector p2 = makeVector(PINCH, 0.0f, 0.0f); - Vector p3 = makeVector(straightF - PINCH, 0.0f, offsetF); + Vector p2 = makeVector(pinch, 0.0f, 0.0f); + Vector p3 = makeVector(straightF - pinch, 0.0f, offsetF); Vector p4 = makeVector(straightF, 0.0f, offsetF); curve = makeBezierCurve(p1, p2, p3, p4); @@ -128,22 +128,30 @@ track::Connection SBend::nextPosition(const track::TravelToken& token) const { ensureValidDirection(token.direction); + Point disp; + if (token.direction == axis::X) - return make_pair(makePoint(origin.x + 1, origin.y), axis::X); + disp = makePoint(straight, offset); else if (token.direction == -axis::X) - return make_pair(makePoint(origin.x - 1, origin.y), -axis::X); + disp = makePoint(-1, 0); else if (token.direction == axis::Y) - return make_pair(makePoint(origin.x, origin.y + 1), axis::Y); + disp = makePoint(offset, straight); else if (token.direction == -axis::Y) - return make_pair(makePoint(origin.x, origin.y - 1), -axis::Y); + disp = makePoint(0, -1); else assert(false); + + return make_pair(origin + disp, token.direction); } void SBend::getEndpoints(vector >& output) const { output.push_back(origin); - // output.push_back(origin + makePoint(xOffset, yOffset)); + + if (axis == axis::X) + output.push_back(origin + makePoint(straight - 1, offset)); + else + output.push_back(origin + makePoint(offset, straight - 1)); } void SBend::getCovers(vector >& output) const @@ -159,12 +167,62 @@ ITrackSegmentPtr SBend::mergeExit(Point where, track::Direction dir) track::TravelToken SBend::getTravelToken(track::Position pos, track::Direction dir) const { - assert(false); + using namespace placeholders; + + ensureValidDirection(dir); + + track::TravelToken tok = { + dir, + pos, + bind(&SBend::transform, this, _1, _2), + track::flatGradientFunc, + 1 + }; + return tok; } void SBend::transform(const track::TravelToken& token, float delta) const { - assert(false); + assert(delta < curve.length); + + const bool backwards = token.direction == -axis; + if (backwards) + delta = curve.length - delta; + + const float curveDelta = delta / curve.length; + + Vector curveValue = curve(curveDelta); + + const Vector deriv = curve.deriv(curveDelta); + const float angle = + radToDeg(atanf(deriv.z / deriv.x)); + + float xTrans, yTrans; + if (axis == axis::X) { + xTrans = curveValue.x; + yTrans = curveValue.z; + } + else if (axis == axis::Y) { + xTrans = -curveValue.z; + yTrans = curveValue.x; + } + else + assert(false); + + glTranslatef( + static_cast(origin.x) + xTrans, + height, + static_cast(origin.y) + yTrans); + + if (axis == axis::Y) + glRotatef(-90.0f, 0.0f, 1.0f, 0.0f); + + glTranslatef(-0.5f, 0.0f, 0.0f); + + glRotatef(-angle, 0.0f, 1.0f, 0.0f); + + if (backwards) + glRotatef(180.0f, 0.0f, 1.0f, 0.0f); } void SBend::ensureValidDirection(track::Direction dir) const -- 2.39.2