Norm() public method

public Norm ( ) : float
return float
Ejemplo n.º 1
0
        public void UpdateTopplingCantAndSpring()
        {
            if (CarSections.Length != 0)
            {
                //FRONT BOGIE

                // get direction, up and side vectors
                Vector3 d = new Vector3(FrontAxle.Follower.WorldPosition - RearAxle.Follower.WorldPosition);
                Vector3 s;
                {
                    double t = 1.0 / d.Norm();
                    d *= t;
                    t  = 1.0 / Math.Sqrt(d.X * d.X + d.Z * d.Z);
                    double ex = d.X * t;
                    double ez = d.Z * t;
                    s  = new Vector3(ez, 0.0, -ex);
                    Up = Vector3.Cross(d, s);
                }
                // cant and radius

                //TODO: This currently uses the figures from the base car
                // apply position due to cant/toppling
                {
                    double a = baseCar.Specs.RollDueToTopplingAngle +
                               baseCar.Specs.RollDueToCantAngle;
                    double  x = Math.Sign(a) * 0.5 * TrainManagerBase.currentHost.Tracks[FrontAxle.Follower.TrackIndex].RailGauge * (1.0 - Math.Cos(a));
                    double  y = Math.Abs(0.5 * TrainManagerBase.currentHost.Tracks[FrontAxle.Follower.TrackIndex].RailGauge * Math.Sin(a));
                    Vector3 c = new Vector3(s.X * x + Up.X * y, s.Y * x + Up.Y * y, s.Z * x + Up.Z * y);
                    FrontAxle.Follower.WorldPosition += c;
                    RearAxle.Follower.WorldPosition  += c;
                }
                // apply rolling
                {
                    s.Rotate(d, -baseCar.Specs.RollDueToTopplingAngle - baseCar.Specs.RollDueToCantAngle);
                    Up.Rotate(d, -baseCar.Specs.RollDueToTopplingAngle - baseCar.Specs.RollDueToCantAngle);
                }
                // apply pitching
                if (CurrentCarSection >= 0 && CarSections[CurrentCarSection].Groups[0].Type == ObjectType.Overlay)
                {
                    d.Rotate(s, baseCar.Specs.PitchDueToAccelerationAngle);
                    Up.Rotate(s, baseCar.Specs.PitchDueToAccelerationAngle);
                    Vector3 cc = 0.5 * (FrontAxle.Follower.WorldPosition + RearAxle.Follower.WorldPosition);
                    FrontAxle.Follower.WorldPosition -= cc;
                    RearAxle.Follower.WorldPosition  -= cc;
                    FrontAxle.Follower.WorldPosition.Rotate(s, baseCar.Specs.PitchDueToAccelerationAngle);
                    RearAxle.Follower.WorldPosition.Rotate(s, baseCar.Specs.PitchDueToAccelerationAngle);
                    FrontAxle.Follower.WorldPosition += cc;
                    RearAxle.Follower.WorldPosition  += cc;
                }
            }
        }
Ejemplo n.º 2
0
        public Vector3 Get(int x, int y)
        {
            var camera = _cameraProvider.Get();
            var config = _config.Get();

            var xNorm = (x - config.Width / 2) / (float)config.Width * 2;
            var yNorm = -(y - config.Height / 2) / (float)config.Height * 2;

            var vec = new Vector3(xNorm, 0, yNorm);

            vec -= camera.Position;
            vec += camera.Direction;


            return(vec.Norm());
        }
        public void Vectors_ShouldAllBeOfUnitLength(Vector3 vector)
        {
            // Fixture setup

            // Exercise system

            // Verify outcome
            var result         = vector.Norm();
            var expectedResult = 1.0;

            var failureString = String.Format("Had length {0}, expected 1.0", vector);

            Assert.True(Number.AlmostEqual(result, expectedResult), failureString);

            // Teardown
        }
