The Train Framework and Example Solution

by Mike Gleicher on October 13, 2014

This is a little bit of documentation for the framework code provided for the CS559 Train Project.

The framework code that we provide for you to do your project with (and strongly recommend that you use) was also used to create an example solution. We won’t give you the source code to the example solution, but you can see where it hooks in in the example code.

The framework code is Note that the framework code is in the “TrainFiles” subdirectory. There is also a “Utilities” directory that has some Utility code that we used to give to 559 students. Not all of it is used in the Train project. In Trainfiles, there is a Visual Studio 2013 solution file that loads a project file that builds the framework.

You can download the example solution executable, an executable of the empty framework, and some example tracks as: We recommend that you download it and try it out. Make sure you can use it (manipulate the control points). Get a sense of what a solution to the project looks like.


For the UI (which you will need to know since it will be your UI):

Camera Controls

  • Right Mouse = ArcBall (rotates world)
  • ALT-RightMouse = Pan (translate view)
  • double click Right Mouse = reset view
  • Mousewheel = Zoom In / Zoom Out

Moving Points

The program provides a “Mouse Pole” user interface.

Use the Left Mouse to select and move (with dragging).

When dragging, things move parallel to the ground plane. Unless the CTRL key is held down, in which case things move perpindicular to the ground plane.

Some Features of the Sample Solution

The sample solution was written for simplicity, not for efficiency. This might be a problem for you if you don’t have a good computer with a decent graphics card, it might not run fast enough.

Some silly things you might notice:

  • The parallel rails are flat ribbons. And they Z-Fight with the tops of the rail ties. I was going to make them thicker ribbons, but I didn’t get to it.
  • The wheels on the cars are “trucked” (they swivel to stay on the track), but the center of the car is also locked onto the track and the car rotates around that point. You won’t notice this unless the curve is really sharp.
  • The wheels on the engine are fixed, so they go off the track in a sharp turn.
  • Physics conserves energy – and that’s it. The amount of energy in the system is set to be sufficient that the train doesn’t stop at the highest point, so a tall track will have the train going really fast at the bottom. There is no friction or anything like that, just potential energy and kinetic energy transfering back and forth like in a pendulum.
  • Save and Load is relative to where the executable is run from (so if you run in visual studio, its relative to the project/solution file).
  • The interface for rotating the control points is terrible. But it let me make some tracks. I actually made the more complicated ones in excel.
  • The “NoAL” buttons let you see what happens if you implement fancy tracks or multiple cars without arc length. Its helpful for why understanding arc-length is useful.

Looking into the framework code…

We recommend that you take some time to try to understand the framework code before trying to add things to it.

open up the solution and have a look. If you search for “TODO:” you will see places in the code that we expect you to want to add your own things.

You don’t need to understand everything – you can do the entire assignment just by adding things where we day “TODO”. In fact, you can see all of the places where the Example Solution (which is relatively complete) had to add things to the code.

The code was written to make it possible to get the assignment done quickly. It’s not exemplary software engineering. It’s a good reality check: often in the real world, you’re asked to finish something that someone else started.

Some Hints:


  • TrainWindow is the outer window. TrainView is the widget in which OpenGL drawing takes place – even when it’s a view of the train, not a view from the train.
  • Notice that in the “draw” method, “drawStuff” is called twice. One of the times draws the objects for real. For the second time, the projection is changed to squish the objects onto the floor, so they can be drawn as shadows. I call this “hack shadows.” Make sure that when you draw something, you’re careful not to use colors when drawing in shadow mode.
  • I wrote this code before GLM existed. I have my own matrix and 3D point class. GLM is better. This was simple
  • If you want to add widgets to the control panel, add them in TrainWindow.H first, then add them in TrainWindow’s constructor. (there are TODO).
  • You probably want to give your widget a callback. If it just changes the state, the damageCB is a good option (it forces a redraw).
  • The control points keep an extra 3 variables for an orientation. You might only want the position of the control points. But notice what the example solution does with them. The code tries to keep the orientations normalized.
  • The world is set with Y going up (so the groundplane is XZ) and the ground has size 100×100 (to give you some scale).
  • Change as little of the framework as possible. You can see exactly where the ExampleSolution connects to the framework.
  • The Example Solution tries to keep the files separate from the framework (so we can keep it from the students). So most things are function calls (or in the case of the extra widgets in TrainWindow, a class). But you can put things right into the framework.

Known issues (this list will probably grow…)

  • There is no checking for points that co-incident. If you put 4 points on top of one another, a spline segment will collapse to a point. This probably should be prohibited by the UI, but right now it will probably cause my arc-length code (in the example solution) to do bad things.
  • Up vectors are interpolated in a simple way. (I guess this is actually the example solution) – but some checking in the UI could be done to avoid having the up-vectors (the orientations of the control point) do bad things.

Previous post:

Next post: