logo SERENITY
Game Systems Foundation
Search Results for

    Show / Hide Table of Contents

    Class AudioPortalRouting

    Pure rules for hearing a sound through a doorway: how long the way through a portal is, which portal to use without flipping between two near-equal ones, and how that route changes what the depth cues hear. Engine-free on purpose: only System.Numerics types.

    Inheritance
    object
    AudioPortalRouting
    Inherited Members
    object.ToString()
    object.Equals(object)
    object.Equals(object, object)
    object.ReferenceEquals(object, object)
    object.GetHashCode()
    object.GetType()
    object.MemberwiseClone()
    Namespace: Serenity.AudioPlayer.Domain.Services
    Assembly: Serenity.AudioPlayer.Domain.dll
    Syntax
    public static class AudioPortalRouting

    Fields

    NoPortal

    The index SelectPortal(Vector3, Vector3, ReadOnlySpan<Vector3>, int) answers when no portal can be used.

    Declaration
    public const int NoPortal = -1
    Field Value
    Type Description
    int

    PortalSwitchMarginMeters

    How much shorter another portal's path must be before a voice leaves the portal it is already heard through.

    Declaration
    public const float PortalSwitchMarginMeters = 0.5
    Field Value
    Type Description
    float

    RouteKeepMarginAmount

    How much more occluded than the straight line a kept route may read before the voice stops being routed.

    Declaration
    public const float RouteKeepMarginAmount = 0.05
    Field Value
    Type Description
    float

    Methods

    ExtraPathViaPortal(Vector3, Vector3, Vector3)

    How much longer than the straight line the way through the portal is. Never negative: rounding that makes the path a hair shorter than the straight line reads as no extra path. Positive infinity when the positions are unusable (not a number), like the extra path around a box, so a measurement that cannot be trusted reads as a long way round.

    Declaration
    public static float ExtraPathViaPortal(Vector3 listener, Vector3 source, Vector3 portal)
    Parameters
    Type Name Description
    Vector3 listener
    Vector3 source
    Vector3 portal
    Returns
    Type Description
    float

    PathLengthViaPortal(Vector3, Vector3, Vector3)

    The length of the way from the listener to the source through the portal: both legs added.

    Declaration
    public static float PathLengthViaPortal(Vector3 listener, Vector3 source, Vector3 portal)
    Parameters
    Type Name Description
    Vector3 listener
    Vector3 source
    Vector3 portal
    Returns
    Type Description
    float

    RoutedAmount(float, float)

    The occlusion a routed voice is heard with: the lower of the straight line and the way through the portal, so a route never makes things worse. A way through the portal that is not a number counts as blocked: the straight line stands.

    Declaration
    public static float RoutedAmount(float directAmount, float viaPortalAmount)
    Parameters
    Type Name Description
    float directAmount
    float viaPortalAmount
    Returns
    Type Description
    float

    SelectPortal(Vector3, Vector3, ReadOnlySpan<Vector3>, int)

    The index of the portal with the shortest way through it, or NoPortal when none is usable. Equal paths pick the lowest index. A previously selected portal is kept unless another is shorter by more than PortalSwitchMarginMeters, so a source orbiting between two doorways does not make the route flicker. A portal whose position is not a number is never selected.

    Declaration
    public static int SelectPortal(Vector3 listener, Vector3 source, ReadOnlySpan<Vector3> portals, int previousIndex)
    Parameters
    Type Name Description
    Vector3 listener
    Vector3 source
    ReadOnlySpan<Vector3> portals
    int previousIndex
    Returns
    Type Description
    int

    ShouldAskPortalQuestion(float, bool, bool, bool)

    Whether to ask the portal question for a voice: its straight line is occluded, exactly one of the listener and the source is inside the room, and the room has an open portal. Both in the same room, or in two different rooms, keep the straight-line occlusion.

    Declaration
    public static bool ShouldAskPortalQuestion(float directAmount, bool listenerInside, bool sourceInside, bool roomHasOpenPortal)
    Parameters
    Type Name Description
    float directAmount
    bool listenerInside
    bool sourceInside
    bool roomHasOpenPortal
    Returns
    Type Description
    bool

    ShouldRoute(float, float, bool)

    Whether the voice is routed: only while the straight line is occluded and the way through the portal is not fully blocked. It is taken when the portal is less occluded than the straight line, and kept until it is RouteKeepMarginAmount more occluded, so two near-equal amounts do not flip the route every probe.

    Declaration
    public static bool ShouldRoute(float directAmount, float viaPortalAmount, bool isRouted)
    Parameters
    Type Name Description
    float directAmount
    float viaPortalAmount
    bool isRouted
    Returns
    Type Description
    bool

    ViaPortalAmount(float, float, float)

    How occluded the way through the portal is. A leg that is not a number counts as blocked. When occlusion is all-or-nothing it is the portal leg alone; otherwise it is the larger of the leg and the curve for the extra path, so a long way round reads as more muffled than a short one, and an extra path that is not a number as fully blocked.

    Declaration
    public static float ViaPortalAmount(float legAmount, float extraPathMeters, float fullOcclusionDetourMeters)
    Parameters
    Type Name Description
    float legAmount
    float extraPathMeters
    float fullOcclusionDetourMeters
    Returns
    Type Description
    float
    In this article
    © 2026 Serenity. All Rights Reserved