Represents a three-dimensional vector.
Exemple #1
0
 // constructors
 /// <summary>Creates a new instance of this class.</summary>
 /// <param name="ambientLight">The ambient light color.</param>
 /// <param name="diffuseLight">The diffuse light color.</param>
 /// <param name="specularLight">The specular light color.</param>
 /// <param name="lightDirection">The direction the light shines at.</param>
 public DirectionalLight(Color.ColorRGB ambientLight, Color.ColorRGB diffuseLight, Color.ColorRGB specularLight, Math.Vector3 lightDirection)
 {
     this.AmbientLight = ambientLight;
     this.DiffuseLight = diffuseLight;
     this.SpecularLight = specularLight;
     this.LightDirection = lightDirection;
 }
Exemple #2
0
            /// <summary>Releases the emergency brake</summary>
            internal void UnapplyEmergencyBrake()
            {
                if (Handles.EmergencyBrake.Driver)
                {
                    // sound
                    Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.BrakeHandleRelease.Buffer;
                    if (buffer != null)
                    {
                        OpenBveApi.Math.Vector3 pos = Cars[DriverCar].Sounds.BrakeHandleRelease.Position;
                        Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false);
                    }

                    // apply

                    if (Handles.Brake is AirBrakeHandle)
                    {
                        ApplyAirBrakeHandle(AirBrakeHandleState.Service);
                    }
                    else
                    {
                        ApplyNotch(0, !Handles.SingleHandle, Handles.Brake.MaximumNotch, true);
                    }
                    Handles.EmergencyBrake.Driver = false;
                    // plugin
                    if (Plugin == null)
                    {
                        return;
                    }
                    Plugin.UpdatePower();
                    Plugin.UpdateBrake();
                }
            }
Exemple #3
0
        /// <summary>Draws a 3D cube</summary>
        /// <param name="VAO"></param>
        /// <param name="Position">The position in world-space</param>
        /// <param name="Direction">The direction vector</param>
        /// <param name="Up">The up vector</param>
        /// <param name="Side">The side vector</param>
        /// <param name="Size">A 3D vector describing the size of the cube</param>
        /// <param name="Camera">The camera position</param>
        /// <param name="TextureIndex">The texture to apply</param>
        public void Draw(VertexArrayObject VAO, OpenBveApi.Math.Vector3 Position, OpenBveApi.Math.Vector3 Direction, OpenBveApi.Math.Vector3 Up, OpenBveApi.Math.Vector3 Side, OpenBveApi.Math.Vector3 Size, OpenBveApi.Math.Vector3 Camera, Texture TextureIndex)
        {
            renderer.DefaultShader.Activate();
            renderer.ResetShader(renderer.DefaultShader);

            // matrix
            renderer.DefaultShader.SetCurrentProjectionMatrix(renderer.CurrentProjectionMatrix);
            renderer.DefaultShader.SetCurrentModelViewMatrix(Matrix4D.Scale(Size) * (Matrix4D) new Transformation(Direction, Up, Side) * Matrix4D.CreateTranslation(Position.X - Camera.X, Position.Y - Camera.Y, -Position.Z + Camera.Z) * renderer.CurrentViewMatrix);

            // texture
            if (TextureIndex != null && renderer.currentHost.LoadTexture(TextureIndex, OpenGlTextureWrapMode.ClampClamp))
            {
                renderer.DefaultShader.SetIsTexture(true);
                renderer.DefaultShader.SetTexture(0);

                GL.Enable(EnableCap.Texture2D);
                GL.BindTexture(TextureTarget.Texture2D, TextureIndex.OpenGlTextures[(int)OpenGlTextureWrapMode.ClampClamp].Name);
            }
            else
            {
                GL.Disable(EnableCap.Texture2D);
            }

            // render polygon
            VAO.Bind();
            VAO.Draw(renderer.DefaultShader.VertexLayout, PrimitiveType.Quads);
            VAO.UnBind();

            GL.BindTexture(TextureTarget.Texture2D, 0);
            renderer.DefaultShader.Deactivate();

            GL.Disable(EnableCap.Texture2D);
        }
Exemple #4
0
 internal void CreateObject(UnifiedObject Prototype, Vector3 Position, Transformation BaseTransformation, Transformation AuxTransformation, bool AccurateObjectDisposal, double StartingDistance, double EndingDistance, double BlockLength, double TrackPosition)
 {
     if (Prototype != null)
     {
         CreateObject(Prototype, Position, BaseTransformation, AuxTransformation, -1, AccurateObjectDisposal, StartingDistance, EndingDistance, BlockLength, TrackPosition, 1.0);
     }
 }
Exemple #5
0
            /// <summary>Applies a loco brake notch to this train</summary>
            /// <param name="NotchValue">The loco brake notch value</param>
            /// <param name="Relative">Whether this is relative to the current notch</param>
            internal void ApplyLocoBrakeNotch(int NotchValue, bool Relative)
            {
                int b = Relative ? NotchValue + Handles.LocoBrake.Driver : NotchValue;

                if (b < 0)
                {
                    b = 0;
                }
                else if (b > Handles.LocoBrake.MaximumNotch)
                {
                    b = Handles.LocoBrake.MaximumNotch;
                }

                // brake sound
                if (b < Handles.LocoBrake.Driver)
                {
                    // brake release
                    Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.Brake.Buffer;
                    if (buffer != null)
                    {
                        OpenBveApi.Math.Vector3 pos = Cars[DriverCar].Sounds.Brake.Position;
                        Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false);
                    }

                    if (b > 0)
                    {
                        // brake release (not min)
                        buffer = Cars[DriverCar].Sounds.BrakeHandleRelease.Buffer;
                        if (buffer != null)
                        {
                            OpenBveApi.Math.Vector3 pos = Cars[DriverCar].Sounds.BrakeHandleRelease.Position;
                            Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false);
                        }
                    }
                    else
                    {
                        // brake min
                        buffer = Cars[DriverCar].Sounds.BrakeHandleMin.Buffer;
                        if (buffer != null)
                        {
                            OpenBveApi.Math.Vector3 pos = Cars[DriverCar].Sounds.BrakeHandleMin.Position;
                            Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false);
                        }
                    }
                }
                else if (b > Handles.LocoBrake.Driver)
                {
                    // brake
                    Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.BrakeHandleApply.Buffer;
                    if (buffer != null)
                    {
                        OpenBveApi.Math.Vector3 pos = Cars[DriverCar].Sounds.BrakeHandleApply.Position;
                        Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false);
                    }
                }

                Handles.LocoBrake.Driver = b;
                Handles.LocoBrake.Actual = b;                 //TODO: FIXME
            }
Exemple #6
0
 /// <summary>Draws a 3D cube</summary>
 /// <param name="Position">The position in world-space</param>
 /// <param name="Direction">The direction vector</param>
 /// <param name="Up">The up vector</param>
 /// <param name="Side">The side vector</param>
 /// <param name="Size">A 3D vector describing the size of the cube</param>
 /// <param name="Camera">The camera position</param>
 /// <param name="TextureIndex">The texture to apply</param>
 public void Draw(OpenBveApi.Math.Vector3 Position, OpenBveApi.Math.Vector3 Direction, OpenBveApi.Math.Vector3 Up, OpenBveApi.Math.Vector3 Side, OpenBveApi.Math.Vector3 Size, OpenBveApi.Math.Vector3 Camera, Texture TextureIndex)
 {
     if (renderer.currentOptions.IsUseNewRenderer)
     {
         Draw(defaultVAO, Position, Direction, Up, Side, Size, Camera, TextureIndex);
     }
     else
     {
         DrawImmediate(Position, Direction, Up, Side, Size, Camera, TextureIndex);
     }
 }
Exemple #7
0
        internal int CreateStaticObject(UnifiedObject Prototype, Vector3 Position, Transformation BaseTransformation, Transformation AuxTransformation, bool AccurateObjectDisposal, double AccurateObjectDisposalZOffset, double StartingDistance, double EndingDistance, double BlockLength, double TrackPosition, double Brightness)
        {
            StaticObject obj = Prototype as StaticObject;

            if (obj == null)
            {
                Interface.AddMessage(MessageType.Error, false, "Attempted to use an animated object where only static objects are allowed.");
                return(-1);
            }
            return(base.CreateStaticObject(obj, Position, BaseTransformation, AuxTransformation, AccurateObjectDisposal, AccurateObjectDisposalZOffset, StartingDistance, EndingDistance, BlockLength, TrackPosition, Brightness));
        }
Exemple #8
0
 // reset camera
 internal static void ResetCamera()
 {
     Renderer.Camera.AbsolutePosition  = new Vector3(0.0, 2.5, -5.0);
     Renderer.Camera.AbsoluteDirection = new Vector3(-Renderer.Camera.AbsolutePosition.X, -Renderer.Camera.AbsolutePosition.Y, -Renderer.Camera.AbsolutePosition.Z);
     Renderer.Camera.AbsoluteSide      = new Vector3(-Renderer.Camera.AbsolutePosition.Z, 0.0, Renderer.Camera.AbsolutePosition.X);
     Renderer.Camera.AbsoluteDirection.Normalize();
     Renderer.Camera.AbsoluteSide.Normalize();
     Renderer.Camera.AbsoluteUp                   = Vector3.Cross(Renderer.Camera.AbsoluteDirection, Renderer.Camera.AbsoluteSide);
     Renderer.Camera.VerticalViewingAngle         = 45.0.ToRadians();
     Renderer.Camera.HorizontalViewingAngle       = 2.0 * Math.Atan(Math.Tan(0.5 * Renderer.Camera.VerticalViewingAngle) * Renderer.Screen.AspectRatio);
     Renderer.Camera.OriginalVerticalViewingAngle = Renderer.Camera.VerticalViewingAngle;
 }
Exemple #9
0
 internal void CreateObject(UnifiedObject Prototype, Vector3 Position, Transformation BaseTransformation, Transformation AuxTransformation, int SectionIndex, bool AccurateObjectDisposal, double StartingDistance, double EndingDistance, double BlockLength, double TrackPosition, double Brightness)
 {
     if (Prototype is StaticObject)
     {
         StaticObject s = (StaticObject)Prototype;
         if (s.Mesh.Faces.Length == 0)
         {
             return;
         }
         CreateStaticObject(s, Position, BaseTransformation, AuxTransformation, AccurateObjectDisposal, 0.0, StartingDistance, EndingDistance, BlockLength, TrackPosition, Brightness);
     }
     else if (Prototype is AnimatedObjectCollection)
     {
         AnimatedObjectCollection a = (AnimatedObjectCollection)Prototype;
         a.CreateObject(Position, BaseTransformation, AuxTransformation, SectionIndex, AccurateObjectDisposal, StartingDistance, EndingDistance, BlockLength, TrackPosition, Brightness, true);
     }
 }
