Example #1
0
        // update absolute camera
        internal static void UpdateAbsoluteCamera(double TimeElapsed)
        {
            // zoom
            double zm = World.CameraCurrentAlignment.Zoom;

            AdjustAlignment(ref World.CameraCurrentAlignment.Zoom, World.CameraAlignmentDirection.Zoom, ref World.CameraAlignmentSpeed.Zoom, TimeElapsed, true);
            if (zm != World.CameraCurrentAlignment.Zoom)
            {
                ApplyZoom();
            }
            if (CameraMode == CameraViewMode.FlyBy | CameraMode == CameraViewMode.FlyByZooming)
            {
                // fly-by
                AdjustAlignment(ref World.CameraCurrentAlignment.Position.X, World.CameraAlignmentDirection.Position.X, ref World.CameraAlignmentSpeed.Position.X, TimeElapsed);
                AdjustAlignment(ref World.CameraCurrentAlignment.Position.Y, World.CameraAlignmentDirection.Position.Y, ref World.CameraAlignmentSpeed.Position.Y, TimeElapsed);
                double tr = World.CameraCurrentAlignment.TrackPosition;
                AdjustAlignment(ref World.CameraCurrentAlignment.TrackPosition, World.CameraAlignmentDirection.TrackPosition, ref World.CameraAlignmentSpeed.TrackPosition, TimeElapsed);
                if (tr != World.CameraCurrentAlignment.TrackPosition)
                {
                    World.CameraTrackFollower.Update(World.CameraCurrentAlignment.TrackPosition, true, false);
                    UpdateViewingDistances();
                }
                // camera
                double px = World.CameraTrackFollower.WorldPosition.X;
                double py = World.CameraTrackFollower.WorldPosition.Y;
                double pz = World.CameraTrackFollower.WorldPosition.Z;
                // position to focus on
                double tx, ty, tz;
                double zoomMultiplier;
                {
                    const double       heightFactor              = 0.75;
                    TrainManager.Train bestTrain                 = null;
                    double             bestDistanceSquared       = double.MaxValue;
                    TrainManager.Train secondBestTrain           = null;
                    double             secondBestDistanceSquared = double.MaxValue;
                    foreach (TrainManager.Train train in TrainManager.Trains)
                    {
                        if (train.State == TrainState.Available)
                        {
                            double x  = 0.5 * (train.Cars[0].FrontAxle.Follower.WorldPosition.X + train.Cars[0].RearAxle.Follower.WorldPosition.X);
                            double y  = 0.5 * (train.Cars[0].FrontAxle.Follower.WorldPosition.Y + train.Cars[0].RearAxle.Follower.WorldPosition.Y) + heightFactor * train.Cars[0].Height;
                            double z  = 0.5 * (train.Cars[0].FrontAxle.Follower.WorldPosition.Z + train.Cars[0].RearAxle.Follower.WorldPosition.Z);
                            double dx = x - px;
                            double dy = y - py;
                            double dz = z - pz;
                            double d  = dx * dx + dy * dy + dz * dz;
                            if (d < bestDistanceSquared)
                            {
                                secondBestTrain           = bestTrain;
                                secondBestDistanceSquared = bestDistanceSquared;
                                bestTrain           = train;
                                bestDistanceSquared = d;
                            }
                            else if (d < secondBestDistanceSquared)
                            {
                                secondBestTrain           = train;
                                secondBestDistanceSquared = d;
                            }
                        }
                    }
                    if (bestTrain != null)
                    {
                        const double maxDistance        = 100.0;
                        double       bestDistance       = Math.Sqrt(bestDistanceSquared);
                        double       secondBestDistance = Math.Sqrt(secondBestDistanceSquared);
                        if (secondBestTrain != null && secondBestDistance - bestDistance <= maxDistance)
                        {
                            double x1 = 0.5 * (bestTrain.Cars[0].FrontAxle.Follower.WorldPosition.X + bestTrain.Cars[0].RearAxle.Follower.WorldPosition.X);
                            double y1 = 0.5 * (bestTrain.Cars[0].FrontAxle.Follower.WorldPosition.Y + bestTrain.Cars[0].RearAxle.Follower.WorldPosition.Y) + heightFactor * bestTrain.Cars[0].Height;
                            double z1 = 0.5 * (bestTrain.Cars[0].FrontAxle.Follower.WorldPosition.Z + bestTrain.Cars[0].RearAxle.Follower.WorldPosition.Z);
                            double x2 = 0.5 * (secondBestTrain.Cars[0].FrontAxle.Follower.WorldPosition.X + secondBestTrain.Cars[0].RearAxle.Follower.WorldPosition.X);
                            double y2 = 0.5 * (secondBestTrain.Cars[0].FrontAxle.Follower.WorldPosition.Y + secondBestTrain.Cars[0].RearAxle.Follower.WorldPosition.Y) + heightFactor * secondBestTrain.Cars[0].Height;
                            double z2 = 0.5 * (secondBestTrain.Cars[0].FrontAxle.Follower.WorldPosition.Z + secondBestTrain.Cars[0].RearAxle.Follower.WorldPosition.Z);
                            double t  = 0.5 - (secondBestDistance - bestDistance) / (2.0 * maxDistance);
                            if (t < 0.0)
                            {
                                t = 0.0;
                            }

                            t              = 2.0 * t * t;                /* in order to change the shape of the interpolation curve */
                            tx             = (1.0 - t) * x1 + t * x2;
                            ty             = (1.0 - t) * y1 + t * y2;
                            tz             = (1.0 - t) * z1 + t * z2;
                            zoomMultiplier = 1.0 - 2.0 * t;
                        }
                        else
                        {
                            tx             = 0.5 * (bestTrain.Cars[0].FrontAxle.Follower.WorldPosition.X + bestTrain.Cars[0].RearAxle.Follower.WorldPosition.X);
                            ty             = 0.5 * (bestTrain.Cars[0].FrontAxle.Follower.WorldPosition.Y + bestTrain.Cars[0].RearAxle.Follower.WorldPosition.Y) + heightFactor * bestTrain.Cars[0].Height;
                            tz             = 0.5 * (bestTrain.Cars[0].FrontAxle.Follower.WorldPosition.Z + bestTrain.Cars[0].RearAxle.Follower.WorldPosition.Z);
                            zoomMultiplier = 1.0;
                        }
                    }
                    else
                    {
                        tx             = 0.0;
                        ty             = 0.0;
                        tz             = 0.0;
                        zoomMultiplier = 1.0;
                    }
                }
                // camera
                {
                    AbsoluteCameraDirection = new Vector3(CameraTrackFollower.WorldDirection);
                    double ox = World.CameraCurrentAlignment.Position.X;
                    double oy = World.CameraCurrentAlignment.Position.Y;
                    double oz = World.CameraCurrentAlignment.Position.Z;
                    double cx = px + CameraTrackFollower.WorldSide.X * ox + CameraTrackFollower.WorldUp.X * oy + AbsoluteCameraDirection.X * oz;
                    double cy = py + CameraTrackFollower.WorldSide.Y * ox + CameraTrackFollower.WorldUp.Y * oy + AbsoluteCameraDirection.Y * oz;
                    double cz = pz + CameraTrackFollower.WorldSide.Z * ox + CameraTrackFollower.WorldUp.Z * oy + AbsoluteCameraDirection.Z * oz;
                    AbsoluteCameraPosition    = new Vector3(cx, cy, cz);
                    AbsoluteCameraDirection.X = tx - cx;
                    AbsoluteCameraDirection.Y = ty - cy;
                    AbsoluteCameraDirection.Z = tz - cz;
                    double t  = AbsoluteCameraDirection.Norm();
                    double ti = 1.0 / t;
                    AbsoluteCameraDirection *= ti;

                    AbsoluteCameraSide = new Vector3(AbsoluteCameraDirection.Z, 0.0, -AbsoluteCameraDirection.X);
                    AbsoluteCameraSide.Normalize();
                    AbsoluteCameraUp = Vector3.Cross(AbsoluteCameraDirection, AbsoluteCameraSide);
                    UpdateViewingDistances();
                    if (CameraMode == CameraViewMode.FlyByZooming)
                    {
                        // zoom
                        const double fadeOutDistance = 600.0;                     /* the distance with the highest zoom factor is half the fade-out distance */
                        const double maxZoomFactor   = 7.0;                       /* the zoom factor at half the fade-out distance */
                        const double factor          = 256.0 / (fadeOutDistance * fadeOutDistance * fadeOutDistance * fadeOutDistance * fadeOutDistance * fadeOutDistance * fadeOutDistance * fadeOutDistance);
                        double       zoom;
                        if (t < fadeOutDistance)
                        {
                            double tdist4 = fadeOutDistance - t; tdist4 *= tdist4; tdist4 *= tdist4;
                            double t4     = t * t; t4 *= t4;
                            zoom = 1.0 + factor * zoomMultiplier * (maxZoomFactor - 1.0) * tdist4 * t4;
                        }
                        else
                        {
                            zoom = 1.0;
                        }
                        World.VerticalViewingAngle = World.OriginalVerticalViewingAngle / zoom;
                        Renderer.UpdateViewport(Renderer.ViewPortChangeMode.NoChange);
                    }
                }
            }
            else
            {
                // non-fly-by
                {
                    // current alignment
                    AdjustAlignment(ref World.CameraCurrentAlignment.Position.X, World.CameraAlignmentDirection.Position.X, ref World.CameraAlignmentSpeed.Position.X, TimeElapsed);
                    AdjustAlignment(ref World.CameraCurrentAlignment.Position.Y, World.CameraAlignmentDirection.Position.Y, ref World.CameraAlignmentSpeed.Position.Y, TimeElapsed);
                    AdjustAlignment(ref World.CameraCurrentAlignment.Position.Z, World.CameraAlignmentDirection.Position.Z, ref World.CameraAlignmentSpeed.Position.Z, TimeElapsed);
                    if ((CameraMode == CameraViewMode.Interior | World.CameraMode == CameraViewMode.InteriorLookAhead) & CameraRestriction == Camera.RestrictionMode.On)
                    {
                        if (CameraCurrentAlignment.Position.Z > 0.75)
                        {
                            CameraCurrentAlignment.Position.Z = 0.75;
                        }
                    }
                    bool q = World.CameraAlignmentSpeed.Yaw != 0.0 | World.CameraAlignmentSpeed.Pitch != 0.0 | World.CameraAlignmentSpeed.Roll != 0.0;
                    AdjustAlignment(ref World.CameraCurrentAlignment.Yaw, World.CameraAlignmentDirection.Yaw, ref World.CameraAlignmentSpeed.Yaw, TimeElapsed);
                    AdjustAlignment(ref World.CameraCurrentAlignment.Pitch, World.CameraAlignmentDirection.Pitch, ref World.CameraAlignmentSpeed.Pitch, TimeElapsed);
                    AdjustAlignment(ref World.CameraCurrentAlignment.Roll, World.CameraAlignmentDirection.Roll, ref World.CameraAlignmentSpeed.Roll, TimeElapsed);
                    double tr = World.CameraCurrentAlignment.TrackPosition;
                    AdjustAlignment(ref World.CameraCurrentAlignment.TrackPosition, World.CameraAlignmentDirection.TrackPosition, ref World.CameraAlignmentSpeed.TrackPosition, TimeElapsed);
                    if (tr != World.CameraCurrentAlignment.TrackPosition)
                    {
                        World.CameraTrackFollower.Update(World.CameraCurrentAlignment.TrackPosition, true, false);
                        q = true;
                    }
                    if (q)
                    {
                        UpdateViewingDistances();
                    }
                }
                // camera
                Vector3 cF = new Vector3(CameraTrackFollower.WorldPosition);
                Vector3 dF = new Vector3(CameraTrackFollower.WorldDirection);
                Vector3 uF = new Vector3(CameraTrackFollower.WorldUp);
                Vector3 sF = new Vector3(CameraTrackFollower.WorldSide);
                double  lookaheadYaw;
                double  lookaheadPitch;
                if (CameraMode == CameraViewMode.InteriorLookAhead)
                {
                    // look-ahead
                    double d = 20.0;
                    if (TrainManager.PlayerTrain.Specs.CurrentAverageSpeed > 0.0)
                    {
                        d += 3.0 * (Math.Sqrt(TrainManager.PlayerTrain.Specs.CurrentAverageSpeed * TrainManager.PlayerTrain.Specs.CurrentAverageSpeed + 1.0) - 1.0);
                    }
                    d -= TrainManager.PlayerTrain.Cars[TrainManager.PlayerTrain.DriverCar].FrontAxle.Position;
                    TrackManager.TrackFollower f = TrainManager.PlayerTrain.Cars[TrainManager.PlayerTrain.DriverCar].FrontAxle.Follower;
                    f.TriggerType = TrackManager.EventTriggerType.None;
                    f.Update(f.TrackPosition + d, true, false);
                    Vector3 r = new Vector3(f.WorldPosition - cF + World.CameraTrackFollower.WorldSide * TrainManager.PlayerTrain.Cars[TrainManager.PlayerTrain.DriverCar].Driver.X + World.CameraTrackFollower.WorldUp * TrainManager.PlayerTrain.Cars[TrainManager.PlayerTrain.DriverCar].Driver.Y + World.CameraTrackFollower.WorldDirection * TrainManager.PlayerTrain.Cars[TrainManager.PlayerTrain.DriverCar].Driver.Z);
                    r.Normalize();
                    double t = dF.Z * (sF.Y * uF.X - sF.X * uF.Y) + dF.Y * (-sF.Z * uF.X + sF.X * uF.Z) + dF.X * (sF.Z * uF.Y - sF.Y * uF.Z);
                    if (t != 0.0)
                    {
                        t = 1.0 / t;

                        double tx = (r.Z * (-dF.Y * uF.X + dF.X * uF.Y) + r.Y * (dF.Z * uF.X - dF.X * uF.Z) + r.X * (-dF.Z * uF.Y + dF.Y * uF.Z)) * t;
                        double ty = (r.Z * (dF.Y * sF.X - dF.X * sF.Y) + r.Y * (-dF.Z * sF.X + dF.X * sF.Z) + r.X * (dF.Z * sF.Y - dF.Y * sF.Z)) * t;
                        double tz = (r.Z * (sF.Y * uF.X - sF.X * uF.Y) + r.Y * (-sF.Z * uF.X + sF.X * uF.Z) + r.X * (sF.Z * uF.Y - sF.Y * uF.Z)) * t;
                        lookaheadYaw = tx * tz != 0.0 ? Math.Atan2(tx, tz) : 0.0;
                        if (ty < -1.0)
                        {
                            lookaheadPitch = -0.5 * Math.PI;
                        }
                        else if (ty > 1.0)
                        {
                            lookaheadPitch = 0.5 * Math.PI;
                        }
                        else
                        {
                            lookaheadPitch = Math.Asin(ty);
                        }
                    }
                    else
                    {
                        lookaheadYaw   = 0.0;
                        lookaheadPitch = 0.0;
                    }
                }
                else
                {
                    lookaheadYaw   = 0.0;
                    lookaheadPitch = 0.0;
                }
                {
                    // cab pitch and yaw
                    Vector3 d2 = new Vector3(dF);
                    Vector3 u2 = new Vector3(uF);
                    if ((World.CameraMode == CameraViewMode.Interior | World.CameraMode == CameraViewMode.InteriorLookAhead) & TrainManager.PlayerTrain != null)
                    {
                        int c = TrainManager.PlayerTrain.DriverCar;
                        if (c >= 0)
                        {
                            if (TrainManager.PlayerTrain.Cars[c].CarSections.Length == 0 || !TrainManager.PlayerTrain.Cars[c].CarSections[0].Groups[0].Overlay)
                            {
                                double a    = TrainManager.PlayerTrain.Cars[TrainManager.PlayerTrain.DriverCar].DriverPitch;
                                double cosa = Math.Cos(-a);
                                double sina = Math.Sin(-a);
                                d2.Rotate(sF, cosa, sina);
                                u2.Rotate(sF, cosa, sina);
                            }
                        }
                    }

                    cF += sF * CameraCurrentAlignment.Position.X + u2 * CameraCurrentAlignment.Position + d2 * CameraCurrentAlignment.Position.Z;
                }
                // yaw, pitch, roll
                double headYaw = World.CameraCurrentAlignment.Yaw + lookaheadYaw;
                if ((World.CameraMode == CameraViewMode.Interior | World.CameraMode == CameraViewMode.InteriorLookAhead) & TrainManager.PlayerTrain != null)
                {
                    if (TrainManager.PlayerTrain.DriverCar >= 0)
                    {
                        headYaw += TrainManager.PlayerTrain.Cars[TrainManager.PlayerTrain.DriverCar].DriverYaw;
                    }
                }
                double headPitch = World.CameraCurrentAlignment.Pitch + lookaheadPitch;
                if ((World.CameraMode == CameraViewMode.Interior | World.CameraMode == CameraViewMode.InteriorLookAhead) & TrainManager.PlayerTrain != null)
                {
                    if (TrainManager.PlayerTrain.DriverCar >= 0)
                    {
                        headPitch += TrainManager.PlayerTrain.Cars[TrainManager.PlayerTrain.DriverCar].DriverPitch;
                    }
                }
                double bodyPitch = 0.0;
                double bodyRoll  = 0.0;
                double headRoll  = World.CameraCurrentAlignment.Roll;
                // rotation
                if (CameraRestriction == Camera.RestrictionMode.NotAvailable & (CameraMode == CameraViewMode.Interior | CameraMode == CameraViewMode.InteriorLookAhead))
                {
                    // with body and head
                    bodyPitch += CurrentDriverBody.Pitch;
                    headPitch -= 0.2 * CurrentDriverBody.Pitch;
                    bodyRoll  += CurrentDriverBody.Roll;
                    headRoll  += 0.2 * CurrentDriverBody.Roll;
                    const double bodyHeight = 0.6;
                    const double headHeight = 0.1;
                    {
                        // body pitch
                        double ry = (Math.Cos(-bodyPitch) - 1.0) * bodyHeight;
                        double rz = Math.Sin(-bodyPitch) * bodyHeight;
                        cF += dF * rz + uF * ry;
                        if (bodyPitch != 0.0)
                        {
                            double cosa = Math.Cos(-bodyPitch);
                            double sina = Math.Sin(-bodyPitch);
                            dF.Rotate(sF, cosa, sina);
                            uF.Rotate(sF, cosa, sina);
                        }
                    }
                    {
                        // body roll
                        double rx = Math.Sin(bodyRoll) * bodyHeight;
                        double ry = (Math.Cos(bodyRoll) - 1.0) * bodyHeight;
                        cF += sF * rx + uF * ry;
                        if (bodyRoll != 0.0)
                        {
                            double cosa = Math.Cos(-bodyRoll);
                            double sina = Math.Sin(-bodyRoll);
                            uF.Rotate(dF, cosa, sina);
                            sF.Rotate(dF, cosa, sina);
                        }
                    }
                    {
                        // head yaw
                        double rx = Math.Sin(headYaw) * headHeight;
                        double rz = (Math.Cos(headYaw) - 1.0) * headHeight;
                        cF += sF * rx + dF * rz;
                        if (headYaw != 0.0)
                        {
                            double cosa = Math.Cos(headYaw);
                            double sina = Math.Sin(headYaw);
                            dF.Rotate(uF, cosa, sina);
                            sF.Rotate(uF, cosa, sina);
                        }
                    }
                    {
                        // head pitch
                        double ry = (Math.Cos(-headPitch) - 1.0) * headHeight;
                        double rz = Math.Sin(-headPitch) * headHeight;
                        cF += dF * rz + uF * ry;
                        if (headPitch != 0.0)
                        {
                            double cosa = Math.Cos(-headPitch);
                            double sina = Math.Sin(-headPitch);
                            dF.Rotate(sF, cosa, sina);
                            uF.Rotate(sF, cosa, sina);
                        }
                    }
                    {
                        // head roll
                        double rx = Math.Sin(headRoll) * headHeight;
                        double ry = (Math.Cos(headRoll) - 1.0) * headHeight;
                        cF += sF * rx + uF * ry;
                        if (headRoll != 0.0)
                        {
                            double cosa = Math.Cos(-headRoll);
                            double sina = Math.Sin(-headRoll);
                            uF.Rotate(dF, cosa, sina);
                            sF.Rotate(dF, cosa, sina);
                        }
                    }
                }
                else
                {
                    // without body or head
                    double totalYaw   = headYaw;
                    double totalPitch = headPitch + bodyPitch;
                    double totalRoll  = bodyRoll + headRoll;
                    if (totalYaw != 0.0)
                    {
                        double cosa = Math.Cos(totalYaw);
                        double sina = Math.Sin(totalYaw);
                        dF.Rotate(uF, cosa, sina);
                        sF.Rotate(uF, cosa, sina);
                    }
                    if (totalPitch != 0.0)
                    {
                        double cosa = Math.Cos(-totalPitch);
                        double sina = Math.Sin(-totalPitch);
                        dF.Rotate(sF, cosa, sina);
                        uF.Rotate(sF, cosa, sina);
                    }
                    if (totalRoll != 0.0)
                    {
                        double cosa = Math.Cos(-totalRoll);
                        double sina = Math.Sin(-totalRoll);
                        uF.Rotate(dF, cosa, sina);
                        sF.Rotate(dF, cosa, sina);
                    }
                }
                // finish
                AbsoluteCameraPosition  = cF;
                AbsoluteCameraDirection = dF;
                AbsoluteCameraUp        = uF;
                AbsoluteCameraSide      = sF;
            }
        }
