Rotate() статический приватный Метод

Rotates a 2D vector
static private Rotate ( Vector2 &Vector, double cosa, double sina ) : void
Vector Vector2 The vector to rotate
cosa double The Cosine of the angle to rotate by
sina double The Sine of the angle to rotate by
Результат void
Пример #1
0
 internal static void MouseMovement()
 {
     if (MouseButton == 0)
     {
         return;
     }
     currentMouseState = Mouse.GetState();
     if (currentMouseState != previousMouseState)
     {
         if (MouseButton == 1)
         {
             World.AbsoluteCameraDirection = MouseCameraDirection;
             World.AbsoluteCameraUp        = MouseCameraUp;
             World.AbsoluteCameraSide      = MouseCameraSide;
             {
                 double dx   = 0.0025 * (double)(previousMouseState.X - currentMouseState.X);
                 double cosa = Math.Cos(dx);
                 double sina = Math.Sin(dx);
                 World.Rotate(ref World.AbsoluteCameraDirection.X, ref World.AbsoluteCameraDirection.Y, ref World.AbsoluteCameraDirection.Z, 0.0, 1.0, 0.0, cosa, sina);
                 World.Rotate(ref World.AbsoluteCameraUp.X, ref World.AbsoluteCameraUp.Y, ref World.AbsoluteCameraUp.Z, 0.0, 1.0, 0.0, cosa, sina);
                 World.Rotate(ref World.AbsoluteCameraSide.X, ref World.AbsoluteCameraSide.Y, ref World.AbsoluteCameraSide.Z, 0.0, 1.0, 0.0, cosa, sina);
             }
             {
                 double dy   = 0.0025 * (double)(previousMouseState.Y - currentMouseState.Y);
                 double cosa = Math.Cos(dy);
                 double sina = Math.Sin(dy);
                 World.Rotate(ref World.AbsoluteCameraDirection.X, ref World.AbsoluteCameraDirection.Y, ref World.AbsoluteCameraDirection.Z, World.AbsoluteCameraSide.X, World.AbsoluteCameraSide.Y, World.AbsoluteCameraSide.Z, cosa, sina);
                 World.Rotate(ref World.AbsoluteCameraUp.X, ref World.AbsoluteCameraUp.Y, ref World.AbsoluteCameraUp.Z, World.AbsoluteCameraSide.X, World.AbsoluteCameraSide.Y, World.AbsoluteCameraSide.Z, cosa, sina);
             }
             ReducedMode = false;
         }
         else if (MouseButton == 2)
         {
             World.AbsoluteCameraPosition = MouseCameraPosition;
             double dx = -0.025 * (double)(currentMouseState.X - previousMouseState.X);
             World.AbsoluteCameraPosition.X += dx * World.AbsoluteCameraSide.X;
             World.AbsoluteCameraPosition.Y += dx * World.AbsoluteCameraSide.Y;
             World.AbsoluteCameraPosition.Z += dx * World.AbsoluteCameraSide.Z;
             double dy = 0.025 * (double)(currentMouseState.Y - previousMouseState.Y);
             World.AbsoluteCameraPosition.X += dy * World.AbsoluteCameraUp.X;
             World.AbsoluteCameraPosition.Y += dy * World.AbsoluteCameraUp.Y;
             World.AbsoluteCameraPosition.Z += dy * World.AbsoluteCameraUp.Z;
             ReducedMode = false;
         }
         else
         {
             World.AbsoluteCameraPosition = MouseCameraPosition;
             double dx = -0.025 * (double)(currentMouseState.X - previousMouseState.X);
             World.AbsoluteCameraPosition.X += dx * World.AbsoluteCameraSide.X;
             World.AbsoluteCameraPosition.Y += dx * World.AbsoluteCameraSide.Y;
             World.AbsoluteCameraPosition.Z += dx * World.AbsoluteCameraSide.Z;
             double dz = -0.025 * (double)(currentMouseState.Y - previousMouseState.Y);
             World.AbsoluteCameraPosition.X += dz * World.AbsoluteCameraDirection.X;
             World.AbsoluteCameraPosition.Y += dz * World.AbsoluteCameraDirection.Y;
             World.AbsoluteCameraPosition.Z += dz * World.AbsoluteCameraDirection.Z;
             ReducedMode = false;
         }
     }
 }
Пример #2
0
            /// <summary>Updates the position and rotation of an animated object which follows a track</summary>
            private void UpdateObjectPosition()
            {
                //Get vectors
                double dx, dy, dz;
                double ux, uy, uz;
                double sx, sy, sz;

                {
                    dx = FrontAxleFollower.WorldPosition.X - RearAxleFollower.WorldPosition.X;
                    dy = FrontAxleFollower.WorldPosition.Y - RearAxleFollower.WorldPosition.Y;
                    dz = FrontAxleFollower.WorldPosition.Z - RearAxleFollower.WorldPosition.Z;
                    double t = 1.0 / Math.Sqrt(dx * dx + dy * dy + dz * dz);
                    dx *= t;
                    dy *= t;
                    dz *= t;
                    t   = 1.0 / Math.Sqrt(dx * dx + dz * dz);
                    double ex = dx * t;
                    double ez = dz * t;
                    sx = ez;
                    sy = 0.0;
                    sz = -ex;
                    World.Cross(dx, dy, dz, sx, sy, sz, out ux, out uy, out uz);
                }

                // apply position due to cant/toppling
                {
                    double a  = CurrentRollDueToTopplingAngle + CurrentRollDueToCantAngle;
                    double x  = Math.Sign(a) * 0.5 * Game.RouteRailGauge * (1.0 - Math.Cos(a));
                    double y  = Math.Abs(0.5 * Game.RouteRailGauge * Math.Sin(a));
                    double cx = sx * x + ux * y;
                    double cy = sy * x + uy * y;
                    double cz = sz * x + uz * y;
                    FrontAxleFollower.WorldPosition.X += cx;
                    FrontAxleFollower.WorldPosition.Y += cy;
                    FrontAxleFollower.WorldPosition.Z += cz;
                    RearAxleFollower.WorldPosition.X  += cx;
                    RearAxleFollower.WorldPosition.Y  += cy;
                    RearAxleFollower.WorldPosition.Z  += cz;
                }
                // apply rolling
                {
                    double a    = CurrentRollDueToTopplingAngle - CurrentRollDueToCantAngle;
                    double cosa = Math.Cos(a);
                    double sina = Math.Sin(a);
                    World.Rotate(ref sx, ref sy, ref sz, dx, dy, dz, cosa, sina);
                    World.Rotate(ref ux, ref uy, ref uz, dx, dy, dz, cosa, sina);
                    Up.X = ux;
                    Up.Y = uy;
                    Up.Z = uz;
                }
                Direction.X = dx;
                Direction.Y = dy;
                Direction.Z = dz;
                Side.X      = sx;
                Side.Y      = sy;
                Side.Z      = sz;
            }
Пример #3
0
        private static void ApplyRotation(MeshBuilder Builder, double x, double y, double z, double a)
        {
            double cosa = Math.Cos(a);
            double sina = Math.Sin(a);

            for (int i = 0; i < Builder.Vertices.Length; i++)
            {
                World.Rotate(ref Builder.Vertices[i].Coordinates.X, ref Builder.Vertices[i].Coordinates.Y, ref Builder.Vertices[i].Coordinates.Z, x, y, z, cosa, sina);
            }
            for (int i = 0; i < Builder.Faces.Length; i++)
            {
                for (int j = 0; j < Builder.Faces[i].Vertices.Length; j++)
                {
                    World.Rotate(ref Builder.Faces[i].Vertices[j].Normal.X, ref Builder.Faces[i].Vertices[j].Normal.Y, ref Builder.Faces[i].Vertices[j].Normal.Z, x, y, z, cosa, sina);
                }
            }
        }
Пример #4
0
            internal void ApplyRotation(double x, double y, double z, double a)
            {
                double cosa = Math.Cos(a);
                double sina = Math.Sin(a);

                for (int j = 0; j < Mesh.Vertices.Length; j++)
                {
                    World.Rotate(ref Mesh.Vertices[j].Coordinates, x, y, z, cosa, sina);
                }
                for (int j = 0; j < Mesh.Faces.Length; j++)
                {
                    for (int k = 0; k < Mesh.Faces[j].Vertices.Length; k++)
                    {
                        World.Rotate(ref Mesh.Faces[j].Vertices[k].Normal, x, y, z, cosa, sina);
                    }
                }
            }
Пример #5
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, World.CameraAlignmentSpeed.Zoom != 0.0);
            if (zm != World.CameraCurrentAlignment.Zoom)
            {
                ApplyZoom();
            }
            // 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);
            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)
            {
                TrackManager.UpdateTrackFollower(ref World.CameraTrackFollower, World.CameraCurrentAlignment.TrackPosition, true, false);
                q = true;
            }
            if (q)
            {
                UpdateViewingDistances();
            }
            double dx = World.CameraTrackFollower.WorldDirection.X;
            double dy = World.CameraTrackFollower.WorldDirection.Y;
            double dz = World.CameraTrackFollower.WorldDirection.Z;
            double ux = World.CameraTrackFollower.WorldUp.X;
            double uy = World.CameraTrackFollower.WorldUp.Y;
            double uz = World.CameraTrackFollower.WorldUp.Z;
            double sx = World.CameraTrackFollower.WorldSide.X;
            double sy = World.CameraTrackFollower.WorldSide.Y;
            double sz = World.CameraTrackFollower.WorldSide.Z;
            double tx = World.CameraCurrentAlignment.Position.X;
            double ty = World.CameraCurrentAlignment.Position.Y;
            double tz = World.CameraCurrentAlignment.Position.Z;
            double dx2 = dx, dy2 = dy, dz2 = dz;
            double ux2 = ux, uy2 = uy, uz2 = uz;
            double cx = World.CameraTrackFollower.WorldPosition.X + sx * tx + ux2 * ty + dx2 * tz;
            double cy = World.CameraTrackFollower.WorldPosition.Y + sy * tx + uy2 * ty + dy2 * tz;
            double cz = World.CameraTrackFollower.WorldPosition.Z + sz * tx + uz2 * ty + dz2 * tz;

            if (World.CameraCurrentAlignment.Yaw != 0.0)
            {
                double cosa = Math.Cos(World.CameraCurrentAlignment.Yaw);
                double sina = Math.Sin(World.CameraCurrentAlignment.Yaw);
                World.Rotate(ref dx, ref dy, ref dz, ux, uy, uz, cosa, sina);
                World.Rotate(ref sx, ref sy, ref sz, ux, uy, uz, cosa, sina);
            }
            double p = World.CameraCurrentAlignment.Pitch;

            if (p != 0.0)
            {
                double cosa = Math.Cos(-p);
                double sina = Math.Sin(-p);
                World.Rotate(ref dx, ref dy, ref dz, sx, sy, sz, cosa, sina);
                World.Rotate(ref ux, ref uy, ref uz, sx, sy, sz, cosa, sina);
            }
            if (World.CameraCurrentAlignment.Roll != 0.0)
            {
                double cosa = Math.Cos(-World.CameraCurrentAlignment.Roll);
                double sina = Math.Sin(-World.CameraCurrentAlignment.Roll);
                World.Rotate(ref ux, ref uy, ref uz, dx, dy, dz, cosa, sina);
                World.Rotate(ref sx, ref sy, ref sz, dx, dy, dz, cosa, sina);
            }
            AbsoluteCameraPosition  = new Vector3D(cx, cy, cz);
            AbsoluteCameraDirection = new Vector3D(dx, dy, dz);
            AbsoluteCameraUp        = new Vector3D(ux, uy, uz);
            AbsoluteCameraSide      = new Vector3D(sx, sy, sz);
        }
Пример #6
0
            internal void ApplyData(StaticObject Prototype, Vector3 Position, World.Transformation BaseTransformation, World.Transformation AuxTransformation, bool AccurateObjectDisposal, double AccurateObjectDisposalZOffset, double startingDistance, double endingDistance, double BlockLength, double TrackPosition, double Brightness, bool DuplicateMaterials)
            {
                StartingDistance = float.MaxValue;
                EndingDistance   = float.MinValue;
                Mesh.Vertices    = new World.Vertex[Prototype.Mesh.Vertices.Length];
                // vertices
                for (int j = 0; j < Prototype.Mesh.Vertices.Length; j++)
                {
                    Mesh.Vertices[j] = Prototype.Mesh.Vertices[j];
                    if (AccurateObjectDisposal)
                    {
                        World.Rotate(ref Mesh.Vertices[j].Coordinates.X, ref Mesh.Vertices[j].Coordinates.Y, ref Mesh.Vertices[j].Coordinates.Z, AuxTransformation);
                        if (Mesh.Vertices[j].Coordinates.Z < StartingDistance)
                        {
                            StartingDistance = (float)Mesh.Vertices[j].Coordinates.Z;
                        }
                        if (Mesh.Vertices[j].Coordinates.Z > EndingDistance)
                        {
                            EndingDistance = (float)Mesh.Vertices[j].Coordinates.Z;
                        }
                        Mesh.Vertices[j].Coordinates = Prototype.Mesh.Vertices[j].Coordinates;
                    }
                    World.Rotate(ref Mesh.Vertices[j].Coordinates.X, ref Mesh.Vertices[j].Coordinates.Y, ref Mesh.Vertices[j].Coordinates.Z, AuxTransformation);
                    World.Rotate(ref Mesh.Vertices[j].Coordinates.X, ref Mesh.Vertices[j].Coordinates.Y, ref Mesh.Vertices[j].Coordinates.Z, BaseTransformation);
                    Mesh.Vertices[j].Coordinates.X += Position.X;
                    Mesh.Vertices[j].Coordinates.Y += Position.Y;
                    Mesh.Vertices[j].Coordinates.Z += Position.Z;
                }
                if (AccurateObjectDisposal)
                {
                    StartingDistance += (float)AccurateObjectDisposalZOffset;
                    EndingDistance   += (float)AccurateObjectDisposalZOffset;
                }
                // faces
                Mesh.Faces = new World.MeshFace[Prototype.Mesh.Faces.Length];
                for (int j = 0; j < Prototype.Mesh.Faces.Length; j++)
                {
                    Mesh.Faces[j].Flags    = Prototype.Mesh.Faces[j].Flags;
                    Mesh.Faces[j].Material = Prototype.Mesh.Faces[j].Material;
                    Mesh.Faces[j].Vertices = new World.MeshFaceVertex[Prototype.Mesh.Faces[j].Vertices.Length];
                    for (int k = 0; k < Prototype.Mesh.Faces[j].Vertices.Length; k++)
                    {
                        Mesh.Faces[j].Vertices[k] = Prototype.Mesh.Faces[j].Vertices[k];
                        double nx = Mesh.Faces[j].Vertices[k].Normal.X;
                        double ny = Mesh.Faces[j].Vertices[k].Normal.Y;
                        double nz = Mesh.Faces[j].Vertices[k].Normal.Z;
                        if (nx * nx + ny * ny + nz * nz != 0.0)
                        {
                            World.Rotate(ref Mesh.Faces[j].Vertices[k].Normal.X, ref Mesh.Faces[j].Vertices[k].Normal.Y, ref Mesh.Faces[j].Vertices[k].Normal.Z, AuxTransformation);
                            World.Rotate(ref Mesh.Faces[j].Vertices[k].Normal.X, ref Mesh.Faces[j].Vertices[k].Normal.Y, ref Mesh.Faces[j].Vertices[k].Normal.Z, BaseTransformation);
                        }
                    }
                }
                // materials
                Mesh.Materials = new World.MeshMaterial[Prototype.Mesh.Materials.Length];
                for (int j = 0; j < Prototype.Mesh.Materials.Length; j++)
                {
                    Mesh.Materials[j]         = Prototype.Mesh.Materials[j];
                    Mesh.Materials[j].Color.R = (byte)Math.Round((double)Prototype.Mesh.Materials[j].Color.R * Brightness);
                    Mesh.Materials[j].Color.G = (byte)Math.Round((double)Prototype.Mesh.Materials[j].Color.G * Brightness);
                    Mesh.Materials[j].Color.B = (byte)Math.Round((double)Prototype.Mesh.Materials[j].Color.B * Brightness);
                }
                const double minBlockLength = 20.0;

                if (BlockLength < minBlockLength)
                {
                    BlockLength = BlockLength * Math.Ceiling(minBlockLength / BlockLength);
                }
                if (AccurateObjectDisposal)
                {
                    StartingDistance += (float)TrackPosition;
                    EndingDistance   += (float)TrackPosition;
                    double z = BlockLength * Math.Floor(TrackPosition / BlockLength);
                    startingDistance = Math.Min(z - BlockLength, (double)StartingDistance);
                    endingDistance   = Math.Max(z + 2.0 * BlockLength, (double)EndingDistance);
                    StartingDistance = (float)(BlockLength * Math.Floor(startingDistance / BlockLength));
                    EndingDistance   = (float)(BlockLength * Math.Ceiling(endingDistance / BlockLength));
                }
                else
                {
                    StartingDistance = (float)startingDistance;
                    EndingDistance   = (float)endingDistance;
                }
                if (BlockLength != 0.0)
                {
                    checked
                    {
                        GroupIndex = (short)Mod(Math.Floor(StartingDistance / BlockLength), Math.Ceiling(Interface.CurrentOptions.ViewingDistance / BlockLength));
                    }
                }
            }
Пример #7
0
            /// <summary>Call this method to update a single track follower</summary>
            /// <param name="NewTrackPosition">The new track position of the follower</param>
            /// <param name="UpdateWorldCoordinates">Whether to update the world co-ordinates</param>
            /// <param name="AddTrackInaccurary">Whether to add track innacuracy</param>
            internal void Update(double NewTrackPosition, bool UpdateWorldCoordinates, bool AddTrackInaccurary)
            {
                if (CurrentTrack.Elements.Length == 0)
                {
                    return;
                }
                int i = LastTrackElement;

                while (i >= 0 && NewTrackPosition < CurrentTrack.Elements[i].StartingTrackPosition)
                {
                    double ta = TrackPosition - CurrentTrack.Elements[i].StartingTrackPosition;
                    double tb = -0.01;
                    CheckEvents(i, -1, ta, tb);
                    i--;
                }
                if (i >= 0)
                {
                    while (i < CurrentTrack.Elements.Length - 1)
                    {
                        if (NewTrackPosition < CurrentTrack.Elements[i + 1].StartingTrackPosition)
                        {
                            break;
                        }
                        double ta = TrackPosition - CurrentTrack.Elements[i].StartingTrackPosition;
                        double tb = CurrentTrack.Elements[i + 1].StartingTrackPosition - CurrentTrack.Elements[i].StartingTrackPosition + 0.01;
                        CheckEvents(i, 1, ta, tb);
                        i++;
                    }
                }
                else
                {
                    i = 0;
                }
                double da = TrackPosition - CurrentTrack.Elements[i].StartingTrackPosition;
                double db = NewTrackPosition - CurrentTrack.Elements[i].StartingTrackPosition;

                // track
                if (UpdateWorldCoordinates)
                {
                    if (db != 0.0)
                    {
                        if (CurrentTrack.Elements[i].CurveRadius != 0.0)
                        {
                            // curve
                            double  r = CurrentTrack.Elements[i].CurveRadius;
                            double  p = CurrentTrack.Elements[i].WorldDirection.Y / Math.Sqrt(CurrentTrack.Elements[i].WorldDirection.X * CurrentTrack.Elements[i].WorldDirection.X + CurrentTrack.Elements[i].WorldDirection.Z * CurrentTrack.Elements[i].WorldDirection.Z);
                            double  s = db / Math.Sqrt(1.0 + p * p);
                            double  h = s * p;
                            double  b = s / Math.Abs(r);
                            double  f = 2.0 * r * r * (1.0 - Math.Cos(b));
                            double  c = (double)Math.Sign(db) * Math.Sqrt(f >= 0.0 ? f : 0.0);
                            double  a = 0.5 * (double)Math.Sign(r) * b;
                            Vector3 D = new Vector3(CurrentTrack.Elements[i].WorldDirection.X, 0.0, CurrentTrack.Elements[i].WorldDirection.Z);
                            World.Normalize(ref D.X, ref D.Y, ref D.Z);
                            double cosa = Math.Cos(a);
                            double sina = Math.Sin(a);
                            World.Rotate(ref D, 0.0, 1.0, 0.0, cosa, sina);
                            WorldPosition.X = CurrentTrack.Elements[i].WorldPosition.X + c * D.X;
                            WorldPosition.Y = CurrentTrack.Elements[i].WorldPosition.Y + h;
                            WorldPosition.Z = CurrentTrack.Elements[i].WorldPosition.Z + c * D.Z;
                            World.Rotate(ref D, 0.0, 1.0, 0.0, cosa, sina);
                            WorldDirection.X = D.X;
                            WorldDirection.Y = p;
                            WorldDirection.Z = D.Z;
                            World.Normalize(ref WorldDirection.X, ref WorldDirection.Y, ref WorldDirection.Z);
                            double cos2a = Math.Cos(2.0 * a);
                            double sin2a = Math.Sin(2.0 * a);
                            WorldSide = CurrentTrack.Elements[i].WorldSide;
                            World.Rotate(ref WorldSide, 0.0, 1.0, 0.0, cos2a, sin2a);
                            World.Cross(WorldDirection, WorldSide, out WorldUp);
                        }
                        else
                        {
                            // straight
                            WorldPosition.X = CurrentTrack.Elements[i].WorldPosition.X + db * CurrentTrack.Elements[i].WorldDirection.X;
                            WorldPosition.Y = CurrentTrack.Elements[i].WorldPosition.Y + db * CurrentTrack.Elements[i].WorldDirection.Y;
                            WorldPosition.Z = CurrentTrack.Elements[i].WorldPosition.Z + db * CurrentTrack.Elements[i].WorldDirection.Z;
                            WorldDirection  = CurrentTrack.Elements[i].WorldDirection;
                            WorldUp         = CurrentTrack.Elements[i].WorldUp;
                            WorldSide       = CurrentTrack.Elements[i].WorldSide;
                            CurveRadius     = 0.0;
                        }

                        // cant
                        if (i < CurrentTrack.Elements.Length - 1)
                        {
                            double t = db / (CurrentTrack.Elements[i + 1].StartingTrackPosition - CurrentTrack.Elements[i].StartingTrackPosition);
                            if (t < 0.0)
                            {
                                t = 0.0;
                            }
                            else if (t > 1.0)
                            {
                                t = 1.0;
                            }
                            double t2 = t * t;
                            double t3 = t2 * t;
                            CurveCant =
                                (2.0 * t3 - 3.0 * t2 + 1.0) * CurrentTrack.Elements[i].CurveCant +
                                (t3 - 2.0 * t2 + t) * CurrentTrack.Elements[i].CurveCantTangent +
                                (-2.0 * t3 + 3.0 * t2) * CurrentTrack.Elements[i + 1].CurveCant +
                                (t3 - t2) * CurrentTrack.Elements[i + 1].CurveCantTangent;
                            CurveRadius = CurrentTrack.Elements[i].CurveRadius;
                        }
                        else
                        {
                            CurveCant = CurrentTrack.Elements[i].CurveCant;
                        }
                    }
                    else
                    {
                        WorldPosition  = CurrentTrack.Elements[i].WorldPosition;
                        WorldDirection = CurrentTrack.Elements[i].WorldDirection;
                        WorldUp        = CurrentTrack.Elements[i].WorldUp;
                        WorldSide      = CurrentTrack.Elements[i].WorldSide;
                        CurveRadius    = CurrentTrack.Elements[i].CurveRadius;
                        CurveCant      = CurrentTrack.Elements[i].CurveCant;
                    }
                }
                else
                {
                    if (db != 0.0)
                    {
                        if (CurrentTrack.Elements[i].CurveRadius != 0.0)
                        {
                            CurveRadius = CurrentTrack.Elements[i].CurveRadius;
                        }
                        else
                        {
                            CurveRadius = 0.0;
                        }
                        if (i < CurrentTrack.Elements.Length - 1)
                        {
                            double t = db / (CurrentTrack.Elements[i + 1].StartingTrackPosition - CurrentTrack.Elements[i].StartingTrackPosition);
                            if (t < 0.0)
                            {
                                t = 0.0;
                            }
                            else if (t > 1.0)
                            {
                                t = 1.0;
                            }
                            double t2 = t * t;
                            double t3 = t2 * t;
                            CurveCant =
                                (2.0 * t3 - 3.0 * t2 + 1.0) * CurrentTrack.Elements[i].CurveCant +
                                (t3 - 2.0 * t2 + t) * CurrentTrack.Elements[i].CurveCantTangent +
                                (-2.0 * t3 + 3.0 * t2) * CurrentTrack.Elements[i + 1].CurveCant +
                                (t3 - t2) * CurrentTrack.Elements[i + 1].CurveCantTangent;
                        }
                        else
                        {
                            CurveCant = CurrentTrack.Elements[i].CurveCant;
                        }
                    }
                    else
                    {
                        CurveRadius = CurrentTrack.Elements[i].CurveRadius;
                        CurveCant   = CurrentTrack.Elements[i].CurveCant;
                    }
                }
                AdhesionMultiplier = CurrentTrack.Elements[i].AdhesionMultiplier;
                //Pitch added for Plugin Data usage
                //Mutliply this by 1000 to get the original value
                Pitch = CurrentTrack.Elements[i].Pitch * 1000;
                // inaccuracy
                if (AddTrackInaccurary)
                {
                    double x, y, c;
                    if (i < CurrentTrack.Elements.Length - 1)
                    {
                        double t = db / (CurrentTrack.Elements[i + 1].StartingTrackPosition - CurrentTrack.Elements[i].StartingTrackPosition);
                        if (t < 0.0)
                        {
                            t = 0.0;
                        }
                        else if (t > 1.0)
                        {
                            t = 1.0;
                        }
                        double x1, y1, c1;
                        double x2, y2, c2;
                        GetInaccuracies(NewTrackPosition, CurrentTrack.Elements[i].CsvRwAccuracyLevel, out x1, out y1, out c1);
                        GetInaccuracies(NewTrackPosition, CurrentTrack.Elements[i + 1].CsvRwAccuracyLevel, out x2, out y2, out c2);
                        x = (1.0 - t) * x1 + t * x2;
                        y = (1.0 - t) * y1 + t * y2;
                        c = (1.0 - t) * c1 + t * c2;
                    }
                    else
                    {
                        GetInaccuracies(NewTrackPosition, CurrentTrack.Elements[i].CsvRwAccuracyLevel, out x, out y, out c);
                    }
                    WorldPosition.X    += x * WorldSide.X + y * WorldUp.X;
                    WorldPosition.Y    += x * WorldSide.Y + y * WorldUp.Y;
                    WorldPosition.Z    += x * WorldSide.Z + y * WorldUp.Z;
                    CurveCant          += c;
                    CantDueToInaccuracy = c;
                }
                else
                {
                    CantDueToInaccuracy = 0.0;
                }
                // events
                CheckEvents(i, Math.Sign(db - da), da, db);
                //Update the odometer
                if (TrackPosition != NewTrackPosition)
                {
                    //HACK: Reset the odometer if we've moved more than 10m this frame
                    if (Math.Abs(NewTrackPosition - TrackPosition) > 10)
                    {
                        Odometer = 0;
                    }
                    else
                    {
                        Odometer += NewTrackPosition - TrackPosition;
                    }
                }
                // finish
                TrackPosition    = NewTrackPosition;
                LastTrackElement = i;
            }