Exemple #10
0
 /// <summary>May be called from a .Net plugin, in order to play a sound from a specific car of a train</summary>
 /// <param name="index">The plugin-based of the sound to play</param>
 /// <param name="volume">The volume of the sound- A volume of 1.0 represents nominal volume</param>
 /// <param name="pitch">The pitch of the sound- A pitch of 1.0 represents nominal pitch</param>
 /// <param name="looped">Whether the sound is looped</param>
 /// <param name="CarIndex">The index of the car which is to emit the sound</param>
 /// <returns>The sound handle, or null if not successful</returns>
 internal SoundHandleEx PlaySound(int index, double volume, double pitch, bool looped, int CarIndex)
 {
     if (index >= 0 && index < this.Train.Cars[this.Train.DriverCar].Sounds.Plugin.Length && this.Train.Cars[this.Train.DriverCar].Sounds.Plugin[index].Buffer != null && CarIndex < this.Train.Cars.Length && CarIndex >= 0)
     {
         SoundBuffer buffer = Train.Cars[Train.DriverCar].Sounds.Plugin[index].Buffer;
         OpenBveApi.Math.Vector3 position = this.Train.Cars[this.Train.DriverCar].Sounds.Plugin[index].Position;
         SoundSource source = Program.Sounds.PlaySound(buffer, pitch, volume, position, Train.Cars[CarIndex], looped);
         if (this.SoundHandlesCount == this.SoundHandles.Length)
         {
             Array.Resize(ref this.SoundHandles, this.SoundHandles.Length << 1);
         }
         this.SoundHandles[this.SoundHandlesCount] = new SoundHandleEx(volume, pitch, source);
         this.SoundHandlesCount++;
         return(this.SoundHandles[this.SoundHandlesCount - 1]);
     }
     return(null);
 }
Exemple #11
0
            /// <summary>Applies a reverser notch</summary>
            /// <param name="Value">The notch to apply</param>
            /// <param name="Relative">Whether this is an absolute value or relative to the previous</param>
            internal void ApplyReverser(int Value, bool Relative)
            {
                int a = (int)Handles.Reverser.Driver;
                int r = Relative ? a + Value : Value;

                if (r < -1)
                {
                    r = -1;
                }
                if (r > 1)
                {
                    r = 1;
                }
                if (a != r)
                {
                    Handles.Reverser.Driver = (ReverserPosition)r;
                    if (Plugin != null)
                    {
                        Plugin.UpdateReverser();
                    }
                    Game.AddBlackBoxEntry(Game.BlackBoxEventToken.None);
                    // sound
                    if (a == 0 & r != 0)
                    {
                        Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.ReverserOn.Buffer;
                        if (buffer == null)
                        {
                            return;
                        }
                        OpenBveApi.Math.Vector3 pos = Cars[DriverCar].Sounds.ReverserOn.Position;
                        Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false);
                    }
                    else if (a != 0 & r == 0)
                    {
                        Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.ReverserOff.Buffer;
                        if (buffer == null)
                        {
                            return;
                        }
                        OpenBveApi.Math.Vector3 pos = Cars[DriverCar].Sounds.ReverserOff.Position;
                        Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false);
                    }
                }
            }
Exemple #12
0
 internal static void MouseEvent(object sender, MouseButtonEventArgs e)
 {
     MouseCameraPosition  = Camera.AbsolutePosition;
     MouseCameraDirection = Camera.AbsoluteDirection;
     MouseCameraUp        = Camera.AbsoluteUp;
     MouseCameraSide      = Camera.AbsoluteSide;
     if (e.Button == OpenTK.Input.MouseButton.Left)
     {
         MouseButton = e.Mouse.LeftButton == ButtonState.Pressed ? 1 : 0;
     }
     if (e.Button == OpenTK.Input.MouseButton.Right)
     {
         MouseButton = e.Mouse.RightButton == ButtonState.Pressed ? 2 : 0;
     }
     if (e.Button == OpenTK.Input.MouseButton.Middle)
     {
         MouseButton = e.Mouse.RightButton == ButtonState.Pressed ? 3 : 0;
     }
     previousMouseState = Mouse.GetState();
 }
Exemple #13
0
        // render scene
        internal void RenderScene(double TimeElapsed)
        {
            // initialize
            ResetOpenGlState();

            if (OptionWireFrame)
            {
                if (Program.CurrentRoute.CurrentFog.Start < Program.CurrentRoute.CurrentFog.End)
                {
                    const float fogDistance = 600.0f;
                    float       n           = (fogDistance - Program.CurrentRoute.CurrentFog.Start) / (Program.CurrentRoute.CurrentFog.End - Program.CurrentRoute.CurrentFog.Start);
                    float       cr          = n * inv255 * Program.CurrentRoute.CurrentFog.Color.R;
                    float       cg          = n * inv255 * Program.CurrentRoute.CurrentFog.Color.G;
                    float       cb          = n * inv255 * Program.CurrentRoute.CurrentFog.Color.B;
                    GL.ClearColor(cr, cg, cb, 1.0f);
                }
                else
                {
                    GL.ClearColor(0.0f, 0.0f, 0.0f, 1.0f);
                }
            }

            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

            UpdateViewport(ViewportChangeMode.ChangeToScenery);

            // set up camera
            CurrentViewMatrix = Matrix4D.LookAt(Vector3.Zero, new Vector3(Camera.AbsoluteDirection.X, Camera.AbsoluteDirection.Y, -Camera.AbsoluteDirection.Z), new Vector3(Camera.AbsoluteUp.X, Camera.AbsoluteUp.Y, -Camera.AbsoluteUp.Z));
            if (!AvailableNewRenderer)
            {
                GL.Light(LightName.Light0, LightParameter.Position, new[] { (float)Lighting.OptionLightPosition.X, (float)Lighting.OptionLightPosition.Y, (float)-Lighting.OptionLightPosition.Z, 0.0f });
            }

            Lighting.OptionLightingResultingAmount = (Lighting.OptionAmbientColor.R + Lighting.OptionAmbientColor.G + Lighting.OptionAmbientColor.B) / 480.0f;

            if (Lighting.OptionLightingResultingAmount > 1.0f)
            {
                Lighting.OptionLightingResultingAmount = 1.0f;
            }
            // fog
            double fd = Program.CurrentRoute.NextFog.TrackPosition - Program.CurrentRoute.PreviousFog.TrackPosition;

            if (fd != 0.0)
            {
                float fr  = (float)((CameraTrackFollower.TrackPosition - Program.CurrentRoute.PreviousFog.TrackPosition) / fd);
                float frc = 1.0f - fr;
                Program.CurrentRoute.CurrentFog.Start   = Program.CurrentRoute.PreviousFog.Start * frc + Program.CurrentRoute.NextFog.Start * fr;
                Program.CurrentRoute.CurrentFog.End     = Program.CurrentRoute.PreviousFog.End * frc + Program.CurrentRoute.NextFog.End * fr;
                Program.CurrentRoute.CurrentFog.Color.R = (byte)(Program.CurrentRoute.PreviousFog.Color.R * frc + Program.CurrentRoute.NextFog.Color.R * fr);
                Program.CurrentRoute.CurrentFog.Color.G = (byte)(Program.CurrentRoute.PreviousFog.Color.G * frc + Program.CurrentRoute.NextFog.Color.G * fr);
                Program.CurrentRoute.CurrentFog.Color.B = (byte)(Program.CurrentRoute.PreviousFog.Color.B * frc + Program.CurrentRoute.NextFog.Color.B * fr);
                if (!Program.CurrentRoute.CurrentFog.IsLinear)
                {
                    Program.CurrentRoute.CurrentFog.Density = (byte)(Program.CurrentRoute.PreviousFog.Density * frc + Program.CurrentRoute.NextFog.Density * fr);
                }
            }
            else
            {
                Program.CurrentRoute.CurrentFog = Program.CurrentRoute.PreviousFog;
            }

            // render background
            GL.Disable(EnableCap.DepthTest);
            Program.CurrentRoute.UpdateBackground(TimeElapsed, Program.Renderer.CurrentInterface != InterfaceType.Normal);

            events.Render(Camera.AbsolutePosition);

            // fog
            float aa = Program.CurrentRoute.CurrentFog.Start;
            float bb = Program.CurrentRoute.CurrentFog.End;

            if (aa < bb & aa < Program.CurrentRoute.CurrentBackground.BackgroundImageDistance)
            {
                OptionFog    = true;
                Fog.Start    = aa;
                Fog.End      = bb;
                Fog.Color    = Program.CurrentRoute.CurrentFog.Color;
                Fog.Density  = Program.CurrentRoute.CurrentFog.Density;
                Fog.IsLinear = Program.CurrentRoute.CurrentFog.IsLinear;
                Fog.SetForImmediateMode();
            }
            else
            {
                OptionFog = false;
            }

            // world layer
            // opaque face
            if (AvailableNewRenderer)
            {
                //Setup the shader for rendering the scene
                DefaultShader.Activate();
                if (OptionLighting)
                {
                    DefaultShader.SetIsLight(true);
                    TransformedLightPosition = new Vector3(Lighting.OptionLightPosition.X, Lighting.OptionLightPosition.Y, -Lighting.OptionLightPosition.Z);
                    DefaultShader.SetLightPosition(TransformedLightPosition);
                    DefaultShader.SetLightAmbient(Lighting.OptionAmbientColor);
                    DefaultShader.SetLightDiffuse(Lighting.OptionDiffuseColor);
                    DefaultShader.SetLightSpecular(Lighting.OptionSpecularColor);
                    DefaultShader.SetLightModel(Lighting.LightModel);
                }
                if (OptionFog)
                {
                    DefaultShader.SetIsFog(true);
                    DefaultShader.SetFog(Fog);
                }
                DefaultShader.SetTexture(0);
                DefaultShader.SetCurrentProjectionMatrix(CurrentProjectionMatrix);
            }
            ResetOpenGlState();
            foreach (FaceState face in VisibleObjects.OpaqueFaces)
            {
                face.Draw();
            }

            // alpha face
            ResetOpenGlState();
            VisibleObjects.SortPolygonsInAlphaFaces();
            if (Interface.CurrentOptions.TransparencyMode == TransparencyMode.Performance)
            {
                SetBlendFunc();
                SetAlphaFunc(AlphaFunction.Greater, 0.0f);
                GL.DepthMask(false);

                foreach (FaceState face in VisibleObjects.AlphaFaces)
                {
                    face.Draw();
                }
            }
            else
            {
                UnsetBlendFunc();
                SetAlphaFunc(AlphaFunction.Equal, 1.0f);
                GL.DepthMask(true);

                foreach (FaceState face in VisibleObjects.AlphaFaces)
                {
                    if (face.Object.Prototype.Mesh.Materials[face.Face.Material].BlendMode == MeshMaterialBlendMode.Normal && face.Object.Prototype.Mesh.Materials[face.Face.Material].GlowAttenuationData == 0)
                    {
                        if (face.Object.Prototype.Mesh.Materials[face.Face.Material].Color.A == 255)
                        {
                            face.Draw();
                        }
                    }
                }

                SetBlendFunc();
                SetAlphaFunc(AlphaFunction.Less, 1.0f);
                GL.DepthMask(false);
                bool additive = false;

                foreach (FaceState face in VisibleObjects.AlphaFaces)
                {
                    if (face.Object.Prototype.Mesh.Materials[face.Face.Material].BlendMode == MeshMaterialBlendMode.Additive)
                    {
                        if (!additive)
                        {
                            UnsetAlphaFunc();
                            additive = true;
                        }

                        face.Draw();
                    }
                    else
                    {
                        if (additive)
                        {
                            SetAlphaFunc();
                            additive = false;
                        }
                        face.Draw();
                    }
                }
            }

            // motion blur
            ResetOpenGlState();
            SetAlphaFunc(AlphaFunction.Greater, 0.0f);
            GL.Disable(EnableCap.DepthTest);
            GL.DepthMask(false);
            OptionLighting = false;

            if (Interface.CurrentOptions.MotionBlur != MotionBlurMode.None)
            {
                DefaultShader.Deactivate();
                MotionBlur.RenderFullscreen(Interface.CurrentOptions.MotionBlur, FrameRate, Math.Abs(Camera.CurrentSpeed));
            }
            // overlay layer
            OptionFog = false;
            UpdateViewport(ViewportChangeMode.ChangeToCab);
            if (AvailableNewRenderer)
            {
                /*
                 * We must reset the shader between overlay and world layers for correct lighting results.
                 * Additionally, the viewport change updates the projection matrix
                 */
                DefaultShader.Activate();
                ResetShader(DefaultShader);
                DefaultShader.SetCurrentProjectionMatrix(CurrentProjectionMatrix);
            }
            CurrentViewMatrix = Matrix4D.LookAt(Vector3.Zero, new Vector3(Camera.AbsoluteDirection.X, Camera.AbsoluteDirection.Y, -Camera.AbsoluteDirection.Z), new Vector3(Camera.AbsoluteUp.X, Camera.AbsoluteUp.Y, -Camera.AbsoluteUp.Z));
            if (Camera.CurrentRestriction == CameraRestrictionMode.NotAvailable || Camera.CurrentRestriction == CameraRestrictionMode.Restricted3D)
            {
                ResetOpenGlState();                 // TODO: inserted
                GL.Clear(ClearBufferMask.DepthBufferBit);
                OptionLighting = true;
                Color24 prevOptionAmbientColor = Lighting.OptionAmbientColor;
                Color24 prevOptionDiffuseColor = Lighting.OptionDiffuseColor;
                Lighting.OptionAmbientColor = Color24.LightGrey;
                Lighting.OptionDiffuseColor = Color24.LightGrey;
                if (AvailableNewRenderer)
                {
                    DefaultShader.SetIsLight(true);
                    TransformedLightPosition = new Vector3(Lighting.OptionLightPosition.X, Lighting.OptionLightPosition.Y, -Lighting.OptionLightPosition.Z);
                    DefaultShader.SetLightPosition(TransformedLightPosition);
                    DefaultShader.SetLightAmbient(Lighting.OptionAmbientColor);
                    DefaultShader.SetLightDiffuse(Lighting.OptionDiffuseColor);
                    DefaultShader.SetLightSpecular(Lighting.OptionSpecularColor);
                    DefaultShader.SetLightModel(Lighting.LightModel);
                }
                else
                {
                    GL.Light(LightName.Light0, LightParameter.Ambient, new[] { inv255 * 178, inv255 * 178, inv255 * 178, 1.0f });
                    GL.Light(LightName.Light0, LightParameter.Diffuse, new[] { inv255 * 178, inv255 * 178, inv255 * 178, 1.0f });
                }


                // overlay opaque face
                foreach (FaceState face in VisibleObjects.OverlayOpaqueFaces)
                {
                    face.Draw();
                }

                // overlay alpha face
                ResetOpenGlState();
                VisibleObjects.SortPolygonsInOverlayAlphaFaces();

                if (Interface.CurrentOptions.TransparencyMode == TransparencyMode.Performance)
                {
                    SetBlendFunc();
                    SetAlphaFunc(AlphaFunction.Greater, 0.0f);
                    GL.DepthMask(false);

                    foreach (FaceState face in VisibleObjects.OverlayAlphaFaces)
                    {
                        face.Draw();
                    }
                }
                else
                {
                    UnsetBlendFunc();
                    SetAlphaFunc(AlphaFunction.Equal, 1.0f);
                    GL.DepthMask(true);

                    foreach (FaceState face in VisibleObjects.OverlayAlphaFaces)
                    {
                        if (face.Object.Prototype.Mesh.Materials[face.Face.Material].BlendMode == MeshMaterialBlendMode.Normal && face.Object.Prototype.Mesh.Materials[face.Face.Material].GlowAttenuationData == 0)
                        {
                            if (face.Object.Prototype.Mesh.Materials[face.Face.Material].Color.A == 255)
                            {
                                face.Draw();
                            }
                        }
                    }

                    SetBlendFunc();
                    SetAlphaFunc(AlphaFunction.Less, 1.0f);
                    GL.DepthMask(false);
                    bool additive = false;

                    foreach (FaceState face in VisibleObjects.OverlayAlphaFaces)
                    {
                        if (face.Object.Prototype.Mesh.Materials[face.Face.Material].BlendMode == MeshMaterialBlendMode.Additive)
                        {
                            if (!additive)
                            {
                                UnsetAlphaFunc();
                                additive = true;
                            }

                            face.Draw();
                        }
                        else
                        {
                            if (additive)
                            {
                                SetAlphaFunc();
                                additive = false;
                            }

                            face.Draw();
                        }
                    }
                }

                Lighting.OptionAmbientColor = prevOptionAmbientColor;
                Lighting.OptionDiffuseColor = prevOptionDiffuseColor;
                Lighting.Initialize();
            }
            else
            {
                /*
                 * Render 2D Cab
                 * This is actually an animated object generated on the fly and held in memory
                 */
                ResetOpenGlState();
                OptionLighting = false;
                if (AvailableNewRenderer)
                {
                    DefaultShader.SetIsLight(false);
                }

                SetBlendFunc();
                UnsetAlphaFunc();
                GL.Disable(EnableCap.DepthTest);
                GL.DepthMask(false);
                VisibleObjects.SortPolygonsInOverlayAlphaFaces();
                foreach (FaceState face in VisibleObjects.OverlayAlphaFaces)
                {
                    face.Draw();
                }
            }
            if (AvailableNewRenderer)
            {
                /*
                 * Must remember to de-activate at the end of the render sequence if in GL3 mode.
                 * The overlays currently use immediate mode and do not work correctly with the shader active
                 */
                DefaultShader.Deactivate();
            }
            // render touch
            OptionLighting = false;
            Touch.RenderScene();

            // render overlays
            ResetOpenGlState();
            UnsetAlphaFunc();
            SetBlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);             //FIXME: Remove when text switches between two renderer types
            GL.Disable(EnableCap.DepthTest);
            overlays.Render(TimeElapsed);
            OptionLighting = true;
        }
