// Updates room properties with the given |reverbProbe|. For a reverb probe, the room properties // are used only in computing the distance attenuation. private static void UpdateRoomProperties(ResonanceAudioReverbProbe reverbProbe) { Vector3 scale = Vector3.zero; if (reverbProbe.runtimeApplicationRegionShape == ResonanceAudioReverbProbe.ApplicationRegionShape.Sphere) { // Use the minimum enclosing cube of the sphere for distance attenuation. var diameter = 2.0f * reverbProbe.GetScaledSphericalApplicationRegionRadius(); scale = diameter * Vector3.one; } else { scale = reverbProbe.GetScaledBoxApplicationRegionSize(); } FillGeometryOfRoomProperties(reverbProbe.transform.position, reverbProbe.transform.rotation, scale); // Surface materials are not needed for reverb probes. var surfaceMaterial = ResonanceAudioRoomManager.SurfaceMaterial.Transparent; FillWallMaterialsOfRoomProperties(surfaceMaterial, surfaceMaterial, surfaceMaterial, surfaceMaterial, surfaceMaterial, surfaceMaterial); // Reflectivity is not a responsibility of reverb probes. float reflectivity = 0.0f; FillModifiersOfRoomProperties(reverbProbe.reverbGainDb, reverbProbe.reverbTime, reverbProbe.reverbBrightness, reflectivity); }
// Returns room properties of the given |reverbProbe|. For a reverb probe, the room properties // are used only in computing the distance attenuation. private static RoomProperties GetRoomProperties(ResonanceAudioReverbProbe reverbProbe) { RoomProperties roomProperties = new RoomProperties(); Vector3 scale; if (reverbProbe.runtimeApplicationRegionShape == ResonanceAudioReverbProbe.ApplicationRegionShape.Sphere) { // Use the minimum enclosing cube of the sphere for distance attenuation. var diameter = 2.0f * reverbProbe.GetScaledSphericalApplicationRegionRadius(); scale = new Vector3(diameter, diameter, diameter); } else { scale = reverbProbe.GetScaledBoxApplicationRegionSize(); } FillGeometryOfRoomProperties(reverbProbe.transform.position, reverbProbe.transform.rotation, scale, ref roomProperties); float reflectivity = 0.0f; // Reflectivity is not a responsibility of reverb probes. FillModifiersOfRoomProperties(reverbProbe.reverbGainDb, reverbProbe.reverbTime, reverbProbe.reverbBrightness, reflectivity, ref roomProperties); return(roomProperties); }
/// Updates the room effects of the environment with given |reverbProbe|. /// @note This should only be called from the main Unity thread. public static void UpdateReverbProbe(ResonanceAudioReverbProbe reverbPobe) { if (roomPropertiesPtr == IntPtr.Zero) { // Allocate the unmanaged memory only once. roomPropertiesPtr = Marshal.AllocHGlobal(Marshal.SizeOf(roomProperties)); } UpdateRoomProperties(reverbPobe); Marshal.StructureToPtr(roomProperties, roomPropertiesPtr, false); SetRoomProperties(roomPropertiesPtr, reverbPobe.rt60s); Marshal.DestroyStructure(roomPropertiesPtr, typeof(RoomProperties)); }
// Updates room properties with the given |reverbProbe|. private static void UpdateRoomProperties(ResonanceAudioReverbProbe reverbProbe) { FillGeometryOfRoomProperties(reverbProbe.proxyRoomPosition, reverbProbe.proxyRoomRotation, reverbProbe.proxyRoomSize); FillWallMaterialsOfRoomProperties(reverbProbe.proxyRoomLeftWall, reverbProbe.proxyRoomRightWall, reverbProbe.proxyRoomFloor, reverbProbe.proxyRoomCeiling, reverbProbe.proxyRoomFrontWall, reverbProbe.proxyRoomBackWall); // We do not modify the reflectivity of proxy rooms. float reflectivity = 1.0f; FillModifiersOfRoomProperties(reverbProbe.reverbGainDb, reverbProbe.reverbTime, reverbProbe.reverbBrightness, reflectivity); }
/// Updates the room effects of the environment with given |reverbProbe|. /// @note This should only be called from the main Unity thread. public static void UpdateReverbProbe(ResonanceAudioReverbProbe currentReverbProbe) { if (roomPropertiesPtr == IntPtr.Zero) { // Allocate the unmanaged memory only once. roomPropertiesPtr = Marshal.AllocHGlobal(Marshal.SizeOf(roomProperties)); } UpdateRoomProperties(currentReverbProbe); Marshal.StructureToPtr(roomProperties, roomPropertiesPtr, false); SetRoomProperties(roomPropertiesPtr); // Proxy room properties. Used in calculating reflection effects. UpdateProxyRoomProperties(currentReverbProbe); Marshal.StructureToPtr(roomProperties, roomPropertiesPtr, true); SetRt60ValuesAndProxyRoomProperties(currentReverbProbe.rt60s, roomPropertiesPtr); Marshal.DestroyStructure(roomPropertiesPtr, typeof(RoomProperties)); }
// Returns proxy room properties of the given |reverbProbe|. private static RoomProperties GetProxyRoomProperties(ResonanceAudioReverbProbe reverbProbe) { RoomProperties proxyRoomProperties = new RoomProperties(); FillGeometryOfRoomProperties(reverbProbe.proxyRoomPosition, reverbProbe.proxyRoomRotation, reverbProbe.proxyRoomSize, ref proxyRoomProperties); FillWallMaterialsOfRoomProperties(reverbProbe.proxyRoomLeftWall, reverbProbe.proxyRoomRightWall, reverbProbe.proxyRoomFloor, reverbProbe.proxyRoomCeiling, reverbProbe.proxyRoomFrontWall, reverbProbe.proxyRoomBackWall, ref proxyRoomProperties); float reflectivity = 1.0f; // We do not modify the reflectivity of proxy rooms. FillModifiersOfRoomProperties(reverbProbe.reverbGainDb, reverbProbe.reverbTime, reverbProbe.reverbBrightness, reflectivity, ref proxyRoomProperties); return(proxyRoomProperties); }
/// Updates the room effects of the environment with given |reverbProbe|. /// @note This should only be called from the main Unity thread. public static void UpdateReverbProbe(ResonanceAudioReverbProbe currentReverbProbe) { // Room properties. Used in calculating distance attenuation. RoomProperties roomProperties = GetRoomProperties(currentReverbProbe); // Pass the room properties into a pointer. IntPtr roomPropertiesPtr = Marshal.AllocHGlobal(Marshal.SizeOf(roomProperties)); Marshal.StructureToPtr(roomProperties, roomPropertiesPtr, false); SetRoomProperties(roomPropertiesPtr); Marshal.FreeHGlobal(roomPropertiesPtr); // Proxy room properties. Used in calculating reflection effects. RoomProperties proxyRoomProperties = GetProxyRoomProperties(currentReverbProbe); // Pass the proxy room properties into a pointer. IntPtr proxyRoomPropertiesPtr = Marshal.AllocHGlobal(Marshal.SizeOf(proxyRoomProperties)); Marshal.StructureToPtr(proxyRoomProperties, proxyRoomPropertiesPtr, false); SetRt60ValuesAndProxyRoomProperties(currentReverbProbe.rt60s, proxyRoomPropertiesPtr); Marshal.FreeHGlobal(proxyRoomPropertiesPtr); }
/// Sets computed |proxyRoomProperties| for the given |reverbProbe|. Proxy rooms are estimated by /// the ray-tracing engine and passed back to be used in real-time early reflections. private static void SetProxyRoomProperties(ResonanceAudioReverbProbe reverbProbe, RoomProperties proxyRoomProperties) { reverbProbe.proxyRoomPosition.x = proxyRoomProperties.positionX; reverbProbe.proxyRoomPosition.y = proxyRoomProperties.positionY; reverbProbe.proxyRoomPosition.z = proxyRoomProperties.positionZ; reverbProbe.proxyRoomRotation.x = proxyRoomProperties.rotationX; reverbProbe.proxyRoomRotation.y = proxyRoomProperties.rotationY; reverbProbe.proxyRoomRotation.z = proxyRoomProperties.rotationZ; reverbProbe.proxyRoomRotation.w = proxyRoomProperties.rotationW; reverbProbe.proxyRoomSize.x = proxyRoomProperties.dimensionsX; reverbProbe.proxyRoomSize.y = proxyRoomProperties.dimensionsY; reverbProbe.proxyRoomSize.z = proxyRoomProperties.dimensionsZ; reverbProbe.proxyRoomLeftWall = proxyRoomProperties.materialLeft; reverbProbe.proxyRoomRightWall = proxyRoomProperties.materialRight; reverbProbe.proxyRoomFloor = proxyRoomProperties.materialBottom; reverbProbe.proxyRoomCeiling = proxyRoomProperties.materialTop; reverbProbe.proxyRoomBackWall = proxyRoomProperties.materialBack; reverbProbe.proxyRoomFrontWall = proxyRoomProperties.materialFront; }
// Updates the list of room effects regions with the given |reverbProbe|. private static void UpdateRoomEffectsRegions(ResonanceAudioReverbProbe reverbProbe, bool isEnabled) { int regionIndex = -1; for (int i = 0; i < roomEffectsRegions.Count; ++i) { if (roomEffectsRegions[i].reverbProbe == reverbProbe) { regionIndex = i; break; } } if (isEnabled && regionIndex == -1) { roomEffectsRegions.Add(new RoomEffectsRegion(null, reverbProbe)); } else if (!isEnabled && regionIndex != -1) { roomEffectsRegions.RemoveAt(regionIndex); } }
/// Returns whether the listener is currently inside the application region of the given /// |reverb_probe|, subject to the visibility test if |reverbProbe.onlyWhenVisible| is true. private static bool IsListenerInsideVisibleReverbProbe(ResonanceAudioReverbProbe reverbProbe) { Transform listenerTransform = ResonanceAudio.ListenerTransform; if (listenerTransform != null) { Vector3 relativePosition = listenerTransform.position - reverbProbe.transform.position; // First the containing test. if (reverbProbe.runtimeApplicationRegionShape == ResonanceAudioReverbProbe.ApplicationRegionShape.Sphere) { if (relativePosition.magnitude > reverbProbe.GetScaledSphericalApplicationRegionRadius()) { return(false); } } else { Quaternion rotationInverse = Quaternion.Inverse(reverbProbe.transform.rotation); bounds.size = reverbProbe.GetScaledBoxApplicationRegionSize(); if (!bounds.Contains(rotationInverse * relativePosition)) { return(false); } } // Then the visibility test. if (reverbProbe.onlyApplyWhenVisible) { if (ResonanceAudio.ComputeOcclusion(reverbProbe.transform) > 0.0f) { return(false); } } return(true); } return(false); }
/// Computes the RT60s and proxy room properties. /// @note This should only be called from the main Unity thread. public static bool ComputeRt60sAndProxyRoom(ResonanceAudioReverbProbe reverbProbe, int totalNumPaths, int numPathsPerBatch, int maxDepth, float energyThreshold, float listenerSphereRadius) { #if UNITY_EDITOR Vector3 reverbProbePosition = reverbProbe.transform.position; roomPosition[0] = reverbProbePosition.x; roomPosition[1] = reverbProbePosition.y; roomPosition[2] = reverbProbePosition.z; IntPtr proxyRoomPropertiesPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(RoomProperties))); float sampleRate = (float)AudioSettings.GetConfiguration().sampleRate; int impulseResponseNumSamples = (int)(maxReverbTime * sampleRate); if (!ComputeRt60sAndProxyRoom(totalNumPaths, numPathsPerBatch, maxDepth, energyThreshold, roomPosition, listenerSphereRadius, sampleRate, impulseResponseNumSamples, reverbProbe.rt60s, proxyRoomPropertiesPtr)) { return(false); } // Validate the computed RT60s for all frequency bands to the reverb probe. for (int band = 0; band < reverbProbe.rt60s.Length; ++band) { reverbProbe.rt60s[band] = Mathf.Clamp(reverbProbe.rt60s[band], 0.0f, ResonanceAudio.maxReverbTime); } // Copy the estimated proxy room properties to the reverb probe. RoomProperties proxyRoomProperties = (RoomProperties)Marshal.PtrToStructure(proxyRoomPropertiesPtr, typeof(RoomProperties)); SetProxyRoomProperties(reverbProbe, proxyRoomProperties); Marshal.FreeHGlobal(proxyRoomPropertiesPtr); return(true); #else return(false); #endif // UNITY_EDITOR }
public RoomEffectsRegion(ResonanceAudioRoom room, ResonanceAudioReverbProbe reverbProbe) { this.room = room; this.reverbProbe = reverbProbe; }
/// Removes a Resonance Audio reverb probe. public static void RemoveReverbProbe(ResonanceAudioReverbProbe reverbProbe) { UpdateRoomEffectsRegions(reverbProbe, false); UpdateRoomEffects(); }
/// Adds or removes a Resonance Audio reverb probe depending on whether the listener is inside /// |reverbProbe|. public static void UpdateReverbProbe(ResonanceAudioReverbProbe reverbProbe) { UpdateRoomEffectsRegions(reverbProbe, IsListenerInsideVisibleReverbProbe(reverbProbe)); UpdateRoomEffects(); }
/// Constructs an instance that holds a Resonance Audio room. public RoomEffectsRegion(ResonanceAudioRoom room) { this.room = room; this.reverbProbe = null; }