Пример #8
0
        protected override void OnRenderFrame(FrameEventArgs e)
        {
            Program.MouseMovement();
            double   timeElapsed = CPreciseTimer.GetElapsedTime();
            DateTime time        = DateTime.Now;

            Game.SecondsSinceMidnight = (double)(3600 * time.Hour + 60 * time.Minute + time.Second) + 0.001 * (double)time.Millisecond;
            ObjectManager.UpdateAnimatedWorldObjects(timeElapsed, false);
            if (Program.ReducedMode)
            {
                System.Threading.Thread.Sleep(125);
            }
            else
            {
                System.Threading.Thread.Sleep(1);
            }
            bool updatelight = false;
            bool keep        = false;

            // rotate x
            if (Program.RotateX == 0)
            {
                double d = (1.0 + Math.Abs(RotateXSpeed)) * timeElapsed;
                if (RotateXSpeed >= -d & RotateXSpeed <= d)
                {
                    RotateXSpeed = 0.0;
                }
                else
                {
                    RotateXSpeed -= (double)Math.Sign(RotateXSpeed) * d;
                }
            }
            else
            {
                double d = (1.0 + 1.0 - 1.0 / (1.0 + RotateXSpeed * RotateXSpeed)) * timeElapsed;
                double m = 1.0;
                RotateXSpeed += (double)Program.RotateX * d;
                if (RotateXSpeed < -m)
                {
                    RotateXSpeed = -m;
                }
                else if (RotateXSpeed > m)
                {
                    RotateXSpeed = m;
                }
            }
            if (RotateXSpeed != 0.0)
            {
                double cosa = Math.Cos(RotateXSpeed * timeElapsed);
                double sina = Math.Sin(RotateXSpeed * timeElapsed);
                World.Rotate(ref World.AbsoluteCameraDirection.X, ref World.AbsoluteCameraDirection.Y, ref World.AbsoluteCameraDirection.Z, 0.0, 1.0, 0.0, cosa, sina);
                World.Rotate(ref World.AbsoluteCameraUp.X, ref World.AbsoluteCameraUp.Y, ref World.AbsoluteCameraUp.Z, 0.0, 1.0, 0.0, cosa, sina);
                World.Rotate(ref World.AbsoluteCameraSide.X, ref World.AbsoluteCameraSide.Y, ref World.AbsoluteCameraSide.Z, 0.0, 1.0, 0.0, cosa, sina);
                keep = true;
            }
            // rotate y
            if (Program.RotateY == 0)
            {
                double d = (1.0 + Math.Abs(RotateYSpeed)) * timeElapsed;
                if (RotateYSpeed >= -d & RotateYSpeed <= d)
                {
                    RotateYSpeed = 0.0;
                }
                else
                {
                    RotateYSpeed -= (double)Math.Sign(RotateYSpeed) * d;
                }
            }
            else
            {
                double d = (1.0 + 1.0 - 1.0 / (1.0 + RotateYSpeed * RotateYSpeed)) * timeElapsed;
                double m = 1.0;
                RotateYSpeed += (double)Program.RotateY * d;
                if (RotateYSpeed < -m)
                {
                    RotateYSpeed = -m;
                }
                else if (RotateYSpeed > m)
                {
                    RotateYSpeed = m;
                }
            }
            if (RotateYSpeed != 0.0)
            {
                double cosa = Math.Cos(RotateYSpeed * timeElapsed);
                double sina = Math.Sin(RotateYSpeed * timeElapsed);
                World.Rotate(ref World.AbsoluteCameraDirection.X, ref World.AbsoluteCameraDirection.Y, ref World.AbsoluteCameraDirection.Z, World.AbsoluteCameraSide.X, World.AbsoluteCameraSide.Y, World.AbsoluteCameraSide.Z, cosa, sina);
                World.Rotate(ref World.AbsoluteCameraUp.X, ref World.AbsoluteCameraUp.Y, ref World.AbsoluteCameraUp.Z, World.AbsoluteCameraSide.X, World.AbsoluteCameraSide.Y, World.AbsoluteCameraSide.Z, cosa, sina);
                keep = true;
            }
            // move x
            if (Program.MoveX == 0)
            {
                double d = (2.5 + Math.Abs(MoveXSpeed)) * timeElapsed;
                if (MoveXSpeed >= -d & MoveXSpeed <= d)
                {
                    MoveXSpeed = 0.0;
                }
                else
                {
                    MoveXSpeed -= (double)Math.Sign(MoveXSpeed) * d;
                }
            }
            else
            {
                double d = (5.0 + 10.0 - 10.0 / (1.0 + MoveXSpeed * MoveXSpeed)) * timeElapsed;
                double m = 25.0;
                MoveXSpeed += (double)Program.MoveX * d;
                if (MoveXSpeed < -m)
                {
                    MoveXSpeed = -m;
                }
                else if (MoveXSpeed > m)
                {
                    MoveXSpeed = m;
                }
            }
            if (MoveXSpeed != 0.0)
            {
                World.AbsoluteCameraPosition.X += MoveXSpeed * timeElapsed * World.AbsoluteCameraSide.X;
                World.AbsoluteCameraPosition.Y += MoveXSpeed * timeElapsed * World.AbsoluteCameraSide.Y;
                World.AbsoluteCameraPosition.Z += MoveXSpeed * timeElapsed * World.AbsoluteCameraSide.Z;
                keep = true;
            }
            // move y
            if (Program.MoveY == 0)
            {
                double d = (2.5 + Math.Abs(MoveYSpeed)) * timeElapsed;
                if (MoveYSpeed >= -d & MoveYSpeed <= d)
                {
                    MoveYSpeed = 0.0;
                }
                else
                {
                    MoveYSpeed -= (double)Math.Sign(MoveYSpeed) * d;
                }
            }
            else
            {
                double d = (5.0 + 10.0 - 10.0 / (1.0 + MoveYSpeed * MoveYSpeed)) * timeElapsed;
                double m = 25.0;
                MoveYSpeed += (double)Program.MoveY * d;
                if (MoveYSpeed < -m)
                {
                    MoveYSpeed = -m;
                }
                else if (MoveYSpeed > m)
                {
                    MoveYSpeed = m;
                }
            }
            if (MoveYSpeed != 0.0)
            {
                World.AbsoluteCameraPosition.X += MoveYSpeed * timeElapsed * World.AbsoluteCameraUp.X;
                World.AbsoluteCameraPosition.Y += MoveYSpeed * timeElapsed * World.AbsoluteCameraUp.Y;
                World.AbsoluteCameraPosition.Z += MoveYSpeed * timeElapsed * World.AbsoluteCameraUp.Z;
                keep = true;
            }
            // move z
            if (Program.MoveZ == 0)
            {
                double d = (2.5 + Math.Abs(MoveZSpeed)) * timeElapsed;
                if (MoveZSpeed >= -d & MoveZSpeed <= d)
                {
                    MoveZSpeed = 0.0;
                }
                else
                {
                    MoveZSpeed -= (double)Math.Sign(MoveZSpeed) * d;
                }
            }
            else
            {
                double d = (5.0 + 10.0 - 10.0 / (1.0 + MoveZSpeed * MoveZSpeed)) * timeElapsed;
                double m = 25.0;
                MoveZSpeed += (double)Program.MoveZ * d;
                if (MoveZSpeed < -m)
                {
                    MoveZSpeed = -m;
                }
                else if (MoveZSpeed > m)
                {
                    MoveZSpeed = m;
                }
            }
            if (MoveZSpeed != 0.0)
            {
                World.AbsoluteCameraPosition.X += MoveZSpeed * timeElapsed * World.AbsoluteCameraDirection.X;
                World.AbsoluteCameraPosition.Y += MoveZSpeed * timeElapsed * World.AbsoluteCameraDirection.Y;
                World.AbsoluteCameraPosition.Z += MoveZSpeed * timeElapsed * World.AbsoluteCameraDirection.Z;
                keep = true;
            }
            // lighting
            if (Program.LightingRelative == -1)
            {
                Program.LightingRelative = (double)Program.LightingTarget;
                updatelight = true;
            }
            if (Program.LightingTarget == 0)
            {
                if (Program.LightingRelative != 0.0)
                {
                    Program.LightingRelative -= 0.5 * timeElapsed;
                    if (Program.LightingRelative < 0.0)
                    {
                        Program.LightingRelative = 0.0;
                    }
                    updatelight = true;
                    keep        = true;
                }
            }
            else
            {
                if (Program.LightingRelative != 1.0)
                {
                    Program.LightingRelative += 0.5 * timeElapsed;
                    if (Program.LightingRelative > 1.0)
                    {
                        Program.LightingRelative = 1.0;
                    }
                    updatelight = true;
                    keep        = true;
                }
            }
            // continue
            if (Program.ReducedMode)
            {
                ReducedModeEnteringTime = 3.0;
            }
            else
            {
                if (keep)
                {
                    ReducedModeEnteringTime = 3.0;
                }
                else if (ReducedModeEnteringTime <= 0)
                {
                    Program.ReducedMode        = true;
                    World.AbsoluteCameraSide.Y = 0.0;
                    World.Normalize(ref World.AbsoluteCameraSide.X, ref World.AbsoluteCameraSide.Y, ref World.AbsoluteCameraSide.Z);
                    World.Normalize(ref World.AbsoluteCameraDirection.X, ref World.AbsoluteCameraDirection.Y, ref World.AbsoluteCameraDirection.Z);
                    World.AbsoluteCameraUp = Vector3.Cross(World.AbsoluteCameraDirection, World.AbsoluteCameraSide);
                }
                else
                {
                    ReducedModeEnteringTime -= timeElapsed;
                }
            }
            if (updatelight)
            {
                Renderer.OptionAmbientColor.R = (byte)Math.Round(32.0 + 128.0 * Program.LightingRelative * (2.0 - Program.LightingRelative));
                Renderer.OptionAmbientColor.G = (byte)Math.Round(32.0 + 128.0 * 0.5 * (Program.LightingRelative + Program.LightingRelative * (2.0 - Program.LightingRelative)));
                Renderer.OptionAmbientColor.B = (byte)Math.Round(32.0 + 128.0 * Program.LightingRelative);
                Renderer.OptionDiffuseColor.R = (byte)Math.Round(32.0 + 128.0 * Program.LightingRelative);
                Renderer.OptionDiffuseColor.G = (byte)Math.Round(32.0 + 128.0 * Program.LightingRelative);
                Renderer.OptionDiffuseColor.B = (byte)Math.Round(32.0 + 128.0 * Math.Sqrt(Program.LightingRelative));
                Renderer.InitializeLighting();
            }
            Renderer.RenderScene();
            SwapBuffers();
        }