Exemple #14
0
        /// <summary>Draws a 3D cube in immediate mode</summary>
        /// <param name="Position">The position in world-space</param>
        /// <param name="Direction">The direction vector</param>
        /// <param name="Up">The up vector</param>
        /// <param name="Side">The side vector</param>
        /// <param name="Size">A 3D vector describing the size of the cube</param>
        /// <param name="Camera">The camera position</param>
        /// <param name="TextureIndex">The texture to apply</param>
        public void DrawImmediate(OpenBveApi.Math.Vector3 Position, OpenBveApi.Math.Vector3 Direction, OpenBveApi.Math.Vector3 Up, OpenBveApi.Math.Vector3 Side, OpenBveApi.Math.Vector3 Size, OpenBveApi.Math.Vector3 Camera, Texture TextureIndex)
        {
            renderer.LastBoundTexture = null;
            GL.MatrixMode(MatrixMode.Projection);
            GL.PushMatrix();
            GL.LoadIdentity();
            OpenTK.Matrix4d perspective = OpenTK.Matrix4d.Perspective(renderer.Camera.VerticalViewingAngle, -renderer.Screen.AspectRatio, 0.2, 1000.0);
            GL.MultMatrix(ref perspective);
            double dx = renderer.Camera.AbsoluteDirection.X;
            double dy = renderer.Camera.AbsoluteDirection.Y;
            double dz = renderer.Camera.AbsoluteDirection.Z;
            double ux = renderer.Camera.AbsoluteUp.X;
            double uy = renderer.Camera.AbsoluteUp.Y;
            double uz = renderer.Camera.AbsoluteUp.Z;

            OpenTK.Matrix4d lookat = OpenTK.Matrix4d.LookAt(0.0, 0.0, 0.0, dx, dy, dz, ux, uy, uz);
            GL.MatrixMode(MatrixMode.Modelview);
            GL.PushMatrix();
            GL.LoadMatrix(ref lookat);
            Vector3[] v = new Vector3[8];
            v[0] = new Vector3(Size.X, Size.Y, -Size.Z);
            v[1] = new Vector3(Size.X, -Size.Y, -Size.Z);
            v[2] = new Vector3(-Size.X, -Size.Y, -Size.Z);
            v[3] = new Vector3(-Size.X, Size.Y, -Size.Z);
            v[4] = new Vector3(Size.X, Size.Y, Size.Z);
            v[5] = new Vector3(Size.X, -Size.Y, Size.Z);
            v[6] = new Vector3(-Size.X, -Size.Y, Size.Z);
            v[7] = new Vector3(-Size.X, Size.Y, Size.Z);
            for (int i = 0; i < 8; i++)
            {
                v[i].Rotate(Direction, Up, Side);
                v[i] += Position - Camera;
            }
            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 || !renderer.currentHost.LoadTexture(TextureIndex, OpenGlTextureWrapMode.ClampClamp))
            {
                GL.Disable(EnableCap.Texture2D);
                for (int i = 0; i < 6; i++)
                {
                    GL.Begin(PrimitiveType.Quads);
                    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;
            }
            GL.Enable(EnableCap.Texture2D);
            GL.BindTexture(TextureTarget.Texture2D, TextureIndex.OpenGlTextures[(int)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();
            }
            GL.PopMatrix();

            GL.MatrixMode(MatrixMode.Projection);
            GL.PopMatrix();
        }
Exemple #15
0
        /// <summary>Updates the sound component. Should be called every frame.</summary>
        /// <param name="timeElapsed">The time in seconds that elapsed since the last call to this function.</param>
        private static void UpdateInverseModel(double timeElapsed)
        {
            /*
             * Set up the listener.
             * */
            OpenBveApi.Math.Vector3      listenerPosition    = World.AbsoluteCameraPosition;
            OpenBveApi.Math.Orientation3 listenerOrientation = new OpenBveApi.Math.Orientation3(World.AbsoluteCameraSide, World.AbsoluteCameraUp, World.AbsoluteCameraDirection);
            OpenBveApi.Math.Vector3      listenerVelocity;
            if (World.CameraMode == World.CameraViewMode.Interior | World.CameraMode == World.CameraViewMode.InteriorLookAhead | World.CameraMode == World.CameraViewMode.Exterior)
            {
                TrainManager.Car        car  = TrainManager.PlayerTrain.Cars[TrainManager.PlayerTrain.DriverCar];
                OpenBveApi.Math.Vector3 diff = car.FrontAxle.Follower.WorldPosition - car.RearAxle.Follower.WorldPosition;
                if (diff.IsNullVector())
                {
                    listenerVelocity = car.Specs.CurrentSpeed * OpenBveApi.Math.Vector3.Forward;
                }
                else
                {
                    listenerVelocity = car.Specs.CurrentSpeed * OpenBveApi.Math.Vector3.Normalize(diff);
                }
            }
            else
            {
                listenerVelocity = OpenBveApi.Math.Vector3.Null;
            }
            AL.Listener(ALListener3f.Position, 0.0f, 0.0f, 0.0f);
            AL.Listener(ALListener3f.Velocity, (float)listenerVelocity.X, (float)listenerVelocity.Y, (float)listenerVelocity.Z);
            var Orientation = new float[] { (float)listenerOrientation.Z.X, (float)listenerOrientation.Z.Y, (float)listenerOrientation.Z.Z, -(float)listenerOrientation.Y.X, -(float)listenerOrientation.Y.Y, -(float)listenerOrientation.Y.Z };

            AL.Listener(ALListenerfv.Orientation, ref Orientation);

            /*
             * Set up the atmospheric attributes.
             * */
            double elevation      = World.AbsoluteCameraPosition.Y + Game.RouteInitialElevation;
            double airTemperature = Game.GetAirTemperature(elevation);
            double airPressure    = Game.GetAirPressure(elevation, airTemperature);
            double speedOfSound   = Game.GetSpeedOfSound(airPressure, airTemperature);

            try {
                AL.SpeedOfSound((float)speedOfSound);
            } catch { }

            /*
             * Collect all sounds that are to be played
             * and ensure that all others are stopped.
             * */
            List <SoundSourceAttenuation> toBePlayed = new List <SoundSourceAttenuation>();

            for (int i = 0; i < SourceCount; i++)
            {
                if (Sources[i].State == SoundSourceState.StopPending)
                {
                    /*
                     * The sound is still playing but is to be stopped.
                     * Stop the sound, then remove it from the list of
                     * sound sources.
                     * */
                    AL.DeleteSources(1, ref Sources[i].OpenAlSourceName);
                    Sources[i].State            = SoundSourceState.Stopped;
                    Sources[i].OpenAlSourceName = 0;
                    Sources[i] = Sources[SourceCount - 1];
                    SourceCount--;
                    i--;
                }
                else if (Sources[i].State == SoundSourceState.Stopped)
                {
                    /*
                     * The sound was already stopped. Remove it from
                     * the list of sound sources.
                     * */
                    Sources[i] = Sources[SourceCount - 1];
                    SourceCount--;
                    i--;
                }
                else if (GlobalMute)
                {
                    /*
                     * The sound is playing or about to be played, but
                     * the global mute option is enabled. Stop the sound
                     * sound if necessary, then remove it from the list
                     * of sound sources if the sound is not looping.
                     * */
                    if (Sources[i].State == SoundSourceState.Playing)
                    {
                        AL.DeleteSources(1, ref Sources[i].OpenAlSourceName);
                        Sources[i].State            = SoundSourceState.PlayPending;
                        Sources[i].OpenAlSourceName = 0;
                    }
                    if (!Sources[i].Looped)
                    {
                        Sources[i].State            = SoundSourceState.Stopped;
                        Sources[i].OpenAlSourceName = 0;
                        Sources[i] = Sources[SourceCount - 1];
                        SourceCount--;
                        i--;
                    }
                }
                else
                {
                    /*
                     * The sound is to be played or is already playing.
                     * */
                    if (Sources[i].State == SoundSourceState.Playing)
                    {
                        int state;
                        AL.GetSource(Sources[i].OpenAlSourceName, ALGetSourcei.SourceState, out state);
                        if (state != (int)ALSourceState.Initial & state != (int)ALSourceState.Playing)
                        {
                            /*
                             * The sound is not playing any longer.
                             * Remove it from the list of sound sources.
                             * */
                            AL.DeleteSources(1, ref Sources[i].OpenAlSourceName);
                            Sources[i].State            = SoundSourceState.Stopped;
                            Sources[i].OpenAlSourceName = 0;
                            Sources[i] = Sources[SourceCount - 1];
                            SourceCount--;
                            i--;
                            continue;
                        }
                    }

                    /*
                     * Calculate the gain, then add the sound
                     * to the list of sounds to be played.
                     * */
                    OpenBveApi.Math.Vector3 position;
                    switch (Sources[i].Type)
                    {
                    case SoundType.TrainCar:
                        OpenBveApi.Math.Vector3 direction;
                        var Train = (TrainManager.Train)Sources[i].Parent;
                        Train.Cars[Sources[i].Car].CreateWorldCoordinates(Sources[i].Position.X, Sources[i].Position.Y, Sources[i].Position.Z, out position.X, out position.Y, out position.Z, out direction.X, out direction.Y, out direction.Z);
                        break;

                    case SoundType.AnimatedObject:
                        var WorldSound = (ObjectManager.WorldSound)Sources[i].Parent;
                        position = WorldSound.Follower.WorldPosition + WorldSound.Position;
                        break;

                    default:
                        position = Sources[i].Position;
                        break;
                    }
                    OpenBveApi.Math.Vector3 positionDifference = position - listenerPosition;
                    double distance = positionDifference.Norm();
                    double radius   = Sources[i].Radius;
                    if (World.CameraMode == World.CameraViewMode.Interior | World.CameraMode == World.CameraViewMode.InteriorLookAhead)
                    {
                        if (Sources[i].Parent != TrainManager.PlayerTrain || Sources[i].Car != TrainManager.PlayerTrain.DriverCar)
                        {
                            radius *= 0.5;
                        }
                    }
                    double gain;
                    if (distance < 2.0 * radius)
                    {
                        gain = 1.0 - distance * distance * (4.0 * radius - distance) / (16.0 * radius * radius * radius);
                    }
                    else
                    {
                        gain = radius / distance;
                    }
                    gain *= Sources[i].Volume;
                    if (gain <= 0.0)
                    {
                        /*
                         * The gain is too low. Stop the sound if playing,
                         * but keep looping sounds pending.
                         * */
                        if (Sources[i].State == SoundSourceState.Playing)
                        {
                            AL.DeleteSources(1, ref Sources[i].OpenAlSourceName);
                            Sources[i].State            = SoundSourceState.PlayPending;
                            Sources[i].OpenAlSourceName = 0;
                        }
                        if (!Sources[i].Looped)
                        {
                            Sources[i].State            = SoundSourceState.Stopped;
                            Sources[i].OpenAlSourceName = 0;
                            Sources[i] = Sources[SourceCount - 1];
                            SourceCount--;
                            i--;
                        }
                    }
                    else
                    {
                        /*
                         * Add the source.
                         * */
                        toBePlayed.Add(new SoundSourceAttenuation(Sources[i], gain, distance));
                    }
                }
            }

            /*
             * Now that we have the list of sounds that are to be played,
             * sort them by their gain so that we can determine and
             * adjust the clamp factor.
             * */
            double clampFactor = Math.Exp(LogClampFactor);

            for (int i = 0; i < toBePlayed.Count; i++)
            {
                toBePlayed[i].Gain -= clampFactor * toBePlayed[i].Distance * toBePlayed[i].Distance;
            }
            toBePlayed.Sort();
            for (int i = 0; i < toBePlayed.Count; i++)
            {
                toBePlayed[i].Gain += clampFactor * toBePlayed[i].Distance * toBePlayed[i].Distance;
            }
            double desiredLogClampFactor;
            int    index = Interface.CurrentOptions.SoundNumber;

            if (toBePlayed.Count <= index)
            {
                desiredLogClampFactor = MinLogClampFactor;
            }
            else
            {
                double cutoffDistance = toBePlayed[index].Distance;
                if (cutoffDistance <= 0.0)
                {
                    desiredLogClampFactor = MaxLogClampFactor;
                }
                else
                {
                    double cutoffGain = toBePlayed[index].Gain;
                    desiredLogClampFactor = Math.Log(cutoffGain / (cutoffDistance * cutoffDistance));
                    if (desiredLogClampFactor < MinLogClampFactor)
                    {
                        desiredLogClampFactor = MinLogClampFactor;
                    }
                    else if (desiredLogClampFactor > MaxLogClampFactor)
                    {
                        desiredLogClampFactor = MaxLogClampFactor;
                    }
                }
            }
            const double rate = 3.0;

            if (LogClampFactor < desiredLogClampFactor)
            {
                LogClampFactor += timeElapsed * rate;
                if (LogClampFactor > desiredLogClampFactor)
                {
                    LogClampFactor = desiredLogClampFactor;
                }
            }
            else if (LogClampFactor > desiredLogClampFactor)
            {
                LogClampFactor -= timeElapsed * rate;
                if (LogClampFactor < desiredLogClampFactor)
                {
                    LogClampFactor = desiredLogClampFactor;
                }
            }

            /*
             * Play the sounds.
             * */
            clampFactor = Math.Exp(LogClampFactor);
            for (int i = index; i < toBePlayed.Count; i++)
            {
                toBePlayed[i].Gain = 0.0;
            }
            for (int i = 0; i < toBePlayed.Count; i++)
            {
                SoundSource source = toBePlayed[i].Source;
                double      gain   = toBePlayed[i].Gain - clampFactor * toBePlayed[i].Distance * toBePlayed[i].Distance;
                if (gain <= 0.0)
                {
                    /*
                     * Stop the sound.
                     * */
                    if (source.State == SoundSourceState.Playing)
                    {
                        AL.DeleteSources(1, ref source.OpenAlSourceName);
                        source.State            = SoundSourceState.PlayPending;
                        source.OpenAlSourceName = 0;
                    }
                    if (!source.Looped)
                    {
                        source.State            = SoundSourceState.Stopped;
                        source.OpenAlSourceName = 0;
                    }
                }
                else
                {
                    /*
                     * Ensure the buffer is loaded, then play the sound.
                     * */
                    if (source.State != SoundSourceState.Playing)
                    {
                        LoadBuffer(source.Buffer);
                        if (source.Buffer.Loaded)
                        {
                            AL.GenSources(1, out source.OpenAlSourceName);
                            AL.Source(source.OpenAlSourceName, ALSourcei.Buffer, source.Buffer.OpenAlBufferName);
                        }
                        else
                        {
                            /*
                             * We cannot play the sound because
                             * the buffer could not be loaded.
                             * */
                            source.State = SoundSourceState.Stopped;
                            continue;
                        }
                    }
                    OpenBveApi.Math.Vector3 position;
                    OpenBveApi.Math.Vector3 velocity;
                    switch (source.Type)
                    {
                    case SoundType.TrainCar:
                        OpenBveApi.Math.Vector3 direction;
                        var Train = (TrainManager.Train)source.Parent;
                        Train.Cars[source.Car].CreateWorldCoordinates(source.Position.X, source.Position.Y, source.Position.Z, out position.X, out position.Y, out position.Z, out direction.X, out direction.Y, out direction.Z);
                        velocity = Train.Cars[source.Car].Specs.CurrentSpeed * direction;
                        break;

                    case SoundType.AnimatedObject:
                        var WorldSound = (ObjectManager.WorldSound)source.Parent;
                        position = WorldSound.Follower.WorldPosition + WorldSound.Position;
                        velocity = OpenBveApi.Math.Vector3.Null;
                        break;

                    default:
                        position = source.Position;
                        velocity = OpenBveApi.Math.Vector3.Null;
                        break;
                    }
                    position -= listenerPosition;
                    AL.Source(source.OpenAlSourceName, ALSource3f.Position, (float)position.X, (float)position.Y, (float)position.Z);
                    AL.Source(source.OpenAlSourceName, ALSource3f.Velocity, (float)velocity.X, (float)velocity.Y, (float)velocity.Z);
                    AL.Source(source.OpenAlSourceName, ALSourcef.Pitch, (float)source.Pitch);
                    AL.Source(source.OpenAlSourceName, ALSourcef.Gain, (float)gain);
                    if (source.State != SoundSourceState.Playing)
                    {
                        AL.Source(source.OpenAlSourceName, ALSourceb.Looping, source.Looped);
                        AL.SourcePlay(source.OpenAlSourceName);
                        source.State = SoundSourceState.Playing;
                    }
                }
            }
        }
Exemple #16
0
 // constructors
 /// <summary>Creates a new instance of this class.</summary>
 /// <param name="position">The default position of the camera.</param>
 /// <param name="orientation">The default orientation of the camera.</param>
 /// <param name="lightingModel">The lighting model used by this route.</param>
 public RouteData(Math.Vector3 position, Math.Orientation3 orientation, LightingModel lightingModel)
 {
     this.Position = position;
     this.Orientation = orientation;
     this.LightingModel = lightingModel;
 }
Exemple #17
0
 internal int CreateStaticObject(StaticObject Prototype, Vector3 Position, Transformation BaseTransformation, Transformation AuxTransformation, bool AccurateObjectDisposal, double StartingDistance, double EndingDistance, double BlockLength, double TrackPosition)
 {
     return(base.CreateStaticObject(Prototype, Position, BaseTransformation, AuxTransformation, AccurateObjectDisposal, 0.0, StartingDistance, EndingDistance, BlockLength, TrackPosition, 1.0));
 }
Exemple #18
0
        /// <summary>Updates the sound component. Should be called every frame.</summary>
        /// <param name="timeElapsed">The time in seconds that elapsed since the last call to this function.</param>
        private static void UpdateLinearModel(double timeElapsed)
        {
            /*
             * Set up the listener
             * */
            OpenBveApi.Math.Vector3      listenerPosition    = World.AbsoluteCameraPosition;
            OpenBveApi.Math.Orientation3 listenerOrientation = new OpenBveApi.Math.Orientation3(World.AbsoluteCameraSide, World.AbsoluteCameraUp, World.AbsoluteCameraDirection);
            OpenBveApi.Math.Vector3      listenerVelocity;
            if (World.CameraMode == World.CameraViewMode.Interior | World.CameraMode == World.CameraViewMode.InteriorLookAhead | World.CameraMode == World.CameraViewMode.Exterior)
            {
                TrainManager.Car        car  = TrainManager.PlayerTrain.Cars[TrainManager.PlayerTrain.DriverCar];
                OpenBveApi.Math.Vector3 diff = car.FrontAxle.Follower.WorldPosition - car.RearAxle.Follower.WorldPosition;
                listenerVelocity = car.Specs.CurrentSpeed * OpenBveApi.Math.Vector3.Normalize(diff) + World.CameraAlignmentSpeed.Position;
            }
            else
            {
                listenerVelocity = World.CameraAlignmentSpeed.Position;
            }
            AL.Listener(ALListener3f.Position, 0.0f, 0.0f, 0.0f);
            AL.Listener(ALListener3f.Velocity, (float)listenerVelocity.X, (float)listenerVelocity.Y, (float)listenerVelocity.Z);
            var Orientation = new[] { (float)listenerOrientation.Z.X, (float)listenerOrientation.Z.Y, (float)listenerOrientation.Z.Z, -(float)listenerOrientation.Y.X, -(float)listenerOrientation.Y.Y, -(float)listenerOrientation.Y.Z };

            AL.Listener(ALListenerfv.Orientation, ref Orientation);

            /*
             * Set up the atmospheric attributes
             * */
            double elevation      = World.AbsoluteCameraPosition.Y + Game.RouteInitialElevation;
            double airTemperature = Game.GetAirTemperature(elevation);
            double airPressure    = Game.GetAirPressure(elevation, airTemperature);
            double speedOfSound   = Game.GetSpeedOfSound(airPressure, airTemperature);

            try {
                AL.SpeedOfSound((float)speedOfSound);
            } catch { }

            /*
             * Update the sound sources
             * */
            int actuallyPlaying = 0;

            for (int i = 0; i < SourceCount; i++)
            {
                if (Sources[i].State == SoundSourceState.StopPending)
                {
                    /*
                     * The sound is still playing but is to be stopped.
                     * Stop the sound, then remove it from the list of
                     * sound sources.
                     * */
                    AL.DeleteSources(1, ref Sources[i].OpenAlSourceName);
                    Sources[i].State            = SoundSourceState.Stopped;
                    Sources[i].OpenAlSourceName = 0;
                    Sources[i] = Sources[SourceCount - 1];
                    SourceCount--;
                    i--;
                }
                else if (Sources[i].State == SoundSourceState.Stopped)
                {
                    /*
                     * The sound was already stopped. Remove it from
                     * the list of sound sources.
                     * */
                    Sources[i] = Sources[SourceCount - 1];
                    SourceCount--;
                    i--;
                }
                else if (GlobalMute)
                {
                    /*
                     * The sound is playing or about to be played, but
                     * the global mute option is enabled. Stop the sound
                     * sound if necessary, then remove it from the list
                     * of sound sources if the sound is not looping.
                     * */
                    if (Sources[i].State == SoundSourceState.Playing)
                    {
                        AL.DeleteSources(1, ref Sources[i].OpenAlSourceName);
                        Sources[i].State            = SoundSourceState.PlayPending;
                        Sources[i].OpenAlSourceName = 0;
                    }
                    if (!Sources[i].Looped)
                    {
                        Sources[i].State            = SoundSourceState.Stopped;
                        Sources[i].OpenAlSourceName = 0;
                        Sources[i] = Sources[SourceCount - 1];
                        SourceCount--;
                        i--;
                    }
                }
                else
                {
                    /*
                     * The sound is to be played or is already playing.
                     * Calculate the sound gain.
                     * */
                    OpenBveApi.Math.Vector3 direction;
                    OpenBveApi.Math.Vector3 position;
                    OpenBveApi.Math.Vector3 velocity;

                    switch (Sources[i].Type)
                    {
                    case SoundType.TrainCar:
                        var Train = (TrainManager.Train)Sources[i].Parent;
                        Train.Cars[Sources[i].Car].CreateWorldCoordinates(Sources[i].Position.X, Sources[i].Position.Y, Sources[i].Position.Z, out position.X, out position.Y, out position.Z, out direction.X, out direction.Y, out direction.Z);
                        velocity = Train.Cars[Sources[i].Car].Specs.CurrentSpeed * direction;
                        break;

                    case SoundType.AnimatedObject:
                        var WorldSound = (ObjectManager.WorldSound)Sources[i].Parent;
                        //TODO: Calculate speed...
                        position = WorldSound.Follower.WorldPosition + WorldSound.Position;
                        velocity = Vector3.Null;
                        break;

                    default:
                        position = Sources[i].Position;
                        velocity = Vector3.Null;
                        break;
                    }
                    OpenBveApi.Math.Vector3 positionDifference = position - listenerPosition;
                    double gain;
                    if (GlobalMute)
                    {
                        gain = 0.0;
                    }
                    else
                    {
                        double distance    = positionDifference.Norm();
                        double innerRadius = Sources[i].Radius;
                        if (World.CameraMode == World.CameraViewMode.Interior | World.CameraMode == World.CameraViewMode.InteriorLookAhead)
                        {
                            if (Sources[i].Parent != TrainManager.PlayerTrain || Sources[i].Car != TrainManager.PlayerTrain.DriverCar)
                            {
                                innerRadius *= 0.5;
                            }
                        }
                        double outerRadius = OuterRadiusFactor * innerRadius;
                        if (distance < outerRadius)
                        {
                            if (distance <= innerRadius)
                            {
                                gain = Sources[i].Volume;
                            }
                            else
                            {
                                gain  = (distance - outerRadius) / (innerRadius - outerRadius);
                                gain *= Sources[i].Volume;
                            }
                            gain = 3.0 * gain * gain - 2.0 * gain * gain * gain;
                        }
                        else
                        {
                            gain = 0.0;
                        }
                    }
                    if (gain <= GainThreshold)
                    {
                        /*
                         * If the gain is too low to be audible, stop the sound.
                         * If the sound is not looping, stop it if necessary,
                         * then remove it from the list of sound sources.
                         * */
                        if (Sources[i].State == SoundSourceState.Playing)
                        {
                            AL.DeleteSources(1, ref Sources[i].OpenAlSourceName);
                            Sources[i].State            = SoundSourceState.PlayPending;
                            Sources[i].OpenAlSourceName = 0;
                        }
                        if (!Sources[i].Looped)
                        {
                            Sources[i].State            = SoundSourceState.Stopped;
                            Sources[i].OpenAlSourceName = 0;
                            Sources[i] = Sources[SourceCount - 1];
                            SourceCount--;
                            i--;
                        }
                    }
                    else
                    {
                        /*
                         * Play the sound and update position, velocity, pitch and gain.
                         * For non-looping sounds, check if the sound is still playing.
                         * */
                        gain = (gain - GainThreshold) / (1.0 - GainThreshold);
                        if (Sources[i].State != SoundSourceState.Playing)
                        {
                            LoadBuffer(Sources[i].Buffer);
                            if (Sources[i].Buffer.Loaded)
                            {
                                AL.GenSources(1, out Sources[i].OpenAlSourceName);
                                AL.Source(Sources[i].OpenAlSourceName, ALSourcei.Buffer, Sources[i].Buffer.OpenAlBufferName);
                            }
                            else
                            {
                                /*
                                 * We cannot play the sound because
                                 * the buffer could not be loaded.
                                 * */
                                Sources[i].State = SoundSourceState.Stopped;
                                continue;
                            }
                        }
                        AL.Source(Sources[i].OpenAlSourceName, ALSource3f.Position, (float)positionDifference.X, (float)positionDifference.Y, (float)positionDifference.Z);
                        AL.Source(Sources[i].OpenAlSourceName, ALSource3f.Velocity, (float)velocity.X, (float)velocity.Y, (float)velocity.Z);
                        AL.Source(Sources[i].OpenAlSourceName, ALSourcef.Pitch, (float)Sources[i].Pitch);
                        AL.Source(Sources[i].OpenAlSourceName, ALSourcef.Gain, (float)gain);
                        if (Sources[i].State != SoundSourceState.Playing)
                        {
                            AL.Source(Sources[i].OpenAlSourceName, ALSourceb.Looping, Sources[i].Looped);
                            AL.SourcePlay(Sources[i].OpenAlSourceName);
                            Sources[i].State = SoundSourceState.Playing;
                        }
                        if (!Sources[i].Looped)
                        {
                            int state;
                            AL.GetSource(Sources[i].OpenAlSourceName, ALGetSourcei.SourceState, out state);
                            if (state != (int)ALSourceState.Initial & state != (int)ALSourceState.Playing)
                            {
                                /*
                                 * The sound is not playing any longer.
                                 * Remove it from the list of sound sources.
                                 * */
                                AL.DeleteSources(1, ref Sources[i].OpenAlSourceName);
                                Sources[i].State            = SoundSourceState.Stopped;
                                Sources[i].OpenAlSourceName = 0;
                                Sources[i] = Sources[SourceCount - 1];
                                SourceCount--;
                                i--;
                            }
                            else
                            {
                                actuallyPlaying++;
                            }
                        }
                        else
                        {
                            actuallyPlaying++;
                        }
                    }
                }
            }

            /*
             * Adjust the outer radius factor / the clamp factor.
             * */
            if (actuallyPlaying >= Interface.CurrentOptions.SoundNumber - 2)
            {
                /*
                 * Too many sounds are playing.
                 * Reduce the outer radius factor.
                 * */
                OuterRadiusFactorSpeed -= timeElapsed;
                if (OuterRadiusFactorSpeed < -OuterRadiusFactorMaximumSpeed)
                {
                    OuterRadiusFactorSpeed = -OuterRadiusFactorMaximumSpeed;
                }
            }
            else if (actuallyPlaying <= Interface.CurrentOptions.SoundNumber - 6)
            {
                /*
                 * Only few sounds are playing.
                 * Increase the outer radius factor.
                 * */
                OuterRadiusFactorSpeed += timeElapsed;
                if (OuterRadiusFactorSpeed > OuterRadiusFactorMaximumSpeed)
                {
                    OuterRadiusFactorSpeed = OuterRadiusFactorMaximumSpeed;
                }
            }
            else
            {
                /*
                 * Neither too many nor too few sounds are playing.
                 * Stabilize the outer radius factor.
                 * */
                if (OuterRadiusFactorSpeed < 0.0)
                {
                    OuterRadiusFactorSpeed += timeElapsed;
                    if (OuterRadiusFactorSpeed > 0.0)
                    {
                        OuterRadiusFactorSpeed = 0.0;
                    }
                }
                else
                {
                    OuterRadiusFactorSpeed -= timeElapsed;
                    if (OuterRadiusFactorSpeed < 0.0)
                    {
                        OuterRadiusFactorSpeed = 0.0;
                    }
                }
            }
            OuterRadiusFactor += OuterRadiusFactorSpeed * timeElapsed;
            if (OuterRadiusFactor < OuterRadiusFactorMinimum)
            {
                OuterRadiusFactor      = OuterRadiusFactorMinimum;
                OuterRadiusFactorSpeed = 0.0;
            }
            else if (OuterRadiusFactor > OuterRadiusFactorMaximum)
            {
                OuterRadiusFactor      = OuterRadiusFactorMaximum;
                OuterRadiusFactorSpeed = 0.0;
            }
        }
Exemple #19
0
        public void RenderFace(Shader Shader, ObjectState State, MeshFace Face, Vector3 EyePosition, bool IsDebugTouchMode = false)
        {
            if (State.Prototype.Mesh.Vertices.Length < 1)
            {
                return;
            }

            VertexTemplate[]  vertices   = State.Prototype.Mesh.Vertices;
            MeshMaterial      material   = State.Prototype.Mesh.Materials[Face.Material];
            VertexArrayObject VAO        = (VertexArrayObject)State.Prototype.Mesh.VAO;
            VertexArrayObject NormalsVAO = (VertexArrayObject)State.Prototype.Mesh.NormalsVAO;

            if (!OptionBackFaceCulling || (Face.Flags & MeshFace.Face2Mask) != 0)
            {
                GL.Disable(EnableCap.CullFace);
            }
            else if (OptionBackFaceCulling)
            {
                if ((Face.Flags & MeshFace.Face2Mask) == 0)
                {
                    GL.Enable(EnableCap.CullFace);
                }
            }

            // matrix
            Matrix4D modelMatrix     = State.Scale * State.Rotate * State.Translation * Matrix4D.CreateTranslation(-EyePosition);
            Matrix4D modelViewMatrix = modelMatrix * CurrentViewMatrix;

            Shader.SetCurrentProjectionMatrix(CurrentProjectionMatrix);
            Shader.SetCurrentModelViewMatrix(modelViewMatrix);
            Shader.SetCurrentNormalMatrix(Matrix4D.Transpose(Matrix4D.Invert(modelViewMatrix)));
            Shader.SetCurrentTextureMatrix(State.TextureTranslation);

            if (OptionWireFrame || IsDebugTouchMode)
            {
                VAO.Bind();
                VAO.Draw(Shader.VertexLayout, PrimitiveType.LineLoop, Face.IboStartIndex, Face.Vertices.Length);
                VAO.UnBind();
                return;
            }

            // lighting
            if (material.NighttimeTexture == null)
            {
                if (OptionLighting)
                {
                    Shader.SetIsLight(true);
                    Shader.SetLightPosition(new Vector3(Lighting.OptionLightPosition.X, Lighting.OptionLightPosition.Y, -Lighting.OptionLightPosition.Z));
                    Shader.SetLightAmbient(new Color4(Lighting.OptionAmbientColor.R, Lighting.OptionAmbientColor.G, Lighting.OptionAmbientColor.B, 255));
                    Shader.SetLightDiffuse(new Color4(Lighting.OptionDiffuseColor.R, Lighting.OptionDiffuseColor.G, Lighting.OptionDiffuseColor.B, 255));
                    Shader.SetLightSpecular(new Color4(Lighting.OptionSpecularColor.R, Lighting.OptionSpecularColor.G, Lighting.OptionSpecularColor.B, 255));
                    Shader.SetMaterialAmbient(new Color4(material.Color.R, material.Color.G, material.Color.B, material.Color.A));                      // TODO
                    Shader.SetMaterialDiffuse(new Color4(material.Color.R, material.Color.G, material.Color.B, material.Color.A));
                    Shader.SetMaterialSpecular(new Color4(material.Color.R, material.Color.G, material.Color.B, material.Color.A));                     // TODO

                    if ((material.Flags & MeshMaterial.EmissiveColorMask) != 0)
                    {
                        Shader.SetMaterialEmission(new Color4(material.EmissiveColor.R, material.EmissiveColor.G, material.EmissiveColor.B, 255));
                    }
                    else
                    {
                        Shader.SetMaterialEmission(new Color4(0.0f, 0.0f, 0.0f, 1.0f));
                    }

                    Shader.SetMaterialShininess(1.0f);

                    Lighting.OptionLightingResultingAmount = (Lighting.OptionAmbientColor.R + Lighting.OptionAmbientColor.G + Lighting.OptionAmbientColor.B) / 480.0f;

                    if (Lighting.OptionLightingResultingAmount > 1.0f)
                    {
                        Lighting.OptionLightingResultingAmount = 1.0f;
                    }
                }
                else
                {
                    Shader.SetMaterialAmbient(new Color4(material.Color.R, material.Color.G, material.Color.B, material.Color.A));                      // TODO
                }
            }
            else
            {
                Shader.SetMaterialAmbient(new Color4(material.Color.R, material.Color.G, material.Color.B, material.Color.A));                  // TODO
            }

            // fog
            if (OptionFog)
            {
                Shader.SetIsFog(true);
                Shader.SetFogStart(Fog.Start);
                Shader.SetFogEnd(Fog.End);
                Shader.SetFogColor(new Color4(Fog.Color.R, Fog.Color.G, Fog.Color.B, 255));
            }

            PrimitiveType DrawMode;

            switch (Face.Flags & MeshFace.FaceTypeMask)
            {
            case MeshFace.FaceTypeTriangles:
                DrawMode = PrimitiveType.Triangles;
                break;

            case MeshFace.FaceTypeTriangleStrip:
                DrawMode = PrimitiveType.TriangleStrip;
                break;

            case MeshFace.FaceTypeQuads:
                DrawMode = PrimitiveType.Quads;
                break;

            case MeshFace.FaceTypeQuadStrip:
                DrawMode = PrimitiveType.QuadStrip;
                break;

            default:
                DrawMode = PrimitiveType.Polygon;
                break;
            }

            // daytime polygon
            {
                // texture
                if (material.DaytimeTexture != null)
                {
                    if (currentHost.LoadTexture(material.DaytimeTexture, (OpenGlTextureWrapMode)material.WrapMode))
                    {
                        GL.Enable(EnableCap.Texture2D);
                        Shader.SetIsTexture(true);
                        Shader.SetTexture(0);
                        GL.BindTexture(TextureTarget.Texture2D, material.DaytimeTexture.OpenGlTextures[(int)material.WrapMode].Name);
                    }
                }

                // blend mode
                float factor;
                if (material.BlendMode == MeshMaterialBlendMode.Additive)
                {
                    factor = 1.0f;
                    GL.Enable(EnableCap.Blend);
                    GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.One);
                    Shader.SetIsFog(false);
                }
                else if (material.NighttimeTexture == null)
                {
                    float blend = inv255 * material.DaytimeNighttimeBlend + 1.0f - Lighting.OptionLightingResultingAmount;

                    if (blend > 1.0f)
                    {
                        blend = 1.0f;
                    }

                    factor = 1.0f - 0.7f * blend;
                }
                else
                {
                    factor = 1.0f;
                }
                Shader.SetBrightness(factor);

                float alphaFactor;
                if (material.GlowAttenuationData != 0)
                {
                    alphaFactor = (float)Glow.GetDistanceFactor(modelMatrix, vertices, ref Face, material.GlowAttenuationData);
                }
                else
                {
                    alphaFactor = 1.0f;
                }
                Shader.SetOpacity(inv255 * material.Color.A * alphaFactor);

                // render polygon
                VAO.Bind();
                VAO.Draw(Shader.VertexLayout, DrawMode, Face.IboStartIndex, Face.Vertices.Length);
                VAO.UnBind();

                GL.BindTexture(TextureTarget.Texture2D, 0);
            }

            // nighttime polygon
            if (material.NighttimeTexture != null && currentHost.LoadTexture(material.NighttimeTexture, (OpenGlTextureWrapMode)material.WrapMode))
            {
                // texture
                GL.Enable(EnableCap.Texture2D);
                Shader.SetIsTexture(true);
                Shader.SetTexture(0);
                GL.BindTexture(TextureTarget.Texture2D, material.NighttimeTexture.OpenGlTextures[(int)material.WrapMode].Name);

                GL.Enable(EnableCap.Blend);

                // alpha test
                GL.Enable(EnableCap.AlphaTest);
                GL.AlphaFunc(AlphaFunction.Greater, 0.0f);

                // blend mode
                float alphaFactor;
                if (material.GlowAttenuationData != 0)
                {
                    alphaFactor = (float)Glow.GetDistanceFactor(modelMatrix, vertices, ref Face, material.GlowAttenuationData);
                    float blend = inv255 * material.DaytimeNighttimeBlend + 1.0f - Lighting.OptionLightingResultingAmount;
                    if (blend > 1.0f)
                    {
                        blend = 1.0f;
                    }

                    alphaFactor *= blend;
                }
                else
                {
                    alphaFactor = inv255 * material.DaytimeNighttimeBlend + 1.0f - Lighting.OptionLightingResultingAmount;
                    if (alphaFactor > 1.0f)
                    {
                        alphaFactor = 1.0f;
                    }
                }

                Shader.SetOpacity(alphaFactor);

                // render polygon
                VAO.Bind();
                VAO.Draw(Shader.VertexLayout, DrawMode, Face.IboStartIndex, Face.Vertices.Length);
                VAO.UnBind();

                GL.BindTexture(TextureTarget.Texture2D, 0);

                RestoreBlendFunc();
                RestoreAlphaFunc();
            }

            GL.Disable(EnableCap.Texture2D);

            // normals
            if (OptionNormals)
            {
                Shader.SetIsTexture(false);
                Shader.SetBrightness(1.0f);
                Shader.SetOpacity(1.0f);

                NormalsVAO.Bind();
                NormalsVAO.Draw(Shader.VertexLayout, PrimitiveType.Lines, Face.NormalsIboStartIndex, Face.Vertices.Length * 2);
                NormalsVAO.UnBind();
            }

            // finalize
            if (material.BlendMode == MeshMaterialBlendMode.Additive)
            {
                RestoreBlendFunc();
            }
        }