Ejemplo n.º 4
0
        private List <FaceState> SortPolygons(List <FaceState> faces)
        {
            // calculate distance
            double[] distances = new double[faces.Count];

            Parallel.For(0, faces.Count, i =>
            {
                if (faces[i].Face.Vertices.Length >= 3)
                {
                    Vector4 v0   = new Vector4(faces[i].Object.Prototype.Mesh.Vertices[faces[i].Face.Vertices[0].Index].Coordinates, 1.0);
                    Vector4 v1   = new Vector4(faces[i].Object.Prototype.Mesh.Vertices[faces[i].Face.Vertices[1].Index].Coordinates, 1.0);
                    Vector4 v2   = new Vector4(faces[i].Object.Prototype.Mesh.Vertices[faces[i].Face.Vertices[2].Index].Coordinates, 1.0);
                    Vector4 w1   = v1 - v0;
                    Vector4 w2   = v2 - v0;
                    v0.Z        *= -1.0;
                    w1.Z        *= -1.0;
                    w2.Z        *= -1.0;
                    Matrix4D mat = faces[i].Object.Scale * faces[i].Object.Rotate * faces[i].Object.Translation;
                    v0           = Vector4.Transform(v0, mat);
                    w1           = Vector4.Transform(w1, mat);
                    w2           = Vector4.Transform(w2, mat);
                    v0.Z        *= -1.0;
                    w1.Z        *= -1.0;
                    w2.Z        *= -1.0;
                    Vector3 d    = Vector3.Cross(w1.Xyz, w2.Xyz);
                    double t     = d.Norm();

                    if (t != 0.0)
                    {
                        d           /= t;
                        Vector3 w0   = v0.Xyz - camera.AbsolutePosition;
                        t            = Vector3.Dot(d, w0);
                        distances[i] = -t * t;
                    }
                }
            });

            // sort
            return(faces.Select((face, index) => new { Face = face, Distance = distances[index] }).OrderBy(list => list.Distance).Select(list => list.Face).ToList());
        }
Ejemplo n.º 5
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>
        protected override void UpdateInverseModel(double timeElapsed)
        {
            /*
             * Set up the listener.
             * */
            Vector3      listenerPosition    = Program.Renderer.Camera.AbsolutePosition;
            Orientation3 listenerOrientation = new Orientation3(Program.Renderer.Camera.AbsoluteSide, Program.Renderer.Camera.AbsoluteUp, Program.Renderer.Camera.AbsoluteDirection);
            Vector3      listenerVelocity;

            if (Program.Renderer.Camera.CurrentMode == CameraViewMode.Interior | Program.Renderer.Camera.CurrentMode == CameraViewMode.InteriorLookAhead | Program.Renderer.Camera.CurrentMode == CameraViewMode.Exterior)
            {
                CarBase car  = TrainManager.PlayerTrain.Cars[TrainManager.PlayerTrain.DriverCar];
                Vector3 diff = car.FrontAxle.Follower.WorldPosition - car.RearAxle.Follower.WorldPosition;
                if (diff.IsNullVector())
                {
                    listenerVelocity = car.CurrentSpeed * Vector3.Forward;
                }
                else
                {
                    listenerVelocity = car.CurrentSpeed * Vector3.Normalize(diff);
                }
            }
            else
            {
                listenerVelocity = Vector3.Zero;
            }
            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      = Program.Renderer.Camera.AbsolutePosition.Y + Program.CurrentRoute.Atmosphere.InitialElevation;
            double airTemperature = Program.CurrentRoute.Atmosphere.GetAirTemperature(elevation);
            double airPressure    = Program.CurrentRoute.Atmosphere.GetAirPressure(elevation, airTemperature);
            double speedOfSound   = Program.CurrentRoute.Atmosphere.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.
                     * */
                    Vector3 position;
                    switch (Sources[i].Type)
                    {
                    case SoundType.TrainCar:
                        Vector3 direction;
                        var     Car = (AbstractCar)Sources[i].Parent;
                        Car.CreateWorldCoordinates(Sources[i].Position, out position, out direction);
                        break;

                    default:
                        position = Sources[i].Position;
                        break;
                    }
                    Vector3 positionDifference = position - listenerPosition;
                    double  distance           = positionDifference.Norm();
                    double  radius             = Sources[i].Radius;
                    if (Program.Renderer.Camera.CurrentMode == CameraViewMode.Interior | Program.Renderer.Camera.CurrentMode == CameraViewMode.InteriorLookAhead)
                    {
                        if (Sources[i].Parent != TrainManager.PlayerTrain.Cars[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;
                        }
                    }
                    Vector3 position;
                    Vector3 velocity;
                    switch (source.Type)
                    {
                    case SoundType.TrainCar:
                        Vector3 direction;
                        var     Car = (AbstractCar)Sources[i].Parent;
                        Car.CreateWorldCoordinates(source.Position, out position, out direction);
                        velocity = Car.CurrentSpeed * direction;
                        break;

                    default:
                        position = source.Position;
                        velocity = Vector3.Zero;
                        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;
                    }
                }
            }
        }
