Skip to content
This repository has been archived by the owner on Dec 19, 2022. It is now read-only.

Commit

Permalink
Resonance Audio Unity SDK 1.2.1
Browse files Browse the repository at this point in the history
  • Loading branch information
anokta committed Apr 5, 2018
1 parent 2ae1c7b commit 78a4246
Show file tree
Hide file tree
Showing 21 changed files with 180 additions and 162 deletions.
9 changes: 9 additions & 0 deletions Assets/ResonanceAudio/Editor/ResonanceAudioBuildProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
using UnityEditor;
using UnityEditor.Build;
using UnityEngine;
#if UNITY_2018_1_OR_NEWER
using UnityEditor.Build.Reporting;
#endif // UNITY_2018_1_OR_NEWER

// Notify developer if conflicting Google VR audio libraries are present.
class ResonanceAudioBuildProcessor : IPreprocessBuild {
Expand Down Expand Up @@ -48,6 +51,12 @@ public int callbackOrder {
get { return 0; }
}

#if UNITY_2018_1_OR_NEWER
public void OnPreprocessBuild(BuildReport report) {
OnPreprocessBuild(report.summary.platform, report.summary.outputPath);
}
#endif // UNITY_2018_1_OR_NEWER

public void OnPreprocessBuild(BuildTarget target, string path) {
// Find Google VR audio asset to delete.
List<string> assetPaths = new List<string>();
Expand Down
30 changes: 4 additions & 26 deletions Assets/ResonanceAudio/Editor/ResonanceAudioReverbComputer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -126,39 +126,17 @@ private static bool ComputeReverbForSceneGeometry() {
// Initializes the reverb computation engine: creates the scene, sets up the surface materials,
// and prepares the ray tracer.
ResonanceAudio.InitializeReverbComputer(vertices, triangles, materials, scatteringCoefficient);

// Iterate through the selected reverb probes.
for (int i = 0; i < selectedReverbProbes.Count; ++i) {
var reverbProbe = selectedReverbProbes[i];
string probeName = "Probe[" + i + "] " + reverbProbe.gameObject.name;
Undo.RecordObject(reverbProbe, "Bake Reverb To Reverb Probes");

// Compute the RT60s and estimate the proxy room.
var probePosition = reverbProbe.gameObject.transform.position;
var outputRt60s = reverbProbe.rt60s;
ResonanceAudio.RoomProperties outputProxyRoomProperties = new ResonanceAudio.RoomProperties();
if (!ResonanceAudio.ComputeRt60sAndProxyRoom(totalNumPaths, numPathsPerBatch, maxDepth,
energyThreshold, probePosition,
listenerSphereRadius, ref outputRt60s,
ref outputProxyRoomProperties)) {
Debug.LogError("FAILED c++ ComputeRT60sAndProxyRoom for " + probeName);
if (!ResonanceAudio.ComputeRt60sAndProxyRoom(reverbProbe, totalNumPaths, numPathsPerBatch,
maxDepth, energyThreshold,
listenerSphereRadius)) {
Debug.LogError("Failed to compute reverb probe[" + i + "] " + reverbProbe.gameObject.name);
return false;
}

// Validate the computed RT60s for all frequency bands to the reverb probe.
for (int band = 0; band < outputRt60s.Length; ++band) {
float outputRt60Value = outputRt60s[band];
if (Single.IsNaN(outputRt60Value) || Single.IsInfinity(outputRt60Value)) {
Debug.Log("Invalid RT60 for " + probeName + ": " + outputRt60Value + "; set to zero");
outputRt60Value = 0.0f;
} else if (outputRt60Value > ResonanceAudio.maxReverbTime || outputRt60Value < 0.0f) {
outputRt60Value = Mathf.Clamp(outputRt60Value, 0.0f, ResonanceAudio.maxReverbTime);
}
outputRt60s[band] = outputRt60Value;
}

// Copy the estimated proxy room properties to the reverb probe.
reverbProbe.SetProxyRoomProperties(outputProxyRoomProperties);
}
return true;
}
Expand Down
32 changes: 15 additions & 17 deletions Assets/ResonanceAudio/Editor/ResonanceAudioReverbProbeEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,18 @@
[CustomEditor(typeof(ResonanceAudioReverbProbe))]
[CanEditMultipleObjects]
public class ResonanceAudioReverbProbeEditor : Editor {
private SerializedProperty runtimeApplicationRegionShape = null;
private SerializedProperty boxApplicationRegionSize = null;
private SerializedProperty sphereApplicationRegionRadius = null;
private SerializedProperty regionShape = null;
private SerializedProperty boxRegionSize = null;
private SerializedProperty sphereRegionRadius = null;
private SerializedProperty onlyApplyWhenVisible = null;
private SerializedProperty reverbGainDb = null;
private SerializedProperty reverbBrightness = null;
private SerializedProperty reverbTime = null;
private SerializedProperty rt60s = null;

private GUIContent applicationRegionShapeLabel = new GUIContent("Shape");
private GUIContent boxApplicationRegionSizeLabel = new GUIContent("Size");
private GUIContent sphereApplicationRegionRadiusLabel = new GUIContent("Radius");
private GUIContent regionShapeLabel = new GUIContent("Shape");
private GUIContent boxRegionSizeLabel = new GUIContent("Size");
private GUIContent sphereRegionRadiusLabel = new GUIContent("Radius");
private GUIContent onlyApplyWhenVisibleLabel = new GUIContent("Only When Visible");
private GUIContent reverbPropertiesLabel = new GUIContent("Reverb Properties",
"Parameters to adjust the reverb properties of the room.");
Expand All @@ -50,9 +50,9 @@ public class ResonanceAudioReverbProbeEditor : Editor {
private const int rt60ValueFieldMinWidth = 20;

void OnEnable () {
runtimeApplicationRegionShape = serializedObject.FindProperty("runtimeApplicationRegionShape");
boxApplicationRegionSize = serializedObject.FindProperty("boxApplicationRegionSize");
sphereApplicationRegionRadius = serializedObject.FindProperty("sphereApplicationRegionRadius");
regionShape = serializedObject.FindProperty("regionShape");
boxRegionSize = serializedObject.FindProperty("boxRegionSize");
sphereRegionRadius = serializedObject.FindProperty("sphereRegionRadius");
onlyApplyWhenVisible = serializedObject.FindProperty("onlyApplyWhenVisible");
reverbGainDb = serializedObject.FindProperty("reverbGainDb");
reverbBrightness = serializedObject.FindProperty("reverbBrightness");
Expand Down Expand Up @@ -80,15 +80,13 @@ public override void OnInspectorGUI () {

// Show the parameters of the region of application.
private void DrawApplicationRegion() {
EditorGUILayout.PropertyField(runtimeApplicationRegionShape, applicationRegionShapeLabel);
switch ((ResonanceAudioReverbProbe.ApplicationRegionShape)
runtimeApplicationRegionShape.enumValueIndex) {
case ResonanceAudioReverbProbe.ApplicationRegionShape.Sphere:
EditorGUILayout.PropertyField(sphereApplicationRegionRadius,
sphereApplicationRegionRadiusLabel);
EditorGUILayout.PropertyField(regionShape, regionShapeLabel);
switch ((ResonanceAudioReverbProbe.RegionShape) regionShape.enumValueIndex) {
case ResonanceAudioReverbProbe.RegionShape.Sphere:
EditorGUILayout.PropertyField(sphereRegionRadius, sphereRegionRadiusLabel);
break;
case ResonanceAudioReverbProbe.ApplicationRegionShape.Box:
EditorGUILayout.PropertyField(boxApplicationRegionSize, boxApplicationRegionSizeLabel);
case ResonanceAudioReverbProbe.RegionShape.Box:
EditorGUILayout.PropertyField(boxRegionSize, boxRegionSizeLabel);
break;
}
EditorGUILayout.PropertyField(onlyApplyWhenVisible, onlyApplyWhenVisibleLabel);
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
117 changes: 58 additions & 59 deletions Assets/ResonanceAudio/Scripts/ResonanceAudio.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,43 +72,37 @@ public static void UpdateAudioListener(ResonanceAudioListener listener) {
/// @note This should only be called from the main Unity thread.
public static void DisableRoomEffects() {
// Set the room properties to null, which will effectively disable the room effects.
SetRoomProperties(IntPtr.Zero);
SetRt60ValuesAndProxyRoomProperties(null, IntPtr.Zero);
SetRoomProperties(IntPtr.Zero, null);
if (roomPropertiesPtr != IntPtr.Zero) {
// Free up the unmanaged memory.
Marshal.FreeHGlobal(roomPropertiesPtr);
roomPropertiesPtr = IntPtr.Zero;
}
}

/// Updates the room effects of the environment with given |room| properties.
/// Updates the room effects of the environment with the given |room|.
/// @note This should only be called from the main Unity thread.
public static void UpdateRoom(ResonanceAudioRoom currentRoom) {
public static void UpdateRoom(ResonanceAudioRoom room) {
if (roomPropertiesPtr == IntPtr.Zero) {
// Allocate the unmanaged memory only once.
roomPropertiesPtr = Marshal.AllocHGlobal(Marshal.SizeOf(roomProperties));
}
UpdateRoomProperties(currentRoom);
UpdateRoomProperties(room);
Marshal.StructureToPtr(roomProperties, roomPropertiesPtr, false);
SetRoomProperties(roomPropertiesPtr);
SetRt60ValuesAndProxyRoomProperties(null, IntPtr.Zero);
SetRoomProperties(roomPropertiesPtr, null);
Marshal.DestroyStructure(roomPropertiesPtr, typeof(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 currentReverbProbe) {
public static void UpdateReverbProbe(ResonanceAudioReverbProbe reverbPobe) {
if (roomPropertiesPtr == IntPtr.Zero) {
// Allocate the unmanaged memory only once.
roomPropertiesPtr = Marshal.AllocHGlobal(Marshal.SizeOf(roomProperties));
}
UpdateRoomProperties(currentReverbProbe);
UpdateRoomProperties(reverbPobe);
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);
SetRoomProperties(roomPropertiesPtr, reverbPobe.rt60s);
Marshal.DestroyStructure(roomPropertiesPtr, typeof(RoomProperties));
}

Expand Down Expand Up @@ -144,27 +138,36 @@ public static void InitializeReverbComputer(float[] vertices, int[] triangles,

/// Computes the RT60s and proxy room properties.
/// @note This should only be called from the main Unity thread.
public static bool ComputeRt60sAndProxyRoom(
int totalNumPaths, int numPathsPerBatch, int maxDepth, float energyThreshold,
Vector3 probePosition, float listenerSphereRadius, ref float[] outputRt60s,
ref RoomProperties outputProxyRoomProperties) {
public static bool ComputeRt60sAndProxyRoom(ResonanceAudioReverbProbe reverbProbe,
int totalNumPaths, int numPathsPerBatch, int maxDepth,
float energyThreshold, float listenerSphereRadius) {
#if UNITY_EDITOR
float[] probePositionFloatArray =
new float[] {probePosition.x, probePosition.y, probePosition.z};
IntPtr outputProxyRoomPropertiesPtr =
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,
probePositionFloatArray, listenerSphereRadius, sampleRate,
impulseResponseNumSamples, outputRt60s,
outputProxyRoomPropertiesPtr)) {
roomPosition, listenerSphereRadius, sampleRate,
impulseResponseNumSamples, reverbProbe.rt60s,
proxyRoomPropertiesPtr)) {
return false;
}

outputProxyRoomProperties = (RoomProperties) Marshal.PtrToStructure(
outputProxyRoomPropertiesPtr, typeof(RoomProperties));
Marshal.FreeHGlobal(outputProxyRoomPropertiesPtr);
// 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;
Expand Down Expand Up @@ -252,7 +255,7 @@ public static Vector2[] Generate2dPolarPattern(float alpha, float order, int res
public const float occlusionDetectionInterval = 0.2f;

[StructLayout(LayoutKind.Sequential)]
public class RoomProperties {
private class RoomProperties {
// Center position of the room in world space.
public float positionX;
public float positionY;
Expand Down Expand Up @@ -301,6 +304,28 @@ private static void ConvertAudioTransformFromUnity(ref Vector3 position,
rotation = Quaternion.LookRotation(transformMatrix.GetColumn(2), transformMatrix.GetColumn(1));
}

/// 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 room properties with the given |room|.
private static void UpdateRoomProperties(ResonanceAudioRoom room) {
FillGeometryOfRoomProperties(room.transform.position, room.transform.rotation,
Expand All @@ -311,35 +336,10 @@ private static void UpdateRoomProperties(ResonanceAudioRoom room) {
room.reflectivity);
}

// Updates room properties with the given |reverbProbe|. For a reverb probe, the room properties
// are used only in computing the distance attenuation.
// Updates room properties with the given |reverbProbe|.
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);
}

// Updates room properties with the proxy room of the given |reverbProbe|.
private static void UpdateProxyRoomProperties(ResonanceAudioReverbProbe reverbProbe) {
FillGeometryOfRoomProperties(reverbProbe.proxyRoomPosition, reverbProbe.proxyRoomRotation,
reverbProbe.proxyRoomSize);

FillWallMaterialsOfRoomProperties(reverbProbe.proxyRoomLeftWall, reverbProbe.proxyRoomRightWall,
reverbProbe.proxyRoomFloor, reverbProbe.proxyRoomCeiling,
reverbProbe.proxyRoomFrontWall,
Expand Down Expand Up @@ -401,6 +401,9 @@ private static void FillModifiersOfRoomProperties(float reverbGainDb, float reve
// Occlusion layer mask.
private static int occlusionMaskValue = -1;

// Pre-allocated position array for proxy room computation.
private static float[] roomPosition = new float[3];

// Pre-allocated room properties instance for room effects computation.
private static RoomProperties roomProperties = new RoomProperties();

Expand All @@ -425,11 +428,7 @@ private static void FillModifiersOfRoomProperties(float reverbGainDb, float reve

// Room handlers.
[DllImport(pluginName)]
private static extern void SetRoomProperties(IntPtr roomProperties);

[DllImport(pluginName)]
private static extern void SetRt60ValuesAndProxyRoomProperties(float[] rt60s,
IntPtr proxyRoomProperties);
private static extern void SetRoomProperties(IntPtr roomProperties, float[] rt60s);

#if UNITY_EDITOR
// Soundfield recorder handlers.
Expand Down
6 changes: 6 additions & 0 deletions Assets/ResonanceAudio/Scripts/ResonanceAudioAcousticMesh.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,12 @@ public static ResonanceAudioAcousticMesh GenerateFromMeshFilter(MeshFilter meshF
Shader surfaceMaterialShader) {
var sourceObject = meshFilter.gameObject;
var sourceMesh = meshFilter.sharedMesh;
if (sourceMesh == null) {
Debug.LogWarning("GameObject: " + sourceObject.name + " has no mesh and will not be " +
"included in reverb baking.");
return null;
}

int numTriangleIndices = CountTriangleIndices(sourceMesh);
int numVertices = sourceMesh.vertexCount;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,6 @@ private void BuildUnityMaterialData(MeshRenderer[] meshRenderers,
var acousticMesh = ResonanceAudioAcousticMesh.GenerateFromMeshFilter(
gameObject.GetComponent<MeshFilter>(), surfaceMaterialShader);
if (acousticMesh == null) {
Debug.LogError("acousticMesh == null");
continue;
}

Expand Down
Loading

0 comments on commit 78a4246

Please sign in to comment.