Exemple #20
0
 public void RenderFace(Shader Shader, FaceState State, Vector3 EyePosition, bool IsDebugTouchMode = false)
 {
     RenderFace(Shader, State.Object, State.Face, EyePosition, IsDebugTouchMode);
 }
Exemple #21
0
            /// <summary>Applies a power and / or brake notch to this train</summary>
            /// <param name="PowerValue">The power notch value</param>
            /// <param name="PowerRelative">Whether this is relative to the current notch</param>
            /// <param name="BrakeValue">The brake notch value</param>
            /// <param name="BrakeRelative">Whether this is relative to the current notch</param>
            internal void ApplyNotch(int PowerValue, bool PowerRelative, int BrakeValue, bool BrakeRelative)
            {
                // determine notch
                int p = PowerRelative ? PowerValue + Handles.Power.Driver : PowerValue;

                if (p < 0)
                {
                    p = 0;
                }
                else if (p > Handles.Power.MaximumNotch)
                {
                    p = Handles.Power.MaximumNotch;
                }

                int b = BrakeRelative ? BrakeValue + Handles.Brake.Driver : BrakeValue;

                if (b < 0)
                {
                    b = 0;
                }
                else if (b > Handles.Brake.MaximumNotch)
                {
                    b = Handles.Brake.MaximumNotch;
                }

                // power sound
                if (p < Handles.Power.Driver)
                {
                    if (p > 0)
                    {
                        // down (not min)
                        Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.MasterControllerDown.Buffer;
                        if (buffer != null)
                        {
                            Vector3 pos = Cars[DriverCar].Sounds.MasterControllerDown.Position;
                            Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false);
                        }
                    }
                    else
                    {
                        // min
                        Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.MasterControllerMin.Buffer;
                        if (buffer != null)
                        {
                            Vector3 pos = Cars[DriverCar].Sounds.MasterControllerMin.Position;
                            Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false);
                        }
                    }
                }
                else if (p > Handles.Power.Driver)
                {
                    if (p < Handles.Power.MaximumNotch)
                    {
                        // up (not max)
                        Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.MasterControllerUp.Buffer;
                        if (buffer != null)
                        {
                            OpenBveApi.Math.Vector3 pos = Cars[DriverCar].Sounds.MasterControllerUp.Position;
                            Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false);
                        }
                    }
                    else
                    {
                        // max
                        Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.MasterControllerMax.Buffer;
                        if (buffer != null)
                        {
                            OpenBveApi.Math.Vector3 pos = Cars[DriverCar].Sounds.MasterControllerMax.Position;
                            Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false);
                        }
                    }
                }

                // brake sound
                if (b < Handles.Brake.Driver)
                {
                    // brake release
                    Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.Brake.Buffer;
                    if (buffer != null)
                    {
                        OpenBveApi.Math.Vector3 pos = Cars[DriverCar].Sounds.Brake.Position;
                        Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false);
                    }

                    if (b > 0)
                    {
                        // brake release (not min)
                        buffer = Cars[DriverCar].Sounds.BrakeHandleRelease.Buffer;
                        if (buffer != null)
                        {
                            OpenBveApi.Math.Vector3 pos = Cars[DriverCar].Sounds.BrakeHandleRelease.Position;
                            Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false);
                        }
                    }
                    else
                    {
                        // brake min
                        buffer = Cars[DriverCar].Sounds.BrakeHandleMin.Buffer;
                        if (buffer != null)
                        {
                            OpenBveApi.Math.Vector3 pos = Cars[DriverCar].Sounds.BrakeHandleMin.Position;
                            Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false);
                        }
                    }
                }
                else if (b > Handles.Brake.Driver)
                {
                    // brake
                    Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.BrakeHandleApply.Buffer;
                    if (buffer != null)
                    {
                        OpenBveApi.Math.Vector3 pos = Cars[DriverCar].Sounds.BrakeHandleApply.Position;
                        Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false);
                    }
                }

                // apply notch
                if (Handles.SingleHandle)
                {
                    if (b != 0)
                    {
                        p = 0;
                    }
                }

                Handles.Power.Driver = p;
                Handles.Brake.Driver = b;
                Game.AddBlackBoxEntry(Game.BlackBoxEventToken.None);
                // plugin
                if (Plugin != null)
                {
                    Plugin.UpdatePower();
                    Plugin.UpdateBrake();
                }
            }