Пример #9
0
        internal static void UpdateTrackFollower(ref TrackFollower Follower, double NewTrackPosition, bool UpdateWorldCoordinates, bool AddTrackInaccurary)
        {
            if (CurrentTrack.Elements.Length == 0)
            {
                return;
            }
            int i = Follower.LastTrackElement;

            while (i >= 0 && NewTrackPosition < CurrentTrack.Elements[i].StartingTrackPosition)
            {
                double ta = Follower.TrackPosition - CurrentTrack.Elements[i].StartingTrackPosition;
                double tb = -0.01;
                CheckEvents(ref Follower, i, -1, ta, tb);
                i--;
            }
            if (i >= 0)
            {
                while (i < CurrentTrack.Elements.Length - 1)
                {
                    if (NewTrackPosition < CurrentTrack.Elements[i + 1].StartingTrackPosition)
                    {
                        break;
                    }
                    double ta = Follower.TrackPosition - CurrentTrack.Elements[i].StartingTrackPosition;
                    double tb = CurrentTrack.Elements[i + 1].StartingTrackPosition - CurrentTrack.Elements[i].StartingTrackPosition + 0.01;
                    CheckEvents(ref Follower, i, 1, ta, tb);
                    i++;
                }
            }
            else
            {
                i = 0;
            }
            double da = Follower.TrackPosition - CurrentTrack.Elements[i].StartingTrackPosition;
            double db = NewTrackPosition - CurrentTrack.Elements[i].StartingTrackPosition;

            // track
            if (UpdateWorldCoordinates)
            {
                if (db != 0.0)
                {
                    if (CurrentTrack.Elements[i].CurveRadius != 0.0)
                    {
                        // curve
                        double  r = CurrentTrack.Elements[i].CurveRadius;
                        double  p = CurrentTrack.Elements[i].WorldDirection.Y / Math.Sqrt(CurrentTrack.Elements[i].WorldDirection.X * CurrentTrack.Elements[i].WorldDirection.X + CurrentTrack.Elements[i].WorldDirection.Z * CurrentTrack.Elements[i].WorldDirection.Z);
                        double  s = db / Math.Sqrt(1.0 + p * p);
                        double  h = s * p;
                        double  b = s / Math.Abs(r);
                        double  f = 2.0 * r * r * (1.0 - Math.Cos(b));
                        double  c = (double)Math.Sign(db) * Math.Sqrt(f >= 0.0 ? f : 0.0);
                        double  a = 0.5 * (double)Math.Sign(r) * b;
                        Vector3 D = new Vector3(CurrentTrack.Elements[i].WorldDirection.X, 0.0, CurrentTrack.Elements[i].WorldDirection.Z);
                        World.Normalize(ref D.X, ref D.Y, ref D.Z);
                        double cosa = Math.Cos(a);
                        double sina = Math.Sin(a);
                        World.Rotate(ref D.X, ref D.Y, ref D.Z, 0.0, 1.0, 0.0, cosa, sina);
                        Follower.WorldPosition.X = CurrentTrack.Elements[i].WorldPosition.X + c * D.X;
                        Follower.WorldPosition.Y = CurrentTrack.Elements[i].WorldPosition.Y + h;
                        Follower.WorldPosition.Z = CurrentTrack.Elements[i].WorldPosition.Z + c * D.Z;
                        World.Rotate(ref D.X, ref D.Y, ref D.Z, 0.0, 1.0, 0.0, cosa, sina);
                        Follower.WorldDirection.X = D.X;
                        Follower.WorldDirection.Y = p;
                        Follower.WorldDirection.Z = D.Z;
                        World.Normalize(ref Follower.WorldDirection.X, ref Follower.WorldDirection.Y, ref Follower.WorldDirection.Z);
                        double cos2a = Math.Cos(2.0 * a);
                        double sin2a = Math.Sin(2.0 * a);
                        Follower.WorldSide = CurrentTrack.Elements[i].WorldSide;
                        World.Rotate(ref Follower.WorldSide.X, ref Follower.WorldSide.Y, ref Follower.WorldSide.Z, 0.0, 1.0, 0.0, cos2a, sin2a);
                        Follower.WorldUp     = Vector3.Cross(Follower.WorldDirection, Follower.WorldSide);
                        Follower.CurveRadius = CurrentTrack.Elements[i].CurveRadius;
                    }
                    else
                    {
                        // straight
                        Follower.WorldPosition.X = CurrentTrack.Elements[i].WorldPosition.X + db * CurrentTrack.Elements[i].WorldDirection.X;
                        Follower.WorldPosition.Y = CurrentTrack.Elements[i].WorldPosition.Y + db * CurrentTrack.Elements[i].WorldDirection.Y;
                        Follower.WorldPosition.Z = CurrentTrack.Elements[i].WorldPosition.Z + db * CurrentTrack.Elements[i].WorldDirection.Z;
                        Follower.WorldDirection  = CurrentTrack.Elements[i].WorldDirection;
                        Follower.WorldUp         = CurrentTrack.Elements[i].WorldUp;
                        Follower.WorldSide       = CurrentTrack.Elements[i].WorldSide;
                        Follower.CurveRadius     = 0.0;
                    }
                    // cant
                    if (i < CurrentTrack.Elements.Length - 1)
                    {
                        double t = db / (CurrentTrack.Elements[i + 1].StartingTrackPosition - CurrentTrack.Elements[i].StartingTrackPosition);
                        if (t < 0.0)
                        {
                            t = 0.0;
                        }
                        else if (t > 1.0)
                        {
                            t = 1.0;
                        }
                        double t2 = t * t;
                        double t3 = t2 * t;
                        Follower.CurveCant =
                            (2.0 * t3 - 3.0 * t2 + 1.0) * CurrentTrack.Elements[i].CurveCant +
                            (t3 - 2.0 * t2 + t) * CurrentTrack.Elements[i].CurveCantTangent +
                            (-2.0 * t3 + 3.0 * t2) * CurrentTrack.Elements[i + 1].CurveCant +
                            (t3 - t2) * CurrentTrack.Elements[i + 1].CurveCantTangent;
                    }
                    else
                    {
                        Follower.CurveCant = CurrentTrack.Elements[i].CurveCant;
                    }
                }
                else
                {
                    Follower.WorldPosition  = CurrentTrack.Elements[i].WorldPosition;
                    Follower.WorldDirection = CurrentTrack.Elements[i].WorldDirection;
                    Follower.WorldUp        = CurrentTrack.Elements[i].WorldUp;
                    Follower.WorldSide      = CurrentTrack.Elements[i].WorldSide;
                    Follower.CurveRadius    = CurrentTrack.Elements[i].CurveRadius;
                    Follower.CurveCant      = CurrentTrack.Elements[i].CurveCant;
                }
            }
            else
            {
                if (db != 0.0)
                {
                    if (CurrentTrack.Elements[i].CurveRadius != 0.0)
                    {
                        Follower.CurveRadius = CurrentTrack.Elements[i].CurveRadius;
                    }
                    else
                    {
                        Follower.CurveRadius = 0.0;
                    }
                    if (i < CurrentTrack.Elements.Length - 1)
                    {
                        double t = db / (CurrentTrack.Elements[i + 1].StartingTrackPosition - CurrentTrack.Elements[i].StartingTrackPosition);
                        if (t < 0.0)
                        {
                            t = 0.0;
                        }
                        else if (t > 1.0)
                        {
                            t = 1.0;
                        }
                        double t2 = t * t;
                        double t3 = t2 * t;
                        Follower.CurveCant =
                            (2.0 * t3 - 3.0 * t2 + 1.0) * CurrentTrack.Elements[i].CurveCant +
                            (t3 - 2.0 * t2 + t) * CurrentTrack.Elements[i].CurveCantTangent +
                            (-2.0 * t3 + 3.0 * t2) * CurrentTrack.Elements[i + 1].CurveCant +
                            (t3 - t2) * CurrentTrack.Elements[i + 1].CurveCantTangent;
                    }
                    else
                    {
                        Follower.CurveCant = CurrentTrack.Elements[i].CurveCant;
                    }
                }
                else
                {
                    Follower.CurveRadius = CurrentTrack.Elements[i].CurveRadius;
                    Follower.CurveCant   = CurrentTrack.Elements[i].CurveCant;
                }
            }
            Follower.AdhesionMultiplier = CurrentTrack.Elements[i].AdhesionMultiplier;
            // inaccuracy
            if (AddTrackInaccurary)
            {
                double x, y, c;
                if (i < CurrentTrack.Elements.Length - 1)
                {
                    double t = db / (CurrentTrack.Elements[i + 1].StartingTrackPosition - CurrentTrack.Elements[i].StartingTrackPosition);
                    if (t < 0.0)
                    {
                        t = 0.0;
                    }
                    else if (t > 1.0)
                    {
                        t = 1.0;
                    }
                    double x1, y1, c1;
                    double x2, y2, c2;
                    GetInaccuracies(NewTrackPosition, CurrentTrack.Elements[i].CsvRwAccuracyLevel, out x1, out y1, out c1);
                    GetInaccuracies(NewTrackPosition, CurrentTrack.Elements[i + 1].CsvRwAccuracyLevel, out x2, out y2, out c2);
                    x = (1.0 - t) * x1 + t * x2;
                    y = (1.0 - t) * y1 + t * y2;
                    c = (1.0 - t) * c1 + t * c2;
                }
                else
                {
                    GetInaccuracies(NewTrackPosition, CurrentTrack.Elements[i].CsvRwAccuracyLevel, out x, out y, out c);
                }
                Follower.WorldPosition.X    += x * Follower.WorldSide.X + y * Follower.WorldUp.X;
                Follower.WorldPosition.Y    += x * Follower.WorldSide.Y + y * Follower.WorldUp.Y;
                Follower.WorldPosition.Z    += x * Follower.WorldSide.Z + y * Follower.WorldUp.Z;
                Follower.CurveCant          += c;
                Follower.CantDueToInaccuracy = c;
            }
            else
            {
                Follower.CantDueToInaccuracy = 0.0;
            }
            // events
            CheckEvents(ref Follower, i, Math.Sign(db - da), da, db);
            // finish
            Follower.TrackPosition    = NewTrackPosition;
            Follower.LastTrackElement = i;
        }