#pragma warning restore 0649

            public override void Update(double TimeElapsed, bool ForceUpdate)
            {
                const double extraRadius = 10.0;
                double       z           = Object.TranslateZFunction == null ? 0.0 : Object.TranslateZFunction.LastResult;
                double       pa          = TrackPosition + z - Radius - extraRadius;
                double       pb          = TrackPosition + z + Radius + extraRadius;
                double       ta          = World.CameraTrackFollower.TrackPosition + Camera.CurrentAlignment.Position.Z - Backgrounds.BackgroundImageDistance - World.ExtraViewingDistance;
                double       tb          = World.CameraTrackFollower.TrackPosition + Camera.CurrentAlignment.Position.Z + Backgrounds.BackgroundImageDistance + World.ExtraViewingDistance;
                bool         visible     = pb >= ta & pa <= tb;

                if (visible | ForceUpdate)
                {
                    if (Object.SecondsSinceLastUpdate >= Object.RefreshRate | ForceUpdate)
                    {
                        double timeDelta = Object.SecondsSinceLastUpdate + TimeElapsed;
                        Object.SecondsSinceLastUpdate = 0.0;
                        TrainManager.Train train         = null;
                        double             trainDistance = double.MaxValue;
                        for (int j = 0; j < TrainManager.Trains.Length; j++)
                        {
                            if (TrainManager.Trains[j].State == TrainState.Available)
                            {
                                double distance;
                                if (TrainManager.Trains[j].Cars[0].FrontAxle.Follower.TrackPosition < TrackPosition)
                                {
                                    distance = TrackPosition - TrainManager.Trains[j].Cars[0].FrontAxle.Follower.TrackPosition;
                                }
                                else if (TrainManager.Trains[j].Cars[TrainManager.Trains[j].Cars.Length - 1].RearAxle.Follower.TrackPosition > TrackPosition)
                                {
                                    distance = TrainManager.Trains[j].Cars[TrainManager.Trains[j].Cars.Length - 1].RearAxle.Follower.TrackPosition - TrackPosition;
                                }
                                else
                                {
                                    distance = 0;
                                }
                                if (distance < trainDistance)
                                {
                                    train         = TrainManager.Trains[j];
                                    trainDistance = distance;
                                }
                            }
                        }
                        if (Visible)
                        {
                            //Calculate the distance travelled
                            double delta = UpdateTrackFollowerScript(false, train, train == null ? 0 : train.DriverCar, SectionIndex, TrackPosition, Position, true, timeDelta);
                            //Update the front and rear axle track followers
                            FrontAxleFollower.Update((TrackPosition + FrontAxlePosition) + delta, true, true);
                            RearAxleFollower.Update((TrackPosition + RearAxlePosition) + delta, true, true);
                            //Update the base object position
                            FrontAxleFollower.UpdateWorldCoordinates(false);
                            RearAxleFollower.UpdateWorldCoordinates(false);
                            UpdateObjectPosition();
                        }
                        //Update the actual animated object- This must be done last in case the user has used Translation or Rotation
                        Object.Update(false, train, train == null ? 0 : train.DriverCar, SectionIndex, FrontAxleFollower.TrackPosition, FrontAxleFollower.WorldPosition, Direction, Up, Side, false, true, true, timeDelta, true);
                    }
                    else
                    {
                        Object.SecondsSinceLastUpdate += TimeElapsed;
                    }
                    if (!Visible)
                    {
                        Renderer.ShowObject(Object.ObjectIndex, ObjectType.Dynamic);
                        Visible = true;
                    }
                }
                else
                {
                    Object.SecondsSinceLastUpdate += TimeElapsed;
                    if (Visible)
                    {
                        Renderer.HideObject(Object.ObjectIndex);
                        Visible = false;
                    }
                }
            }
