Animation with the ArcGIS Pro 1.2 SDK: The Millennium Force Coaster at Cedar Point

3D GIS animation is an exciting capability of ArcGIS Pro, and now even more so with expanded functionality with the Pro 1.2 SDK for .NET. There is already a rich set of animation features you can leverage directly from the Pro UI, and even more potential to automate the creation of complex animations using the Pro SDK.  There are a broad range of applications, and this post will focus on a great simulated fly-through, or as you’ll see, a “ride-through”.  Anyone who wants to create compelling visualizations, especially in 3D, would find this functionality useful.  For example, the ability to fly around a new proposed high rise in a downtown area to get an idea of how the city skyline will change or flying along the path of a new elevated train through a city center to give people a sense of the impact it may have on the community.

Chris Fox and Nathan Shephard of the Map Exploration team have created an exciting demonstration and video which showcases the new 3D animation functionality available in the Pro 1.2 SDK, showcasing how you can automate the creation of a complex fly-through in 3D using animation.  Previously through the SDK you could navigate the viewer by zooming to a known camera location and you could create a fly-through by zooming to multiple camera positions in succession.  Now, animation at Pro 1.2 makes it easier to author and edit a fly-through by creating smooth interpolated paths between camera positions to create a nice smooth visualization. In addition, you can simulate the movement of features by creating a time or range animation.

Without further ado, take a ride on the Millennium Force Coaster at Cedar Point in the video below, and then we’ll walk through how it was developed.

The video above is made up of two individual animations created with ArcGIS Pro. Making up the animation are keyframes and transitions.  A keyframe defines the state of the view and includes properties like the camera, layer visibility as well as map time and range.  The transitions define the math used to interpolate between the values of the keyframes, essentially how you get from A to B. In the SDK we can automate the creation of these keyframes and transitions to create a very precise and interesting fly-through.

The following two sections will walk through the steps used to create the two perspective animations.

Front Car Rider Perspective

Here are some of the steps used to create the animation shown in the upper left corner of the above video – from the perspective of riding on the roller coaster:

1.  An existing 3D model of the Millennium Force roller coaster at Cedar Point was downloaded from 3D Warehouse.

2.  The model was in KMZ format, so the KML to Layer tool was then used to convert the model to a multipatch feature class so it could be used in ArcGIS Pro.

3.  Next a new Z-aware polyline feature class was created, and the left and right rail of the roller coaster track were sketched using the multipatch feature class. This gave very precise locations along the track that could be used to interpolate the camera positions or the position along the track.  Two track lines were needed rather than just a line down the middle in order to calculate the roll of the camera or the angle of the bank as you go around a curve.  Note: modifying the roll of the camera is something that can only be done in the SDK.

4.  Next, an add-in was created for Pro.  The add-in took the geometry of the two lines and looped through the vertices.  Within the loop it used the left and right point at the current location and the left and right point at the next position along the tracks to calculate the forward, right and up vectors at that point in the track.  These vectors define the rotation of the point which supply the values of the Pitch, Heading, and Roll of the camera. The heading controls the direction we are looking in the view. The pitch controls the angle we look up or down and roll controls the rotation of the bank as we go around a curve. The camera’s XYZ location was calculated from the average of the left and right point. The location of the camera was also offset along the up vector so the camera was positioned above the track, as if you were sitting right in the front roller coaster car.  Here is some sample SDK code to illustrate, further samples follow:

          //Create the camera with an XYZ location offset on the track along the up vector

          var camera = new ArcGIS.Desktop.Mapping.Camera(currentPoint.X + (_meterOffset * vectors[1].X),

            currentPoint.Y + (_meterOffset * vectors[1].Y),

            currentPoint.Z + (_meterOffset * vectors[1].Z),

            0.0, 0.0, currentPoint.SpatialReference, CameraViewpoint.LookFrom);

          //Calculate heading using the forward vector

          var radian = Math.Atan2(vectors[0].X, vectors[0].Y);

          var heading = radian * -180 / Math.PI;

          camera.Heading = heading;

           //Calculate pitch using the forward vector

          var hypotenuse = Math.Sqrt(Math.Pow(vectors[0].X, 2) + Math.Pow(vectors[0].Y, 2));

          radian = Math.Atan2(vectors[0].Z, hypotenuse);

          var pitch = (radian * 180 / Math.PI);

          camera.Pitch = pitch;

           //Calculate roll using the forward and right vectors

          var d0 = new Vector3D(vectors[0].X, vectors[0].Y, 0);

          var u0 = new Vector3D(0, 0, 1);

          var r0 = Vector3D.CrossProduct(u0, d0);

          var roll = Vector3D.AngleBetween(r0, vectors[2]);

          if (vectors[2].Z < 0)

            roll *= -1;

       camera.Roll = roll;