Пример #10
0
        internal static void Main(string[] args)
        {
            // platform and mono
            int p = (int)Environment.OSVersion.Platform;

            if (p == 4 | p == 128)
            {
                // general Unix
                CurrentPlatform = Platform.Linux;
            }
            else if (p == 6)
            {
                // Mac
                CurrentPlatform = Platform.Mac;
            }
            else
            {
                // non-Unix
                CurrentPlatform = Platform.Windows;
            }
            CurrentlyRunOnMono = Type.GetType("Mono.Runtime") != null;
            // file system
            FileSystem = FileSystem.FromCommandLineArgs(args);
            FileSystem.CreateFileSystem();
            SetPackageLookupDirectories();
            // command line arguments
            bool[] SkipArgs = new bool[args.Length];
            if (args.Length != 0)
            {
                string File = System.IO.Path.Combine(Application.StartupPath, "RouteViewer.exe");
                if (System.IO.File.Exists(File))
                {
                    int Skips = 0;
                    System.Text.StringBuilder NewArgs = new System.Text.StringBuilder();
                    for (int i = 0; i < args.Length; i++)
                    {
                        if (System.IO.File.Exists(args[i]))
                        {
                            if (System.IO.Path.GetExtension(args[i]).Equals(".csv", StringComparison.OrdinalIgnoreCase))
                            {
                                string Text = System.IO.File.ReadAllText(args[i], System.Text.Encoding.UTF8);
                                if (Text.Length != -1 && Text.IndexOf("CreateMeshBuilder", StringComparison.OrdinalIgnoreCase) == -1)
                                {
                                    if (NewArgs.Length != 0)
                                    {
                                        NewArgs.Append(" ");
                                    }
                                    NewArgs.Append("\"" + args[i] + "\"");
                                    SkipArgs[i] = true;
                                    Skips++;
                                }
                            }
                        }
                        else
                        {
                            SkipArgs[i] = true;
                            Skips++;
                        }
                    }
                    if (NewArgs.Length != 0)
                    {
                        System.Diagnostics.Process.Start(File, NewArgs.ToString());
                    }
                    if (Skips == args.Length)
                    {
                        return;
                    }
                }
            }
            // application
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            if (SDL.SDL_Init(SDL.SDL_INIT_VIDEO) != 0)
            {
                MessageBox.Show("SDL failed to initialize the video subsystem.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Hand);
                return;
            }
            Interface.CurrentOptions.ObjectOptimizationBasicThreshold = 1000;
            Interface.CurrentOptions.ObjectOptimizationFullThreshold  = 250;
            // initialize sdl window
            SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_DOUBLEBUFFER, 1);
            SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_DEPTH_SIZE, 16);
            SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_RED_SIZE, 8);
            SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_GREEN_SIZE, 8);
            SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_BLUE_SIZE, 8);
            SDL.SDL_GL_SetAttribute(SDL.SDL_GLattr.SDL_GL_ALPHA_SIZE, 8);
            SDL.SDL_ShowCursor(1);
            // initialize camera
            ResetCamera();
            // create window
            Renderer.ScreenWidth  = 960;
            Renderer.ScreenHeight = 600;
            // int Bits = 32;
            //Sdl.SDL_SetVideoMode(Renderer.ScreenWidth, Renderer.ScreenHeight, Bits, Sdl.SDL_OPENGL | Sdl.SDL_DOUBLEBUF);
            SDLWindow = SDL.SDL_CreateWindow(Application.ProductName,
                                             SDL.SDL_WINDOWPOS_UNDEFINED, SDL.SDL_WINDOWPOS_UNDEFINED,
                                             Renderer.ScreenWidth, Renderer.ScreenHeight,
                                             SDL.SDL_WindowFlags.SDL_WINDOW_OPENGL | SDL.SDL_WindowFlags.SDL_WINDOW_RESIZABLE);
            if (SDLWindow != IntPtr.Zero)
            {
                // create window
                string File = OpenBveApi.Path.CombineFile(Program.FileSystem.GetDataFolder(), "icon.png");
                if (System.IO.File.Exists(File))
                {
                    // set up icon
                    iconBmp  = new Bitmap(File);                    // load file
                    iconData = iconBmp.LockBits(new Rectangle(0, 0, iconBmp.Width, iconBmp.Height),
                                                System.Drawing.Imaging.ImageLockMode.ReadOnly,
                                                System.Drawing.Imaging.PixelFormat.Format32bppArgb);            // lock data
                    iconSurface = SDL.SDL_CreateRGBSurfaceFrom(iconData.Scan0, iconBmp.Width, iconBmp.Height, 32, iconData.Stride,
                                                               0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000); // upload to sdl
                    SDL.SDL_SetWindowIcon(SDLWindow, iconSurface);                                              // use icon
                    // free is on the end of the program

                    /*
                     * IntPtr bitmap = SDL.SDL_LoadBMP(File);
                     * if (bitmap != IntPtr.Zero) {
                     *      SDL.SDL_Surface Surface = (SDL.SDL_Surface)System.Runtime.InteropServices.Marshal.PtrToStructure(bitmap, typeof(SDL.SDL_Surface));
                     *      uint ColorKey = SDL.SDL_MapRGB(Surface.format, 0, 0, 255);
                     *      SDL.SDL_SetColorKey(bitmap, 1, ColorKey);
                     *      SDL.SDL_SetWindowIcon(SDLWindow,bitmap);
                     * }
                     */
                }
                GLContext = SDL.SDL_GL_CreateContext(SDLWindow);
                tkContext = new GraphicsContext(new ContextHandle(GLContext),
                                                SDL.SDL_GL_GetProcAddress,
                                                () => new ContextHandle(SDL.SDL_GL_GetCurrentContext()));
                // anisotropic filtering
                string[] extensions = GL.GetString(StringName.Extensions).Split(new [] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                Interface.CurrentOptions.AnisotropicFilteringMaximum = 0;
                for (int i = 0; i < extensions.Length; i++)
                {
                    if (extensions[i] == "GL_EXT_texture_filter_anisotropic")
                    {
                        float n;
                        GL.GetFloat((GetPName)ExtTextureFilterAnisotropic.MaxTextureMaxAnisotropyExt, out n);
                        Interface.CurrentOptions.AnisotropicFilteringMaximum = (int)Math.Round((double)n);
                        break;
                    }
                }
                if (Interface.CurrentOptions.AnisotropicFilteringMaximum <= 0)
                {
                    Interface.CurrentOptions.AnisotropicFilteringMaximum = 0;
                    Interface.CurrentOptions.AnisotropicFilteringLevel   = 0;
                    Interface.CurrentOptions.Interpolation = TextureManager.InterpolationMode.AnisotropicFiltering;
                }
                else
                {
                    Interface.CurrentOptions.AnisotropicFilteringLevel = Interface.CurrentOptions.AnisotropicFilteringMaximum;
                    Interface.CurrentOptions.Interpolation             = TextureManager.InterpolationMode.TrilinearMipmapped;
                }
                // module initialization
                Renderer.Initialize();
                Renderer.InitializeLighting();
                SDL.SDL_GL_SwapWindow(SDLWindow);
                Fonts.Initialize();
                UpdateViewport();
                // command line arguments
                for (int i = 0; i < args.Length; i++)
                {
                    if (!SkipArgs[i] && System.IO.File.Exists(args[i]))
                    {
                        try {
                            ObjectManager.UnifiedObject o = ObjectManager.LoadObject(args[i], System.Text.Encoding.UTF8, ObjectManager.ObjectLoadMode.Normal, false, false, false);
                            ObjectManager.CreateObject(o, new World.Vector3D(0.0, 0.0, 0.0), new World.Transformation(0.0, 0.0, 0.0), new World.Transformation(0.0, 0.0, 0.0), true, 0.0, 0.0, 25.0, 0.0);
                        } catch (Exception ex) {
                            Interface.AddMessage(Interface.MessageType.Critical, false, "Unhandled error (" + ex.Message + ") encountered while processing the file " + args[i] + ".");
                        }
                        Array.Resize <string>(ref Files, Files.Length + 1);
                        Files[Files.Length - 1] = args[i];
                    }
                }
                ObjectManager.InitializeVisibility();
                ObjectManager.FinishCreatingObjects();
                ObjectManager.UpdateVisibility(0.0, true);
                ObjectManager.UpdateAnimatedWorldObjects(0.01, true);
                UpdateCaption();
                Stopwatch timer = new Stopwatch();
                timer.Start();
                LastTicks = timer.ElapsedMilliseconds;
                // loop
                while (!Quit)
                {
                    long   ticks       = timer.ElapsedMilliseconds;
                    double timeElapsed = 0.001 * (double)(ticks - LastTicks);
                    if (timeElapsed < 0.0001)
                    {
                        timeElapsed = 0.0001;
                    }
                    LastTicks = ticks;
                    DateTime time = DateTime.Now;
                    Game.SecondsSinceMidnight = (double)(3600 * time.Hour + 60 * time.Minute + time.Second) + 0.001 * (double)time.Millisecond;
                    ObjectManager.UpdateAnimatedWorldObjects(timeElapsed, false);
                    ProcessEvents();
                    if (ReducedMode)
                    {
                        System.Threading.Thread.Sleep(125);
                    }
                    else
                    {
                        System.Threading.Thread.Sleep(1);
                    }
                    bool updatelight = false;
                    bool keep        = false;
                    // rotate x
                    if (RotateX == 0)
                    {
                        double d = (1.0 + Math.Abs(RotateXSpeed)) * timeElapsed;
                        if (RotateXSpeed >= -d & RotateXSpeed <= d)
                        {
                            RotateXSpeed = 0.0;
                        }
                        else
                        {
                            RotateXSpeed -= (double)Math.Sign(RotateXSpeed) * d;
                        }
                    }
                    else
                    {
                        double d = (1.0 + 1.0 - 1.0 / (1.0 + RotateXSpeed * RotateXSpeed)) * timeElapsed;
                        double m = 1.0;
                        RotateXSpeed += (double)RotateX * d;
                        if (RotateXSpeed < -m)
                        {
                            RotateXSpeed = -m;
                        }
                        else if (RotateXSpeed > m)
                        {
                            RotateXSpeed = m;
                        }
                    }
                    if (RotateXSpeed != 0.0)
                    {
                        double cosa = Math.Cos(RotateXSpeed * timeElapsed);
                        double sina = Math.Sin(RotateXSpeed * timeElapsed);
                        World.Rotate(ref World.AbsoluteCameraDirection.X, ref World.AbsoluteCameraDirection.Y, ref World.AbsoluteCameraDirection.Z, 0.0, 1.0, 0.0, cosa, sina);
                        World.Rotate(ref World.AbsoluteCameraUp.X, ref World.AbsoluteCameraUp.Y, ref World.AbsoluteCameraUp.Z, 0.0, 1.0, 0.0, cosa, sina);
                        World.Rotate(ref World.AbsoluteCameraSide.X, ref World.AbsoluteCameraSide.Y, ref World.AbsoluteCameraSide.Z, 0.0, 1.0, 0.0, cosa, sina);
                        keep = true;
                    }
                    // rotate y
                    if (RotateY == 0)
                    {
                        double d = (1.0 + Math.Abs(RotateYSpeed)) * timeElapsed;
                        if (RotateYSpeed >= -d & RotateYSpeed <= d)
                        {
                            RotateYSpeed = 0.0;
                        }
                        else
                        {
                            RotateYSpeed -= (double)Math.Sign(RotateYSpeed) * d;
                        }
                    }
                    else
                    {
                        double d = (1.0 + 1.0 - 1.0 / (1.0 + RotateYSpeed * RotateYSpeed)) * timeElapsed;
                        double m = 1.0;
                        RotateYSpeed += (double)RotateY * d;
                        if (RotateYSpeed < -m)
                        {
                            RotateYSpeed = -m;
                        }
                        else if (RotateYSpeed > m)
                        {
                            RotateYSpeed = m;
                        }
                    }
                    if (RotateYSpeed != 0.0)
                    {
                        double cosa = Math.Cos(RotateYSpeed * timeElapsed);
                        double sina = Math.Sin(RotateYSpeed * timeElapsed);
                        World.Rotate(ref World.AbsoluteCameraDirection.X, ref World.AbsoluteCameraDirection.Y, ref World.AbsoluteCameraDirection.Z, World.AbsoluteCameraSide.X, World.AbsoluteCameraSide.Y, World.AbsoluteCameraSide.Z, cosa, sina);
                        World.Rotate(ref World.AbsoluteCameraUp.X, ref World.AbsoluteCameraUp.Y, ref World.AbsoluteCameraUp.Z, World.AbsoluteCameraSide.X, World.AbsoluteCameraSide.Y, World.AbsoluteCameraSide.Z, cosa, sina);
                        keep = true;
                    }
                    // move x
                    if (MoveX == 0)
                    {
                        double d = (2.5 + Math.Abs(MoveXSpeed)) * timeElapsed;
                        if (MoveXSpeed >= -d & MoveXSpeed <= d)
                        {
                            MoveXSpeed = 0.0;
                        }
                        else
                        {
                            MoveXSpeed -= (double)Math.Sign(MoveXSpeed) * d;
                        }
                    }
                    else
                    {
                        double d = (5.0 + 10.0 - 10.0 / (1.0 + MoveXSpeed * MoveXSpeed)) * timeElapsed;
                        double m = 25.0;
                        MoveXSpeed += (double)MoveX * d;
                        if (MoveXSpeed < -m)
                        {
                            MoveXSpeed = -m;
                        }
                        else if (MoveXSpeed > m)
                        {
                            MoveXSpeed = m;
                        }
                    }
                    if (MoveXSpeed != 0.0)
                    {
                        World.AbsoluteCameraPosition.X += MoveXSpeed * timeElapsed * World.AbsoluteCameraSide.X;
                        World.AbsoluteCameraPosition.Y += MoveXSpeed * timeElapsed * World.AbsoluteCameraSide.Y;
                        World.AbsoluteCameraPosition.Z += MoveXSpeed * timeElapsed * World.AbsoluteCameraSide.Z;
                        keep = true;
                    }
                    // move y
                    if (MoveY == 0)
                    {
                        double d = (2.5 + Math.Abs(MoveYSpeed)) * timeElapsed;
                        if (MoveYSpeed >= -d & MoveYSpeed <= d)
                        {
                            MoveYSpeed = 0.0;
                        }
                        else
                        {
                            MoveYSpeed -= (double)Math.Sign(MoveYSpeed) * d;
                        }
                    }
                    else
                    {
                        double d = (5.0 + 10.0 - 10.0 / (1.0 + MoveYSpeed * MoveYSpeed)) * timeElapsed;
                        double m = 25.0;
                        MoveYSpeed += (double)MoveY * d;
                        if (MoveYSpeed < -m)
                        {
                            MoveYSpeed = -m;
                        }
                        else if (MoveYSpeed > m)
                        {
                            MoveYSpeed = m;
                        }
                    }
                    if (MoveYSpeed != 0.0)
                    {
                        World.AbsoluteCameraPosition.X += MoveYSpeed * timeElapsed * World.AbsoluteCameraUp.X;
                        World.AbsoluteCameraPosition.Y += MoveYSpeed * timeElapsed * World.AbsoluteCameraUp.Y;
                        World.AbsoluteCameraPosition.Z += MoveYSpeed * timeElapsed * World.AbsoluteCameraUp.Z;
                        keep = true;
                    }
                    // move z
                    if (MoveZ == 0)
                    {
                        double d = (2.5 + Math.Abs(MoveZSpeed)) * timeElapsed;
                        if (MoveZSpeed >= -d & MoveZSpeed <= d)
                        {
                            MoveZSpeed = 0.0;
                        }
                        else
                        {
                            MoveZSpeed -= (double)Math.Sign(MoveZSpeed) * d;
                        }
                    }
                    else
                    {
                        double d = (5.0 + 10.0 - 10.0 / (1.0 + MoveZSpeed * MoveZSpeed)) * timeElapsed;
                        double m = 25.0;
                        MoveZSpeed += (double)MoveZ * d;
                        if (MoveZSpeed < -m)
                        {
                            MoveZSpeed = -m;
                        }
                        else if (MoveZSpeed > m)
                        {
                            MoveZSpeed = m;
                        }
                    }
                    if (MoveZSpeed != 0.0)
                    {
                        World.AbsoluteCameraPosition.X += MoveZSpeed * timeElapsed * World.AbsoluteCameraDirection.X;
                        World.AbsoluteCameraPosition.Y += MoveZSpeed * timeElapsed * World.AbsoluteCameraDirection.Y;
                        World.AbsoluteCameraPosition.Z += MoveZSpeed * timeElapsed * World.AbsoluteCameraDirection.Z;
                        keep = true;
                    }
                    // lighting
                    if (LightingRelative == -1)
                    {
                        LightingRelative = (double)LightingTarget;
                        updatelight      = true;
                    }
                    if (LightingTarget == 0)
                    {
                        if (LightingRelative != 0.0)
                        {
                            LightingRelative -= 0.5 * timeElapsed;
                            if (LightingRelative < 0.0)
                            {
                                LightingRelative = 0.0;
                            }
                            updatelight = true;
                            keep        = true;
                        }
                    }
                    else
                    {
                        if (LightingRelative != 1.0)
                        {
                            LightingRelative += 0.5 * timeElapsed;
                            if (LightingRelative > 1.0)
                            {
                                LightingRelative = 1.0;
                            }
                            updatelight = true;
                            keep        = true;
                        }
                    }
                    // continue
                    if (ReducedMode)
                    {
                        ReducedModeEnteringTime = (int)(ticks + 3000);
                    }
                    else
                    {
                        if (keep)
                        {
                            ReducedModeEnteringTime = (int)(ticks + 3000);
                        }
                        else if (ticks > ReducedModeEnteringTime)
                        {
                            ReducedMode = true;
                            World.AbsoluteCameraSide.Y = 0.0;
                            World.Normalize(ref World.AbsoluteCameraSide.X, ref World.AbsoluteCameraSide.Y, ref World.AbsoluteCameraSide.Z);
                            World.Normalize(ref World.AbsoluteCameraDirection.X, ref World.AbsoluteCameraDirection.Y, ref World.AbsoluteCameraDirection.Z);
                            World.AbsoluteCameraUp = World.Cross(World.AbsoluteCameraDirection, World.AbsoluteCameraSide);
                        }
                    }
                    if (updatelight)
                    {
                        Renderer.OptionAmbientColor.R = (byte)Math.Round(32.0 + 128.0 * LightingRelative * (2.0 - LightingRelative));
                        Renderer.OptionAmbientColor.G = (byte)Math.Round(32.0 + 128.0 * 0.5 * (LightingRelative + LightingRelative * (2.0 - LightingRelative)));
                        Renderer.OptionAmbientColor.B = (byte)Math.Round(32.0 + 128.0 * LightingRelative);
                        Renderer.OptionDiffuseColor.R = (byte)Math.Round(32.0 + 128.0 * LightingRelative);
                        Renderer.OptionDiffuseColor.G = (byte)Math.Round(32.0 + 128.0 * LightingRelative);
                        Renderer.OptionDiffuseColor.B = (byte)Math.Round(32.0 + 128.0 * Math.Sqrt(LightingRelative));
                        Renderer.InitializeLighting();
                    }
                    Renderer.RenderScene();
                    SDL.SDL_GL_SwapWindow(SDLWindow);
                }
                // quit
                TextureManager.UnuseAllTextures();
                if (iconSurface != IntPtr.Zero)
                {
                    SDL.SDL_FreeSurface(iconSurface);                     // free surface
                }
                if (iconBmp != null && iconData != null)
                {
                    iconBmp.UnlockBits(iconData);                     // free pixels
                    iconBmp.Dispose();
                }
                SDL.SDL_GL_DeleteContext(GLContext);
                SDL.SDL_DestroyWindow(SDLWindow);
                SDL.SDL_Quit();
            }
            else
            {
                MessageBox.Show("SDL failed to create the window.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Hand);
            }
        }
Пример #11
0
        // process events
        private static void ProcessEvents()
        {
            SDL.SDL_Event Event;
            while (SDL.SDL_PollEvent(out Event) != 0)
            {
                switch (Event.type)
                {
                // quit
                case SDL.SDL_EventType.SDL_QUIT:
                    Quit = true;
                    return;

                // resize
                case SDL.SDL_EventType.SDL_WINDOWEVENT:
                    if (Event.window.windowEvent == SDL.SDL_WindowEventID.SDL_WINDOWEVENT_RESIZED)
                    {
                        Renderer.ScreenWidth  = Event.window.data1;
                        Renderer.ScreenHeight = Event.window.data2;
                        UpdateViewport();
                    }
                    break;

                // mouse
                case SDL.SDL_EventType.SDL_MOUSEBUTTONDOWN:
                    MouseCenterX         = (short)Event.button.x;
                    MouseCenterY         = (short)Event.button.y;
                    MouseCameraPosition  = World.AbsoluteCameraPosition;
                    MouseCameraDirection = World.AbsoluteCameraDirection;
                    MouseCameraUp        = World.AbsoluteCameraUp;
                    MouseCameraSide      = World.AbsoluteCameraSide;
                    MouseButton          = Event.button.button;
                    break;

                case SDL.SDL_EventType.SDL_MOUSEBUTTONUP:
                    MouseButton = 0;
                    break;

                case SDL.SDL_EventType.SDL_MOUSEMOTION:
                    if (MouseButton == SDL.SDL_BUTTON_LEFT)
                    {
                        World.AbsoluteCameraDirection = MouseCameraDirection;
                        World.AbsoluteCameraUp        = MouseCameraUp;
                        World.AbsoluteCameraSide      = MouseCameraSide;
                        {
                            double dx   = 0.0025 * (double)(MouseCenterX - Event.motion.x);
                            double cosa = Math.Cos(dx);
                            double sina = Math.Sin(dx);
                            World.Rotate(ref World.AbsoluteCameraDirection.X, ref World.AbsoluteCameraDirection.Y, ref World.AbsoluteCameraDirection.Z, 0.0, 1.0, 0.0, cosa, sina);
                            World.Rotate(ref World.AbsoluteCameraUp.X, ref World.AbsoluteCameraUp.Y, ref World.AbsoluteCameraUp.Z, 0.0, 1.0, 0.0, cosa, sina);
                            World.Rotate(ref World.AbsoluteCameraSide.X, ref World.AbsoluteCameraSide.Y, ref World.AbsoluteCameraSide.Z, 0.0, 1.0, 0.0, cosa, sina);
                        }
                        {
                            double dy   = 0.0025 * (double)(MouseCenterY - Event.motion.y);
                            double cosa = Math.Cos(dy);
                            double sina = Math.Sin(dy);
                            World.Rotate(ref World.AbsoluteCameraDirection.X, ref World.AbsoluteCameraDirection.Y, ref World.AbsoluteCameraDirection.Z, World.AbsoluteCameraSide.X, World.AbsoluteCameraSide.Y, World.AbsoluteCameraSide.Z, cosa, sina);
                            World.Rotate(ref World.AbsoluteCameraUp.X, ref World.AbsoluteCameraUp.Y, ref World.AbsoluteCameraUp.Z, World.AbsoluteCameraSide.X, World.AbsoluteCameraSide.Y, World.AbsoluteCameraSide.Z, cosa, sina);
                        }
                        ReducedMode = false;
                    }
                    else if (MouseButton == SDL.SDL_BUTTON_RIGHT)
                    {
                        World.AbsoluteCameraPosition = MouseCameraPosition;
                        double dx = -0.025 * (double)(Event.motion.x - MouseCenterX);
                        World.AbsoluteCameraPosition.X += dx * World.AbsoluteCameraSide.X;
                        World.AbsoluteCameraPosition.Y += dx * World.AbsoluteCameraSide.Y;
                        World.AbsoluteCameraPosition.Z += dx * World.AbsoluteCameraSide.Z;
                        double dy = 0.025 * (double)(Event.motion.y - MouseCenterY);
                        World.AbsoluteCameraPosition.X += dy * World.AbsoluteCameraUp.X;
                        World.AbsoluteCameraPosition.Y += dy * World.AbsoluteCameraUp.Y;
                        World.AbsoluteCameraPosition.Z += dy * World.AbsoluteCameraUp.Z;
                        ReducedMode = false;
                    }
                    else if (MouseButton == SDL.SDL_BUTTON_MIDDLE)
                    {
                        World.AbsoluteCameraPosition = MouseCameraPosition;
                        double dx = -0.025 * (double)(Event.motion.x - MouseCenterX);
                        World.AbsoluteCameraPosition.X += dx * World.AbsoluteCameraSide.X;
                        World.AbsoluteCameraPosition.Y += dx * World.AbsoluteCameraSide.Y;
                        World.AbsoluteCameraPosition.Z += dx * World.AbsoluteCameraSide.Z;
                        double dz = -0.025 * (double)(Event.motion.y - MouseCenterY);
                        World.AbsoluteCameraPosition.X += dz * World.AbsoluteCameraDirection.X;
                        World.AbsoluteCameraPosition.Y += dz * World.AbsoluteCameraDirection.Y;
                        World.AbsoluteCameraPosition.Z += dz * World.AbsoluteCameraDirection.Z;
                        ReducedMode = false;
                    }
                    break;

                // key down
                case SDL.SDL_EventType.SDL_KEYDOWN:
                    switch (Event.key.keysym.sym)
                    {
                    case SDL.SDL_Keycode.SDLK_LSHIFT:
                    case SDL.SDL_Keycode.SDLK_RSHIFT:
                        ShiftPressed = true;
                        break;

                    case SDL.SDL_Keycode.SDLK_F5:
                        // reset
                        ReducedMode      = false;
                        LightingRelative = -1.0;
                        Game.Reset();
                        TextureManager.UnuseAllTextures();
                        Fonts.Initialize();
                        Interface.ClearMessages();
                        for (int i = 0; i < Files.Length; i++)
                        {
                                                                        #if !DEBUG
                            try {
                                                                                #endif
                            ObjectManager.UnifiedObject o = ObjectManager.LoadObject(Files[i], System.Text.Encoding.UTF8, ObjectManager.ObjectLoadMode.Normal, false, false, false);
                            ObjectManager.CreateObject(o, new World.Vector3D(0.0, 0.0, 0.0), new World.Transformation(0.0, 0.0, 0.0), new World.Transformation(0.0, 0.0, 0.0), true, 0.0, 0.0, 25.0, 0.0);
                                                                                #if !DEBUG
                        }
                        catch (Exception ex) {
                            Interface.AddMessage(Interface.MessageType.Critical, false, "Unhandled error (" + ex.Message + ") encountered while processing the file " + Files[i] + ".");
                        }
                                                                        #endif
                        }
                        ObjectManager.InitializeVisibility();
                        ObjectManager.UpdateVisibility(0.0, true);
                        ObjectManager.UpdateAnimatedWorldObjects(0.01, true);
                        break;

                    case SDL.SDL_Keycode.SDLK_F7:
                    {
                        OpenFileDialog Dialog = new OpenFileDialog();
                        Dialog.CheckFileExists = true;
                        Dialog.Multiselect     = true;
                        Dialog.Filter          = "CSV/B3D/X/ANIMATED files|*.csv;*.b3d;*.x;*.animated|All files|*";
                        if (Dialog.ShowDialog() == DialogResult.OK)
                        {
                            string[] f = Dialog.FileNames;
                            int      n = Files.Length;
                            Array.Resize <string>(ref Files, n + f.Length);
                            for (int i = 0; i < f.Length; i++)
                            {
                                Files[n + i] = f[i];
                            }
                            // reset
                            ReducedMode      = false;
                            LightingRelative = -1.0;
                            Game.Reset();
                            TextureManager.UnuseAllTextures();
                            Fonts.Initialize();
                            Interface.ClearMessages();
                            for (int i = 0; i < Files.Length; i++)
                            {
                                                                                        #if !DEBUG
                                try {
                                                                                                #endif
                                ObjectManager.UnifiedObject o = ObjectManager.LoadObject(Files[i], System.Text.Encoding.UTF8, ObjectManager.ObjectLoadMode.Normal, false, false, false);
                                ObjectManager.CreateObject(o, new World.Vector3D(0.0, 0.0, 0.0), new World.Transformation(0.0, 0.0, 0.0), new World.Transformation(0.0, 0.0, 0.0), true, 0.0, 0.0, 25.0, 0.0);
                                                                                                #if !DEBUG
                            }
                            catch (Exception ex) {
                                Interface.AddMessage(Interface.MessageType.Critical, false, "Unhandled error (" + ex.Message + ") encountered while processing the file " + Files[i] + ".");
                            }
                                                                                        #endif
                            }
                            ObjectManager.InitializeVisibility();
                            ObjectManager.FinishCreatingObjects();
                            ObjectManager.UpdateVisibility(0.0, true);
                            ObjectManager.UpdateAnimatedWorldObjects(0.01, true);
                        }
                    } break;

                    case SDL.SDL_Keycode.SDLK_F9:
                        if (Interface.MessageCount != 0)
                        {
                            formMessages.ShowMessages();
                        }
                        break;

                    case SDL.SDL_Keycode.SDLK_DELETE:
                        ReducedMode      = false;
                        LightingRelative = -1.0;
                        Game.Reset();
                        TextureManager.UnuseAllTextures();
                        Fonts.Initialize();
                        Interface.ClearMessages();
                        Files = new string[] { };
                        UpdateCaption();
                        break;

                    case SDL.SDL_Keycode.SDLK_LEFT:
                        RotateX     = -1;
                        ReducedMode = false;
                        break;

                    case SDL.SDL_Keycode.SDLK_RIGHT:
                        RotateX     = 1;
                        ReducedMode = false;
                        break;

                    case SDL.SDL_Keycode.SDLK_UP:
                        RotateY     = -1;
                        ReducedMode = false;
                        break;

                    case SDL.SDL_Keycode.SDLK_DOWN:
                        RotateY     = 1;
                        ReducedMode = false;
                        break;

                    case SDL.SDL_Keycode.SDLK_a:
                    case SDL.SDL_Keycode.SDLK_KP_4:
                        MoveX       = -1;
                        ReducedMode = false;
                        break;

                    case SDL.SDL_Keycode.SDLK_d:
                    case SDL.SDL_Keycode.SDLK_KP_6:
                        MoveX       = 1;
                        ReducedMode = false;
                        break;

                    case SDL.SDL_Keycode.SDLK_KP_8:
                        MoveY       = 1;
                        ReducedMode = false;
                        break;

                    case SDL.SDL_Keycode.SDLK_KP_2:
                        MoveY       = -1;
                        ReducedMode = false;
                        break;

                    case SDL.SDL_Keycode.SDLK_w:
                    case SDL.SDL_Keycode.SDLK_KP_9:
                        MoveZ       = 1;
                        ReducedMode = false;
                        break;

                    case SDL.SDL_Keycode.SDLK_s:
                    case SDL.SDL_Keycode.SDLK_KP_3:
                        MoveZ       = -1;
                        ReducedMode = false;
                        break;

                    case SDL.SDL_Keycode.SDLK_KP_5:
                        ResetCamera();
                        break;

                    case SDL.SDL_Keycode.SDLK_f:
                    case SDL.SDL_Keycode.SDLK_F1:
                        Renderer.OptionWireframe = !Renderer.OptionWireframe;
                        if (Renderer.OptionWireframe)
                        {
                            GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line);
                        }
                        else
                        {
                            GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill);
                        } break;

                    case SDL.SDL_Keycode.SDLK_n:
                    case SDL.SDL_Keycode.SDLK_F2:
                        Renderer.OptionNormals = !Renderer.OptionNormals;
                        break;

                    case SDL.SDL_Keycode.SDLK_l:
                    case SDL.SDL_Keycode.SDLK_F3:
                        LightingTarget = 1 - LightingTarget;
                        ReducedMode    = false;
                        break;

                    case SDL.SDL_Keycode.SDLK_i:
                    case SDL.SDL_Keycode.SDLK_F4:
                        Renderer.OptionInterface = !Renderer.OptionInterface;
                        ReducedMode = false;
                        break;

                    case SDL.SDL_Keycode.SDLK_g:
                    case SDL.SDL_Keycode.SDLK_c:
                        Renderer.OptionCoordinateSystem = !Renderer.OptionCoordinateSystem;
                        ReducedMode = false;
                        break;

                    case SDL.SDL_Keycode.SDLK_b:
                        if (ShiftPressed)
                        {
                            ColorDialog dialog = new ColorDialog();
                            dialog.FullOpen = true;
                            if (dialog.ShowDialog() == DialogResult.OK)
                            {
                                Renderer.BackgroundColor = -1;
                                Renderer.ApplyBackgroundColor(dialog.Color.R, dialog.Color.G, dialog.Color.B);
                            }
                        }
                        else
                        {
                            Renderer.BackgroundColor++;
                            if (Renderer.BackgroundColor >= Renderer.MaxBackgroundColor)
                            {
                                Renderer.BackgroundColor = 0;
                            }
                            Renderer.ApplyBackgroundColor();
                        }
                        ReducedMode = false;
                        break;
                    }
                    break;

                // key up
                case SDL.SDL_EventType.SDL_KEYUP:
                    switch (Event.key.keysym.sym)
                    {
                    case SDL.SDL_Keycode.SDLK_LSHIFT:
                    case SDL.SDL_Keycode.SDLK_RSHIFT:
                        ShiftPressed = false;
                        break;

                    case SDL.SDL_Keycode.SDLK_LEFT:
                    case SDL.SDL_Keycode.SDLK_RIGHT:
                        RotateX = 0;
                        break;

                    case SDL.SDL_Keycode.SDLK_UP:
                    case SDL.SDL_Keycode.SDLK_DOWN:
                        RotateY = 0;
                        break;

                    case SDL.SDL_Keycode.SDLK_a:
                    case SDL.SDL_Keycode.SDLK_d:
                    case SDL.SDL_Keycode.SDLK_KP_4:
                    case SDL.SDL_Keycode.SDLK_KP_6:
                        MoveX = 0;
                        break;

                    case SDL.SDL_Keycode.SDLK_KP_8:
                    case SDL.SDL_Keycode.SDLK_KP_2:
                        MoveY = 0;
                        break;

                    case SDL.SDL_Keycode.SDLK_w:
                    case SDL.SDL_Keycode.SDLK_s:
                    case SDL.SDL_Keycode.SDLK_KP_9:
                    case SDL.SDL_Keycode.SDLK_KP_3:
                        MoveZ = 0;
                        break;
                    }
                    break;
                }
            }
        }