Ejemplo n.º 6
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>
        protected override void UpdateLinearModel(double timeElapsed)
        {
            /*
             * Set up the listener
             * */
            Vector3      listenerPosition    = Program.Renderer.Camera.AbsolutePosition;
            Orientation3 listenerOrientation = new Orientation3(Program.Renderer.Camera.AbsoluteSide, Program.Renderer.Camera.AbsoluteUp, Program.Renderer.Camera.AbsoluteDirection);
            Vector3      listenerVelocity;

            if (Program.Renderer.Camera.CurrentMode == CameraViewMode.Interior | Program.Renderer.Camera.CurrentMode == CameraViewMode.InteriorLookAhead | Program.Renderer.Camera.CurrentMode == CameraViewMode.Exterior)
            {
                CarBase car  = TrainManager.PlayerTrain.Cars[TrainManager.PlayerTrain.DriverCar];
                Vector3 diff = car.FrontAxle.Follower.WorldPosition - car.RearAxle.Follower.WorldPosition;
                listenerVelocity = car.CurrentSpeed * Vector3.Normalize(diff) + Program.Renderer.Camera.AlignmentSpeed.Position;
            }
            else
            {
                listenerVelocity = Program.Renderer.Camera.AlignmentSpeed.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      = Program.Renderer.Camera.AbsolutePosition.Y + Program.CurrentRoute.Atmosphere.InitialElevation;
            double airTemperature = Program.CurrentRoute.Atmosphere.GetAirTemperature(elevation);
            double airPressure    = Program.CurrentRoute.Atmosphere.GetAirPressure(elevation, airTemperature);
            double speedOfSound   = Program.CurrentRoute.Atmosphere.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.
                     * */
                    Vector3 direction;
                    Vector3 position;
                    Vector3 velocity;

                    switch (Sources[i].Type)
                    {
                    case SoundType.TrainCar:
                        var Car = (AbstractCar)Sources[i].Parent;
                        Car.CreateWorldCoordinates(Sources[i].Position, out position, out direction);
                        velocity = Car.CurrentSpeed * direction;
                        break;

                    default:
                        position = Sources[i].Position;
                        velocity = Vector3.Zero;
                        break;
                    }
                    Vector3 positionDifference = position - listenerPosition;
                    double  gain;
                    if (GlobalMute)
                    {
                        gain = 0.0;
                    }
                    else
                    {
                        double distance    = positionDifference.Norm();
                        double innerRadius = Sources[i].Radius;
                        if (Program.Renderer.Camera.CurrentMode == CameraViewMode.Interior | Program.Renderer.Camera.CurrentMode == CameraViewMode.InteriorLookAhead)
                        {
                            if (Sources[i].Parent != TrainManager.PlayerTrain.Cars[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;
            }
        }
Ejemplo n.º 7
0
        private void RecAndPlay(Vector3 listenerPosition, bool IsLinear, double clampFactor)
        {
            if (OpenAlMic == null)
            {
                return;
            }

            // If the microphone sound playback is invalid, stop recording.
            if (!IsPlayingMicSounds)
            {
                if (OpenAlMic.IsRunning)
                {
                    OpenAlMic.Stop();
                }
                return;
            }

            // Start recording.
            if (!OpenAlMic.IsRunning)
            {
                OpenAlMic.Start();
            }

            // Make sure that the source is playing.
            int[] states = new int[MicSources.Count];

            for (int i = 0; i < MicSources.Count; i++)
            {
                AL.GetSource(MicSources[i].OpenAlSourceName, ALGetSourcei.BuffersProcessed, out states[i]);
            }

            // Get the number of buffers that can be recorded.
            int sample = OpenAlMic.AvailableSamples;

            for (int i = 0; i < MicSources.Count; i++)
            {
                if (listenerPosition.Z < MicSources[i].Position.Z - MicSources[i].BackwardTolerance || listenerPosition.Z > MicSources[i].Position.Z + MicSources[i].ForwardTolerance)
                {
                    continue;
                }

                // When playback is completed and recording is possible.
                if (sample > 0 && states[i] == 1)
                {
                    // Store the recorded data in the buffer.
                    OpenAlMic.ReadSamples(MicStore, sample);

                    // Apply the recording data to the buffer.
                    int buffer = AL.GenBuffer();
                    AL.BufferData(buffer, OpenAlMic.SampleFormat, MicStore, MicStore.Length, OpenAlMic.SampleFrequency);

                    // Apply buffer to source.
                    AL.SourceQueueBuffer(MicSources[i].OpenAlSourceName, buffer);

                    // Delete the buffer where playback has ended.
                    UnloadMicBuffers(MicSources[i].OpenAlSourceName, states[i]);

                    Vector3 positionDifference = MicSources[i].Position - listenerPosition;
                    double  distance           = positionDifference.Norm();
                    double  innerRadius        = 15.0;
                    double  gain = 1.0;

                    if (GlobalMute)
                    {
                        gain = 0.0;
                    }
                    else
                    {
                        if (Program.Renderer.Camera.CurrentMode == CameraViewMode.Interior | Program.Renderer.Camera.CurrentMode == CameraViewMode.InteriorLookAhead)
                        {
                            innerRadius *= 0.5;
                        }
                        if (IsLinear)
                        {
                            double outerRadius = OuterRadiusFactor * innerRadius;
                            if (distance < outerRadius)
                            {
                                if (distance > innerRadius)
                                {
                                    gain = (distance - outerRadius) / (innerRadius - outerRadius);
                                }
                                gain = 3.0 * gain * gain - 2.0 * gain * gain * gain;
                            }
                            else
                            {
                                gain = 0.0;
                            }
                            if (gain <= GainThreshold)
                            {
                                gain = 0.0;
                            }
                            else
                            {
                                gain = (gain - GainThreshold) / (1.0 - GainThreshold);
                            }
                        }
                        else
                        {
                            if (distance < 2.0 * innerRadius)
                            {
                                gain = 1.0 - distance * distance * (4.0 * innerRadius - distance) / (16.0 * innerRadius * innerRadius * innerRadius);
                            }
                            else
                            {
                                gain = innerRadius / distance;
                            }
                            if (gain <= 0.0)
                            {
                                gain = 0.0;
                            }
                            gain -= clampFactor * distance * distance;
                            if (gain <= 0.0)
                            {
                                gain = 0.0;
                            }
                        }
                    }

                    AL.Source(MicSources[i].OpenAlSourceName, ALSource3f.Position, (float)positionDifference.X, (float)positionDifference.Y, (float)positionDifference.Z);
                    AL.Source(MicSources[i].OpenAlSourceName, ALSourcef.Gain, (float)gain);

                    if (AL.GetSourceState(MicSources[i].OpenAlSourceName) != ALSourceState.Playing)
                    {
                        AL.SourcePlay(MicSources[i].OpenAlSourceName);
                    }
                }
            }
        }
Ejemplo n.º 8
0
        /// <summary>
        ///  Geländemodell aus Punkten und Bruchlinien
        /// </summary>
        /// <param name="model">       </param>
        /// <param name="points">     Geländepunkte </param>
        /// <param name="breaklines"> Bruchlinien mit indizes der Punkte </param>
        /// <returns>  </returns>
        private static IfcGeometricCurveSet createGeometricCurveSet(IfcStore model, Vector3 origin, Mesh mesh,
                                                                    double?breakDist,
                                                                    out RepresentationType representationType,
                                                                    out RepresentationIdentifier representationIdentifier)
        {
            //Serilog.Log.Logger = new LoggerConfiguration()
            //   .MinimumLevel.Debug()
            //   .WriteTo.File(System.Configuration.ConfigurationManager.AppSettings["LogFilePath"])
            //   .CreateLogger();
            //begin a transaction
            using (var txn = model.BeginTransaction("Create DTM"))
            {
                // CartesianPoints erzeugen
                var cps = mesh.Points.Select(p => model.Instances.New <IfcCartesianPoint>(c => c.SetXYZ(p.X - origin.X, p.Y - origin.Y, p.Z - origin.Z))).ToList();

                // DTM
                var dtm = model.Instances.New <IfcGeometricCurveSet>(g =>
                {
                    var edges = new HashSet <TupleIdx>();
                    g.Elements.AddRange(cps);
                    if (breakDist is double dist)
                    {
                        // Hilfsfunktion zum Punkte auf Kante erzeugen
                        void addEdgePoints(Point3 start, Point3 dest)
                        {
                            var dir    = dest - start;
                            double len = Vector3.Norm(dir);
                            double fac = len / dist;
                            if (fac > 1.0)
                            {
                                start         -= origin;
                                dir           /= len;
                                double currLen = dist;
                                while (currLen < len)
                                {
                                    var p = start + (dir * currLen);
                                    g.Elements.Add(model.Instances.New <IfcCartesianPoint>(c => c.SetXYZ(p.X, p.Y, p.Z)));
                                    currLen += dist;
                                }
                            }
                        }

                        // evtl. Bruchlinien erzeugen
                        foreach (var edge in mesh.FixedEdges)
                        {
                            addEdgePoints(mesh.Points[edge.Idx1], mesh.Points[edge.Idx2]);
                            edges.Add(edge);
                        }

                        // Kanten der Faces (falls vorhanden und ohne Doppelung)
                        foreach (var edge in mesh.EdgeIndices.Keys)
                        {
                            if (!edges.Contains(TupleIdx.Flipped(edge)) && edges.Add(edge))
                            {
                                addEdgePoints(mesh.Points[edge.Idx1], mesh.Points[edge.Idx2]);
                            }
                        }
                    }
                    else
                    {
                        // evtl. Bruchlinien erzeugen
                        foreach (var edge in mesh.FixedEdges)
                        {
                            g.Elements.Add(model.Instances.New <IfcPolyline>(p => p.Points.AddRange(new[] { cps[edge.Idx1], cps[edge.Idx2] })));
                            edges.Add(edge);
                        }

                        // Kanten der Faces (falls vorhanden und ohne Doppelung)
                        foreach (var edge in mesh.EdgeIndices.Keys)
                        {
                            if (!edges.Contains(TupleIdx.Flipped(edge)) && edges.Add(edge))
                            {
                                g.Elements.Add(model.Instances.New <IfcPolyline>(p => p.Points.AddRange(new[] { cps[edge.Idx1], cps[edge.Idx2] })));
                            }
                        }
                    }
                });

                txn.Commit();
                representationIdentifier = RepresentationIdentifier.SurveyPoints;
                representationType       = RepresentationType.GeometricCurveSet;
                //Log.Information("IfcGeometricCurveSet created");
                return(dtm);
            }
        }
Ejemplo n.º 9
0
        // update absolute camera
        internal static void UpdateAbsoluteCamera(double TimeElapsed)
        {
            // zoom
            double zm = World.CameraCurrentAlignment.Zoom;

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

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

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

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

                    cF += sF * CameraCurrentAlignment.Position.X + u2 * CameraCurrentAlignment.Position + d2 * CameraCurrentAlignment.Position.Z;
                }
                // yaw, pitch, roll
                double headYaw = World.CameraCurrentAlignment.Yaw + lookaheadYaw;
                if ((World.CameraMode == CameraViewMode.Interior | World.CameraMode == CameraViewMode.InteriorLookAhead) & TrainManager.PlayerTrain != null)
                {
                    if (TrainManager.PlayerTrain.DriverCar >= 0)
                    {
                        headYaw += TrainManager.PlayerTrain.Cars[TrainManager.PlayerTrain.DriverCar].DriverYaw;
                    }
                }
                double headPitch = World.CameraCurrentAlignment.Pitch + lookaheadPitch;
                if ((World.CameraMode == CameraViewMode.Interior | World.CameraMode == CameraViewMode.InteriorLookAhead) & TrainManager.PlayerTrain != null)
                {
                    if (TrainManager.PlayerTrain.DriverCar >= 0)
                    {
                        headPitch += TrainManager.PlayerTrain.Cars[TrainManager.PlayerTrain.DriverCar].DriverPitch;
                    }
                }
                double bodyPitch = 0.0;
                double bodyRoll  = 0.0;
                double headRoll  = World.CameraCurrentAlignment.Roll;
                // rotation
                if (CameraRestriction == Camera.RestrictionMode.NotAvailable & (CameraMode == CameraViewMode.Interior | CameraMode == CameraViewMode.InteriorLookAhead))
                {
                    // with body and head
                    bodyPitch += CurrentDriverBody.Pitch;
                    headPitch -= 0.2 * CurrentDriverBody.Pitch;
                    bodyRoll  += CurrentDriverBody.Roll;
                    headRoll  += 0.2 * CurrentDriverBody.Roll;
                    const double bodyHeight = 0.6;
                    const double headHeight = 0.1;
                    {
                        // body pitch
                        double ry = (Math.Cos(-bodyPitch) - 1.0) * bodyHeight;
                        double rz = Math.Sin(-bodyPitch) * bodyHeight;
                        cF += dF * rz + uF * ry;
                        if (bodyPitch != 0.0)
                        {
                            double cosa = Math.Cos(-bodyPitch);
                            double sina = Math.Sin(-bodyPitch);
                            dF.Rotate(sF, cosa, sina);
                            uF.Rotate(sF, cosa, sina);
                        }
                    }
                    {
                        // body roll
                        double rx = Math.Sin(bodyRoll) * bodyHeight;
                        double ry = (Math.Cos(bodyRoll) - 1.0) * bodyHeight;
                        cF += sF * rx + uF * ry;
                        if (bodyRoll != 0.0)
                        {
                            double cosa = Math.Cos(-bodyRoll);
                            double sina = Math.Sin(-bodyRoll);
                            uF.Rotate(dF, cosa, sina);
                            sF.Rotate(dF, cosa, sina);
                        }
                    }
                    {
                        // head yaw
                        double rx = Math.Sin(headYaw) * headHeight;
                        double rz = (Math.Cos(headYaw) - 1.0) * headHeight;
                        cF += sF * rx + dF * rz;
                        if (headYaw != 0.0)
                        {
                            double cosa = Math.Cos(headYaw);
                            double sina = Math.Sin(headYaw);
                            dF.Rotate(uF, cosa, sina);
                            sF.Rotate(uF, cosa, sina);
                        }
                    }
                    {
                        // head pitch
                        double ry = (Math.Cos(-headPitch) - 1.0) * headHeight;
                        double rz = Math.Sin(-headPitch) * headHeight;
                        cF += dF * rz + uF * ry;
                        if (headPitch != 0.0)
                        {
                            double cosa = Math.Cos(-headPitch);
                            double sina = Math.Sin(-headPitch);
                            dF.Rotate(sF, cosa, sina);
                            uF.Rotate(sF, cosa, sina);
                        }
                    }
                    {
                        // head roll
                        double rx = Math.Sin(headRoll) * headHeight;
                        double ry = (Math.Cos(headRoll) - 1.0) * headHeight;
                        cF += sF * rx + uF * ry;
                        if (headRoll != 0.0)
                        {
                            double cosa = Math.Cos(-headRoll);
                            double sina = Math.Sin(-headRoll);
                            uF.Rotate(dF, cosa, sina);
                            sF.Rotate(dF, cosa, sina);
                        }
                    }
                }
                else
                {
                    // without body or head
                    double totalYaw   = headYaw;
                    double totalPitch = headPitch + bodyPitch;
                    double totalRoll  = bodyRoll + headRoll;
                    if (totalYaw != 0.0)
                    {
                        double cosa = Math.Cos(totalYaw);
                        double sina = Math.Sin(totalYaw);
                        dF.Rotate(uF, cosa, sina);
                        sF.Rotate(uF, cosa, sina);
                    }
                    if (totalPitch != 0.0)
                    {
                        double cosa = Math.Cos(-totalPitch);
                        double sina = Math.Sin(-totalPitch);
                        dF.Rotate(sF, cosa, sina);
                        uF.Rotate(sF, cosa, sina);
                    }
                    if (totalRoll != 0.0)
                    {
                        double cosa = Math.Cos(-totalRoll);
                        double sina = Math.Sin(-totalRoll);
                        uF.Rotate(dF, cosa, sina);
                        sF.Rotate(dF, cosa, sina);
                    }
                }
                // finish
                AbsoluteCameraPosition  = cF;
                AbsoluteCameraDirection = dF;
                AbsoluteCameraUp        = uF;
                AbsoluteCameraSide      = sF;
            }
        }
Ejemplo n.º 10
0
 public Vector3 PerspectiveRayDir(double x, double y)
 {
     return(Vector3.Norm(Forward + RecenterX(x) * Right + RecenterY(y) * Up));
 }
Ejemplo n.º 11
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>
        protected override void UpdateInverseModel(double timeElapsed)
        {
            /*
             * Set up the listener.
             * */
            Vector3      listenerPosition    = Vector3.Zero;
            Orientation3 listenerOrientation = new Orientation3(Vector3.Right, Vector3.Up, Vector3.Forward);
            Vector3      listenerVelocity    = Vector3.Zero;

            AL.Listener(ALListener3f.Position, 0.0f, 0.0f, 0.0f);
            AL.Listener(ALListener3f.Velocity, (float)listenerVelocity.X, (float)listenerVelocity.Y, (float)listenerVelocity.Z);
            float[] 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);

            /*
             * 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.
                     * */
                    Vector3 position           = Sources[i].Position;
                    Vector3 positionDifference = position - listenerPosition;
                    double  distance           = positionDifference.Norm();
                    double  radius             = Sources[i].Radius;
                    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 = 16;

            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;
                        }
                    }

                    Vector3 position = source.Position;
                    Vector3 velocity = Vector3.Zero;
                    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;
                    }
                }
            }
        }
Ejemplo n.º 12
0
 public static Vector3 Normalize(this Vector3 v)
 {
     return(Vector3.Multiply(v, 1 / v.Norm()));
 }