From cb09876c8162f01a0a7068345f34a9ed31d0cd12 Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Sat, 27 Mar 2010 22:29:54 +0000 Subject: [PATCH] Compute offsets of Bezier curves to keep rails at constant separation --- include/BezierCurve.hpp | 15 +++++++++++++++ src/Points.cpp | 5 ++++- src/SBend.cpp | 7 ++++++- src/SlopeTrack.cpp | 5 ++++- src/TrackCommon.cpp | 22 +++++++++++++++------- 5 files changed, 44 insertions(+), 10 deletions(-) diff --git a/include/BezierCurve.hpp b/include/BezierCurve.hpp index 78e88bc..3f1ac70 100644 --- a/include/BezierCurve.hpp +++ b/include/BezierCurve.hpp @@ -106,6 +106,21 @@ struct BezierCurve { + p[3].z * 3 * t * t ); } + + // Value of the function at a constant radius in the Z-plane + Vector offset(T t, T p) const + { + Vector v = (*this)(t); + const Vector d = deriv(t); + + const T o = + p / sqrt((d.x * d.x) + (d.z * d.z)); + + v.x += o * d.z; + v.z -= o * d.x; + + return v; + } }; // Generate Bezier curves diff --git a/src/Points.cpp b/src/Points.cpp index 913a009..3623967 100644 --- a/src/Points.cpp +++ b/src/Points.cpp @@ -189,7 +189,10 @@ void Points::render() const else if (myAxis == axis::Y) glRotatef(270.0f, 0.0f, 1.0f, 0.0f); - renderRailMesh(reflected ? reflectMesh : railMesh); + glPushMatrix(); + glTranslatef(-0.5f, 0.0f, 0.0f); + (reflected ? reflectMesh : railMesh)->render(); + glPopMatrix(); glPushMatrix(); glRotatef(90.0f, 0.0f, 1.0f, 0.0f); diff --git a/src/SBend.cpp b/src/SBend.cpp index 65a2ef4..f977619 100644 --- a/src/SBend.cpp +++ b/src/SBend.cpp @@ -106,7 +106,12 @@ void SBend::render() const if (axis == axis::Y) glRotatef(-90.0f, 0.0f, 1.0f, 0.0f); - renderRailMesh(railMesh); + glPushMatrix(); + + glTranslatef(-0.5f, 0.0f, 0.0f); + railMesh->render(); + + glPopMatrix(); for (float i = 0.1f; i < curve.length; i += 0.25f) { glPushMatrix(); diff --git a/src/SlopeTrack.cpp b/src/SlopeTrack.cpp index 78d3473..8c31ae7 100644 --- a/src/SlopeTrack.cpp +++ b/src/SlopeTrack.cpp @@ -111,7 +111,10 @@ void SlopeTrack::render() const if (axis == axis::Y) glRotatef(-90.0f, 0.0f, 1.0f, 0.0f); - renderRailMesh(railMesh); + glPushMatrix(); + glTranslatef(-0.5f, 0.0f, 0.0f); + railMesh->render(); + glPopMatrix(); // Draw the sleepers glTranslatef(-0.5f, 0.0f, 0.0f); diff --git a/src/TrackCommon.cpp b/src/TrackCommon.cpp index 0c6b15f..995ed43 100644 --- a/src/TrackCommon.cpp +++ b/src/TrackCommon.cpp @@ -118,17 +118,16 @@ namespace { theRailMesh = makeMesh(buf); } - // Generate a rail mesh from a Bezier curve - IMeshPtr generateBezierRailMesh(const BezierCurve& aFunc) + void buildOneBezierRail(const BezierCurve& func, + IMeshBufferPtr buf, float p) { - IMeshBufferPtr buf = makeMeshBuffer(); - const float step = 0.1f; for (float t = 0.0f; t < 1.0f; t += step) { - Vector v1 = aFunc(t); - Vector v2 = aFunc(t + step); - + + Vector v1 = func.offset(t, p); + Vector v2 = func.offset(t + step, p); + v1.z -= RAIL_WIDTH / 2.0f; v2.z -= RAIL_WIDTH / 2.0f; @@ -153,6 +152,15 @@ namespace { makeVector(v2.x, v2.y + track::RAIL_HEIGHT, v2.z + RAIL_WIDTH), METAL); } + } + + // Generate a rail mesh from a Bezier curve + IMeshPtr generateBezierRailMesh(const BezierCurve& func) + { + IMeshBufferPtr buf = makeMeshBuffer(); + + buildOneBezierRail(func, buf, GAUGE/2.0f); + buildOneBezierRail(func, buf, -GAUGE/2.0f); return makeMesh(buf); } -- 2.39.2