/// <summary>
 /// output some text, show/hide a dialogue, and change the color of the region
 /// </summary>
 void doSomething(TriggerRegion region, RigidBody otherBody, TriggerReportFlags flags, CollisionReportInfo info)
 {
     if (flags.HasFlag(TriggerReportFlags.Enter)) {
         Console.WriteLine(otherBody.GetName() + " has entered trigger area \"" + region.Name + "\"");
         // cycle through the balloon colors
         region.CycleToNextColor();
     }
     else {
         Console.WriteLine(otherBody.GetName() + " has left trigger area \"" + region.Name + "\"");
         region.CycleToNextColor();
     }
 }
        /// <summary>
        /// Calculates the next waypoint we should drive to
        /// </summary>
        /// <param name="enteredRegion">The trigger region that fired the collision event</param>
        /// <param name="nextRegion">The next trigger region we should drive to</param>
        /// <param name="info">
        /// Contains some information about when we drove into the previous trigger region. 
        /// If this is null, then it's the initial waypoint we got when we loaded the level.
        /// </param>
        public void CalculateNewWaypoint(TriggerRegion enteredRegion, TriggerRegion nextRegion, CollisionReportInfo info)
        {
            // have to check for this because trigger regions like sending duplicate events
            // also we check against the previous region in situations where the kart is in two regions at once
            if ((nextRegion != CurrentRegion && nextRegion != PreviousRegion && enteredRegion != PreviousRegion) || info == null) {

                // do we need to do all of the transform stuff? it's accurate, but do we need to be particularly accurate?
                // forward is -X
                float offset;
                if (info == null || info.Position == null) {
                    // when we're starting, we'll just use our kart's position for things
                    Vector3 relativePos = nextRegion.Ghost.WorldTransform.InverseAffine() * Kart.ActualPosition;
                    offset = MakeOffset(relativePos, nextRegion);
                }
                else {
                    // otherwise calculate using the region we just entered
                    Vector3 relativePos = enteredRegion.Ghost.WorldTransform.InverseAffine() * info.Position.Value;
                    offset = MakeOffset(relativePos, enteredRegion);
                }
                nextWaypoint = nextRegion.Ghost.WorldTransform * new Vector3(0, 0, offset * nextRegion.Width);
                nextWaypoint.y = Kart.ActualPosition.y;

                // update the region pointers
                PreviousRegion = enteredRegion;
                CurrentRegion = nextRegion;

                // update this axis' position
            #if DEBUG
                //axis.RootNode.Position = nextWaypoint;
                //axis.RootNode.Orientation = nextRegion.Body.Orientation;
                nextRegion.CycleToNextColor();
            #endif
            }
        }