Exemple #22
0
 // constructors
 /// <summary>Creates a new instance of this structure.</summary>
 /// <param name="spatialCoordinates">The spatial coordinates.</param>
 /// <param name="normal">The surface normal.</param>
 /// <param name="textureCoordinates">The texture coordinates.</param>
 /// <param name="reflectiveColor">The reflective color.</param>
 /// <param name="tag">A field to convey intermediate information.</param>
 public Vertex(Math.Vector3 spatialCoordinates, Math.Vector2 textureCoordinates, Math.Vector3 normal, Color.ColorRGBA reflectiveColor, int tag)
 {
     this.SpatialCoordinates = spatialCoordinates;
     this.TextureCoordinates = textureCoordinates;
     this.Normal = normal;
     this.ReflectiveColor = reflectiveColor;
     this.Tag = tag;
 }
Exemple #23
0
 public override void PlayMicSound(OpenBveApi.Math.Vector3 position, double backwardTolerance, double forwardTolerance)
 {
     Program.Sounds.PlayMicSound(position, backwardTolerance, forwardTolerance);
 }
Exemple #24
0
 /// <summary>Plays a sound.</summary>
 /// <param name="buffer">The sound buffer.</param>
 /// <param name="pitch">The pitch change factor.</param>
 /// <param name="volume">The volume change factor.</param>
 /// <param name="position">The position. If a train car is specified, the position is relative to the car, otherwise absolute.</param>
 /// <param name="parent">The parent object the sound is attached to, or a null reference.</param>
 /// <param name="looped">Whether to play the sound in a loop.</param>
 /// <returns>The sound source.</returns>
 public virtual object PlaySound(SoundHandle buffer, double pitch, double volume, OpenBveApi.Math.Vector3 position, object parent, bool looped)
 {
     return(null);
 }
