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
AudioPortalRouting
Assembly: Serenity.AudioPlayer.Domain.dll
Syntax
public static class AudioPortalRouting
Fields
NoPortal
Declaration
public const int NoPortal = -1
Field Value
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
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
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
Returns
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
Returns
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
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
Returns
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
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
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