From b20c770f649bd86d1f432b80692c807ac9753bb9 Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Sun, 7 Jun 2009 16:43:20 +0100 Subject: [PATCH] Basic rendering of S-bend curves --- include/ITrackSegment.hpp | 1 + include/TrackCommon.hpp | 2 + src/Editor.cpp | 7 ++++ src/Points.cpp | 32 +++++++++++++-- src/TrackCommon.cpp | 82 +++++++++++++++++++++++++++++++++------ 5 files changed, 110 insertions(+), 14 deletions(-) diff --git a/include/ITrackSegment.hpp b/include/ITrackSegment.hpp index 6cebb25..404d8e4 100644 --- a/include/ITrackSegment.hpp +++ b/include/ITrackSegment.hpp @@ -113,5 +113,6 @@ ITrackSegmentPtr makeStraightTrack(const track::Direction& aDirection); ITrackSegmentPtr makeCurvedTrack(track::Angle aStartAngle, track::Angle aFinishAngle, int aRadius); ITrackSegmentPtr makeCrossoverTrack(); +ITrackSegmentPtr makePoints(); #endif diff --git a/include/TrackCommon.hpp b/include/TrackCommon.hpp index a1b2ec1..d2b3f33 100644 --- a/include/TrackCommon.hpp +++ b/include/TrackCommon.hpp @@ -23,9 +23,11 @@ // Common track rendering functions void renderSleeper(); void renderStraightRail(); +void renderHypTanRail(); void renderCurvedTrack(int baseRadius, track::Angle startAngle, track::Angle endAngle); void transformToOrigin(int baseRadius, track::Angle startAngle); +float hypTanCurveFunc(float x); // Track constants namespace track { diff --git a/src/Editor.cpp b/src/Editor.cpp index 543306a..1c90d9d 100644 --- a/src/Editor.cpp +++ b/src/Editor.cpp @@ -238,6 +238,13 @@ void Editor::drawDraggedStraight(const track::Direction& anAxis, int aLength) // Connect the beginning and end up in the simplest way possible void Editor::drawDraggedTrack() { + // REMOVE + ITrackSegmentPtr p = makePoints(); + p->setOrigin(myDragBegin.x, myDragBegin.y); + myMap->setTrackAt(myDragBegin, p); + return; + + track::Direction straight; // Orientation for straight track section int xmin, xmax, ymin, ymax; diff --git a/src/Points.cpp b/src/Points.cpp index 9d587d4..1c900e9 100644 --- a/src/Points.cpp +++ b/src/Points.cpp @@ -18,6 +18,9 @@ #include "ITrackSegment.hpp" #include "TrackCommon.hpp" #include "XMLBuilder.hpp" +#include "ILogger.hpp" + +#include // Forks in the track class Points : public ITrackSegment { @@ -40,13 +43,36 @@ private: }; Points::Points() + : myX(0), myY(0) { - + } void Points::render() const -{ +{ + glPushMatrix(); + + renderHypTanRail(); + + 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); + } + + glPopMatrix(); + + // Draw the sleepers + glTranslatef(-0.4f, 0.0f, 0.0f); + + for (int i = 0; i < 12; i++) { + renderSleeper(); + glTranslatef(0.25f, 0.0f, 0.0f); + } + + glPopMatrix(); } double Points::segmentLength() const @@ -72,7 +98,7 @@ track::Connection Points::nextPosition(const track::Direction& aDirection) const void Points::getEndpoints(std::list >& aList) const { - + aList.push_back(makePoint(myX, myY)); } ITrackSegmentPtr Points::mergeExit(const Point& aPoint, diff --git a/src/TrackCommon.cpp b/src/TrackCommon.cpp index 3d1b47d..9d210ba 100644 --- a/src/TrackCommon.cpp +++ b/src/TrackCommon.cpp @@ -36,11 +36,13 @@ namespace { const float SLEEPER_LENGTH = 0.8f; - IMeshPtr theSleeperMesh, theRailMesh; + IMeshPtr theSleeperMesh, theRailMesh, theHypTanRailMesh; typedef map CurvedRailMeshMap; CurvedRailMeshMap theCurvedRailMeshes; + const IMeshBuffer::Colour METAL = make_tuple(0.7f, 0.7f, 0.7f); + void generateSleeperMesh() { IMeshBufferPtr buf = makeMeshBuffer(); @@ -95,32 +97,70 @@ namespace { { IMeshBufferPtr buf = makeMeshBuffer(); - const IMeshBuffer::Colour metal = make_tuple(0.7f, 0.7f, 0.7f); - // 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); + 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); + 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); + METAL); theRailMesh = makeMesh(buf); } + // The rail mesh used for points and S-bends + void generateHypTanRailMesh() + { + IMeshBufferPtr buf = makeMeshBuffer(); + + const float step = 0.1f; + const float xmax = 3.0f; + + for (float x = 0.0f; x < xmax - step; x += step) { + const float y1 = hypTanCurveFunc(x); + debug() << x << " --> " << y1; + + const float y2 = hypTanCurveFunc(x + step); + + // Top of rail + buf->addQuad(makeVector(x, track::RAIL_HEIGHT, y1), + makeVector(x, track::RAIL_HEIGHT, y1 + RAIL_WIDTH), + makeVector(x + step, track::RAIL_HEIGHT, y2 + RAIL_WIDTH), + makeVector(x + step, track::RAIL_HEIGHT, y2), + METAL); + + // Outer edge + buf->addQuad(makeVector(x + step, track::RAIL_HEIGHT, y2), + makeVector(x + step , 0.0f, y2), + makeVector(x, 0.0f, y1), + makeVector(x, track::RAIL_HEIGHT, y1), + METAL); + + // Inner edge + buf->addQuad( + makeVector(x, track::RAIL_HEIGHT, y1 + RAIL_WIDTH), + makeVector(x, 0.0f, y1 + RAIL_WIDTH), + makeVector(x + step , 0.0f, y2 + RAIL_WIDTH), + makeVector(x + step, track::RAIL_HEIGHT, y2 + RAIL_WIDTH), + METAL); + } + + theHypTanRailMesh = makeMesh(buf); + } + enum RailType { INNER_RAIL, OUTER_RAIL }; @@ -133,8 +173,6 @@ namespace { const float r = R - RAIL_WIDTH; const float step = 0.1f; - - const IMeshBuffer::Colour metal = make_tuple(0.7f, 0.7f, 0.7f); // Top of rail for (float theta = 0; theta < M_PI / 2.0f; theta += step) { @@ -142,7 +180,7 @@ namespace { 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); + METAL); } // Outer edge @@ -164,7 +202,7 @@ namespace { makeVector(cosT, 0.0f, sinT), makeVector(cosT, 0.0f, sinT), - metal); + METAL); } // Inner edge @@ -186,7 +224,7 @@ namespace { makeVector(-cosT1, 0.0f, -sinT1), makeVector(-cosT1, 0.0f, -sinT1), - metal); + METAL); } return makeMesh(buf); @@ -221,6 +259,12 @@ namespace { } } +// The function that determines the curve of points and S-bends +float hypTanCurveFunc(float x) +{ + return 0.5f * (1.0f + tanh(1.8f * x - 3.5f)); +} + // Draw a sleeper in the current maxtrix location void renderSleeper() { @@ -243,6 +287,22 @@ void renderStraightRail() glPopMatrix(); } +void renderHypTanRail() +{ + if (!theHypTanRailMesh) + generateHypTanRailMesh(); + + glPushMatrix(); + + glTranslatef(-0.5f, 0.0f, -GAUGE/2.0f); + theHypTanRailMesh->render(); + + glTranslatef(0.0f, 0.0f, GAUGE); + theHypTanRailMesh->render(); + + glPopMatrix(); +} + // Move to the origin of a curved section of track void transformToOrigin(int baseRadius, track::Angle startAngle) { -- 2.39.2