Exemple #25
0
 public void SetLightPosition(Vector3 LightPosition)
 {
     GL.ProgramUniform3(handle, UniformLayout.LightPosition, (float)LightPosition.X, (float)LightPosition.Y, (float)LightPosition.Z);
 }
Exemple #26
0
            /// <summary>Applies the emergency brake</summary>
            internal void ApplyEmergencyBrake()
            {
                // sound
                if (!Handles.EmergencyBrake.Driver)
                {
                    Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.BrakeHandleMax.Buffer;
                    if (buffer != null)
                    {
                        OpenBveApi.Math.Vector3 pos = Cars[DriverCar].Sounds.BrakeHandleMax.Position;
                        Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false);
                    }

                    for (int i = 0; i < Cars.Length; i++)
                    {
                        buffer = Cars[DriverCar].Sounds.EmrBrake.Buffer;
                        if (buffer != null)
                        {
                            OpenBveApi.Math.Vector3 pos = Cars[i].Sounds.EmrBrake.Position;
                            Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false);
                        }
                    }
                }

                // apply
                ApplyNotch(0, !Handles.SingleHandle, Handles.Brake.MaximumNotch, true);
                ApplyAirBrakeHandle(AirBrakeHandleState.Service);
                Handles.EmergencyBrake.Driver = true;
                Handles.HoldBrake.Driver      = false;
                Specs.CurrentConstSpeed       = false;
                if (Handles.EmergencyBrake.Driver)
                {
                    switch (Handles.EmergencyBrake.OtherHandlesBehaviour)
                    {
                    case EbHandleBehaviour.PowerNeutral:
                        if (!Handles.SingleHandle)
                        {
                            ApplyNotch(0, false, 0, true);
                        }

                        break;

                    case EbHandleBehaviour.ReverserNeutral:
                        ApplyReverser(0, false);
                        break;

                    case EbHandleBehaviour.PowerReverserNeutral:
                        if (!Handles.SingleHandle)
                        {
                            ApplyNotch(0, false, 0, true);
                        }

                        ApplyReverser(0, false);
                        break;
                    }
                }

                // plugin
                if (Plugin == null)
                {
                    return;
                }
                Plugin.UpdatePower();
                Plugin.UpdateBrake();
            }