Example #3
0
        /// <summary>Renders a graphical visualisation of any events within camera range</summary>
        /// <param name="Camera">The absolute camera position</param>
        private static void RenderEvents(Vector3 Camera)
        {
            if (Interface.CurrentOptions.ShowEvents == false || TrackManager.Tracks[0].Elements == null)
            {
                return;
            }

            if (!Initialized)
            {
                Init();
                Initialized = true;
            }
            GL.Enable(EnableCap.CullFace); LibRender.Renderer.CullEnabled = true;
            GL.Enable(EnableCap.DepthTest);
            GL.DepthMask(true);
            if (LibRender.Renderer.LightingEnabled)
            {
                GL.Disable(EnableCap.Lighting);
                LibRender.Renderer.LightingEnabled = false;
            }
            if (LibRender.Renderer.AlphaTestEnabled)
            {
                GL.Disable(EnableCap.AlphaTest);
                LibRender.Renderer.AlphaTestEnabled = false;
            }
            double da = -World.BackwardViewingDistance - World.ExtraViewingDistance;
            double db = World.ForwardViewingDistance + World.ExtraViewingDistance;

            bool[] sta = new bool[CurrentRoute.Stations.Length];
            // events
            for (int i = 0; i < TrackManager.Tracks[0].Elements.Length; i++)
            {
                double p = TrackManager.Tracks[0].Elements[i].StartingTrackPosition;
                double d = p - World.CameraTrackFollower.TrackPosition;
                if (d >= da & d <= db)
                {
                    for (int j = 0; j < TrackManager.Tracks[0].Elements[i].Events.Length; j++)
                    {
                        dynamic e = TrackManager.Tracks[0].Elements[i].Events[j];
                        double  dy, dx = 0.0, dz = 0.0;
                        double  s; Texture t;
                        if (e is TrackManager.BrightnessChangeEvent)
                        {
                            s  = 0.15;
                            dy = 4.0;
                            t  = BrightnessChangeTexture;
                        }
                        else if (e is BackgroundChangeEvent)
                        {
                            s  = 0.25;
                            dy = 3.5;
                            t  = BackgroundChangeTexture;
                        }
                        else if (e is TrackManager.StationStartEvent)
                        {
                            s  = 0.25;
                            dy = 1.6;
                            t  = StationStartTexture;
                            TrackManager.StationStartEvent f = (TrackManager.StationStartEvent)e;
                            sta[f.StationIndex] = true;
                        }
                        else if (e is TrackManager.StationEndEvent)
                        {
                            s  = 0.25;
                            dy = 1.6;
                            t  = StationEndTexture;
                            TrackManager.StationEndEvent f = (TrackManager.StationEndEvent)e;
                            sta[f.StationIndex] = true;
                        }
                        else if (e is TrackManager.LimitChangeEvent)
                        {
                            s  = 0.2;
                            dy = 1.1;
                            t  = LimitTexture;
                        }
                        else if (e is TrackManager.SectionChangeEvent)
                        {
                            s  = 0.2;
                            dy = 0.8;
                            t  = SectionTexture;
                        }
                        else if (e is TrackManager.TransponderEvent)
                        {
                            s  = 0.15;
                            dy = 0.4;
                            t  = TransponderTexture;
                        }
                        else if (e is TrackManager.SoundEvent)
                        {
                            TrackManager.SoundEvent f = (TrackManager.SoundEvent)e;
                            s  = 0.2;
                            dx = f.Position.X;
                            dy = f.Position.Y < 0.1 ? 0.1 : f.Position.Y;
                            dz = f.Position.Z;
                            t  = SoundTexture;
                        }
                        else if (e is TrackManager.PointSoundEvent)
                        {
                            s  = 0.2;
                            dx = 0;
                            dy = 0.2;
                            dz = 0;
                            t  = PointSoundTexture;
                        }
                        else
                        {
                            s  = 0.2;
                            dy = 1.0;
                            t  = null;
                        }
                        if (t != null)
                        {
                            TrackManager.TrackFollower f = new TrackManager.TrackFollower();
                            f.TriggerType   = EventTriggerType.None;
                            f.TrackPosition = p;
                            f.Update(p + e.TrackPositionDelta, true, false);
                            f.WorldPosition.X += dx * f.WorldSide.X + dy * f.WorldUp.X + dz * f.WorldDirection.X;
                            f.WorldPosition.Y += dx * f.WorldSide.Y + dy * f.WorldUp.Y + dz * f.WorldDirection.Y;
                            f.WorldPosition.Z += dx * f.WorldSide.Z + dy * f.WorldUp.Z + dz * f.WorldDirection.Z;
                            LibRender.Renderer.DrawCube(f.WorldPosition, f.WorldDirection, f.WorldUp, f.WorldSide, s, Camera, t);
                        }
                    }
                }
            }
            // stops
            for (int i = 0; i < sta.Length; i++)
            {
                if (sta[i])
                {
                    for (int j = 0; j < CurrentRoute.Stations[i].Stops.Length; j++)
                    {
                        const double dy = 1.4;
                        const double s  = 0.2;
                        double       p  = CurrentRoute.Stations[i].Stops[j].TrackPosition;
                        TrackManager.TrackFollower f = new TrackManager.TrackFollower();
                        f.TriggerType   = EventTriggerType.None;
                        f.TrackPosition = p;
                        f.Update(p, true, false);
                        f.WorldPosition.X += dy * f.WorldUp.X;
                        f.WorldPosition.Y += dy * f.WorldUp.Y;
                        f.WorldPosition.Z += dy * f.WorldUp.Z;
                        LibRender.Renderer.DrawCube(f.WorldPosition, f.WorldDirection, f.WorldUp, f.WorldSide, s, Camera, StopTexture);
                    }
                }
            }
            // buffers
            for (int i = 0; i < Game.BufferTrackPositions.Length; i++)
            {
                double p = Game.BufferTrackPositions[i];
                double d = p - World.CameraTrackFollower.TrackPosition;
                if (d >= da & d <= db)
                {
                    const double dy = 2.5;
                    const double s  = 0.25;
                    TrackManager.TrackFollower f = new TrackManager.TrackFollower();
                    f.TriggerType   = EventTriggerType.None;
                    f.TrackPosition = p;
                    f.Update(p, true, false);
                    f.WorldPosition.X += dy * f.WorldUp.X;
                    f.WorldPosition.Y += dy * f.WorldUp.Y;
                    f.WorldPosition.Z += dy * f.WorldUp.Z;
                    LibRender.Renderer.DrawCube(f.WorldPosition, f.WorldDirection, f.WorldUp, f.WorldSide, s, Camera, BufferTexture);
                }
            }
        }