Exemple #1
0
 public virtual void Awake()
 {
     transform = new Components.Transform();
 }
Exemple #2
0
        /// <summary>
        /// Updates the SoundInstance
        /// </summary>
        public void Update()
        {
            // Check existence of attachTo object
            if (this.attachedTo != null && this.attachedTo.Disposed)
            {
                this.attachedTo = null;
            }

            // Retrieve sound resource values
            Sound     soundRes     = this.sound.Res;
            AudioData audioDataRes = this.audioData.Res;

            if (soundRes == null || audioDataRes == null)
            {
                this.Dispose();
                return;
            }

            // Set up local variables for state calculation
            Vector3          listenerPos        = DualityApp.Sound.ListenerPos;
            bool             attachedToListener = this.attachedTo != null && ((this.attachedTo == DualityApp.Sound.Listener) || this.attachedTo.IsChildOf(DualityApp.Sound.Listener));
            float            optVolFactor       = this.GetTypeVolFactor();
            float            priorityTemp       = 1000.0f;
            AudioSourceState nativeState        = AudioSourceState.Default;

            nativeState.MinDistance = soundRes.MinDist;
            nativeState.MaxDistance = soundRes.MaxDist;
            nativeState.Volume      = optVolFactor * soundRes.VolumeFactor * this.vol * this.curFade * this.pauseFade;
            nativeState.Pitch       = soundRes.PitchFactor * this.pitch;
            nativeState.Lowpass     = soundRes.LowpassFactor * this.lowpass;
            priorityTemp           *= nativeState.Volume;

            // Calculate 3D source values, distance and priority
            nativeState.Position = this.pos;
            nativeState.Velocity = this.vel;
            if (this.is3D)
            {
                Components.Transform attachTransform = this.attachedTo != null ? this.attachedTo.Transform : null;

                // Attach to object
                if (this.attachedTo != null)
                {
                    MathF.TransformCoord(ref nativeState.Position.X, ref nativeState.Position.Y, attachTransform.Angle);
                    MathF.TransformCoord(ref nativeState.Velocity.X, ref nativeState.Velocity.Y, attachTransform.Angle);
                    nativeState.Position += attachTransform.Pos;
                    nativeState.Velocity += attachTransform.Vel;
                }

                // Distance check
                float dist = MathF.Sqrt(
                    (nativeState.Position.X - listenerPos.X) * (nativeState.Position.X - listenerPos.X) +
                    (nativeState.Position.Y - listenerPos.Y) * (nativeState.Position.Y - listenerPos.Y) +
                    (nativeState.Position.Z - listenerPos.Z) * (nativeState.Position.Z - listenerPos.Z) * 0.25f);
                if (dist > nativeState.MaxDistance)
                {
                    this.Dispose();
                    return;
                }
                else
                {
                    priorityTemp *= Math.Max(0.0f, 1.0f - (dist - nativeState.MinDistance) / (nativeState.MaxDistance - nativeState.MinDistance));
                }
            }

            if (this.notYetAssigned)
            {
                // Grab a native audio source
                if (this.GrabNativeSource())
                {
                    this.RegisterPlaying();
                }
                // If there is none available, just stop right there.
                else
                {
                    this.Dispose();
                    return;
                }
            }

            // If the source is stopped / finished, dispose and return
            if (this.native == null || this.native.IsFinished)
            {
                this.Dispose();
                return;
            }

            // Fading in and out
            bool fadeOut = this.fadeTarget <= 0.0f;

            if (!this.paused)
            {
                if (this.fadeTarget != this.curFade)
                {
                    float fadeTemp = Time.TimeMult * Time.SPFMult / Math.Max(0.05f, this.fadeTimeSec);

                    if (this.fadeTarget > this.curFade)
                    {
                        this.curFade += fadeTemp;
                    }
                    else
                    {
                        this.curFade -= fadeTemp;
                    }

                    if (Math.Abs(this.curFade - this.fadeTarget) < fadeTemp * 2.0f)
                    {
                        this.curFade = this.fadeTarget;
                    }
                }
            }

            // Special paused-fading
            if (this.paused && this.pauseFade > 0.0f)
            {
                this.pauseFade = MathF.Max(0.0f, this.pauseFade - Time.TimeMult * Time.SPFMult * 5.0f);
            }
            else if (!this.paused && this.pauseFade < 1.0f)
            {
                this.pauseFade = MathF.Min(1.0f, this.pauseFade + Time.TimeMult * Time.SPFMult * 5.0f);
            }

            // Apply the sounds state to its internal native audio source
            if (this.native != null)
            {
                if (this.is3D)
                {
                    nativeState.RelativeToListener = attachedToListener;
                    if (attachedToListener)
                    {
                        nativeState.Position -= listenerPos;
                    }

                    // Convert from Duality units to (physical) audio backend units.
                    nativeState.Position    *= AudioUnit.LengthToPhysical;
                    nativeState.Velocity    *= AudioUnit.VelocityToPhysical;
                    nativeState.MinDistance *= AudioUnit.LengthToPhysical;
                    nativeState.MaxDistance *= AudioUnit.LengthToPhysical;

                    // Post-process sound instance data in listener space
                    float   listenerAngle = DualityApp.Sound.ListenerAngle;
                    Vector3 adjustedPos   = nativeState.RelativeToListener ? nativeState.Position : nativeState.Position - listenerPos * AudioUnit.LengthToPhysical;
                    MathF.TransformCoord(ref adjustedPos.X, ref adjustedPos.Z, -listenerAngle);

                    // Flatten depth position a little, so far away sounds that can still be seen appear louder
                    adjustedPos.Z *= 0.5f;

                    // Normalize audio position for smooth panning when near. Do it in physical
                    // units, so this remains constant regardless of unit changes.
                    float smoothPanRadius   = 5.0f;
                    float listenerSpaceDist = adjustedPos.Length;
                    if (listenerSpaceDist < smoothPanRadius)
                    {
                        float panningActive = listenerSpaceDist / smoothPanRadius;

                        adjustedPos = Vector3.Lerp(
                            new Vector3(0.0f, 0.0f, 1.0f + (smoothPanRadius - 1.0f) * panningActive),
                            adjustedPos,
                            panningActive);
                    }

                    MathF.TransformCoord(ref adjustedPos.X, ref adjustedPos.Z, listenerAngle);
                    nativeState.Position = nativeState.RelativeToListener ? adjustedPos : adjustedPos + listenerPos * AudioUnit.LengthToPhysical;
                }
                else
                {
                    // We'll do a +/- 30° panning for 2D audio
                    Vector2 localPos = Vector2.FromAngleLength(
                        MathF.DegToRad(30.0f * this.panning),
                        1.0f);

                    nativeState.RelativeToListener = true;
                    nativeState.Position           = new Vector3(localPos.X, 0.0f, -localPos.Y);
                    nativeState.Velocity           = Vector3.Zero;
                }
                nativeState.Looped = this.looped;
                nativeState.Paused = this.paused && this.pauseFade == 0.0f;

                this.native.ApplyState(ref nativeState);
            }

            // Update play time
            if (!this.paused)
            {
                this.playTime += MathF.Max(0.5f, nativeState.Pitch) * Time.TimeMult * Time.SPFMult;
                if (this.sound.Res.FadeOutAt > 0.0f && this.playTime >= this.sound.Res.FadeOutAt)
                {
                    this.FadeOut(this.sound.Res.FadeOutTime);
                }
            }

            // Finish priority calculation
            this.curPriority = (int)Math.Round(priorityTemp / Math.Sqrt(DualityApp.Sound.GetNumPlaying(this.sound)));

            // Initially play the source
            if (this.native.IsInitial && !this.paused)
            {
                if (audioDataRes.IsStreamed)
                {
                    this.native.Play(this);
                }
                else if (audioDataRes.Native != null)
                {
                    this.native.Play(audioDataRes.Native);
                }
            }

            // Remove faded out sources
            if (fadeOut && nativeState.Volume <= 0.0f)
            {
                this.fadeWaitEnd += Time.TimeMult * Time.MsPFMult;
                // After fading out entirely, wait 50 ms before actually stopping the source to prevent unpleasant audio tick / glitch noises
                if (this.fadeWaitEnd > 50.0f)
                {
                    this.Dispose();
                    return;
                }
            }
            else
            {
                this.fadeWaitEnd = 0.0f;
            }
        }
        /// <summary>
        /// Updates the SoundInstance
        /// </summary>
        public void Update()
        {
            // Check existence of attachTo object
            if (this.attachedTo != null && this.attachedTo.Disposed)
            {
                this.attachedTo = null;
            }

            // Retrieve sound resource values
            Sound     soundRes     = this.sound.Res;
            AudioData audioDataRes = this.audioData.Res;

            if (soundRes == null || audioDataRes == null)
            {
                this.Dispose();
                return;
            }

            // Set up local variables for state calculation
            Vector3          listenerPos        = DualityApp.Sound.ListenerPos;
            bool             attachedToListener = this.attachedTo != null && ((this.attachedTo == DualityApp.Sound.Listener) || this.attachedTo.IsChildOf(DualityApp.Sound.Listener));
            float            optVolFactor       = this.GetTypeVolFactor();
            float            priorityTemp       = 1000.0f;
            AudioSourceState nativeState        = AudioSourceState.Default;

            nativeState.MinDistance = soundRes.MinDist;
            nativeState.MaxDistance = soundRes.MaxDist;
            nativeState.Volume      = optVolFactor * soundRes.VolumeFactor * this.vol * this.curFade * this.pauseFade;
            nativeState.Pitch       = soundRes.PitchFactor * this.pitch;
            nativeState.Lowpass     = soundRes.LowpassFactor * this.lowpass;
            priorityTemp           *= nativeState.Volume;

            // Calculate 3D source values, distance and priority
            nativeState.Position = this.pos;
            nativeState.Velocity = this.vel;
            if (this.is3D)
            {
                Components.Transform attachTransform = this.attachedTo != null ? this.attachedTo.Transform : null;

                // Attach to object
                if (this.attachedTo != null)
                {
                    MathF.TransformCoord(ref nativeState.Position.X, ref nativeState.Position.Y, attachTransform.Angle);
                    MathF.TransformCoord(ref nativeState.Velocity.X, ref nativeState.Velocity.Y, attachTransform.Angle);
                    nativeState.Position += attachTransform.Pos;
                    nativeState.Velocity += attachTransform.Vel;
                }

                // Distance check
                float dist = MathF.Sqrt(
                    (nativeState.Position.X - listenerPos.X) * (nativeState.Position.X - listenerPos.X) +
                    (nativeState.Position.Y - listenerPos.Y) * (nativeState.Position.Y - listenerPos.Y) +
                    (nativeState.Position.Z - listenerPos.Z) * (nativeState.Position.Z - listenerPos.Z) * 0.25f);
                if (dist > nativeState.MaxDistance)
                {
                    this.Dispose();
                    return;
                }
                else
                {
                    priorityTemp *= Math.Max(0.0f, 1.0f - (dist - nativeState.MinDistance) / (nativeState.MaxDistance - nativeState.MinDistance));
                }
            }

            if (this.notYetAssigned)
            {
                // Grab a native audio source
                if (this.GrabNativeSource())
                {
                    this.RegisterPlaying();
                }
                // If there is none available, just stop right there.
                else
                {
                    this.Dispose();
                    return;
                }
            }

            // If the source is stopped / finished, dispose and return
            if (this.native == null || this.native.IsFinished)
            {
                this.Dispose();
                return;
            }

            // Fading in and out
            bool fadeOut = this.fadeTarget <= 0.0f;

            if (!this.paused)
            {
                if (this.fadeTarget != this.curFade)
                {
                    float fadeTemp = Time.TimeMult * Time.SPFMult / Math.Max(0.05f, this.fadeTimeSec);

                    if (this.fadeTarget > this.curFade)
                    {
                        this.curFade += fadeTemp;
                    }
                    else
                    {
                        this.curFade -= fadeTemp;
                    }

                    if (Math.Abs(this.curFade - this.fadeTarget) < fadeTemp * 2.0f)
                    {
                        this.curFade = this.fadeTarget;
                    }
                }
            }

            // Special paused-fading
            if (this.paused && this.pauseFade > 0.0f)
            {
                this.pauseFade = MathF.Max(0.0f, this.pauseFade - Time.TimeMult * Time.SPFMult * 5.0f);
            }
            else if (!this.paused && this.pauseFade < 1.0f)
            {
                this.pauseFade = MathF.Min(1.0f, this.pauseFade + Time.TimeMult * Time.SPFMult * 5.0f);
            }

            // Apply the sounds state to its internal native audio source
            if (this.native != null)
            {
                if (this.is3D)
                {
                    nativeState.RelativeToListener = attachedToListener;
                    if (attachedToListener)
                    {
                        nativeState.Position -= listenerPos;
                    }
                }
                else
                {
                    nativeState.RelativeToListener = true;
                    nativeState.Position           = new Vector3(this.panning, 0.0f, 0.0f);
                    nativeState.Velocity           = Vector3.Zero;
                }
                nativeState.Looped = this.looped;
                nativeState.Paused = this.paused && this.pauseFade == 0.0f;

                this.native.ApplyState(ref nativeState);
            }

            // Update play time
            if (!this.paused)
            {
                this.playTime += MathF.Max(0.5f, nativeState.Pitch) * Time.TimeMult * Time.SPFMult;
                if (this.sound.Res.FadeOutAt > 0.0f && this.playTime >= this.sound.Res.FadeOutAt)
                {
                    this.FadeOut(this.sound.Res.FadeOutTime);
                }
            }

            // Finish priority calculation
            this.curPriority = (int)Math.Round(priorityTemp / Math.Sqrt(DualityApp.Sound.GetNumPlaying(this.sound)));

            // Initially play the source
            if (this.native.IsInitial && !this.paused)
            {
                if (audioDataRes.IsStreamed)
                {
                    this.native.Play(this);
                }
                else if (audioDataRes.Native != null)
                {
                    this.native.Play(audioDataRes.Native);
                }
            }

            // Remove faded out sources
            if (fadeOut && nativeState.Volume <= 0.0f)
            {
                this.fadeWaitEnd += Time.TimeMult * Time.MsPFMult;
                // After fading out entirely, wait 50 ms before actually stopping the source to prevent unpleasant audio tick / glitch noises
                if (this.fadeWaitEnd > 50.0f)
                {
                    this.Dispose();
                    return;
                }
            }
            else
            {
                this.fadeWaitEnd = 0.0f;
            }
        }