Exemple #27
0
            /// <summary>Moves the air brake handle to the specified state</summary>
            /// <param name="State">The state</param>
            internal void ApplyLocoAirBrakeHandle(AirBrakeHandleState State)
            {
                if (Handles.LocoBrake is LocoAirBrakeHandle)
                {
                    if ((int)State != Handles.LocoBrake.Driver)
                    {
                        // sound when moved to service
                        if (State == AirBrakeHandleState.Service)
                        {
                            Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.Brake.Buffer;
                            if (buffer != null)
                            {
                                OpenBveApi.Math.Vector3 pos = Cars[DriverCar].Sounds.Brake.Position;
                                Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false);
                            }
                        }

                        // sound
                        if ((int)State < (int)Handles.Brake.Driver)
                        {
                            // brake release
                            if ((int)State > 0)
                            {
                                // brake release (not min)
                                Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.BrakeHandleRelease.Buffer;
                                if (buffer != null)
                                {
                                    OpenBveApi.Math.Vector3 pos = Cars[DriverCar].Sounds.BrakeHandleRelease.Position;
                                    Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false);
                                }
                            }
                            else
                            {
                                // brake min
                                Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.BrakeHandleMin.Buffer;
                                if (buffer != null)
                                {
                                    OpenBveApi.Math.Vector3 pos = Cars[DriverCar].Sounds.BrakeHandleMin.Position;
                                    Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false);
                                }
                            }
                        }
                        else if ((int)State > (int)Handles.LocoBrake.Driver)
                        {
                            // brake
                            Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.BrakeHandleApply.Buffer;
                            if (buffer != null)
                            {
                                OpenBveApi.Math.Vector3 pos = Cars[DriverCar].Sounds.BrakeHandleApply.Position;
                                Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false);
                            }
                        }

                        // apply
                        Handles.LocoBrake.Driver = (int)State;
                        Handles.LocoBrake.Actual = (int)State;                          //TODO: FIXME
                        Game.AddBlackBoxEntry(Game.BlackBoxEventToken.None);
                        // plugin
                        if (Plugin != null)
                        {
                            Plugin.UpdatePower();
                            Plugin.UpdateBrake();
                        }
                    }
                }
            }
Exemple #28
0
 public void SetLightPosition(Vector3 LightPosition)
 {
     GL.Uniform3(UniformLayout.LightPosition, new OpenTK.Vector3((float)LightPosition.X, (float)LightPosition.Y, (float)LightPosition.Z));
 }
Exemple #29
0
        public int CreateStaticObject(StaticObject Prototype, Transformation AuxTransformation, Matrix4D Rotate, Matrix4D Translate, bool AccurateObjectDisposal, double AccurateObjectDisposalZOffset, double StartingDistance, double EndingDistance, double BlockLength, double TrackPosition, double Brightness)
        {
            if (Prototype == null)
            {
                return(-1);
            }

            float startingDistance = float.MaxValue;
            float endingDistance   = float.MinValue;

            if (AccurateObjectDisposal)
            {
                foreach (VertexTemplate vertex in Prototype.Mesh.Vertices)
                {
                    Vector3 Coordinates = new Vector3(vertex.Coordinates);
                    Coordinates.Rotate(AuxTransformation);

                    if (Coordinates.Z < startingDistance)
                    {
                        startingDistance = (float)Coordinates.Z;
                    }

                    if (Coordinates.Z > endingDistance)
                    {
                        endingDistance = (float)Coordinates.Z;
                    }
                }

                startingDistance += (float)AccurateObjectDisposalZOffset;
                endingDistance   += (float)AccurateObjectDisposalZOffset;
            }

            const double minBlockLength = 20.0;

            if (BlockLength < minBlockLength)
            {
                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, startingDistance);
                EndingDistance   = Math.Max(z + 2.0 * BlockLength, endingDistance);
                startingDistance = (float)(BlockLength * Math.Floor(StartingDistance / BlockLength));
                endingDistance   = (float)(BlockLength * Math.Ceiling(EndingDistance / BlockLength));
            }
            else
            {
                startingDistance = (float)StartingDistance;
                endingDistance   = (float)EndingDistance;
            }

            StaticObjectStates.Add(new ObjectState
            {
                Prototype        = Prototype,
                Translation      = Translate,
                Rotate           = Rotate,
                Brightness       = Brightness,
                StartingDistance = startingDistance,
                EndingDistance   = endingDistance
            });

            foreach (MeshFace face in Prototype.Mesh.Faces)
            {
                switch (face.Flags & MeshFace.FaceTypeMask)
                {
                case MeshFace.FaceTypeTriangles:
                    InfoTotalTriangles++;
                    break;

                case MeshFace.FaceTypeTriangleStrip:
                    InfoTotalTriangleStrip++;
                    break;

                case MeshFace.FaceTypeQuads:
                    InfoTotalQuads++;
                    break;

                case MeshFace.FaceTypeQuadStrip:
                    InfoTotalQuadStrip++;
                    break;

                case MeshFace.FaceTypePolygon:
                    InfoTotalPolygon++;
                    break;
                }
            }

            return(StaticObjectStates.Count - 1);
        }
