From bb74c5ba5f37183aa8420f44d583a9176d82b309 Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Fri, 5 Feb 2010 22:06:38 +0000 Subject: [PATCH] Re-indent some files to 4-spaces --- include/IMap.hpp | 119 ++++--- include/OpenGLHelper.hpp | 26 +- src/Editor.cpp | 661 ++++++++++++++++++++------------------- src/Game.cpp | 438 +++++++++++++------------- src/LTree.cpp | 294 ++++++++--------- src/OpenGLHelper.cpp | 222 ++++++------- src/Points.cpp | 592 +++++++++++++++++------------------ src/TrackCommon.cpp | 488 ++++++++++++++--------------- src/Train.cpp | 514 +++++++++++++++--------------- 9 files changed, 1677 insertions(+), 1677 deletions(-) diff --git a/include/IMap.hpp b/include/IMap.hpp index 7eb905a..fc0b4a1 100644 --- a/include/IMap.hpp +++ b/include/IMap.hpp @@ -32,86 +32,85 @@ // It also contains the track layout and any scenery items class IMap { public: - virtual int width() const = 0; - virtual int depth() const = 0; + virtual int width() const = 0; + virtual int depth() const = 0; - // Return the track segment at the given position - // It is invalid to call this with a position that doesn't - // contain the *origin* of a track segment -- call isValidTrack - // first - virtual ITrackSegmentPtr trackAt(const Point& aPoint) const = 0; + // Return the track segment at the given position + // It is invalid to call this with a position that doesn't + // contain the *origin* of a track segment -- call isValidTrack + // first + virtual ITrackSegmentPtr trackAt(const Point& aPoint) const = 0; - // True if the given position is the origin of a track segment - virtual bool isValidTrack(const Point& aPoint) const = 0; + // True if the given position is the origin of a track segment + virtual bool isValidTrack(const Point& aPoint) const = 0; - // Change the track segment at the given position - // Set rebuild to true to update the display lists used to render - // the map - virtual void setTrackAt(const Point& aPoint, - ITrackSegmentPtr aTrack) = 0; + // Change the track segment at the given position + // Set rebuild to true to update the display lists used to render + // the map + virtual void setTrackAt(const Point& aPoint, + ITrackSegmentPtr aTrack) = 0; - // Return the station at this track location or a null pointer - virtual IStationPtr stationAt(Point aPoint) const = 0; + // Return the station at this track location or a null pointer + virtual IStationPtr stationAt(Point aPoint) const = 0; - // Delete the contents of a tile - virtual void eraseTile(int x, int y) = 0; + // Delete the contents of a tile + virtual void eraseTile(int x, int y) = 0; - // The start location consists of both a position and - // a direction vector - virtual track::Connection start() const = 0; + // The start location consists of both a position and + // a direction vector + virtual track::Connection start() const = 0; - virtual void render(IGraphicsPtr aContext) const = 0; + virtual void render(IGraphicsPtr aContext) const = 0; - // Draw a white border around the given tile - typedef tuple HighlightColour; - virtual void highlightTile(IGraphicsPtr aContext, - const Point& aPoint, - HighlightColour aColour) const = 0; + // Draw a white border around the given tile + typedef tuple HighlightColour; + virtual void highlightTile(IGraphicsPtr aContext, + const Point& aPoint, HighlightColour aColour) const = 0; - // Given a pick name return the (x, y) co-ordinate - virtual Point pickPosition(unsigned aName) const = 0; + // Given a pick name return the (x, y) co-ordinate + virtual Point pickPosition(unsigned aName) const = 0; - // True if this names a valid tile - virtual bool isValidTileName(unsigned aName) const = 0; + // True if this names a valid tile + virtual bool isValidTileName(unsigned aName) const = 0; - // Save the map to its resource - virtual void save() = 0; + // Save the map to its resource + virtual void save() = 0; - // Return the name of the map resource - virtual string name() const = 0; + // Return the name of the map resource + virtual string name() const = 0; - // Change the start location - // The second variant allows setting the direction as well - virtual void setStart(int x, int y) = 0; - virtual void setStart(int x, int y, int dirX, int dirY) = 0; + // Change the start location + // The second variant allows setting the direction as well + virtual void setStart(int x, int y) = 0; + virtual void setStart(int x, int y, int dirX, int dirY) = 0; - // Toggle display of grid lines - virtual void setGrid(bool onOff) = 0; + // Toggle display of grid lines + virtual void setGrid(bool onOff) = 0; - // Toggle pick mode on and off - // This turns of display of everything but the terrain - // and things that can be clicked on - virtual void setPickMode(bool onOff) = 0; + // Toggle pick mode on and off + // This turns of display of everything but the terrain + // and things that can be clicked on + virtual void setPickMode(bool onOff) = 0; - // Make a hill or valley in the given area - virtual void raiseArea(const Point& aStartPos, - const Point& aFinishPos) = 0; - virtual void lowerArea(const Point& aStartPos, - const Point& aFinishPos) = 0; + // Make a hill or valley in the given area + virtual void raiseArea(const Point& aStartPos, + const Point& aFinishPos) = 0; + virtual void lowerArea(const Point& aStartPos, + const Point& aFinishPos) = 0; - // Make all tiles in the area the same height - virtual void levelArea(Point aStartPos, Point aFinishPos) = 0; + // Make all tiles in the area the same height + virtual void levelArea(Point aStartPos, Point aFinishPos) = 0; - // Create a new station covering this area or extend an existing station - virtual IStationPtr extendStation(Point aStartPos, - Point aFinishPos) = 0; + // Create a new station covering this area or extend an existing station + virtual IStationPtr extendStation(Point aStartPos, + Point aFinishPos) = 0; - // Place a building at this location - virtual void placeBuilding(Point aPoint, IBuildingPtr aBuilding, - float anAngle) = 0; + // Place a building at this location + virtual void placeBuilding(Point aPoint, IBuildingPtr aBuilding, + float anAngle) = 0; - // Get the height above ground at a particular point - virtual float heightAt(float x, float y) const = 0; + // Get the height above ground at a particular point + virtual float heightAt(float x, float y) const = 0; // Place a tree, etc. at a location virtual void addScenery(Point where, ISceneryPtr s) = 0; diff --git a/include/OpenGLHelper.hpp b/include/OpenGLHelper.hpp index f8ba328..25375f9 100644 --- a/include/OpenGLHelper.hpp +++ b/include/OpenGLHelper.hpp @@ -40,19 +40,19 @@ unsigned endPick(unsigned* aBuffer); // as OpenGL types namespace gl { - inline void colour(const Colour& c) - { - glColor4f(c.r, c.g, c.b, c.a); - } - - template - inline void translate(const Vector& v); - - template <> - inline void translate(const Vector& v) - { - glTranslatef(v.x, v.y, v.z); - } + inline void colour(const Colour& c) + { + glColor4f(c.r, c.g, c.b, c.a); + } + + template + inline void translate(const Vector& v); + + template <> + inline void translate(const Vector& v) + { + glTranslatef(v.x, v.y, v.z); + } } #endif diff --git a/src/Editor.cpp b/src/Editor.cpp index 0e5eb12..701ecea 100644 --- a/src/Editor.cpp +++ b/src/Editor.cpp @@ -153,42 +153,42 @@ void Editor::save() // possible directions of dragging void Editor::dragBoxBounds(int& xMin, int& xMax, int &yMin, int& yMax) const { - xMin = min(dragBegin.x, dragEnd.x); - xMax = max(dragBegin.x, dragEnd.x); + xMin = min(dragBegin.x, dragEnd.x); + xMax = max(dragBegin.x, dragEnd.x); - yMin = min(dragBegin.y, dragEnd.y); - yMax = max(dragBegin.y, dragEnd.y); + yMin = min(dragBegin.y, dragEnd.y); + yMax = max(dragBegin.y, dragEnd.y); } // Render the next frame void Editor::display(IGraphicsPtr aContext) const { - if (!map) - return; + if (!map) + return; - aContext->setCamera(myPosition, makeVector(45.0f, 45.0f, 0.0f)); + aContext->setCamera(myPosition, makeVector(45.0f, 45.0f, 0.0f)); - mySun->apply(); + mySun->apply(); - map->render(aContext); + map->render(aContext); - // Draw the highlight if we are dragging track - if (amDragging) { - int xmin, xmax, ymin, ymax; - dragBoxBounds(xmin, xmax, ymin, ymax); + // Draw the highlight if we are dragging track + if (amDragging) { + int xmin, xmax, ymin, ymax; + dragBoxBounds(xmin, xmax, ymin, ymax); - for (int x = xmin; x <= xmax; x++) { - for (int y = ymin; y <= ymax; y++) - map->highlightTile(aContext, makePoint(x, y), - make_tuple(1.0f, 1.0f, 1.0f)); - } - } + for (int x = xmin; x <= xmax; x++) { + for (int y = ymin; y <= ymax; y++) + map->highlightTile(aContext, makePoint(x, y), + make_tuple(1.0f, 1.0f, 1.0f)); + } + } } // Render the overlay void Editor::overlay() const { - layout->render(); + layout->render(); } // Prepare the next frame @@ -200,253 +200,254 @@ void Editor::update(IPickBufferPtr aPickBuffer, int aDelta) // True if the `aFirstPoint' is a valid track segment and it can // connect to `aSecondPoint' bool Editor::canConnect(const Point& aFirstPoint, - const Point& aSecondPoint) const + const Point& aSecondPoint) const { - if (!map->isValidTrack(aFirstPoint)) - return false; + if (!map->isValidTrack(aFirstPoint)) + return false; - ITrackSegmentPtr track = map->trackAt(aFirstPoint); + ITrackSegmentPtr track = map->trackAt(aFirstPoint); - Vector dir = makeVector - (aFirstPoint.x - aSecondPoint.x, 0, - aFirstPoint.y - aSecondPoint.y).normalise(); + Vector dir = makeVector( + aFirstPoint.x - aSecondPoint.x, + 0, + aFirstPoint.y - aSecondPoint.y).normalise(); - return track->isValidDirection(dir) - || track->isValidDirection(-dir); + return track->isValidDirection(dir) + || track->isValidDirection(-dir); } // Draw a single tile of straight track and check for collisions // Returns `false' if track cannot be placed here bool Editor::drawTrackTile(const Point& aPoint, const track::Direction& anAxis) { - if (map->isValidTrack(aPoint)) { - ITrackSegmentPtr merged = map->trackAt(aPoint)->mergeExit(aPoint, anAxis); - if (merged) { - map->setTrackAt(aPoint, merged); - return true; - } - else { - warn() << "Cannot merge track"; - return false; - } - } - else { - map->setTrackAt(aPoint, makeStraightTrack(anAxis)); - return true; - } + if (map->isValidTrack(aPoint)) { + ITrackSegmentPtr merged = map->trackAt(aPoint)->mergeExit(aPoint, anAxis); + if (merged) { + map->setTrackAt(aPoint, merged); + return true; + } + else { + warn() << "Cannot merge track"; + return false; + } + } + else { + map->setTrackAt(aPoint, makeStraightTrack(anAxis)); + return true; + } } // Special case where the user drags a rectangle of width 1 // This just draws straight track along the rectangle void Editor::drawDraggedStraight(const track::Direction& anAxis, int aLength) { - Point where = dragBegin; + Point where = dragBegin; - for (int i = 0; i < aLength; i++) { - drawTrackTile(where, anAxis); + for (int i = 0; i < aLength; i++) { + drawTrackTile(where, anAxis); - where.x += anAxis.x; - where.y += anAxis.z; - } + where.x += anAxis.x; + where.y += anAxis.z; + } } // Called when the user has finished dragging a rectangle for track // Connect the beginning and end up in the simplest way possible void Editor::drawDraggedTrack() { - track::Direction straight; // Orientation for straight track section + track::Direction straight; // Orientation for straight track section - int xmin, xmax, ymin, ymax; - dragBoxBounds(xmin, xmax, ymin, ymax); + int xmin, xmax, ymin, ymax; + dragBoxBounds(xmin, xmax, ymin, ymax); - int xlen = abs(xmax - xmin) + 1; - int ylen = abs(ymax - ymin) + 1; - - // Try to merge the start and end directly - const track::Direction mergeAxis = - xlen > ylen ? (dragBegin.x < dragEnd.x ? -axis::X : axis::X) - : (dragBegin.y < dragEnd.y ? -axis::Y : axis::Y); - if (map->isValidTrack(dragEnd)) { - ITrackSegmentPtr merged = - map->trackAt(dragEnd)->mergeExit(dragBegin, mergeAxis); - - if (merged) { - // Erase all the tiles covered - for (int x = xmin; x <= xmax; x++) { - for (int y = ymin; y <= ymax; y++) - map->eraseTile(x, y); - } + int xlen = abs(xmax - xmin) + 1; + int ylen = abs(ymax - ymin) + 1; + + // Try to merge the start and end directly + const track::Direction mergeAxis = + xlen > ylen ? (dragBegin.x < dragEnd.x ? -axis::X : axis::X) + : (dragBegin.y < dragEnd.y ? -axis::Y : axis::Y); + if (map->isValidTrack(dragEnd)) { + ITrackSegmentPtr merged = + map->trackAt(dragEnd)->mergeExit(dragBegin, mergeAxis); + + if (merged) { + // Erase all the tiles covered + for (int x = xmin; x <= xmax; x++) { + for (int y = ymin; y <= ymax; y++) + map->eraseTile(x, y); + } - map->setTrackAt(dragEnd, merged); - return; - } - } + map->setTrackAt(dragEnd, merged); + return; + } + } - // Normalise the coordinates so the start is always the one with - // the smallest x-coordinate - if (dragBegin.x > dragEnd.x) - swap(dragBegin, dragEnd); - - track::Direction startDir, endDir; - bool startWasGuess = false; - bool endWasGuess = false; - - // Try to work out the direction of the track start - if (canConnect(dragBegin.left(), dragBegin) - || canConnect(dragBegin.right(), dragBegin)) { - startDir = axis::X; - } - else if (canConnect(dragBegin.up(), dragBegin) - || canConnect(dragBegin.down(), dragBegin)) { - startDir = axis::Y; - } - else - startWasGuess = true; - - // Try to work out the direction of the track end - if (canConnect(dragEnd.left(), dragEnd) - || canConnect(dragEnd.right(), dragEnd)) { - endDir = axis::X; - } - else if (canConnect(dragEnd.up(), dragEnd) - || canConnect(dragEnd.down(), dragEnd)) { - endDir = axis::Y; - } - else - endWasGuess = true; - - // If we have to guess both orientations use a heuristic to decide - // between S-bends and curves - if (endWasGuess && startWasGuess) { - if (min(xlen, ylen) <= 2) { - if (xlen > ylen) - startDir = endDir = axis::X; - else - startDir = endDir = axis::Y; - } - else { - startDir = axis::X; - endDir = axis::Y; - } - } - // Otherwise always prefer curves to S-bends - else if (startWasGuess) - startDir = endDir == axis::X ? axis::Y : axis::X; - else if (endWasGuess) - endDir = startDir == axis::X ? axis::Y : axis::X; + // Normalise the coordinates so the start is always the one with + // the smallest x-coordinate + if (dragBegin.x > dragEnd.x) + swap(dragBegin, dragEnd); + + track::Direction startDir, endDir; + bool startWasGuess = false; + bool endWasGuess = false; + + // Try to work out the direction of the track start + if (canConnect(dragBegin.left(), dragBegin) + || canConnect(dragBegin.right(), dragBegin)) { + startDir = axis::X; + } + else if (canConnect(dragBegin.up(), dragBegin) + || canConnect(dragBegin.down(), dragBegin)) { + startDir = axis::Y; + } + else + startWasGuess = true; + + // Try to work out the direction of the track end + if (canConnect(dragEnd.left(), dragEnd) + || canConnect(dragEnd.right(), dragEnd)) { + endDir = axis::X; + } + else if (canConnect(dragEnd.up(), dragEnd) + || canConnect(dragEnd.down(), dragEnd)) { + endDir = axis::Y; + } + else + endWasGuess = true; + + // If we have to guess both orientations use a heuristic to decide + // between S-bends and curves + if (endWasGuess && startWasGuess) { + if (min(xlen, ylen) <= 2) { + if (xlen > ylen) + startDir = endDir = axis::X; + else + startDir = endDir = axis::Y; + } + else { + startDir = axis::X; + endDir = axis::Y; + } + } + // Otherwise always prefer curves to S-bends + else if (startWasGuess) + startDir = endDir == axis::X ? axis::Y : axis::X; + else if (endWasGuess) + endDir = startDir == axis::X ? axis::Y : axis::X; - if (xlen == 1 && ylen == 1) { - // A single tile - drawTrackTile(dragBegin, startDir); - } - else if (xlen == 1) - drawDraggedStraight(dragBegin.y < dragEnd.y ? axis::Y : -axis::Y, ylen); - else if (ylen == 1) - drawDraggedStraight(axis::X, xlen); - else if (startDir == endDir) { - // An S-bend (not implemented) - warn() << "Sorry! No S-bends yet..."; - } - else { - // Curves at the moment cannot be ellipses so lay track down - // until the dragged area is a square - while (xlen != ylen) { - if (xlen > ylen) { - // One of the ends must lie along the x-axis since all - // curves are through 90 degrees so extend that one - if (startDir == axis::X) { - drawTrackTile(dragBegin, axis::X); - dragBegin.x++; - } - else { - drawTrackTile(dragEnd, axis::X); - dragEnd.x--; - } - xlen--; - } - else { - // Need to draw track along y-axis - if (startDir == axis::Y) { - drawTrackTile(dragBegin, axis::Y); - - // The y-coordinate for the drag points is not guaranteed - // to be sorted - if (dragBegin.y > dragEnd.y) - dragBegin.y--; - else - dragBegin.y++; - } - else { - drawTrackTile(dragEnd, axis::Y); + if (xlen == 1 && ylen == 1) { + // A single tile + drawTrackTile(dragBegin, startDir); + } + else if (xlen == 1) + drawDraggedStraight(dragBegin.y < dragEnd.y ? axis::Y : -axis::Y, ylen); + else if (ylen == 1) + drawDraggedStraight(axis::X, xlen); + else if (startDir == endDir) { + // An S-bend (not implemented) + warn() << "Sorry! No S-bends yet..."; + } + else { + // Curves at the moment cannot be ellipses so lay track down + // until the dragged area is a square + while (xlen != ylen) { + if (xlen > ylen) { + // One of the ends must lie along the x-axis since all + // curves are through 90 degrees so extend that one + if (startDir == axis::X) { + drawTrackTile(dragBegin, axis::X); + dragBegin.x++; + } + else { + drawTrackTile(dragEnd, axis::X); + dragEnd.x--; + } + xlen--; + } + else { + // Need to draw track along y-axis + if (startDir == axis::Y) { + drawTrackTile(dragBegin, axis::Y); + + // The y-coordinate for the drag points is not guaranteed + // to be sorted + if (dragBegin.y > dragEnd.y) + dragBegin.y--; + else + dragBegin.y++; + } + else { + drawTrackTile(dragEnd, axis::Y); - if (dragBegin.y > dragEnd.y) - dragEnd.y++; - else - dragEnd.y--; - } - ylen--; - } - } - - track::Angle startAngle, endAngle; - Point where; - - if (startDir == axis::X && endDir == axis::Y) { - if (dragBegin.y < dragEnd.y) { - startAngle = 90; - endAngle = 180; - where = dragEnd; - } - else { - startAngle = 0; - endAngle = 90; - where = dragBegin; - } - } - else { - if (dragBegin.y < dragEnd.y) { - startAngle = 270; - endAngle = 360; - where = dragBegin; - } - else { - startAngle = 180; - endAngle = 270; - where = dragEnd; - } - } - - ITrackSegmentPtr track = makeCurvedTrack(startAngle, endAngle, xlen); - track->setOrigin(where.x, where.y); - - list > exits; - track->getEndpoints(exits); - - bool ok = true; - for (list >::iterator it = exits.begin(); - it != exits.end(); ++it) { - if (map->isValidTrack(*it)) { - warn() << "Cannot place curve here"; - ok = false; - break; - } - } - - if (ok) - map->setTrackAt(where, track); - } + if (dragBegin.y > dragEnd.y) + dragEnd.y++; + else + dragEnd.y--; + } + ylen--; + } + } + + track::Angle startAngle, endAngle; + Point where; + + if (startDir == axis::X && endDir == axis::Y) { + if (dragBegin.y < dragEnd.y) { + startAngle = 90; + endAngle = 180; + where = dragEnd; + } + else { + startAngle = 0; + endAngle = 90; + where = dragBegin; + } + } + else { + if (dragBegin.y < dragEnd.y) { + startAngle = 270; + endAngle = 360; + where = dragBegin; + } + else { + startAngle = 180; + endAngle = 270; + where = dragEnd; + } + } + + ITrackSegmentPtr track = makeCurvedTrack(startAngle, endAngle, xlen); + track->setOrigin(where.x, where.y); + + list > exits; + track->getEndpoints(exits); + + bool ok = true; + for (list >::iterator it = exits.begin(); + it != exits.end(); ++it) { + if (map->isValidTrack(*it)) { + warn() << "Cannot place curve here"; + ok = false; + break; + } + } + + if (ok) + map->setTrackAt(where, track); + } } // Delete all objects in the area selected by the user void Editor::deleteObjects() { - int xmin, xmax, ymin, ymax; - dragBoxBounds(xmin, xmax, ymin, ymax); + int xmin, xmax, ymin, ymax; + dragBoxBounds(xmin, xmax, ymin, ymax); - for (int x = xmin; x <= xmax; x++) { - for (int y = ymin; y <= ymax; y++) - map->eraseTile(x, y); - } + for (int x = xmin; x <= xmax; x++) { + for (int y = ymin; y <= ymax; y++) + map->eraseTile(x, y); + } } void Editor::plantTrees() @@ -461,110 +462,110 @@ void Editor::plantTrees() } void Editor::onMouseMove(IPickBufferPtr aPickBuffer, int x, int y, - int xrel, int yrel) + int xrel, int yrel) { - if (amDragging) { - // Extend the selection rectangle - map->setPickMode(true); - IGraphicsPtr pickContext = aPickBuffer->beginPick(x, y); - display(pickContext); - int id = aPickBuffer->endPick(); - map->setPickMode(false); - - if (id > 0) - dragEnd = map->pickPosition(id); - } - else if (amScrolling) { - const float speed = 0.05f; + if (amDragging) { + // Extend the selection rectangle + map->setPickMode(true); + IGraphicsPtr pickContext = aPickBuffer->beginPick(x, y); + display(pickContext); + int id = aPickBuffer->endPick(); + map->setPickMode(false); + + if (id > 0) + dragEnd = map->pickPosition(id); + } + else if (amScrolling) { + const float speed = 0.05f; - myPosition.x -= xrel * speed; - myPosition.z -= xrel * speed; + myPosition.x -= xrel * speed; + myPosition.z -= xrel * speed; - myPosition.x += yrel * speed; - myPosition.z -= yrel * speed; - } + myPosition.x += yrel * speed; + myPosition.z -= yrel * speed; + } } void Editor::onMouseClick(IPickBufferPtr aPickBuffer, int x, int y, - MouseButton aButton) + MouseButton aButton) { - if (aButton == MOUSE_RIGHT) { - // Start scrolling - amScrolling = true; - } - else if (aButton == MOUSE_LEFT) { - bool clickedOnGUI = layout->click(x, y); - - if (!clickedOnGUI) { - // See if the user clicked on something in the map - map->setPickMode(true); - IGraphicsPtr pickContext = aPickBuffer->beginPick(x, y); - display(pickContext); - int id = aPickBuffer->endPick(); - map->setPickMode(false); + if (aButton == MOUSE_RIGHT) { + // Start scrolling + amScrolling = true; + } + else if (aButton == MOUSE_LEFT) { + bool clickedOnGUI = layout->click(x, y); + + if (!clickedOnGUI) { + // See if the user clicked on something in the map + map->setPickMode(true); + IGraphicsPtr pickContext = aPickBuffer->beginPick(x, y); + display(pickContext); + int id = aPickBuffer->endPick(); + map->setPickMode(false); - if (id > 0) { - // Begin dragging a selection rectangle - Point where = map->pickPosition(id); + if (id > 0) { + // Begin dragging a selection rectangle + Point where = map->pickPosition(id); - dragBegin = dragEnd = where; - amDragging = true; - } - } - } - else if (aButton == MOUSE_WHEEL_UP) { - myPosition.y -= 0.5; - } - else if (aButton == MOUSE_WHEEL_DOWN) { - myPosition.y += 0.5; - } + dragBegin = dragEnd = where; + amDragging = true; + } + } + } + else if (aButton == MOUSE_WHEEL_UP) { + myPosition.y -= 0.5; + } + else if (aButton == MOUSE_WHEEL_DOWN) { + myPosition.y += 0.5; + } } void Editor::onMouseRelease(IPickBufferPtr aPickBuffer, int x, int y, - MouseButton aButton) + MouseButton aButton) { - if (amDragging) { - // Stop dragging and perform the action - switch (myTool) { - case TRACK_TOOL: - drawDraggedTrack(); - break; - case RAISE_TOOL: - map->raiseArea(dragBegin, dragEnd); - break; - case LOWER_TOOL: - map->lowerArea(dragBegin, dragEnd); - break; - case LEVEL_TOOL: - map->levelArea(dragBegin, dragEnd); - break; - case DELETE_TOOL: - deleteObjects(); - break; - case START_TOOL: - map->setStart(dragBegin.x, dragBegin.y); - break; - case STATION_TOOL: - map->extendStation(dragBegin, dragEnd); - break; - case BUILDING_TOOL: - { - float angle; - IBuildingPtr building; - tie(building, angle) = buildingPicker->get(); - map->placeBuilding(dragBegin, building, angle); - } - break; - case TREE_TOOL: - plantTrees(); - break; - } + if (amDragging) { + // Stop dragging and perform the action + switch (myTool) { + case TRACK_TOOL: + drawDraggedTrack(); + break; + case RAISE_TOOL: + map->raiseArea(dragBegin, dragEnd); + break; + case LOWER_TOOL: + map->lowerArea(dragBegin, dragEnd); + break; + case LEVEL_TOOL: + map->levelArea(dragBegin, dragEnd); + break; + case DELETE_TOOL: + deleteObjects(); + break; + case START_TOOL: + map->setStart(dragBegin.x, dragBegin.y); + break; + case STATION_TOOL: + map->extendStation(dragBegin, dragEnd); + break; + case BUILDING_TOOL: + { + float angle; + IBuildingPtr building; + tie(building, angle) = buildingPicker->get(); + map->placeBuilding(dragBegin, building, angle); + } + break; + case TREE_TOOL: + plantTrees(); + break; + } - amDragging = false; - } - else if (amScrolling) { - amScrolling = false; - } + amDragging = false; + } + else if (amScrolling) { + amScrolling = false; + } } void Editor::onKeyUp(SDLKey aKey) @@ -574,18 +575,18 @@ void Editor::onKeyUp(SDLKey aKey) void Editor::onKeyDown(SDLKey aKey) { - switch (aKey) { - case SDLK_g: - // Toggle grid - map->setGrid(true); - break; - default: - break; - } + switch (aKey) { + case SDLK_g: + // Toggle grid + map->setGrid(true); + break; + default: + break; + } } // Create an instance of the editor screen IScreenPtr makeEditorScreen(IMapPtr aMap) { - return IScreenPtr(new Editor(aMap)); + return IScreenPtr(new Editor(aMap)); } diff --git a/src/Game.cpp b/src/Game.cpp index df1ad4c..8982983 100644 --- a/src/Game.cpp +++ b/src/Game.cpp @@ -37,69 +37,69 @@ // Implementation of the main play screen class Game : public IScreen { public: - Game(IMapPtr aMap); - ~Game(); + Game(IMapPtr aMap); + ~Game(); - void display(IGraphicsPtr aContext) const; - void overlay() const; - void update(IPickBufferPtr aPickBuffer, int aDelta); - void onKeyDown(SDLKey aKey); - void onKeyUp(SDLKey aKey); - void onMouseMove(IPickBufferPtr aPickBuffer, int x, int y, int xrel, - int yrel); - void onMouseClick(IPickBufferPtr aPickBuffer, int x, int y, - MouseButton aButton); - void onMouseRelease(IPickBufferPtr aPickBuffer, int x, int y, - MouseButton aButton) {} + void display(IGraphicsPtr aContext) const; + void overlay() const; + void update(IPickBufferPtr aPickBuffer, int aDelta); + void onKeyDown(SDLKey aKey); + void onKeyUp(SDLKey aKey); + void onMouseMove(IPickBufferPtr aPickBuffer, int x, int y, int xrel, + int yrel); + void onMouseClick(IPickBufferPtr aPickBuffer, int x, int y, + MouseButton aButton); + void onMouseRelease(IPickBufferPtr aPickBuffer, int x, int y, + MouseButton aButton) {} private: - void lookAhead(); - void setStatus(const string& s) { statusMsg = s; } - void nearStation(IStationPtr s); - void leftStation(); - Vector cameraPosition(float aRadius) const; - void switchToBirdCamera(); - void stoppedAtStation(); + void lookAhead(); + void setStatus(const string& s) { statusMsg = s; } + void nearStation(IStationPtr s); + void leftStation(); + Vector cameraPosition(float aRadius) const; + void switchToBirdCamera(); + void stoppedAtStation(); - IMapPtr map; - ITrainPtr train; - ILightPtr sun; + IMapPtr map; + ITrainPtr train; + ILightPtr sun; - // Station the train is either approaching or stopped at - IStationPtr activeStation; + // Station the train is either approaching or stopped at + IStationPtr activeStation; - // Camera position - float horizAngle, vertAngle, viewRadius; + // Camera position + float horizAngle, vertAngle, viewRadius; - // Camera adjustment - float cameraHTarget, cameraVTarget; - float cameraSpeed; + // Camera adjustment + float cameraHTarget, cameraVTarget; + float cameraSpeed; - enum CameraMode { CAMERA_FLOATING, CAMERA_FIXED, CAMERA_BIRD }; - CameraMode cameraMode; + enum CameraMode { CAMERA_FLOATING, CAMERA_FIXED, CAMERA_BIRD }; + CameraMode cameraMode; - gui::ILayoutPtr layout; + gui::ILayoutPtr layout; - string statusMsg; - gui::IFontPtr statusFont; + string statusMsg; + gui::IFontPtr statusFont; }; Game::Game(IMapPtr aMap) - : map(aMap), - horizAngle(M_PI/4.0f), - vertAngle(M_PI/4.0f), - viewRadius(20.0f) + : map(aMap), + horizAngle(M_PI/4.0f), + vertAngle(M_PI/4.0f), + viewRadius(20.0f) { - train = makeTrain(map); - sun = makeSunLight(); + train = makeTrain(map); + sun = makeSunLight(); - map->setGrid(false); + map->setGrid(false); - // Build the GUI - layout = gui::makeLayout("layouts/game.xml"); + // Build the GUI + layout = gui::makeLayout("layouts/game.xml"); - statusFont = gui::loadFont("fonts/Vera.ttf", 18); + statusFont = gui::loadFont("fonts/Vera.ttf", 18); - switchToBirdCamera(); + switchToBirdCamera(); } Game::~Game() @@ -109,220 +109,220 @@ Game::~Game() Vector Game::cameraPosition(float aRadius) const { - // Two angles give unique position on surface of a sphere - // Look up ``spherical coordinates'' - const float yCentre = 0.9f; - Vector position = train->front(); - position.x += aRadius * cosf(horizAngle) * sinf(vertAngle); - position.z += aRadius * sinf(horizAngle) * sinf(vertAngle); - position.y = aRadius * cosf(vertAngle) + yCentre; - - return position; + // Two angles give unique position on surface of a sphere + // Look up ``spherical coordinates'' + const float yCentre = 0.9f; + Vector position = train->front(); + position.x += aRadius * cosf(horizAngle) * sinf(vertAngle); + position.z += aRadius * sinf(horizAngle) * sinf(vertAngle); + position.y = aRadius * cosf(vertAngle) + yCentre; + + return position; } void Game::switchToBirdCamera() { - cameraMode = CAMERA_BIRD; + cameraMode = CAMERA_BIRD; - cameraHTarget = M_PI/4.0f; - cameraVTarget = M_PI/4.0f; + cameraHTarget = M_PI/4.0f; + cameraVTarget = M_PI/4.0f; - cameraSpeed = 100.0f; + cameraSpeed = 100.0f; } void Game::display(IGraphicsPtr aContext) const { - Vector trainPos = train->front(); + Vector trainPos = train->front(); - Vector position = cameraPosition(viewRadius); + Vector position = cameraPosition(viewRadius); - aContext->lookAt(position, trainPos); - setBillboardCameraOrigin(position); + aContext->lookAt(position, trainPos); + setBillboardCameraOrigin(position); - sun->apply(); + sun->apply(); - map->render(aContext); - train->render(); + map->render(aContext); + train->render(); - renderBillboards(); + renderBillboards(); } void Game::overlay() const { - //myStatsPanel->render(); + //myStatsPanel->render(); - layout->render(); + layout->render(); - const int screenH = getGameWindow()->height(); - const int screenW = getGameWindow()->width(); - const int len = statusFont->text_width(statusMsg); - statusFont->print((screenW - len)/2, screenH - 50, - colour::WHITE, statusMsg); + const int screenH = getGameWindow()->height(); + const int screenW = getGameWindow()->width(); + const int len = statusFont->text_width(statusMsg); + statusFont->print((screenW - len)/2, screenH - 50, + colour::WHITE, statusMsg); } void Game::stoppedAtStation() { - debug() << "Stopped at " << activeStation->name(); + debug() << "Stopped at " << activeStation->name(); } void Game::update(IPickBufferPtr aPickBuffer, int aDelta) { - train->update(aDelta); + train->update(aDelta); - // Update the GUI elements - layout->cast("/throttle_meter").value( - train->controller()->throttle()); + // Update the GUI elements + layout->cast("/throttle_meter").value( + train->controller()->throttle()); - const double msToMPH = 2.237; - layout->cast("/speed_label").format( - "Speed: %.1lfmph", train->speed() * msToMPH); + const double msToMPH = 2.237; + layout->cast("/speed_label").format( + "Speed: %.1lfmph", train->speed() * msToMPH); - layout->get("/brake_label").visible(train->controller()->brakeOn()); + layout->get("/brake_label").visible(train->controller()->brakeOn()); - lookAhead(); + lookAhead(); - // Move the camera vertically if it's currently underground + // Move the camera vertically if it's currently underground - // Calculate the location of the near clip plane - const float nearClip = getConfig()->get("NearClip"); - Vector clipPosition = cameraPosition(viewRadius - nearClip); + // Calculate the location of the near clip plane + const float nearClip = getConfig()->get("NearClip"); + Vector clipPosition = cameraPosition(viewRadius - nearClip); - // A hack because we don't calculate the height properly - const float MIN_HEIGHT = 0.25f; - float h = map->heightAt(clipPosition.x, clipPosition.z); + // A hack because we don't calculate the height properly + const float MIN_HEIGHT = 0.25f; + float h = map->heightAt(clipPosition.x, clipPosition.z); - if (h + MIN_HEIGHT > clipPosition.y) { - cameraVTarget -= 0.001f * static_cast(aDelta); - cameraSpeed = 200.0f; - } + if (h + MIN_HEIGHT > clipPosition.y) { + cameraVTarget -= 0.001f * static_cast(aDelta); + cameraSpeed = 200.0f; + } - // Bounce the camera if we need to - vertAngle -= (vertAngle - cameraVTarget) / cameraSpeed; - horizAngle -= (horizAngle - cameraHTarget) / cameraSpeed; + // Bounce the camera if we need to + vertAngle -= (vertAngle - cameraVTarget) / cameraSpeed; + horizAngle -= (horizAngle - cameraHTarget) / cameraSpeed; } // Signal that we are approaching a station void Game::nearStation(IStationPtr s) { - leftStation(); // Clear any previous station + leftStation(); // Clear any previous station - if (s != activeStation) { - activeStation = s; - s->setHighlightVisible(true); - } + if (s != activeStation) { + activeStation = s; + s->setHighlightVisible(true); + } } // Signal that we are no longer at or approaching a station void Game::leftStation() { - if (activeStation) { - activeStation->setHighlightVisible(false); - activeStation.reset(); - } + if (activeStation) { + activeStation->setHighlightVisible(false); + activeStation.reset(); + } } // Look along the track and notify the player of any stations, points, etc. // that they are approaching void Game::lookAhead() { - TrackIterator it = iterateTrack(map, train->tile(), - train->direction()); + TrackIterator it = iterateTrack(map, train->tile(), + train->direction()); - // Are we sitting on a station? - if (it.status == TRACK_STATION) { - nearStation(it.station); + // Are we sitting on a station? + if (it.status == TRACK_STATION) { + nearStation(it.station); - if (train->controller()->stopped()) - stoppedAtStation(); - else - setStatus("Stop here for station " + it.station->name()); + if (train->controller()->stopped()) + stoppedAtStation(); + else + setStatus("Stop here for station " + it.station->name()); - return; - } + return; + } - const int maxLook = 10; - for (int i = 0; i < maxLook; i++) { - it = it.next(); + const int maxLook = 10; + for (int i = 0; i < maxLook; i++) { + it = it.next(); - if (it.status != TRACK_OK) { - bool clearStation = true; + if (it.status != TRACK_OK) { + bool clearStation = true; - switch (it.status) { - case TRACK_STATION: - setStatus("Approaching station " + it.station->name()); - nearStation(it.station); - clearStation = false; - return; - case TRACK_NO_MORE: - setStatus("Oh no! You're going to crash!"); - break; - case TRACK_CHOICE: - setStatus("Oh no! You have to make a decision!"); - break; - default: - break; - } - - if (!clearStation) - leftStation(); - return; - } - } + switch (it.status) { + case TRACK_STATION: + setStatus("Approaching station " + it.station->name()); + nearStation(it.station); + clearStation = false; + return; + case TRACK_NO_MORE: + setStatus("Oh no! You're going to crash!"); + break; + case TRACK_CHOICE: + setStatus("Oh no! You have to make a decision!"); + break; + default: + break; + } + + if (!clearStation) + leftStation(); + return; + } + } - // We're not approaching any station - leftStation(); + // We're not approaching any station + leftStation(); - // Nothing to report - setStatus(""); + // Nothing to report + setStatus(""); } void Game::onKeyDown(SDLKey aKey) { - switch (aKey) { - case SDLK_PAGEUP: - viewRadius = max(viewRadius - 0.2f, 0.1f); - break; - case SDLK_PAGEDOWN: - viewRadius += 0.2f; - break; - case SDLK_b: - train->controller()->actOn(BRAKE_TOGGLE); - break; - case SDLK_r: - train->controller()->actOn(TOGGLE_REVERSE); - break; - case SDLK_LCTRL: - train->controller()->actOn(SHOVEL_COAL); - break; - case SDLK_a: - train->controller()->actOn(THROTTLE_DOWN); - break; - case SDLK_s: - train->controller()->actOn(THROTTLE_UP); - break; - case SDLK_PRINT: - getGameWindow()->takeScreenShot(); - break; - case SDLK_LEFT: - train->controller()->actOn(GO_LEFT); - break; - case SDLK_RIGHT: - train->controller()->actOn(GO_RIGHT); - break; - case SDLK_UP: - train->controller()->actOn(GO_STRAIGHT_ON); - break; - case SDLK_TAB: - if (cameraMode == CAMERA_FLOATING) - cameraMode = CAMERA_FIXED; - else if (cameraMode == CAMERA_FIXED) - switchToBirdCamera(); - else - cameraMode = CAMERA_FLOATING; - break; - default: - break; - } + switch (aKey) { + case SDLK_PAGEUP: + viewRadius = max(viewRadius - 0.2f, 0.1f); + break; + case SDLK_PAGEDOWN: + viewRadius += 0.2f; + break; + case SDLK_b: + train->controller()->actOn(BRAKE_TOGGLE); + break; + case SDLK_r: + train->controller()->actOn(TOGGLE_REVERSE); + break; + case SDLK_LCTRL: + train->controller()->actOn(SHOVEL_COAL); + break; + case SDLK_a: + train->controller()->actOn(THROTTLE_DOWN); + break; + case SDLK_s: + train->controller()->actOn(THROTTLE_UP); + break; + case SDLK_PRINT: + getGameWindow()->takeScreenShot(); + break; + case SDLK_LEFT: + train->controller()->actOn(GO_LEFT); + break; + case SDLK_RIGHT: + train->controller()->actOn(GO_RIGHT); + break; + case SDLK_UP: + train->controller()->actOn(GO_STRAIGHT_ON); + break; + case SDLK_TAB: + if (cameraMode == CAMERA_FLOATING) + cameraMode = CAMERA_FIXED; + else if (cameraMode == CAMERA_FIXED) + switchToBirdCamera(); + else + cameraMode = CAMERA_FLOATING; + break; + default: + break; + } } void Game::onKeyUp(SDLKey aKey) @@ -331,43 +331,43 @@ void Game::onKeyUp(SDLKey aKey) } void Game::onMouseClick(IPickBufferPtr aPickBuffer, int x, int y, - MouseButton aButton) + MouseButton aButton) { - switch (aButton) { - case MOUSE_WHEEL_UP: - viewRadius = max(viewRadius - 1.0f, 0.1f); - break; - case MOUSE_WHEEL_DOWN: - viewRadius += 1.0f; - break; - default: - break; - } + switch (aButton) { + case MOUSE_WHEEL_UP: + viewRadius = max(viewRadius - 1.0f, 0.1f); + break; + case MOUSE_WHEEL_DOWN: + viewRadius += 1.0f; + break; + default: + break; + } } void Game::onMouseMove(IPickBufferPtr aPickBuffer, int x, int y, - int xrel, int yrel) + int xrel, int yrel) { - if (cameraMode == CAMERA_FLOATING) { - cameraHTarget -= xrel / 100.0f; - cameraVTarget += yrel / 100.0f; + if (cameraMode == CAMERA_FLOATING) { + cameraHTarget -= xrel / 100.0f; + cameraVTarget += yrel / 100.0f; - // Don't allow the camera to go under the ground - const float ground = (M_PI / 2.0f) - 0.01f; - if (cameraVTarget > ground) - cameraVTarget = ground; + // Don't allow the camera to go under the ground + const float ground = (M_PI / 2.0f) - 0.01f; + if (cameraVTarget > ground) + cameraVTarget = ground; - // Don't let the camera flip over the top - const float top = 0.01f; - if (cameraVTarget < top) - cameraVTarget = top; + // Don't let the camera flip over the top + const float top = 0.01f; + if (cameraVTarget < top) + cameraVTarget = top; - cameraSpeed = 2.0f; - } + cameraSpeed = 2.0f; + } } // Create an instance of the play screen with the given map IScreenPtr makeGameScreen(IMapPtr aMap) { - return IScreenPtr(new Game(aMap)); + return IScreenPtr(new Game(aMap)); } diff --git a/src/LTree.cpp b/src/LTree.cpp index e63ca2a..9118620 100644 --- a/src/LTree.cpp +++ b/src/LTree.cpp @@ -33,90 +33,90 @@ namespace lsystem { - enum Token { - X = 'X', // Only used for replacement - F = 'F', // Draw forward - L = '-', // Turn left N degrees - R = '+', // Turn right N degrees - B = '[', // Push position - E = ']', // Pop position - }; - - typedef list TokenList; - - struct Rule { - Rule(Token lhs, const TokenList& rhs) - : lhs(lhs), rhs(rhs) - {} - - Rule(Token lhs, const char* tokenStr); - - Token lhs; - TokenList rhs; - }; - - struct LSystem { - LSystem(const Rule* rules, int nRules, Token start); - - const Rule* rules; - int nRules; - Token start; - TokenList state; - }; - - void evolve(LSystem& l); - - ostream& operator<<(ostream& os, const LSystem& l) - { - copy(l.state.begin(), l.state.end(), - ostream_iterator(os)); - return os; - } + enum Token { + X = 'X', // Only used for replacement + F = 'F', // Draw forward + L = '-', // Turn left N degrees + R = '+', // Turn right N degrees + B = '[', // Push position + E = ']', // Pop position + }; + + typedef list TokenList; + + struct Rule { + Rule(Token lhs, const TokenList& rhs) + : lhs(lhs), rhs(rhs) + {} + + Rule(Token lhs, const char* tokenStr); + + Token lhs; + TokenList rhs; + }; + + struct LSystem { + LSystem(const Rule* rules, int nRules, Token start); + + const Rule* rules; + int nRules; + Token start; + TokenList state; + }; + + void evolve(LSystem& l); + + ostream& operator<<(ostream& os, const LSystem& l) + { + copy(l.state.begin(), l.state.end(), + ostream_iterator(os)); + return os; + } } lsystem::Rule::Rule(Token lhs, const char* tokenStr) - : lhs(lhs) + : lhs(lhs) { - while (*tokenStr) - rhs.push_back((Token)*tokenStr++); + while (*tokenStr) + rhs.push_back((Token)*tokenStr++); } lsystem::LSystem::LSystem(const Rule* rules, int nRules, Token start) - : rules(rules), nRules(nRules), start(start) + : rules(rules), nRules(nRules), start(start) { - state.push_back(start); + state.push_back(start); } void lsystem::evolve(LSystem& l) { - static UniformInt rnd(0, 1000); + static UniformInt rnd(0, 1000); - TokenList::iterator it = l.state.begin(); - do { - vector applicable; + TokenList::iterator it = l.state.begin(); + do { + vector applicable; - for (int r = 0; r < l.nRules; r++) { - if (l.rules[r].lhs == *it) { - //l.state.insert(it, l.rules[r].rhs.begin(), - // l.rules[r].rhs.end()); - //replaced = true; - //break; - applicable.push_back(&l.rules[r]); - } - } - - if (applicable.empty()) - ++it; - else { - int chosen = rnd() % applicable.size(); + for (int r = 0; r < l.nRules; r++) { + if (l.rules[r].lhs == *it) { + //l.state.insert(it, l.rules[r].rhs.begin(), + // l.rules[r].rhs.end()); + //replaced = true; + //break; + applicable.push_back(&l.rules[r]); + } + } + + if (applicable.empty()) + ++it; + else { + int chosen = rnd() % applicable.size(); - l.state.insert(it, applicable[chosen]->rhs.begin(), - applicable[chosen]->rhs.end()); + l.state.insert(it, applicable[chosen]->rhs.begin(), + applicable[chosen]->rhs.end()); - it = l.state.erase(it); - } + it = l.state.erase(it); + } - } while (it != l.state.end()); + } while (it != l.state.end()); } using namespace lsystem; @@ -124,113 +124,113 @@ using namespace lsystem; // Trees generated by L-systems class LTree : public IScenery { public: - LTree(); + LTree(); - // IScenery interface - void render() const; - void setPosition(float x, float y, float z); + // IScenery interface + void render() const; + void setPosition(float x, float y, float z); private: - struct RenderState { - RenderState() - { - widthStack.push(2.0f); - } - - stack widthStack; - }; + struct RenderState { + RenderState() + { + widthStack.push(2.0f); + } + + stack widthStack; + }; - void interpret(Token t, RenderState& rs) const; + void interpret(Token t, RenderState& rs) const; - LSystem ls; + LSystem ls; Vector position; - static const Rule rules[]; + static const Rule rules[]; }; const Rule LTree::rules[] = { - Rule(X, "F-[[X]+X]+F[+FX]-X"), - Rule(X, "F-[[X]+X]+FF[+FX]-X"), - Rule(X, "F+[[X]-X]-F[-FX]+X"), - Rule(X, "+[[X]-X]-F[-FX]+X"), - Rule(F, "FF"), + Rule(X, "F-[[X]+X]+F[+FX]-X"), + Rule(X, "F-[[X]+X]+FF[+FX]-X"), + Rule(X, "F+[[X]-X]-F[-FX]+X"), + Rule(X, "+[[X]-X]-F[-FX]+X"), + Rule(F, "FF"), }; LTree::LTree() - : ls(rules, sizeof(rules) / sizeof(Rule), X) + : ls(rules, sizeof(rules) / sizeof(Rule), X) { - const int N_GENERATIONS = 5; + const int N_GENERATIONS = 5; - //debug() << "Initial: " << ls; - for (int n = 0; n < N_GENERATIONS; n++) { - evolve(ls); - //debug() << "n=" << n << ": " << ls; - } + //debug() << "Initial: " << ls; + for (int n = 0; n < N_GENERATIONS; n++) { + evolve(ls); + //debug() << "n=" << n << ": " << ls; + } } void LTree::interpret(Token t, RenderState& rs) const { - const float SEGMENT_LEN = 0.025f; - const float LEAF_LEN = 0.1f; + const float SEGMENT_LEN = 0.025f; + const float LEAF_LEN = 0.1f; - switch (t) { - case 'F': - glLineWidth(rs.widthStack.top()); - glBegin(GL_LINES); - glVertex3f(0.0f, 0.0f, 0.0f); - glVertex3f(0.0f, SEGMENT_LEN, 0.0f); - glEnd(); - glTranslatef(0.0f, SEGMENT_LEN, 0.0f); - break; - case 'X': - /*glPushAttrib(GL_CURRENT_BIT); - glColor3f(0.0f, 0.8f, 0.0f); - glBegin(GL_TRIANGLES); - glVertex3f(0.0f, 0.0f, 0.0f); - glVertex3f(LEAF_LEN, 0.0f, 0.0f); - glVertex3f(0.0f, -LEAF_LEN, LEAF_LEN); - glEnd(); - glPopAttrib();*/ - break; - case '-': - glRotatef(25.0, 0.0f, 0.0f, 1.0f); - glRotatef(25.0, 0.0f, 1.0f, 0.0f); - break; - case '+': - glRotatef(-25.0, 0.0f, 0.0f, 1.0f); - glRotatef(-25.0, 0.0f, 1.0f, 0.0f); - break; - case '[': - rs.widthStack.push(rs.widthStack.top() * 0.9f); - glPushMatrix(); - break; - case ']': - rs.widthStack.pop(); - glPopMatrix(); - break; - default: - { - ostringstream ss; - ss << "Bad token in LTree: " << static_cast(t); - throw runtime_error(ss.str()); - } - } + switch (t) { + case 'F': + glLineWidth(rs.widthStack.top()); + glBegin(GL_LINES); + glVertex3f(0.0f, 0.0f, 0.0f); + glVertex3f(0.0f, SEGMENT_LEN, 0.0f); + glEnd(); + glTranslatef(0.0f, SEGMENT_LEN, 0.0f); + break; + case 'X': + /*glPushAttrib(GL_CURRENT_BIT); + glColor3f(0.0f, 0.8f, 0.0f); + glBegin(GL_TRIANGLES); + glVertex3f(0.0f, 0.0f, 0.0f); + glVertex3f(LEAF_LEN, 0.0f, 0.0f); + glVertex3f(0.0f, -LEAF_LEN, LEAF_LEN); + glEnd(); + glPopAttrib();*/ + break; + case '-': + glRotatef(25.0, 0.0f, 0.0f, 1.0f); + glRotatef(25.0, 0.0f, 1.0f, 0.0f); + break; + case '+': + glRotatef(-25.0, 0.0f, 0.0f, 1.0f); + glRotatef(-25.0, 0.0f, 1.0f, 0.0f); + break; + case '[': + rs.widthStack.push(rs.widthStack.top() * 0.9f); + glPushMatrix(); + break; + case ']': + rs.widthStack.pop(); + glPopMatrix(); + break; + default: + { + ostringstream ss; + ss << "Bad token in LTree: " << static_cast(t); + throw runtime_error(ss.str()); + } + } } void LTree::render() const { - using namespace placeholders; + using namespace placeholders; - glPushMatrix(); + glPushMatrix(); - gl::translate(position); + gl::translate(position); - glColor3f(0.0f, 0.0f, 0.0f); + glColor3f(0.0f, 0.0f, 0.0f); - RenderState rs; - for_each(ls.state.begin(), ls.state.end(), - bind(<ree::interpret, this, _1, rs)); + RenderState rs; + for_each(ls.state.begin(), ls.state.end(), + bind(<ree::interpret, this, _1, rs)); - glPopMatrix(); + glPopMatrix(); } void LTree::setPosition(float x, float y, float z) @@ -242,7 +242,7 @@ void LTree::setPosition(float x, float y, float z) ISceneryPtr makeLTree() { - return ISceneryPtr(new LTree); + return ISceneryPtr(new LTree); } diff --git a/src/OpenGLHelper.cpp b/src/OpenGLHelper.cpp index b575770..628f311 100644 --- a/src/OpenGLHelper.cpp +++ b/src/OpenGLHelper.cpp @@ -30,159 +30,159 @@ void drawGLScene(IWindowPtr aWindow, IGraphicsPtr aContext, IScreenPtr aScreen) { - using namespace boost; + using namespace boost; - // Set up for 3D mode - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); + // Set up for 3D mode + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); - const int w = aWindow->width(); - const int h = aWindow->height(); + const int w = aWindow->width(); + const int h = aWindow->height(); - IConfigPtr cfg = getConfig(); - gluPerspective(45.0f, (GLfloat)w/(GLfloat)h, - cfg->get("NearClip"), - cfg->get("FarClip")); + IConfigPtr cfg = getConfig(); + gluPerspective(45.0f, (GLfloat)w/(GLfloat)h, + cfg->get("NearClip"), + cfg->get("FarClip")); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); - // Set default state - glEnable(GL_DEPTH_TEST); - glEnable(GL_TEXTURE_2D); - glEnable(GL_CULL_FACE); + // Set default state + glEnable(GL_DEPTH_TEST); + glEnable(GL_TEXTURE_2D); + glEnable(GL_CULL_FACE); - glEnable(GL_LIGHTING); - glEnable(GL_LIGHT0); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); - // Clear the screen - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glLoadIdentity(); - - // Draw the 3D part - aScreen->display(aContext); - - // Set up for 2D - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluOrtho2D(0.0f, (GLfloat)w, (GLfloat)h, 0.0f); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - // Set 2D defaults - glDisable(GL_LIGHTING); - glDisable(GL_DEPTH_TEST); - glEnable(GL_BLEND); - glDisable(GL_TEXTURE_2D); - glDisable(GL_CULL_FACE); - - // Draw the 2D part - aScreen->overlay(); - - // Check for OpenGL errors - GLenum error = glGetError(); - if (error != GL_NO_ERROR) { - throw runtime_error - ("OpenGL error: " + lexical_cast(gluErrorString(error))); - } + // Clear the screen + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glLoadIdentity(); + + // Draw the 3D part + aScreen->display(aContext); + + // Set up for 2D + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluOrtho2D(0.0f, (GLfloat)w, (GLfloat)h, 0.0f); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + // Set 2D defaults + glDisable(GL_LIGHTING); + glDisable(GL_DEPTH_TEST); + glEnable(GL_BLEND); + glDisable(GL_TEXTURE_2D); + glDisable(GL_CULL_FACE); + + // Draw the 2D part + aScreen->overlay(); + + // Check for OpenGL errors + GLenum error = glGetError(); + if (error != GL_NO_ERROR) { + throw runtime_error + ("OpenGL error: " + lexical_cast(gluErrorString(error))); + } } // Report the current OpenGL version void printGLVersion() { - log() << "OpenGL version: " << glGetString(GL_VERSION); - log() << "GLEW version: " << glewGetString(GLEW_VERSION); + log() << "OpenGL version: " << glGetString(GL_VERSION); + log() << "GLEW version: " << glewGetString(GLEW_VERSION); } // Set initial OpenGL options void initGL() { - using namespace boost; + using namespace boost; - glShadeModel(GL_SMOOTH); - glClearDepth(1.0f); - glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); - glDepthFunc(GL_LEQUAL); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - // Clear to the sky colour - //glClearColor(0.6f, 0.7f, 0.8f, 1.0f); - glClearColor(176.0f/255.0f, 196.0f/255.0f, 222.0f/255.0f, 1.0f); + glShadeModel(GL_SMOOTH); + glClearDepth(1.0f); + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); + glDepthFunc(GL_LEQUAL); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + // Clear to the sky colour + //glClearColor(0.6f, 0.7f, 0.8f, 1.0f); + glClearColor(176.0f/255.0f, 196.0f/255.0f, 222.0f/255.0f, 1.0f); - // Check for OpenGL extensions - GLenum err = glewInit(); - if (err != GLEW_OK) - throw runtime_error("GLEW initialisation failed: " - + lexical_cast(glewGetErrorString(err))); + // Check for OpenGL extensions + GLenum err = glewInit(); + if (err != GLEW_OK) + throw runtime_error("GLEW initialisation failed: " + + lexical_cast(glewGetErrorString(err))); } // Set the current viewport void resizeGLScene(IWindowPtr aWindow) { - glViewport(0, 0, aWindow->width(), aWindow->height()); + glViewport(0, 0, aWindow->width(), aWindow->height()); } void beginPick(IWindowPtr aWindow, unsigned* aBuffer, int x, int y) { - // Set up selection buffer - glSelectBuffer(128, aBuffer); + // Set up selection buffer + glSelectBuffer(128, aBuffer); - // Get viewport coordinates - GLint viewportCoords[4]; - glGetIntegerv(GL_VIEWPORT, viewportCoords); + // Get viewport coordinates + GLint viewportCoords[4]; + glGetIntegerv(GL_VIEWPORT, viewportCoords); - // Switch to projection matrix - glMatrixMode(GL_PROJECTION); - glPushMatrix(); + // Switch to projection matrix + glMatrixMode(GL_PROJECTION); + glPushMatrix(); - // Render the objects, but don't change the frame buffer - glRenderMode(GL_SELECT); - glLoadIdentity(); + // Render the objects, but don't change the frame buffer + glRenderMode(GL_SELECT); + glLoadIdentity(); - // Set picking matrix - gluPickMatrix(x, viewportCoords[3] - y, 2, 2, viewportCoords); + // Set picking matrix + gluPickMatrix(x, viewportCoords[3] - y, 2, 2, viewportCoords); - // Just set the perspective - IConfigPtr cfg = getConfig(); - gluPerspective(45.0f, (GLfloat)(aWindow->width())/(GLfloat)(aWindow->height()), - cfg->get("NearClip"), - cfg->get("FarClip")); + // Just set the perspective + IConfigPtr cfg = getConfig(); + gluPerspective(45.0f, (GLfloat)(aWindow->width())/(GLfloat)(aWindow->height()), + cfg->get("NearClip"), + cfg->get("FarClip")); - glMatrixMode(GL_MODELVIEW); - glInitNames(); + glMatrixMode(GL_MODELVIEW); + glInitNames(); - // Let the user render their stuff - glLoadIdentity(); + // Let the user render their stuff + glLoadIdentity(); } unsigned endPick(unsigned* aBuffer) { - int objectsFound = glRenderMode(GL_RENDER); + int objectsFound = glRenderMode(GL_RENDER); - // Go back to normal - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); + // Go back to normal + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); - // See if we found any objects - if (objectsFound > 0) { - // Find the object with the lowest depth - unsigned int lowestDepth = aBuffer[1]; - int selectedObject = aBuffer[3]; + // See if we found any objects + if (objectsFound > 0) { + // Find the object with the lowest depth + unsigned int lowestDepth = aBuffer[1]; + int selectedObject = aBuffer[3]; - // Go through all the objects found - for (int i = 1; i < objectsFound; i++) { - // See if it's closer than the current nearest - if (aBuffer[(i*4) + 1] < lowestDepth) { // 4 values for each object - lowestDepth = aBuffer[(i * 4) + 1]; - selectedObject = aBuffer[(i * 4) + 3]; - } - } + // Go through all the objects found + for (int i = 1; i < objectsFound; i++) { + // See if it's closer than the current nearest + if (aBuffer[(i*4) + 1] < lowestDepth) { // 4 values for each object + lowestDepth = aBuffer[(i * 4) + 1]; + selectedObject = aBuffer[(i * 4) + 3]; + } + } - // Return closest object - return selectedObject; - } - else - return 0; + // Return closest object + return selectedObject; + } + else + return 0; } diff --git a/src/Points.cpp b/src/Points.cpp index b34dea3..3f93d93 100644 --- a/src/Points.cpp +++ b/src/Points.cpp @@ -29,403 +29,403 @@ // Forks in the track class Points : public ITrackSegment { public: - Points(track::Direction aDirection, bool reflect); - - // ITrackSegment interface - void render() const; - void setOrigin(int x, int y) { myX = x; myY = y; } - double segmentLength(const track::TravelToken& aToken) const; - bool isValidDirection(const track::Direction& aDirection) const; - track::Connection nextPosition(const track::TravelToken& aToken) const; - void getEndpoints(std::list >& aList) const; - ITrackSegmentPtr mergeExit(const Point& aPoint, - const track::Direction& aDirection); - xml::element toXml() const; - track::TravelToken getTravelToken(track::Position aPosition, - track::Direction aDirection) const; + Points(track::Direction aDirection, bool reflect); + + // ITrackSegment interface + void render() const; + void setOrigin(int x, int y) { myX = x; myY = y; } + double segmentLength(const track::TravelToken& aToken) const; + bool isValidDirection(const track::Direction& aDirection) const; + track::Connection nextPosition(const track::TravelToken& aToken) const; + void getEndpoints(std::list >& aList) const; + ITrackSegmentPtr mergeExit(const Point& aPoint, + const track::Direction& aDirection); + xml::element toXml() const; + track::TravelToken getTravelToken(track::Position aPosition, + track::Direction aDirection) const; private: - void transform(const track::TravelToken& aToken, double aDelta) const; - void ensureValidDirection(track::Direction aDirection) const; + void transform(const track::TravelToken& aToken, double aDelta) const; + void ensureValidDirection(track::Direction aDirection) const; - Point displacedEndpoint() const; - Point straightEndpoint() const; + Point displacedEndpoint() const; + Point straightEndpoint() const; - int myX, myY; - track::Direction myAxis; - bool amReflected; + int myX, myY; + track::Direction myAxis; + bool amReflected; - static const BezierCurve myCurve, myReflectedCurve; + static const BezierCurve myCurve, myReflectedCurve; }; const BezierCurve Points::myCurve = makeBezierCurve - (makeVector(0.0f, 0.0f, 0.0f), - makeVector(1.0f, 0.0f, 0.0f), - makeVector(2.0f, 1.0f, 0.0f), - makeVector(3.0f, 1.0f, 0.0f)); + (makeVector(0.0f, 0.0f, 0.0f), + makeVector(1.0f, 0.0f, 0.0f), + makeVector(2.0f, 1.0f, 0.0f), + makeVector(3.0f, 1.0f, 0.0f)); const BezierCurve Points::myReflectedCurve = makeBezierCurve - (makeVector(0.0f, 0.0f, 0.0f), - makeVector(1.0f, 0.0f, 0.0f), - makeVector(2.0f, -1.0f, 0.0f), - makeVector(3.0f, -1.0f, 0.0f)); + (makeVector(0.0f, 0.0f, 0.0f), + makeVector(1.0f, 0.0f, 0.0f), + makeVector(2.0f, -1.0f, 0.0f), + makeVector(3.0f, -1.0f, 0.0f)); Points::Points(track::Direction aDirection, bool reflect) - : myX(0), myY(0), - myAxis(aDirection), amReflected(reflect) + : myX(0), myY(0), + myAxis(aDirection), amReflected(reflect) { } void Points::render() const { - static IMeshPtr railMesh = makeBezierRailMesh(myCurve); - static IMeshPtr reflectMesh = makeBezierRailMesh(myReflectedCurve); + static IMeshPtr railMesh = makeBezierRailMesh(myCurve); + static IMeshPtr reflectMesh = makeBezierRailMesh(myReflectedCurve); - glPushMatrix(); + glPushMatrix(); - if (myAxis == -axis::X) - glRotatef(180.0f, 0.0f, 1.0f, 0.0f); - else if (myAxis == -axis::Y) - glRotatef(90.0f, 0.0f, 1.0f, 0.0f); - else if (myAxis == axis::Y) - glRotatef(270.0f, 0.0f, 1.0f, 0.0f); + if (myAxis == -axis::X) + glRotatef(180.0f, 0.0f, 1.0f, 0.0f); + else if (myAxis == -axis::Y) + glRotatef(90.0f, 0.0f, 1.0f, 0.0f); + else if (myAxis == axis::Y) + glRotatef(270.0f, 0.0f, 1.0f, 0.0f); - renderRailMesh(amReflected ? reflectMesh : railMesh); + renderRailMesh(amReflected ? reflectMesh : railMesh); - glPushMatrix(); - glRotatef(90.0f, 0.0f, 1.0f, 0.0f); + glPushMatrix(); + glRotatef(90.0f, 0.0f, 1.0f, 0.0f); - for (int i = 0; i < 3; i++) { - renderStraightRail(); - glTranslatef(0.0f, 0.0f, 1.0f); - } + for (int i = 0; i < 3; i++) { + renderStraightRail(); + glTranslatef(0.0f, 0.0f, 1.0f); + } - glPopMatrix(); + glPopMatrix(); - // Draw the curved sleepers - for (float i = 0.2f; i < 1.0f; i += 0.08f) { - glPushMatrix(); + // Draw the curved sleepers + for (float i = 0.2f; i < 1.0f; i += 0.08f) { + glPushMatrix(); - Vector v = (amReflected ? myReflectedCurve : myCurve)(i); + Vector v = (amReflected ? myReflectedCurve : myCurve)(i); - glTranslatef(v.x - 0.4f, 0.0f, v.y); + glTranslatef(v.x - 0.4f, 0.0f, v.y); - const Vector deriv = - (amReflected ? myReflectedCurve : myCurve).deriv(i); - const float angle = - radToDeg(atanf(deriv.y / deriv.x)); + const Vector deriv = + (amReflected ? myReflectedCurve : myCurve).deriv(i); + const float angle = + radToDeg(atanf(deriv.y / deriv.x)); - glRotatef(-angle, 0.0f, 1.0f, 0.0f); + glRotatef(-angle, 0.0f, 1.0f, 0.0f); - renderSleeper(); + renderSleeper(); - glPopMatrix(); - } + glPopMatrix(); + } - // Draw the straight sleepers - glTranslatef(-0.4f, 0.0f, 0.0f); + // Draw the straight sleepers + glTranslatef(-0.4f, 0.0f, 0.0f); - for (int i = 0; i < 12; i++) { - renderSleeper(); - glTranslatef(0.25f, 0.0f, 0.0f); - } + for (int i = 0; i < 12; i++) { + renderSleeper(); + glTranslatef(0.25f, 0.0f, 0.0f); + } - glPopMatrix(); + glPopMatrix(); } double Points::segmentLength(const track::TravelToken& aToken) const { - if (aToken.position == displacedEndpoint()) - return myCurve.length; - else - return 3.0; + if (aToken.position == displacedEndpoint()) + return myCurve.length; + else + return 3.0; } track::TravelToken Points::getTravelToken(track::Position aPosition, - track::Direction aDirection) const + track::Direction aDirection) const { - using namespace placeholders; + using namespace placeholders; - ensureValidDirection(aDirection); - - track::TravelToken tok = { - aDirection, - aPosition, - track::CHOOSE_STRAIGHT_ON, - bind(&Points::transform, this, _1, _2) - }; - tok.choices.insert(track::CHOOSE_STRAIGHT_ON); - - if (aPosition.x == myX && aPosition.y == myY) - tok.choices.insert(track::CHOOSE_GO_RIGHT); + ensureValidDirection(aDirection); + + track::TravelToken tok = { + aDirection, + aPosition, + track::CHOOSE_STRAIGHT_ON, + bind(&Points::transform, this, _1, _2) + }; + tok.choices.insert(track::CHOOSE_STRAIGHT_ON); + + if (aPosition.x == myX && aPosition.y == myY) + tok.choices.insert(track::CHOOSE_GO_RIGHT); - return tok; + return tok; } void Points::transform(const track::TravelToken& aToken, double aDelta) const { - const float len = segmentLength(aToken); + const float len = segmentLength(aToken); - assert(aDelta < len); + assert(aDelta < len); - if (myX == aToken.position.x && myY == aToken.position.y - && aToken.activeChoice == track::CHOOSE_STRAIGHT_ON) { + if (myX == aToken.position.x && myY == aToken.position.y + && aToken.activeChoice == track::CHOOSE_STRAIGHT_ON) { - if (aToken.direction == myAxis - && (myAxis == -axis::X || myAxis == -axis::Y)) - aDelta -= 1.0; + if (aToken.direction == myAxis + && (myAxis == -axis::X || myAxis == -axis::Y)) + aDelta -= 1.0; - const double xTrans = - myAxis == axis::X ? aDelta - : (myAxis == -axis::X ? -aDelta : 0.0); - const double yTrans = - myAxis == axis::Y ? aDelta - : (myAxis == -axis::Y ? -aDelta : 0.0); + const double xTrans = + myAxis == axis::X ? aDelta + : (myAxis == -axis::X ? -aDelta : 0.0); + const double yTrans = + myAxis == axis::Y ? aDelta + : (myAxis == -axis::Y ? -aDelta : 0.0); - glTranslatef(static_cast(myX) + xTrans, - 0.0, - static_cast(myY) + yTrans); + glTranslatef(static_cast(myX) + xTrans, + 0.0, + static_cast(myY) + yTrans); - if (myAxis == axis::Y || myAxis == -axis::Y) - glRotated(-90.0, 0.0, 1.0, 0.0); + if (myAxis == axis::Y || myAxis == -axis::Y) + glRotated(-90.0, 0.0, 1.0, 0.0); - glTranslated(-0.5, 0.0, 0.0); - } - else if (aToken.position == straightEndpoint()) { - aDelta = 2.0 - aDelta; - - if (aToken.direction == -myAxis - && (myAxis == axis::X || myAxis == axis::Y)) - aDelta += 1.0; + glTranslated(-0.5, 0.0, 0.0); + } + else if (aToken.position == straightEndpoint()) { + aDelta = 2.0 - aDelta; + + if (aToken.direction == -myAxis + && (myAxis == axis::X || myAxis == axis::Y)) + aDelta += 1.0; - const double xTrans = - myAxis == axis::X ? aDelta - : (myAxis == -axis::X ? -aDelta : 0.0); - const double yTrans = - myAxis == axis::Y ? aDelta - : (myAxis == -axis::Y ? -aDelta : 0.0); + const double xTrans = + myAxis == axis::X ? aDelta + : (myAxis == -axis::X ? -aDelta : 0.0); + const double yTrans = + myAxis == axis::Y ? aDelta + : (myAxis == -axis::Y ? -aDelta : 0.0); - glTranslatef(static_cast(myX) + xTrans, - 0.0, - static_cast(myY) + yTrans); + glTranslatef(static_cast(myX) + xTrans, + 0.0, + static_cast(myY) + yTrans); - if (myAxis == axis::Y || myAxis == -axis::Y) - glRotated(-90.0, 0.0, 1.0, 0.0); + if (myAxis == axis::Y || myAxis == -axis::Y) + glRotated(-90.0, 0.0, 1.0, 0.0); - glTranslated(-0.5, 0.0, 0.0); - } - else if (aToken.position == displacedEndpoint() - || aToken.activeChoice != track::CHOOSE_STRAIGHT_ON) { - // Curving onto the straight section - float xTrans, yTrans, rotate; - - // We have a slight problem in that the domain of the curve - // function is [0,1] but the delta is in [0,len] so we have - // to compress the delta into [0,1] here - const float curveDelta = aDelta / len; - - bool backwards = aToken.position == displacedEndpoint(); + glTranslated(-0.5, 0.0, 0.0); + } + else if (aToken.position == displacedEndpoint() + || aToken.activeChoice != track::CHOOSE_STRAIGHT_ON) { + // Curving onto the straight section + float xTrans, yTrans, rotate; + + // We have a slight problem in that the domain of the curve + // function is [0,1] but the delta is in [0,len] so we have + // to compress the delta into [0,1] here + const float curveDelta = aDelta / len; + + bool backwards = aToken.position == displacedEndpoint(); - const float fValue = backwards ? 1.0f - curveDelta : curveDelta; - const Vector curveValue = myCurve(fValue); + const float fValue = backwards ? 1.0f - curveDelta : curveDelta; + const Vector curveValue = myCurve(fValue); - // Calculate the angle that the tangent to the curve at this - // point makes to (one of) the axis at this point - const Vector deriv = myCurve.deriv(fValue); - const float angle = - radToDeg(atanf(deriv.y / deriv.x)); - - if (myAxis == -axis::X) { - xTrans = 1.0f - curveValue.x; - yTrans = amReflected ? curveValue.y : -curveValue.y; - rotate = amReflected ? angle : -angle; - } - else if (myAxis == axis::X) { - xTrans = curveValue.x; - yTrans = amReflected ? -curveValue.y : curveValue.y; - rotate = amReflected ? angle : -angle; - } - else if (myAxis == -axis::Y) { - xTrans = amReflected ? -curveValue.y : curveValue.y; - yTrans = 1.0f - curveValue.x; - rotate = amReflected ? angle : -angle; - } - else if (myAxis == axis::Y) { - xTrans = amReflected ? curveValue.y : -curveValue.y; - yTrans = curveValue.x; - rotate = amReflected ? angle : -angle; - } - else - assert(false); - - glTranslatef(myX + xTrans, 0.0f, myY + yTrans); + // Calculate the angle that the tangent to the curve at this + // point makes to (one of) the axis at this point + const Vector deriv = myCurve.deriv(fValue); + const float angle = + radToDeg(atanf(deriv.y / deriv.x)); + + if (myAxis == -axis::X) { + xTrans = 1.0f - curveValue.x; + yTrans = amReflected ? curveValue.y : -curveValue.y; + rotate = amReflected ? angle : -angle; + } + else if (myAxis == axis::X) { + xTrans = curveValue.x; + yTrans = amReflected ? -curveValue.y : curveValue.y; + rotate = amReflected ? angle : -angle; + } + else if (myAxis == -axis::Y) { + xTrans = amReflected ? -curveValue.y : curveValue.y; + yTrans = 1.0f - curveValue.x; + rotate = amReflected ? angle : -angle; + } + else if (myAxis == axis::Y) { + xTrans = amReflected ? curveValue.y : -curveValue.y; + yTrans = curveValue.x; + rotate = amReflected ? angle : -angle; + } + else + assert(false); + + glTranslatef(myX + xTrans, 0.0f, myY + yTrans); - if (myAxis == axis::Y || myAxis == -axis::Y) - glRotated(-90.0, 0.0, 1.0, 0.0); + if (myAxis == axis::Y || myAxis == -axis::Y) + glRotated(-90.0, 0.0, 1.0, 0.0); - glTranslated(-0.5, 0.0, 0.0); + glTranslated(-0.5, 0.0, 0.0); - glRotatef(rotate, 0.0f, 1.0f, 0.0f); - } - else - assert(false); + glRotatef(rotate, 0.0f, 1.0f, 0.0f); + } + else + assert(false); - if (aToken.direction == -axis::X || aToken.direction == -axis::Y) - glRotated(-180.0, 0.0, 1.0, 0.0); + if (aToken.direction == -axis::X || aToken.direction == -axis::Y) + glRotated(-180.0, 0.0, 1.0, 0.0); } void Points::ensureValidDirection(track::Direction aDirection) const { - if (!isValidDirection(aDirection)) - throw runtime_error - ("Invalid direction on points: " - + boost::lexical_cast(aDirection) - + " (should be parallel to " - + boost::lexical_cast(myAxis) + ")"); + if (!isValidDirection(aDirection)) + throw runtime_error + ("Invalid direction on points: " + + boost::lexical_cast(aDirection) + + " (should be parallel to " + + boost::lexical_cast(myAxis) + ")"); } bool Points::isValidDirection(const track::Direction& aDirection) const { - if (myAxis == axis::X || myAxis == -axis::X) - return aDirection == axis::X || -aDirection == axis::X; - else - return aDirection == axis::Y || -aDirection == axis::Y; + if (myAxis == axis::X || myAxis == -axis::X) + return aDirection == axis::X || -aDirection == axis::X; + else + return aDirection == axis::Y || -aDirection == axis::Y; } track::Connection Points::nextPosition(const track::TravelToken& aToken) const { - bool branching = aToken.activeChoice != track::CHOOSE_STRAIGHT_ON; + bool branching = aToken.activeChoice != track::CHOOSE_STRAIGHT_ON; - if (myAxis == axis::X) { - if (aToken.direction == -axis::X) { - // Two possible entry points - return make_pair(makePoint(myX - 1, myY), -axis::X); - } - else { - // Two possible exits - if (branching) { - if (amReflected) - return make_pair(makePoint(myX + 3, myY - 1), axis::X); - else - return make_pair(makePoint(myX + 3, myY + 1), axis::X); - } - else - return make_pair(makePoint(myX + 3, myY), axis::X); - } - } - else if (myAxis == -axis::X) { - if (aToken.direction == -axis::X) { - // Two possible exits - if (branching) { - if (amReflected) - return make_pair(makePoint(myX - 3, myY + 1), -axis::X); - else - return make_pair(makePoint(myX - 3, myY - 1), -axis::X); - } - else - return make_pair(makePoint(myX - 3, myY), -axis::X); - } - else { - // Two possible entry points - return make_pair(makePoint(myX + 1, myY), axis::X); - } - } - else if (myAxis == axis::Y) { - if (aToken.direction == -axis::Y) { - // Two possible entry points - return make_pair(makePoint(myX, myY - 1), -axis::Y); - } - else { - // Two possible exits - if (branching) { - if (amReflected) - return make_pair(makePoint(myX + 1, myY + 3), axis::Y); - else - return make_pair(makePoint(myX - 1, myY + 3), axis::Y); - } - else - return make_pair(makePoint(myX, myY + 3), axis::Y); - } - } - else if (myAxis == -axis::Y) { - if (aToken.direction == -axis::Y) { - // Two possible exits - if (branching) { - if (amReflected) - return make_pair(makePoint(myX - 1, myY - 3), -axis::Y); - else - return make_pair(makePoint(myX + 1, myY - 3), -axis::Y); - } - else - return make_pair(makePoint(myX, myY - 3), -axis::Y); - } - else { - // Two possible entry points - return make_pair(makePoint(myX, myY + 1), axis::Y); - } - } - else - assert(false); + if (myAxis == axis::X) { + if (aToken.direction == -axis::X) { + // Two possible entry points + return make_pair(makePoint(myX - 1, myY), -axis::X); + } + else { + // Two possible exits + if (branching) { + if (amReflected) + return make_pair(makePoint(myX + 3, myY - 1), axis::X); + else + return make_pair(makePoint(myX + 3, myY + 1), axis::X); + } + else + return make_pair(makePoint(myX + 3, myY), axis::X); + } + } + else if (myAxis == -axis::X) { + if (aToken.direction == -axis::X) { + // Two possible exits + if (branching) { + if (amReflected) + return make_pair(makePoint(myX - 3, myY + 1), -axis::X); + else + return make_pair(makePoint(myX - 3, myY - 1), -axis::X); + } + else + return make_pair(makePoint(myX - 3, myY), -axis::X); + } + else { + // Two possible entry points + return make_pair(makePoint(myX + 1, myY), axis::X); + } + } + else if (myAxis == axis::Y) { + if (aToken.direction == -axis::Y) { + // Two possible entry points + return make_pair(makePoint(myX, myY - 1), -axis::Y); + } + else { + // Two possible exits + if (branching) { + if (amReflected) + return make_pair(makePoint(myX + 1, myY + 3), axis::Y); + else + return make_pair(makePoint(myX - 1, myY + 3), axis::Y); + } + else + return make_pair(makePoint(myX, myY + 3), axis::Y); + } + } + else if (myAxis == -axis::Y) { + if (aToken.direction == -axis::Y) { + // Two possible exits + if (branching) { + if (amReflected) + return make_pair(makePoint(myX - 1, myY - 3), -axis::Y); + else + return make_pair(makePoint(myX + 1, myY - 3), -axis::Y); + } + else + return make_pair(makePoint(myX, myY - 3), -axis::Y); + } + else { + // Two possible entry points + return make_pair(makePoint(myX, myY + 1), axis::Y); + } + } + else + assert(false); } // Get the endpoint that follows the curve Point Points::displacedEndpoint() const { - const int reflect = amReflected ? -1 : 1; - - if (myAxis == axis::X) - return makePoint(myX + 2, myY + 1*reflect); - else if (myAxis == -axis::X) - return makePoint(myX - 2, myY - 1*reflect); - else if (myAxis == axis::Y) - return makePoint(myX - 1*reflect, myY + 2); - else if (myAxis == -axis::Y) - return makePoint(myX + 1*reflect, myY - 2); - else - assert(false); + const int reflect = amReflected ? -1 : 1; + + if (myAxis == axis::X) + return makePoint(myX + 2, myY + 1*reflect); + else if (myAxis == -axis::X) + return makePoint(myX - 2, myY - 1*reflect); + else if (myAxis == axis::Y) + return makePoint(myX - 1*reflect, myY + 2); + else if (myAxis == -axis::Y) + return makePoint(myX + 1*reflect, myY - 2); + else + assert(false); } // Get the endpoint that follows the straight track Point Points::straightEndpoint() const { - if (myAxis == axis::X) - return makePoint(myX + 2, myY); - else if (myAxis == -axis::X) - return makePoint(myX - 2, myY); - else if (myAxis == axis::Y) - return makePoint(myX, myY + 2); - else if (myAxis == -axis::Y) - return makePoint(myX, myY - 2); - else - assert(false); + if (myAxis == axis::X) + return makePoint(myX + 2, myY); + else if (myAxis == -axis::X) + return makePoint(myX - 2, myY); + else if (myAxis == axis::Y) + return makePoint(myX, myY + 2); + else if (myAxis == -axis::Y) + return makePoint(myX, myY - 2); + else + assert(false); } void Points::getEndpoints(std::list >& aList) const { - aList.push_back(makePoint(myX, myY)); - aList.push_back(straightEndpoint()); - aList.push_back(displacedEndpoint()); + aList.push_back(makePoint(myX, myY)); + aList.push_back(straightEndpoint()); + aList.push_back(displacedEndpoint()); } ITrackSegmentPtr Points::mergeExit(const Point& aPoint, - const track::Direction& aDirection) + const track::Direction& aDirection) { - // Cant merge with anything - return ITrackSegmentPtr(); + // Cant merge with anything + return ITrackSegmentPtr(); } xml::element Points::toXml() const { - return xml::element("points") - .addAttribute("align", - myAxis == axis::X ? "x" - : (myAxis == -axis::X ? "-x" - : (myAxis == axis::Y ? "y" - : (myAxis == -axis::Y ? "-y" : "?")))) - .addAttribute("reflect", amReflected); + return xml::element("points") + .addAttribute("align", + myAxis == axis::X ? "x" + : (myAxis == -axis::X ? "-x" + : (myAxis == axis::Y ? "y" + : (myAxis == -axis::Y ? "-y" : "?")))) + .addAttribute("reflect", amReflected); } ITrackSegmentPtr makePoints(track::Direction aDirection, bool reflect) { - return ITrackSegmentPtr(new Points(aDirection, reflect)); + return ITrackSegmentPtr(new Points(aDirection, reflect)); } diff --git a/src/TrackCommon.cpp b/src/TrackCommon.cpp index 867f96b..12065a4 100644 --- a/src/TrackCommon.cpp +++ b/src/TrackCommon.cpp @@ -29,323 +29,323 @@ using namespace std; using namespace std::tr1; namespace { - const float RAIL_WIDTH = 0.05f; - const float GAUGE = 0.5f; + const float RAIL_WIDTH = 0.05f; + const float GAUGE = 0.5f; - const int SLEEPERS_PER_UNIT = 4; + const int SLEEPERS_PER_UNIT = 4; - const float SLEEPER_LENGTH = 0.8f; + const float SLEEPER_LENGTH = 0.8f; - IMeshPtr theSleeperMesh, theRailMesh; + IMeshPtr theSleeperMesh, theRailMesh; - typedef map CurvedRailMeshMap; - CurvedRailMeshMap theCurvedRailMeshes; + typedef map CurvedRailMeshMap; + CurvedRailMeshMap theCurvedRailMeshes; - const IMeshBuffer::Colour METAL = make_tuple(0.5f, 0.5f, 0.5f); + const IMeshBuffer::Colour METAL = make_tuple(0.5f, 0.5f, 0.5f); - void generateSleeperMesh() - { - IMeshBufferPtr buf = makeMeshBuffer(); - - const IMeshBuffer::Colour brown = make_tuple(0.5f, 0.3f, 0.0f); - - const float sleeperWidth = 0.1f; - const float sleeperDepth = 0.05f; - const float sleeperOff = sleeperWidth / 2.0f; - - const float r = SLEEPER_LENGTH / 2.0f; - - // Top - buf->addQuad(makeVector(-sleeperOff, sleeperDepth, -r), - makeVector(-sleeperOff, sleeperDepth, r), - makeVector(sleeperOff, sleeperDepth, r), - makeVector(sleeperOff, sleeperDepth, -r), - brown); - - // Side 1 - buf->addQuad(makeVector(sleeperOff, sleeperDepth, -r), - makeVector(sleeperOff, 0.0f, -r), - makeVector(-sleeperOff, 0.0f, -r), - makeVector(-sleeperOff, sleeperDepth, -r), - brown); + void generateSleeperMesh() + { + IMeshBufferPtr buf = makeMeshBuffer(); + + const IMeshBuffer::Colour brown = make_tuple(0.5f, 0.3f, 0.0f); + + const float sleeperWidth = 0.1f; + const float sleeperDepth = 0.05f; + const float sleeperOff = sleeperWidth / 2.0f; + + const float r = SLEEPER_LENGTH / 2.0f; + + // Top + buf->addQuad(makeVector(-sleeperOff, sleeperDepth, -r), + makeVector(-sleeperOff, sleeperDepth, r), + makeVector(sleeperOff, sleeperDepth, r), + makeVector(sleeperOff, sleeperDepth, -r), + brown); + + // Side 1 + buf->addQuad(makeVector(sleeperOff, sleeperDepth, -r), + makeVector(sleeperOff, 0.0f, -r), + makeVector(-sleeperOff, 0.0f, -r), + makeVector(-sleeperOff, sleeperDepth, -r), + brown); - // Side 2 - buf->addQuad(makeVector(-sleeperOff, sleeperDepth, r), - makeVector(-sleeperOff, 0.0f, r), - makeVector(sleeperOff, 0.0f, r), - makeVector(sleeperOff, sleeperDepth, r), - brown); - - // Front - buf->addQuad(makeVector(sleeperOff, 0.0f, r), - makeVector(sleeperOff, 0.0f, -r), - makeVector(sleeperOff, sleeperDepth, -r), - makeVector(sleeperOff, sleeperDepth, r), - brown); + // Side 2 + buf->addQuad(makeVector(-sleeperOff, sleeperDepth, r), + makeVector(-sleeperOff, 0.0f, r), + makeVector(sleeperOff, 0.0f, r), + makeVector(sleeperOff, sleeperDepth, r), + brown); + + // Front + buf->addQuad(makeVector(sleeperOff, 0.0f, r), + makeVector(sleeperOff, 0.0f, -r), + makeVector(sleeperOff, sleeperDepth, -r), + makeVector(sleeperOff, sleeperDepth, r), + brown); - // Back - buf->addQuad(makeVector(-sleeperOff, sleeperDepth, r), - makeVector(-sleeperOff, sleeperDepth, -r), - makeVector(-sleeperOff, 0.0f, -r), - makeVector(-sleeperOff, 0.0f, r), - brown); + // Back + buf->addQuad(makeVector(-sleeperOff, sleeperDepth, r), + makeVector(-sleeperOff, sleeperDepth, -r), + makeVector(-sleeperOff, 0.0f, -r), + makeVector(-sleeperOff, 0.0f, r), + brown); - theSleeperMesh = makeMesh(buf); - } - - void generateRailMesh() - { - IMeshBufferPtr buf = makeMeshBuffer(); - - // Top side - buf->addQuad(makeVector(-RAIL_WIDTH/2.0f, track::RAIL_HEIGHT, 0.0f), - makeVector(-RAIL_WIDTH/2.0f, track::RAIL_HEIGHT, 1.0f), - makeVector(RAIL_WIDTH/2.0f, track::RAIL_HEIGHT, 1.0f), - makeVector(RAIL_WIDTH/2.0f, track::RAIL_HEIGHT, 0.0f), - METAL); + theSleeperMesh = makeMesh(buf); + } + + void generateRailMesh() + { + IMeshBufferPtr buf = makeMeshBuffer(); + + // Top side + buf->addQuad(makeVector(-RAIL_WIDTH/2.0f, track::RAIL_HEIGHT, 0.0f), + makeVector(-RAIL_WIDTH/2.0f, track::RAIL_HEIGHT, 1.0f), + makeVector(RAIL_WIDTH/2.0f, track::RAIL_HEIGHT, 1.0f), + makeVector(RAIL_WIDTH/2.0f, track::RAIL_HEIGHT, 0.0f), + METAL); - // Outer side - buf->addQuad(makeVector(-RAIL_WIDTH/2.0f, track::RAIL_HEIGHT, 0.0f), - makeVector(-RAIL_WIDTH/2.0f, 0.0f, 0.0f), - makeVector(-RAIL_WIDTH/2.0f, 0.0f, 1.0f), - makeVector(-RAIL_WIDTH/2.0f, track::RAIL_HEIGHT, 1.0f), - METAL); + // Outer side + buf->addQuad(makeVector(-RAIL_WIDTH/2.0f, track::RAIL_HEIGHT, 0.0f), + makeVector(-RAIL_WIDTH/2.0f, 0.0f, 0.0f), + makeVector(-RAIL_WIDTH/2.0f, 0.0f, 1.0f), + makeVector(-RAIL_WIDTH/2.0f, track::RAIL_HEIGHT, 1.0f), + METAL); - // Inner side - buf->addQuad(makeVector(RAIL_WIDTH/2.0f, track::RAIL_HEIGHT, 1.0f), - makeVector(RAIL_WIDTH/2.0f, 0.0f, 1.0f), - makeVector(RAIL_WIDTH/2.0f, 0.0f, 0.0f), - makeVector(RAIL_WIDTH/2.0f, track::RAIL_HEIGHT, 0.0f), - METAL); + // Inner side + buf->addQuad(makeVector(RAIL_WIDTH/2.0f, track::RAIL_HEIGHT, 1.0f), + makeVector(RAIL_WIDTH/2.0f, 0.0f, 1.0f), + makeVector(RAIL_WIDTH/2.0f, 0.0f, 0.0f), + makeVector(RAIL_WIDTH/2.0f, track::RAIL_HEIGHT, 0.0f), + METAL); - theRailMesh = makeMesh(buf); - } + theRailMesh = makeMesh(buf); + } - // Generate a rail mesh from a Bezier curve - IMeshPtr generateBezierRailMesh(const BezierCurve& aFunc) - { - IMeshBufferPtr buf = makeMeshBuffer(); + // Generate a rail mesh from a Bezier curve + IMeshPtr generateBezierRailMesh(const BezierCurve& aFunc) + { + IMeshBufferPtr buf = makeMeshBuffer(); - const float step = 0.1f; + const float step = 0.1f; - for (float t = 0.0f; t < 1.0f; t += step) { - Vector v1 = aFunc(t); - Vector v2 = aFunc(t + step); + for (float t = 0.0f; t < 1.0f; t += step) { + Vector v1 = aFunc(t); + Vector v2 = aFunc(t + step); - v1.y -= RAIL_WIDTH / 2.0f; - v2.y -= RAIL_WIDTH / 2.0f; - - // Top of rail - buf->addQuad(makeVector(v1.x, track::RAIL_HEIGHT, v1.y), - makeVector(v1.x, track::RAIL_HEIGHT, v1.y + RAIL_WIDTH), - makeVector(v2.x, track::RAIL_HEIGHT, v2.y + RAIL_WIDTH), - makeVector(v2.x, track::RAIL_HEIGHT, v2.y), - METAL); - - // Outer edge - buf->addQuad(makeVector(v2.x, track::RAIL_HEIGHT, v2.y), - makeVector(v2.x , 0.0f, v2.y), - makeVector(v1.x, 0.0f, v1.y), - makeVector(v1.x, track::RAIL_HEIGHT, v1.y), - METAL); - - // Inner edge - buf->addQuad(makeVector(v1.x, track::RAIL_HEIGHT, v1.y + RAIL_WIDTH), - makeVector(v1.x, 0.0f, v1.y + RAIL_WIDTH), - makeVector(v2.x , 0.0f, v2.y + RAIL_WIDTH), - makeVector(v2.x, track::RAIL_HEIGHT, v2.y + RAIL_WIDTH), - METAL); - } - - return makeMesh(buf); - } + v1.y -= RAIL_WIDTH / 2.0f; + v2.y -= RAIL_WIDTH / 2.0f; + + // Top of rail + buf->addQuad(makeVector(v1.x, track::RAIL_HEIGHT, v1.y), + makeVector(v1.x, track::RAIL_HEIGHT, v1.y + RAIL_WIDTH), + makeVector(v2.x, track::RAIL_HEIGHT, v2.y + RAIL_WIDTH), + makeVector(v2.x, track::RAIL_HEIGHT, v2.y), + METAL); + + // Outer edge + buf->addQuad(makeVector(v2.x, track::RAIL_HEIGHT, v2.y), + makeVector(v2.x , 0.0f, v2.y), + makeVector(v1.x, 0.0f, v1.y), + makeVector(v1.x, track::RAIL_HEIGHT, v1.y), + METAL); + + // Inner edge + buf->addQuad(makeVector(v1.x, track::RAIL_HEIGHT, v1.y + RAIL_WIDTH), + makeVector(v1.x, 0.0f, v1.y + RAIL_WIDTH), + makeVector(v2.x , 0.0f, v2.y + RAIL_WIDTH), + makeVector(v2.x, track::RAIL_HEIGHT, v2.y + RAIL_WIDTH), + METAL); + } + + return makeMesh(buf); + } - enum RailType { - INNER_RAIL, OUTER_RAIL - }; + enum RailType { + INNER_RAIL, OUTER_RAIL + }; - IMeshPtr generateCurvedRailMesh(IMeshBufferPtr buf, int baseRadius, RailType type) - { - const float edgeWidth = (1 - GAUGE - RAIL_WIDTH)/2.0f; - const float R = static_cast(baseRadius) - edgeWidth - - (type == OUTER_RAIL ? 0 : GAUGE); - const float r = R - RAIL_WIDTH; + IMeshPtr generateCurvedRailMesh(IMeshBufferPtr buf, int baseRadius, RailType type) + { + const float edgeWidth = (1 - GAUGE - RAIL_WIDTH)/2.0f; + const float R = static_cast(baseRadius) - edgeWidth + - (type == OUTER_RAIL ? 0 : GAUGE); + const float r = R - RAIL_WIDTH; - const float step = 0.2f; + const float step = 0.2f; - // Top of rail - for (float theta = 0; theta < M_PI / 2.0f; theta += step) { - buf->addQuad(makeVector(r * cos(theta), 0.1f, r * sin(theta)), - makeVector(r * cos(theta + step), 0.1f, r * sin(theta + step)), - makeVector(R * cos(theta + step), 0.1f, R * sin(theta + step)), - makeVector(R * cos(theta), 0.1f, R * sin(theta)), - METAL); - } + // Top of rail + for (float theta = 0; theta < M_PI / 2.0f; theta += step) { + buf->addQuad(makeVector(r * cos(theta), 0.1f, r * sin(theta)), + makeVector(r * cos(theta + step), 0.1f, r * sin(theta + step)), + makeVector(R * cos(theta + step), 0.1f, R * sin(theta + step)), + makeVector(R * cos(theta), 0.1f, R * sin(theta)), + METAL); + } - // Outer edge - for (float theta = 0; theta < M_PI / 2.0f; theta += step) { - const float sinT = sin(theta); - const float cosT = cos(theta); - const float sinT1 = sin(theta + step); - const float cosT1 = cos(theta + step); - - buf->addQuad(// Vertices - makeVector(R * cosT1, 0.1f, R * sinT1), - makeVector(R * cosT1, 0.0f, R * sinT1), - makeVector(R * cosT, 0.0f, R * sinT), - makeVector(R * cosT, 0.1f, R * sinT), - - // Normals - makeVector(cosT1, 0.0f, sinT1), - makeVector(cosT1, 0.0f, sinT1), - makeVector(cosT, 0.0f, sinT), - makeVector(cosT, 0.0f, sinT), - - METAL); - } + // Outer edge + for (float theta = 0; theta < M_PI / 2.0f; theta += step) { + const float sinT = sin(theta); + const float cosT = cos(theta); + const float sinT1 = sin(theta + step); + const float cosT1 = cos(theta + step); + + buf->addQuad(// Vertices + makeVector(R * cosT1, 0.1f, R * sinT1), + makeVector(R * cosT1, 0.0f, R * sinT1), + makeVector(R * cosT, 0.0f, R * sinT), + makeVector(R * cosT, 0.1f, R * sinT), + + // Normals + makeVector(cosT1, 0.0f, sinT1), + makeVector(cosT1, 0.0f, sinT1), + makeVector(cosT, 0.0f, sinT), + makeVector(cosT, 0.0f, sinT), + + METAL); + } - // Inner edge - for (float theta = 0; theta < M_PI / 2.0f; theta += step) { - const float sinT = sin(theta); - const float cosT = cos(theta); - const float sinT1 = sin(theta + step); - const float cosT1 = cos(theta + step); - - buf->addQuad(// Vertices - makeVector(r * cosT, 0.1f, r * sinT), - makeVector(r * cosT, 0.0f, r * sinT), - makeVector(r * cosT1, 0.0f, r * sinT1), - makeVector(r * cosT1, 0.1f, r * sinT1), - - // Normals - makeVector(-cosT, 0.0f, -sinT), - makeVector(-cosT, 0.0f, -sinT), - makeVector(-cosT1, 0.0f, -sinT1), - makeVector(-cosT1, 0.0f, -sinT1), - - METAL); - } - - return makeMesh(buf); - } + // Inner edge + for (float theta = 0; theta < M_PI / 2.0f; theta += step) { + const float sinT = sin(theta); + const float cosT = cos(theta); + const float sinT1 = sin(theta + step); + const float cosT1 = cos(theta + step); + + buf->addQuad(// Vertices + makeVector(r * cosT, 0.1f, r * sinT), + makeVector(r * cosT, 0.0f, r * sinT), + makeVector(r * cosT1, 0.0f, r * sinT1), + makeVector(r * cosT1, 0.1f, r * sinT1), + + // Normals + makeVector(-cosT, 0.0f, -sinT), + makeVector(-cosT, 0.0f, -sinT), + makeVector(-cosT1, 0.0f, -sinT1), + makeVector(-cosT1, 0.0f, -sinT1), + + METAL); + } + + return makeMesh(buf); + } - void renderCurvedRail(int baseRadius) - { - IMeshPtr ptr; + void renderCurvedRail(int baseRadius) + { + IMeshPtr ptr; - CurvedRailMeshMap::iterator it = theCurvedRailMeshes.find(baseRadius); - if (it != theCurvedRailMeshes.end()) - ptr = (*it).second; - else { - IMeshBufferPtr buf = makeMeshBuffer(); + CurvedRailMeshMap::iterator it = theCurvedRailMeshes.find(baseRadius); + if (it != theCurvedRailMeshes.end()) + ptr = (*it).second; + else { + IMeshBufferPtr buf = makeMeshBuffer(); - generateCurvedRailMesh(buf, baseRadius, INNER_RAIL); - generateCurvedRailMesh(buf, baseRadius, OUTER_RAIL); + generateCurvedRailMesh(buf, baseRadius, INNER_RAIL); + generateCurvedRailMesh(buf, baseRadius, OUTER_RAIL); - ptr = makeMesh(buf); - theCurvedRailMeshes[baseRadius] = ptr; - } + ptr = makeMesh(buf); + theCurvedRailMeshes[baseRadius] = ptr; + } - ptr->render(); - } + ptr->render(); + } - void renderOneRail() - { - if (!theRailMesh) - generateRailMesh(); + void renderOneRail() + { + if (!theRailMesh) + generateRailMesh(); - theRailMesh->render(); - } + theRailMesh->render(); + } } IMeshPtr makeBezierRailMesh(const BezierCurve& aFunc) { - return generateBezierRailMesh(aFunc); + return generateBezierRailMesh(aFunc); } // Draw a sleeper in the current maxtrix location void renderSleeper() { - if (!theSleeperMesh) - generateSleeperMesh(); + if (!theSleeperMesh) + generateSleeperMesh(); - theSleeperMesh->render(); + theSleeperMesh->render(); } // Render a pre-generated rail mesh in the right place void renderRailMesh(IMeshPtr aMesh) { - glPushMatrix(); + glPushMatrix(); - glTranslatef(-0.5f, 0.0f, -GAUGE/2.0f); - aMesh->render(); + glTranslatef(-0.5f, 0.0f, -GAUGE/2.0f); + aMesh->render(); - glTranslatef(0.0f, 0.0f, GAUGE); - aMesh->render(); + glTranslatef(0.0f, 0.0f, GAUGE); + aMesh->render(); - glPopMatrix(); + glPopMatrix(); } void renderStraightRail() { - glPushMatrix(); + glPushMatrix(); - glTranslatef(-GAUGE/2.0f, 0.0f, -0.5f); - renderOneRail(); + glTranslatef(-GAUGE/2.0f, 0.0f, -0.5f); + renderOneRail(); - glTranslatef(GAUGE, 0.0f, 0.0f); - renderOneRail(); + glTranslatef(GAUGE, 0.0f, 0.0f); + renderOneRail(); - glPopMatrix(); + glPopMatrix(); } // Move to the origin of a curved section of track void transformToOrigin(int baseRadius, track::Angle startAngle) { - glTranslatef((baseRadius-1)*-sin(degToRad(startAngle)) - 0.5f, 0.0f, - (baseRadius-1)*-cos(degToRad(startAngle)) - 0.5f); - - // There *must* be a way to incorporate this in the above translation - // as a neat formula, but I really can't think of it - // This is a complete a hack, but whatever... - if (startAngle >= 90 && startAngle <= 180) - glTranslatef(0.0f, 0.0f, 1.0f); + glTranslatef((baseRadius-1)*-sin(degToRad(startAngle)) - 0.5f, 0.0f, + (baseRadius-1)*-cos(degToRad(startAngle)) - 0.5f); + + // There *must* be a way to incorporate this in the above translation + // as a neat formula, but I really can't think of it + // This is a complete a hack, but whatever... + if (startAngle >= 90 && startAngle <= 180) + glTranslatef(0.0f, 0.0f, 1.0f); - if (startAngle >= 180 && startAngle <= 270) - glTranslatef(1.0f, 0.0f, 0.0f); + if (startAngle >= 180 && startAngle <= 270) + glTranslatef(1.0f, 0.0f, 0.0f); } // `baseRadius' is measured in tiles void renderCurvedTrack(int baseRadius, track::Angle startAngle, - track::Angle endAngle) + track::Angle endAngle) { - glPushMatrix(); + glPushMatrix(); - transformToOrigin(baseRadius, startAngle); + transformToOrigin(baseRadius, startAngle); - glPushMatrix(); + glPushMatrix(); - glRotatef(static_cast(startAngle), 0.0f, 1.0f, 0.0f); - renderCurvedRail(baseRadius); + glRotatef(static_cast(startAngle), 0.0f, 1.0f, 0.0f); + renderCurvedRail(baseRadius); - glPopMatrix(); + glPopMatrix(); - const float length = degToRad(static_cast(endAngle - startAngle)) * baseRadius; - const int numSleepers = static_cast(length * SLEEPERS_PER_UNIT); - const float sleeperAngle = - static_cast(endAngle - startAngle) / numSleepers; + const float length = degToRad(static_cast(endAngle - startAngle)) * baseRadius; + const int numSleepers = static_cast(length * SLEEPERS_PER_UNIT); + const float sleeperAngle = + static_cast(endAngle - startAngle) / numSleepers; - for (int i = 0; i < numSleepers; i++) { - glPushMatrix(); + for (int i = 0; i < numSleepers; i++) { + glPushMatrix(); - glRotatef(static_cast(startAngle) + (i + 0.5f)*sleeperAngle, - 0.0f, 1.0f, 0.0f); - glTranslatef(0.0f, 0.0f, static_cast(baseRadius) - 0.5f); + glRotatef(static_cast(startAngle) + (i + 0.5f)*sleeperAngle, + 0.0f, 1.0f, 0.0f); + glTranslatef(0.0f, 0.0f, static_cast(baseRadius) - 0.5f); - renderSleeper(); + renderSleeper(); - glPopMatrix(); - } + glPopMatrix(); + } - glPopMatrix(); + glPopMatrix(); } diff --git a/src/Train.cpp b/src/Train.cpp index 196fbbd..845a627 100644 --- a/src/Train.cpp +++ b/src/Train.cpp @@ -32,425 +32,425 @@ // Concrete implementation of trains class Train : public ITrain { public: - Train(IMapPtr aMap); + Train(IMapPtr aMap); - void render() const; - void update(int aDelta); + void render() const; + void update(int aDelta); - Vector front() const; - ITrackSegmentPtr trackSegment() const; - track::Direction direction() const; - track::Position tile() const { return engine().travelToken.position; } + Vector front() const; + ITrackSegmentPtr trackSegment() const; + track::Direction direction() const; + track::Position tile() const { return engine().travelToken.position; } - double speed() const { return parts.front().vehicle->speed(); } - IControllerPtr controller() { return parts.front().vehicle->controller(); } + double speed() const { return parts.front().vehicle->speed(); } + IControllerPtr controller() { return parts.front().vehicle->controller(); } private: - // The different parts of the train are on different track segments - struct Part : boost::equality_comparable { - explicit Part(IRollingStockPtr aVehicle, bool amDriving = false) - : vehicle(aVehicle), segmentDelta(0.0), isLeading(amDriving), - movementSign(1.0) - {} + // The different parts of the train are on different track segments + struct Part : boost::equality_comparable { + explicit Part(IRollingStockPtr aVehicle, bool amDriving = false) + : vehicle(aVehicle), segmentDelta(0.0), isLeading(amDriving), + movementSign(1.0) + {} - IRollingStockPtr vehicle; - - // The length of a track segment can be found by calling - // segmentLength() This delta value ranges from 0 to that length and - // indicates how far along the segment the train is - ITrackSegmentPtr segment; - double segmentDelta; - track::TravelToken travelToken; + IRollingStockPtr vehicle; + + // The length of a track segment can be found by calling + // segmentLength() This delta value ranges from 0 to that length and + // indicates how far along the segment the train is + ITrackSegmentPtr segment; + double segmentDelta; + track::TravelToken travelToken; - // Direction train part is travelling along the track - Vector direction; - - // Turns to take if this is not the engine - queue followQueue; - - // True if this is driving the train - bool isLeading; - - // Handles reversal mid-segment - double movementSign; - - bool operator==(const Part& other) const - { - return this == &other; - } - }; - list parts; - - const Part& engine() const; - const Part& leading() const; - Part& engine(); - void move(double aDistance); - void addPart(IRollingStockPtr aVehicle); - Vector partPosition(const Part& aPart) const; - void updateSmokePosition(int aDelta); - void makeFollow(track::Choice aChoice); - void flipLeader(); - void dumpFollowQueue() const; - void eachPart(function callback); - void movePart(Part& part, double distance); - - static track::Connection reverseToken(const track::TravelToken& token); - static void transformToPart(const Part& p); + // Direction train part is travelling along the track + Vector direction; + + // Turns to take if this is not the engine + queue followQueue; + + // True if this is driving the train + bool isLeading; + + // Handles reversal mid-segment + double movementSign; + + bool operator==(const Part& other) const + { + return this == &other; + } + }; + list parts; + + const Part& engine() const; + const Part& leading() const; + Part& engine(); + void move(double aDistance); + void addPart(IRollingStockPtr aVehicle); + Vector partPosition(const Part& aPart) const; + void updateSmokePosition(int aDelta); + void makeFollow(track::Choice aChoice); + void flipLeader(); + void dumpFollowQueue() const; + void eachPart(function callback); + void movePart(Part& part, double distance); + + static track::Connection reverseToken(const track::TravelToken& token); + static void transformToPart(const Part& p); - IMapPtr map; - ISmokeTrailPtr smokeTrail; + IMapPtr map; + ISmokeTrailPtr smokeTrail; - Vector velocityVector; + Vector velocityVector; - // Move part of the train across a connection - void enterSegment(Part& aPart, const track::Connection& aConnection); + // Move part of the train across a connection + void enterSegment(Part& aPart, const track::Connection& aConnection); - // Seperation between waggons - static const double SEPARATION; + // Seperation between waggons + static const double SEPARATION; }; const double Train::SEPARATION(0.1); Train::Train(IMapPtr aMap) - : map(aMap), velocityVector(makeVector(0.0f, 0.0f, 0.0f)) + : map(aMap), velocityVector(makeVector(0.0f, 0.0f, 0.0f)) { - parts.push_front(Part(loadEngine("pclass"), true)); + parts.push_front(Part(loadEngine("pclass"), true)); - enterSegment(engine(), aMap->start()); + enterSegment(engine(), aMap->start()); - // Bit of a hack to put the engine in the right place - move(0.275); + // Bit of a hack to put the engine in the right place + move(0.275); - for (int i = 1; i <= 5; i++) - addPart(loadWaggon("coal_truck")); + for (int i = 1; i <= 5; i++) + addPart(loadWaggon("coal_truck")); - smokeTrail = makeSmokeTrail(); + smokeTrail = makeSmokeTrail(); } void Train::addPart(IRollingStockPtr aVehicle) { - Part part(aVehicle); - enterSegment(part, map->start()); + Part part(aVehicle); + enterSegment(part, map->start()); - // Push the rest of the train along some - move(part.vehicle->length() + SEPARATION); + // Push the rest of the train along some + move(part.vehicle->length() + SEPARATION); - parts.push_back(part); + parts.push_back(part); } // Return the part that is leading the train - i.e. the // first to encounter points, etc. const Train::Part& Train::leading() const { - Part const* p = NULL; - - for (list::const_iterator it = parts.begin(); - it != parts.end(); ++it) { - if ((*it).isLeading) { - if (p) - assert(false && "> 1 leading part!"); - else - p = &(*it); - } - } - - assert(p); - return *p; + Part const* p = NULL; + + for (list::const_iterator it = parts.begin(); + it != parts.end(); ++it) { + if ((*it).isLeading) { + if (p) + assert(false && "> 1 leading part!"); + else + p = &(*it); + } + } + + assert(p); + return *p; } // Make everything that's not the engine follow its choice void Train::makeFollow(track::Choice aChoice) { - const Part& leader = leading(); - for (list::iterator it = parts.begin(); - it != parts.end(); ++it) { - if (*it != leader) - (*it).followQueue.push(aChoice); - } + const Part& leader = leading(); + for (list::iterator it = parts.begin(); + it != parts.end(); ++it) { + if (*it != leader) + (*it).followQueue.push(aChoice); + } } void Train::dumpFollowQueue() const { - ostringstream ss; + ostringstream ss; - for (list::const_iterator it = parts.begin(); - it != parts.end(); ++it) { + for (list::const_iterator it = parts.begin(); + it != parts.end(); ++it) { - if ((*it).isLeading) - ss << ">"; + if ((*it).isLeading) + ss << ">"; - if ((*it).followQueue.empty()) - ss << "-"; - else { - ss << (*it).followQueue.front(); - } + if ((*it).followQueue.empty()) + ss << "-"; + else { + ss << (*it).followQueue.front(); + } - ss << " "; - } + ss << " "; + } - debug() << ss.str(); + debug() << ss.str(); } Train::Part& Train::engine() { - assert(parts.size() > 0); - return parts.front(); + assert(parts.size() > 0); + return parts.front(); } const Train::Part& Train::engine() const { - assert(parts.size() > 0); - return parts.front(); + assert(parts.size() > 0); + return parts.front(); } // Change the leader part from the front to the back or vice // versa void Train::flipLeader() { - if (leading() == engine()) { - // Make the last waggon the leader - engine().isLeading = false; - parts.back().isLeading = true; - } - else { - // Make the engine the leader - parts.back().isLeading = false; - engine().isLeading = true; - } - - for (list::iterator it = parts.begin(); - it != parts.end(); ++it) { - while (!(*it).followQueue.empty()) - (*it).followQueue.pop(); - } + if (leading() == engine()) { + // Make the last waggon the leader + engine().isLeading = false; + parts.back().isLeading = true; + } + else { + // Make the engine the leader + parts.back().isLeading = false; + engine().isLeading = true; + } + + for (list::iterator it = parts.begin(); + it != parts.end(); ++it) { + while (!(*it).followQueue.empty()) + (*it).followQueue.pop(); + } } // Iterate through the parts in order from the front of the // train to the back void Train::eachPart(function callback) { - if (parts.front().isLeading) { - for (list::iterator it = parts.begin(); - it != parts.end(); ++it) - callback(*it); - } - else { - for (list::reverse_iterator it = parts.rbegin(); - it != parts.rend(); ++it) - callback(*it); - } + if (parts.front().isLeading) { + for (list::iterator it = parts.begin(); + it != parts.end(); ++it) + callback(*it); + } + else { + for (list::reverse_iterator it = parts.rbegin(); + it != parts.rend(); ++it) + callback(*it); + } } void Train::movePart(Part& part, double distance) { - // Never move in units greater than 1.0 - double d = abs(distance); - double sign = (distance >= 0.0 ? 1.0 : -1.0) * part.movementSign; - const double step = 0.25; + // Never move in units greater than 1.0 + double d = abs(distance); + double sign = (distance >= 0.0 ? 1.0 : -1.0) * part.movementSign; + const double step = 0.25; - //debug() << "move d=" << distance << " s=" << sign - // << " ms=" << part.movementSign; + //debug() << "move d=" << distance << " s=" << sign + // << " ms=" << part.movementSign; - do { - part.segmentDelta += min(step, d) * sign; + do { + part.segmentDelta += min(step, d) * sign; - const double segmentLength = - part.segment->segmentLength(part.travelToken); - if (part.segmentDelta >= segmentLength) { - // Moved onto a new piece of track - const double over = part.segmentDelta - segmentLength; - enterSegment(part, part.segment->nextPosition(part.travelToken)); - part.segmentDelta = over; - } - else if (part.segmentDelta < 0.0) { - track::Connection prev = reverseToken(part.travelToken); - enterSegment(part, prev); - part.segmentDelta *= -1.0; - part.movementSign *= -1.0; - } + const double segmentLength = + part.segment->segmentLength(part.travelToken); + if (part.segmentDelta >= segmentLength) { + // Moved onto a new piece of track + const double over = part.segmentDelta - segmentLength; + enterSegment(part, part.segment->nextPosition(part.travelToken)); + part.segmentDelta = over; + } + else if (part.segmentDelta < 0.0) { + track::Connection prev = reverseToken(part.travelToken); + enterSegment(part, prev); + part.segmentDelta *= -1.0; + part.movementSign *= -1.0; + } - d -= step; - } while (d > 0.0); + d -= step; + } while (d > 0.0); } // Move the train along the line a bit void Train::move(double aDistance) { - using namespace placeholders; + using namespace placeholders; - eachPart(bind(&Train::movePart, this, _1, aDistance)); + eachPart(bind(&Train::movePart, this, _1, aDistance)); } void Train::updateSmokePosition(int aDelta) { - const Part& e = engine(); - glPushMatrix(); - glLoadIdentity(); + const Part& e = engine(); + glPushMatrix(); + glLoadIdentity(); - transformToPart(e); + transformToPart(e); - const float smokeOffX = 0.63f; - const float smokeOffY = 1.04f; - glTranslatef(smokeOffX, smokeOffY, 0.0f); + const float smokeOffX = 0.63f; + const float smokeOffY = 1.04f; + glTranslatef(smokeOffX, smokeOffY, 0.0f); - float matrix[16]; - glGetFloatv(GL_MODELVIEW_MATRIX, matrix); + float matrix[16]; + glGetFloatv(GL_MODELVIEW_MATRIX, matrix); - glPopMatrix(); + glPopMatrix(); - smokeTrail->setPosition(matrix[12], matrix[13], matrix[14]); - smokeTrail->setVelocity( - velocityVector.x, - velocityVector.y, - velocityVector.z); - smokeTrail->update(aDelta); + smokeTrail->setPosition(matrix[12], matrix[13], matrix[14]); + smokeTrail->setVelocity( + velocityVector.x, + velocityVector.y, + velocityVector.z); + smokeTrail->update(aDelta); - // Make the rate at which new particles are created proportional - // to the throttle of the controller - const int throttle = e.vehicle->controller()->throttle(); - const int baseDelay = 200; + // Make the rate at which new particles are created proportional + // to the throttle of the controller + const int throttle = e.vehicle->controller()->throttle(); + const int baseDelay = 200; - smokeTrail->setDelay(baseDelay - (throttle * 15)); + smokeTrail->setDelay(baseDelay - (throttle * 15)); } void Train::update(int aDelta) { - int oldSpeedSign = engine().vehicle->speed() >= 0.0 ? 1 : 0; + int oldSpeedSign = engine().vehicle->speed() >= 0.0 ? 1 : 0; - for (list::iterator it = parts.begin(); - it != parts.end(); ++it) - (*it).vehicle->update(aDelta); + for (list::iterator it = parts.begin(); + it != parts.end(); ++it) + (*it).vehicle->update(aDelta); - int newSpeedSign = engine().vehicle->speed() >= 0.0 ? 1 : 0; + int newSpeedSign = engine().vehicle->speed() >= 0.0 ? 1 : 0; - if (oldSpeedSign != newSpeedSign) - flipLeader(); + if (oldSpeedSign != newSpeedSign) + flipLeader(); - updateSmokePosition(aDelta); + updateSmokePosition(aDelta); - // How many metres does a tile correspond to? - const double M_PER_UNIT = 5.0; + // How many metres does a tile correspond to? + const double M_PER_UNIT = 5.0; - const Vector oldPos = partPosition(engine()); + const Vector oldPos = partPosition(engine()); - const double deltaSeconds = static_cast(aDelta) / 1000.0f; - move(engine().vehicle->speed() * deltaSeconds / M_PER_UNIT); + const double deltaSeconds = static_cast(aDelta) / 1000.0f; + move(engine().vehicle->speed() * deltaSeconds / M_PER_UNIT); - velocityVector = partPosition(engine()) - oldPos; + velocityVector = partPosition(engine()) - oldPos; - dumpFollowQueue(); + dumpFollowQueue(); } // Called when the train enters a new segment // Resets the delta and gets the length of the new segment void Train::enterSegment(Part& aPart, const track::Connection& aConnection) { - Point pos; - tie(pos, aPart.direction) = aConnection; + Point pos; + tie(pos, aPart.direction) = aConnection; - //debug() << "Train part entered segment at " << pos - // << " moving " << aPart.direction; + //debug() << "Train part entered segment at " << pos + // << " moving " << aPart.direction; - if (!map->isValidTrack(pos)) - throw runtime_error("Train fell off end of track!"); + if (!map->isValidTrack(pos)) + throw runtime_error("Train fell off end of track!"); - aPart.segmentDelta = 0.0; - aPart.segment = map->trackAt(pos); - aPart.travelToken = aPart.segment->getTravelToken(pos, aPart.direction); + aPart.segmentDelta = 0.0; + aPart.segment = map->trackAt(pos); + aPart.travelToken = aPart.segment->getTravelToken(pos, aPart.direction); - if (aPart.travelToken.choices.size() > 1) { - track::Choice choice; + if (aPart.travelToken.choices.size() > 1) { + track::Choice choice; - if (aPart == leading()) { - // Need to make a choice: see what the controller has pre-set - choice = engine().vehicle->controller()->consumeChoice(); - makeFollow(choice); - } - else { - // We're following another part so look in the follow queue - assert(!aPart.followQueue.empty()); - - choice = aPart.followQueue.front(); - aPart.followQueue.pop(); - } + if (aPart == leading()) { + // Need to make a choice: see what the controller has pre-set + choice = engine().vehicle->controller()->consumeChoice(); + makeFollow(choice); + } + else { + // We're following another part so look in the follow queue + assert(!aPart.followQueue.empty()); + + choice = aPart.followQueue.front(); + aPart.followQueue.pop(); + } - aPart.travelToken.activeChoice = choice; - } + aPart.travelToken.activeChoice = choice; + } } void Train::transformToPart(const Part& p) { - p.travelToken.transform(p.segmentDelta); + p.travelToken.transform(p.segmentDelta); - // If we're going backwards, flip the train around - if (p.movementSign < 0.0) - glRotatef(180.0f, 0.0f, 1.0f, 0.0f); + // If we're going backwards, flip the train around + if (p.movementSign < 0.0) + glRotatef(180.0f, 0.0f, 1.0f, 0.0f); } void Train::render() const { - for (list::const_iterator it = parts.begin(); - it != parts.end(); ++it) { - glPushMatrix(); + for (list::const_iterator it = parts.begin(); + it != parts.end(); ++it) { + glPushMatrix(); - transformToPart(*it); - glTranslatef(0.0f, track::RAIL_HEIGHT, 0.0f); + transformToPart(*it); + glTranslatef(0.0f, track::RAIL_HEIGHT, 0.0f); - (*it).vehicle->render(); + (*it).vehicle->render(); - glPopMatrix(); - } + glPopMatrix(); + } - smokeTrail->render(); + smokeTrail->render(); } ITrackSegmentPtr Train::trackSegment() const { - return engine().segment; + return engine().segment; } Vector Train::front() const { - return partPosition(engine()); + return partPosition(engine()); } track::Direction Train::direction() const { - return engine().direction; + return engine().direction; } // Calculate the position of any train part Vector Train::partPosition(const Part& aPart) const { - // Call the transformer to compute the world location - glPushMatrix(); - glLoadIdentity(); + // Call the transformer to compute the world location + glPushMatrix(); + glLoadIdentity(); - aPart.travelToken.transform(aPart.segmentDelta); + aPart.travelToken.transform(aPart.segmentDelta); - float matrix[16]; - glGetFloatv(GL_MODELVIEW_MATRIX, matrix); + float matrix[16]; + glGetFloatv(GL_MODELVIEW_MATRIX, matrix); - glPopMatrix(); + glPopMatrix(); - return makeVector(matrix[12], matrix[13], matrix[14]); + return makeVector(matrix[12], matrix[13], matrix[14]); } // Compute a connection object that reverses the train's // direction of travel track::Connection Train::reverseToken(const track::TravelToken& token) { - track::Position pos = makePoint( - token.position.x - token.direction.x, - token.position.y - token.direction.z); + track::Position pos = makePoint( + token.position.x - token.direction.x, + token.position.y - token.direction.z); - track::Direction dir = -token.direction; + track::Direction dir = -token.direction; - return make_pair(pos, dir); + return make_pair(pos, dir); } // Make an empty train ITrainPtr makeTrain(IMapPtr aMap) { - return ITrainPtr(new Train(aMap)); + return ITrainPtr(new Train(aMap)); } -- 2.39.2