5.  At the start of the animation, a constant speed is used for the initial ride up the launch lift hill, and as soon as the drop begins, the roller coaster accelerates and acceleration due to gravity is used to calculate the approximate speed at each location.  Using the speed at each location, the approximate time in seconds that it would take to get to that point on the track was calculated.

6.  The last step completing the add-in was creation of a keyframe for each camera position at its corresponding time in the animation.

var cameraTrack = animation.Tracks.OfType<CameraTrack>().First();

cameraTrack.CreateKeyframe(camera, TimeSpan.FromSeconds(timeSeconds), AnimationTransition.FixedArc);

7.  Once the keyframes were created in ArcGIS Pro, you can just click play on the Animation tab and go for the ride.  Pro then smoothly moves from keyframe to keyframe in the designated time to create the visualization.  Pro’s export movie option was used to create the first video which you see inset in the video above.

Spectator Perspective

Here are the steps used to create the main animation for the above video, from the spectator perspective of watching the roller coaster cars going along the track:

1.  An existing 3D model of the Millennium Force roller coaster car was downloaded from 3D Warehouse.

2.  Using the Pro SDK, the camera at each frame in the animation was interpolated from the original animation. This would give us the position of the car as well as its rotation at every frame. Because the coaster train has 9 cars this was repeated for each car in the train, so at each frame we would have 9 cameras.

var cameras = new List<Camera>();

var ticksPerFrame = Convert.ToInt64(animation.Duration.Ticks / (animation.NumberOfFrames – 1));

for (int i = 0; i < animation.NumberOfFrames; i++)


var time = TimeSpan.FromTicks(i * ticksPerFrame);

if (time > animation.Duration)

time = animation.Duration;



3.  Next for each camera a new 3D point was in an existing feature class. The camera’s XYZ defined the geometry of the point. The rotation properties of the camera: heading, pitch and roll, along with the frame number were stored as attributes of the point.

for (int i = 0; i < cameras.Count; i++)


var camera = cameras[i];

var mapPoint = MapPointBuilder.CreateMapPoint(camera.X, camera.Y, camera.Z, camera.SpatialReference);

var currentPoint = GeometryEngine.Project(mapPoint, spatialRef) as MapPoint;

var buffer = fc.CreateRowBuffer();

buffer[“Shape”] = mapPoint;

buffer[“Value”] = i+1;

buffer[“Heading”] = camera.Heading;

buffer[“Pitch”] = camera.Pitch;

buffer[“Roll”] = camera.Roll;

var row = fc.CreateRow(buffer);


4.  In Pro, the points were then symbolized using the 3D model from step 1 and were rotated using the 3 rotation properties of the camera – heading, pitch and roll.  The point layer was then range enabled using the Value field or the field storing the frame number associated with the point.

5.  New keyframes were then created using the Pro UI to fly around the roller coaster keeping the cars in view as they moved along the track. The keyframes also stored a corresponding range value so that only the car for that given frame would draw.  For example, at frame 1 the range for the map would be equal to 1 and as a result only the cars with a Value attribute 1 would draw. At frame 2 the range was 2 so only the cars with a Value attribute 2 would draw. Because with each frame the cars locations are shifted slightly further along the track we can simulate the movement of the roller coaster cars very similar to a flipbook where on each page a stick figure’s arm is in a slightly different positon. When the individual frames are played in a video it looks like the cars are moving.

6.  Finally, the 2 videos were combined and their playback synced up so you can experience what it is like to ride on the roller coaster as well as watch from above as it goes around the track.

Some Takeaways

Special thanks to Chris Fox for the creation of this demonstration and the content of this post.

Recommended next steps:


Chris is a product manager on the ArcGIS Desktop Team, focused on the ArcGIS Pro SDK and helping users achieve their Pro customization goals.

Next Article

Embed a Story Map within a Story Map

Read this article