Exemple #30
0
 internal ObjectGroup()
 {
     this.List = new ObjectList();
     this.OpenGlDisplayList = 0;
     this.OpenGlDisplayListAvailable = false;
     this.WorldPosition = new Vector3(0.0, 0.0, 0.0);
     this.Update = true;
 }
Exemple #31
0
 // constructors
 /// <summary>Creates a new instance of this structure.</summary>
 /// <param name="segment">The physical track segment the point lies on.</param>
 /// <param name="position">The position.</param>
 /// <param name="orientation">The orientation, either with or without factoring in the Roll parameter.</param>
 /// <param name="orientationIncludesRoll">Whether the Orientation has the Roll parameter factored in.</param>
 /// <param name="roll">The roll expressed as an angle.</param>
 public SegmentPoint(PhysicalSegment segment, Math.Vector3 position, Math.Orientation3 orientation, bool orientationIncludesRoll, double roll)
 {
     this.Segment = segment;
     this.Position = position;
     if (orientationIncludesRoll) {
         this.OrientationWithRoll = orientation;
         this.OrientationWithoutRoll = Math.Orientation3.RotateAroundZAxis(orientation, System.Math.Cos(roll), -System.Math.Sin(roll));
     } else {
         this.OrientationWithoutRoll = orientation;
         this.OrientationWithRoll = Math.Orientation3.RotateAroundZAxis(orientation, System.Math.Cos(roll), System.Math.Sin(roll));
     }
     this.Roll = roll;
 }
Exemple #32
0
 /// <summary>Register the position to play microphone input.</summary>
 /// <param name="position">The position.</param>
 /// <param name="backwardTolerance">allowed tolerance in the backward direction</param>
 /// <param name="forwardTolerance">allowed tolerance in the forward direction</param>
 public virtual void PlayMicSound(OpenBveApi.Math.Vector3 position, double backwardTolerance, double forwardTolerance)
 {
 }
Exemple #33
0
 /// <summary>Draws a 3D cube</summary>
 /// <param name="Position">The position in world-space</param>
 /// <param name="Direction">The direction vector</param>
 /// <param name="Up">The up vector</param>
 /// <param name="Side">The side vector</param>
 /// <param name="Size">The size of the cube in M</param>
 /// <param name="Camera">The camera position</param>
 /// <param name="TextureIndex">The texture to apply</param>
 public void Draw(OpenBveApi.Math.Vector3 Position, OpenBveApi.Math.Vector3 Direction, OpenBveApi.Math.Vector3 Up, OpenBveApi.Math.Vector3 Side, double Size, OpenBveApi.Math.Vector3 Camera, Texture TextureIndex)
 {
     Draw(Position, Direction, Up, Side, new OpenBveApi.Math.Vector3(Size, Size, Size), Camera, TextureIndex);
 }
Exemple #34
0
        // render scene
        internal void RenderScene(double TimeElapsed)
        {
            ReleaseResources();
            // initialize
            ResetOpenGlState();

            if (OptionWireFrame)
            {
                if (Program.CurrentRoute.CurrentFog.Start < Program.CurrentRoute.CurrentFog.End)
                {
                    const float fogDistance = 600.0f;
                    float       n           = (fogDistance - Program.CurrentRoute.CurrentFog.Start) / (Program.CurrentRoute.CurrentFog.End - Program.CurrentRoute.CurrentFog.Start);
                    float       cr          = n * inv255 * Program.CurrentRoute.CurrentFog.Color.R;
                    float       cg          = n * inv255 * Program.CurrentRoute.CurrentFog.Color.G;
                    float       cb          = n * inv255 * Program.CurrentRoute.CurrentFog.Color.B;
                    GL.ClearColor(cr, cg, cb, 1.0f);
                }
                else
                {
                    GL.ClearColor(0.0f, 0.0f, 0.0f, 1.0f);
                }
            }

            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

            // set up camera
            CurrentViewMatrix        = Matrix4D.LookAt(Vector3.Zero, new Vector3(Camera.AbsoluteDirection.X, Camera.AbsoluteDirection.Y, -Camera.AbsoluteDirection.Z), new Vector3(Camera.AbsoluteUp.X, Camera.AbsoluteUp.Y, -Camera.AbsoluteUp.Z));
            TransformedLightPosition = new Vector3(Lighting.OptionLightPosition.X, Lighting.OptionLightPosition.Y, -Lighting.OptionLightPosition.Z);
            TransformedLightPosition.Transform(CurrentViewMatrix);
            if (!AvailableNewRenderer)
            {
                GL.Light(LightName.Light0, LightParameter.Position, new[] { (float)TransformedLightPosition.X, (float)TransformedLightPosition.Y, (float)TransformedLightPosition.Z, 0.0f });
            }


            Lighting.OptionLightingResultingAmount = (Lighting.OptionAmbientColor.R + Lighting.OptionAmbientColor.G + Lighting.OptionAmbientColor.B) / 480.0f;

            if (Lighting.OptionLightingResultingAmount > 1.0f)
            {
                Lighting.OptionLightingResultingAmount = 1.0f;
            }
            // fog
            double fd = Program.CurrentRoute.NextFog.TrackPosition - Program.CurrentRoute.PreviousFog.TrackPosition;

            if (fd != 0.0)
            {
                float fr  = (float)((CameraTrackFollower.TrackPosition - Program.CurrentRoute.PreviousFog.TrackPosition) / fd);
                float frc = 1.0f - fr;
                Program.CurrentRoute.CurrentFog.Start   = Program.CurrentRoute.PreviousFog.Start * frc + Program.CurrentRoute.NextFog.Start * fr;
                Program.CurrentRoute.CurrentFog.End     = Program.CurrentRoute.PreviousFog.End * frc + Program.CurrentRoute.NextFog.End * fr;
                Program.CurrentRoute.CurrentFog.Color.R = (byte)(Program.CurrentRoute.PreviousFog.Color.R * frc + Program.CurrentRoute.NextFog.Color.R * fr);
                Program.CurrentRoute.CurrentFog.Color.G = (byte)(Program.CurrentRoute.PreviousFog.Color.G * frc + Program.CurrentRoute.NextFog.Color.G * fr);
                Program.CurrentRoute.CurrentFog.Color.B = (byte)(Program.CurrentRoute.PreviousFog.Color.B * frc + Program.CurrentRoute.NextFog.Color.B * fr);
                if (!Program.CurrentRoute.CurrentFog.IsLinear)
                {
                    Program.CurrentRoute.CurrentFog.Density = (byte)(Program.CurrentRoute.PreviousFog.Density * frc + Program.CurrentRoute.NextFog.Density * fr);
                }
            }
            else
            {
                Program.CurrentRoute.CurrentFog = Program.CurrentRoute.PreviousFog;
            }

            // render background
            GL.Disable(EnableCap.DepthTest);
            Program.CurrentRoute.UpdateBackground(TimeElapsed, false);

            if (OptionEvents)
            {
                RenderEvents();
            }

            // fog
            float aa = Program.CurrentRoute.CurrentFog.Start;
            float bb = Program.CurrentRoute.CurrentFog.End;

            if (aa < bb & aa < Program.CurrentRoute.CurrentBackground.BackgroundImageDistance)
            {
                OptionFog    = true;
                Fog.Start    = aa;
                Fog.End      = bb;
                Fog.Color    = Program.CurrentRoute.CurrentFog.Color;
                Fog.Density  = Program.CurrentRoute.CurrentFog.Density;
                Fog.IsLinear = Program.CurrentRoute.CurrentFog.IsLinear;
                Fog.SetForImmediateMode();
            }
            else
            {
                OptionFog = false;
            }

            // world layer
            // opaque face
            if (AvailableNewRenderer)
            {
                //Setup the shader for rendering the scene
                DefaultShader.Activate();
                if (OptionLighting)
                {
                    DefaultShader.SetIsLight(true);
                    DefaultShader.SetLightPosition(TransformedLightPosition);
                    DefaultShader.SetLightAmbient(Lighting.OptionAmbientColor);
                    DefaultShader.SetLightDiffuse(Lighting.OptionDiffuseColor);
                    DefaultShader.SetLightSpecular(Lighting.OptionSpecularColor);
                    DefaultShader.SetLightModel(Lighting.LightModel);
                }
                if (OptionFog)
                {
                    DefaultShader.SetIsFog(true);
                    DefaultShader.SetFog(Fog);
                }
                DefaultShader.SetTexture(0);
                DefaultShader.SetCurrentProjectionMatrix(CurrentProjectionMatrix);
            }
            ResetOpenGlState();

            foreach (FaceState face in VisibleObjects.OpaqueFaces)
            {
                face.Draw();
            }

            // alpha face
            ResetOpenGlState();
            VisibleObjects.SortPolygonsInAlphaFaces();

            if (Interface.CurrentOptions.TransparencyMode == TransparencyMode.Performance)
            {
                SetBlendFunc();
                SetAlphaFunc(AlphaFunction.Greater, 0.0f);
                GL.DepthMask(false);

                foreach (FaceState face in VisibleObjects.AlphaFaces)
                {
                    face.Draw();
                }
            }
            else
            {
                UnsetBlendFunc();
                SetAlphaFunc(AlphaFunction.Equal, 1.0f);
                GL.DepthMask(true);

                foreach (FaceState face in VisibleObjects.AlphaFaces)
                {
                    if (face.Object.Prototype.Mesh.Materials[face.Face.Material].BlendMode == MeshMaterialBlendMode.Normal && face.Object.Prototype.Mesh.Materials[face.Face.Material].GlowAttenuationData == 0)
                    {
                        if (face.Object.Prototype.Mesh.Materials[face.Face.Material].Color.A == 255)
                        {
                            face.Draw();
                        }
                    }
                }

                SetBlendFunc();
                SetAlphaFunc(AlphaFunction.Less, 1.0f);
                GL.DepthMask(false);
                bool additive = false;

                foreach (FaceState face in VisibleObjects.AlphaFaces)
                {
                    if (face.Object.Prototype.Mesh.Materials[face.Face.Material].BlendMode == MeshMaterialBlendMode.Additive)
                    {
                        if (!additive)
                        {
                            UnsetAlphaFunc();
                            additive = true;
                        }

                        face.Draw();
                    }
                    else
                    {
                        if (additive)
                        {
                            SetAlphaFunc();
                            additive = false;
                        }

                        face.Draw();
                    }
                }
            }

            // render overlays
            if (AvailableNewRenderer)
            {
                DefaultShader.Deactivate();
            }
            ResetOpenGlState();
            OptionLighting = false;
            OptionFog      = false;
            UnsetAlphaFunc();
            GL.Disable(EnableCap.DepthTest);
            SetBlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);             //FIXME: Remove when text switches between two renderer types
            RenderOverlays();
            OptionLighting = true;
        }
Exemple #35
0
 /// <summary>Draws a 3D cube</summary>
 /// <param name="Position">The position in world-space</param>
 /// <param name="Direction">The direction vector</param>
 /// <param name="Up">The up vector</param>
 /// <param name="Side">The side vector</param>
 /// <param name="Size">A 3D vector describing the size of the cube</param>
 /// <param name="Camera">The camera position</param>
 /// <param name="TextureIndex">The texture to apply</param>
 public void Draw(OpenBveApi.Math.Vector3 Position, OpenBveApi.Math.Vector3 Direction, OpenBveApi.Math.Vector3 Up, OpenBveApi.Math.Vector3 Side, OpenBveApi.Math.Vector3 Size, OpenBveApi.Math.Vector3 Camera, Texture TextureIndex)
 {
     Draw(defaultVAO, Position, Direction, Up, Side, Size, Camera, TextureIndex);
 }