Пример #12
0
            internal void UpdateTopplingCantAndSpring()
            {
                if (CarSections.Length != 0)
                {
                    //FRONT BOGIE

                    // get direction, up and side vectors
                    double dx, dy, dz;
                    double ux, uy, uz;
                    double sx, sy, sz;
                    {
                        dx = FrontAxle.Follower.WorldPosition.X -
                             RearAxle.Follower.WorldPosition.X;
                        dy = FrontAxle.Follower.WorldPosition.Y -
                             RearAxle.Follower.WorldPosition.Y;
                        dz = FrontAxle.Follower.WorldPosition.Z -
                             RearAxle.Follower.WorldPosition.Z;
                        double t = 1.0 / Math.Sqrt(dx * dx + dy * dy + dz * dz);
                        dx *= t;
                        dy *= t;
                        dz *= t;
                        t   = 1.0 / Math.Sqrt(dx * dx + dz * dz);
                        double ex = dx * t;
                        double ez = dz * t;
                        sx = ez;
                        sy = 0.0;
                        sz = -ex;
                        World.Cross(dx, dy, dz, sx, sy, sz, out ux, out uy, out uz);
                    }
                    // cant and radius

                    //TODO: This currently uses the figures from the base car
                    // apply position due to cant/toppling
                    {
                        double a = baseCar.Specs.CurrentRollDueToTopplingAngle +
                                   baseCar.Specs.CurrentRollDueToCantAngle;
                        double x  = Math.Sign(a) * 0.5 * Game.RouteRailGauge * (1.0 - Math.Cos(a));
                        double y  = Math.Abs(0.5 * Game.RouteRailGauge * Math.Sin(a));
                        double cx = sx * x + ux * y;
                        double cy = sy * x + uy * y;
                        double cz = sz * x + uz * y;
                        FrontAxle.Follower.WorldPosition.X += cx;
                        FrontAxle.Follower.WorldPosition.Y += cy;
                        FrontAxle.Follower.WorldPosition.Z += cz;
                        RearAxle.Follower.WorldPosition.X  += cx;
                        RearAxle.Follower.WorldPosition.Y  += cy;
                        RearAxle.Follower.WorldPosition.Z  += cz;
                    }
                    // apply rolling
                    {
                        double a = -baseCar.Specs.CurrentRollDueToTopplingAngle -
                                   baseCar.Specs.CurrentRollDueToCantAngle;
                        double cosa = Math.Cos(a);
                        double sina = Math.Sin(a);
                        World.Rotate(ref sx, ref sy, ref sz, dx, dy, dz, cosa, sina);
                        World.Rotate(ref ux, ref uy, ref uz, dx, dy, dz, cosa, sina);
                        Up.X = ux;
                        Up.Y = uy;
                        Up.Z = uz;
                    }
                    // apply pitching
                    if (CurrentCarSection >= 0 &&
                        CarSections[CurrentCarSection].Overlay)
                    {
                        double a    = baseCar.Specs.CurrentPitchDueToAccelerationAngle;
                        double cosa = Math.Cos(a);
                        double sina = Math.Sin(a);
                        World.Rotate(ref dx, ref dy, ref dz, sx, sy, sz, cosa, sina);
                        World.Rotate(ref ux, ref uy, ref uz, sx, sy, sz, cosa, sina);
                        double cx = 0.5 *
                                    (FrontAxle.Follower.WorldPosition.X +
                                     RearAxle.Follower.WorldPosition.X);
                        double cy = 0.5 *
                                    (FrontAxle.Follower.WorldPosition.Y +
                                     RearAxle.Follower.WorldPosition.Y);
                        double cz = 0.5 *
                                    (FrontAxle.Follower.WorldPosition.Z +
                                     RearAxle.Follower.WorldPosition.Z);
                        FrontAxle.Follower.WorldPosition.X -= cx;
                        FrontAxle.Follower.WorldPosition.Y -= cy;
                        FrontAxle.Follower.WorldPosition.Z -= cz;
                        RearAxle.Follower.WorldPosition.X  -= cx;
                        RearAxle.Follower.WorldPosition.Y  -= cy;
                        RearAxle.Follower.WorldPosition.Z  -= cz;
                        World.Rotate(ref FrontAxle.Follower.WorldPosition, sx, sy, sz, cosa, sina);
                        World.Rotate(ref RearAxle.Follower.WorldPosition, sx, sy, sz, cosa, sina);
                        FrontAxle.Follower.WorldPosition.X += cx;
                        FrontAxle.Follower.WorldPosition.Y += cy;
                        FrontAxle.Follower.WorldPosition.Z += cz;
                        RearAxle.Follower.WorldPosition.X  += cx;
                        RearAxle.Follower.WorldPosition.Y  += cy;
                        RearAxle.Follower.WorldPosition.Z  += cz;
                        Up.X = ux;
                        Up.Y = uy;
                        Up.Z = uz;
                    }
                }
            }
Пример #13
0
 private static void RenderCube(Vector3 Position, Vector3 Direction, Vector3 Up, Vector3 Side, double Size, double CameraX, double CameraY, double CameraZ, Textures.Texture TextureIndex)
 {
     Vector3[] v = new Vector3[8];
     v[0] = new Vector3(Size, Size, -Size);
     v[1] = new Vector3(Size, -Size, -Size);
     v[2] = new Vector3(-Size, -Size, -Size);
     v[3] = new Vector3(-Size, Size, -Size);
     v[4] = new Vector3(Size, Size, Size);
     v[5] = new Vector3(Size, -Size, Size);
     v[6] = new Vector3(-Size, -Size, Size);
     v[7] = new Vector3(-Size, Size, Size);
     for (int i = 0; i < 8; i++)
     {
         World.Rotate(ref v[i].X, ref v[i].Y, ref v[i].Z, Direction.X, Direction.Y, Direction.Z, Up.X, Up.Y, Up.Z, Side.X, Side.Y, Side.Z);
         v[i].X += Position.X - CameraX;
         v[i].Y += Position.Y - CameraY;
         v[i].Z += Position.Z - CameraZ;
     }
     int[][] Faces = new int[6][];
     Faces[0] = new int[] { 0, 1, 2, 3 };
     Faces[1] = new int[] { 0, 4, 5, 1 };
     Faces[2] = new int[] { 0, 3, 7, 4 };
     Faces[3] = new int[] { 6, 5, 4, 7 };
     Faces[4] = new int[] { 6, 7, 3, 2 };
     Faces[5] = new int[] { 6, 2, 1, 5 };
     if (TextureIndex == null || !Textures.LoadTexture(TextureIndex, Textures.OpenGlTextureWrapMode.ClampClamp))
     {
         if (TexturingEnabled)
         {
             GL.Disable(EnableCap.Texture2D);
             TexturingEnabled = false;
         }
         for (int i = 0; i < 6; i++)
         {
             GL.Begin(PrimitiveType.Quads);
             GL.Color3(1.0, 1.0, 1.0);
             for (int j = 0; j < 4; j++)
             {
                 GL.Vertex3(v[Faces[i][j]].X, v[Faces[i][j]].Y, v[Faces[i][j]].Z);
             }
             GL.End();
         }
         return;
     }
     else
     {
         TexturingEnabled = true;
         GL.Enable(EnableCap.Texture2D);
     }
     GL.BindTexture(TextureTarget.Texture2D, TextureIndex.OpenGlTextures[(int)Textures.OpenGlTextureWrapMode.ClampClamp].Name);
     Vector2[][] t = new Vector2[6][];
     t[0] = new Vector2[] { new Vector2(1.0, 0.0), new Vector2(1.0, 1.0), new Vector2(0.0, 1.0), new Vector2(0.0, 0.0) };
     t[1] = new Vector2[] { new Vector2(0.0, 0.0), new Vector2(1.0, 0.0), new Vector2(1.0, 1.0), new Vector2(0.0, 1.0) };
     t[2] = new Vector2[] { new Vector2(1.0, 1.0), new Vector2(0.0, 1.0), new Vector2(0.0, 0.0), new Vector2(1.0, 0.0) };
     t[3] = new Vector2[] { new Vector2(1.0, 1.0), new Vector2(0.0, 1.0), new Vector2(0.0, 0.0), new Vector2(1.0, 0.0) };
     t[4] = new Vector2[] { new Vector2(0.0, 1.0), new Vector2(0.0, 0.0), new Vector2(1.0, 0.0), new Vector2(1.0, 1.0) };
     t[5] = new Vector2[] { new Vector2(0.0, 1.0), new Vector2(0.0, 0.0), new Vector2(1.0, 0.0), new Vector2(1.0, 1.0) };
     for (int i = 0; i < 6; i++)
     {
         GL.Begin(PrimitiveType.Quads);
         GL.Color3(1.0, 1.0, 1.0);
         for (int j = 0; j < 4; j++)
         {
             GL.TexCoord2(t[i][j].X, t[i][j].Y);
             GL.Vertex3(v[Faces[i][j]].X, v[Faces[i][j]].Y, v[Faces[i][j]].Z);
         }
         GL.End();
     }
 }