clean project

This commit is contained in:
Helar Jaadla
2022-03-07 17:52:41 +02:00
parent a174b45bd2
commit cbeb10ec35
5100 changed files with 837159 additions and 0 deletions

View File

@@ -0,0 +1,142 @@
/************************************************************************************
Filename : ONSPAmbisonicsNative.cs
Content : Native interface into the Oculus Ambisonics
Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
Licensed under the Oculus SDK Version 3.5 (the "License");
you may not use the Oculus SDK except in compliance with the License,
which is provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
You may obtain a copy of the License at
https://developer.oculus.com/licenses/sdk-3.5/
Unless required by applicable law or agreed to in writing, the Oculus SDK
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
************************************************************************************/
using UnityEngine;
using System.Collections;
using System.Runtime.InteropServices;
public class ONSPAmbisonicsNative : MonoBehaviour
{
// this caches the audio source so that per-frame reflection isnt needed to use them.
AudioSource source;
#if !UNITY_5
static int numFOAChannels = 4; // we are only dealing with 1st order Ambisonics at this time
static int paramAmbiStat = 6; // use this to return internal Ambisonic status
// Staus codes that may return from Ambisonic engine
public enum ovrAmbisonicsNativeStatus
{
Uninitialized = -1, // Ambisonic stream not initialized (inital status)
NotEnabled, // Ambisonic has not been enabled on clip
Success, // Stream initialized and playing
StreamError, // Something wrong with input stream (not a 4-channel AmbiX format stream?)
ProcessError, // Handling of stream error
MaxStatValue
};
// current status
ovrAmbisonicsNativeStatus currentStatus = ovrAmbisonicsNativeStatus.Uninitialized;
#endif
/// <summary>
/// OnEnable this instance.
/// </summary>
void OnEnable()
{
// Unity 4 is deprecated; UNITY_5 still valid with plug-in
#if UNITY_5
Debug.Log("Ambisonic ERROR: Ambisonic support in Unity 2017 or higher");
#else
source = GetComponent<AudioSource>();
currentStatus = ovrAmbisonicsNativeStatus.Uninitialized;
if (source == null)
{
Debug.Log("Ambisonic ERROR: AudioSource does not exist.");
}
else
{
if(source.spatialize == true)
{
Debug.Log("Ambisonic WARNING: Turning spatialize field off for Ambisonic sources.");
source.spatialize = false;
}
if (source.clip == null)
{
Debug.Log("Ambisonic ERROR: AudioSource does not contain an audio clip.");
}
else
{
if(source.clip.channels != numFOAChannels)
{
Debug.Log("Ambisonic ERROR: AudioSource clip does not have correct number of channels.");
}
}
}
#endif
}
// Unity 4 is deprecated; UNITY_5 still valid with plug-in
#if !UNITY_5
/// <summary>
/// Update this instance.
/// </summary>
void Update()
{
if (source == null)
{
// We already caught the error in Awake so bail
return;
}
float statusF = 0.0f;
// PGG 5/25/2017 There is a bug in the 2017.2 beta that does not
// allow for ambisonic params to be passed through to native
// from C# Get latest editor from Unity when available
source.GetAmbisonicDecoderFloat(paramAmbiStat, out statusF);
ovrAmbisonicsNativeStatus status = (ovrAmbisonicsNativeStatus)statusF;
// TODO: Add native result/error codes
if (status != currentStatus)
{
switch(status)
{
case (ovrAmbisonicsNativeStatus.NotEnabled):
Debug.Log("Ambisonic Native: Ambisonic not enabled on clip. Check clip field and turn it on");
break;
case (ovrAmbisonicsNativeStatus.Uninitialized):
Debug.Log("Ambisonic Native: Stream uninitialized");
break;
case (ovrAmbisonicsNativeStatus.Success):
Debug.Log("Ambisonic Native: Stream successfully initialized and playing/playable");
break;
case (ovrAmbisonicsNativeStatus.StreamError):
Debug.Log("Ambisonic Native WARNING: Stream error (bad input format?)");
break;
case (ovrAmbisonicsNativeStatus.ProcessError):
Debug.Log("Ambisonic Native WARNING: Stream process error (check default speaker setup)");
break;
default:
break;
}
}
currentStatus = status;
}
#endif
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: bb001ad917b86f148a2c85acdd0d5c6a
timeCreated: 1479161980
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,363 @@
/************************************************************************************
Filename : ONSPAudioSource.cs
Content : Interface into the Oculus Native Spatializer Plugin
Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
Licensed under the Oculus SDK Version 3.5 (the "License");
you may not use the Oculus SDK except in compliance with the License,
which is provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
You may obtain a copy of the License at
https://developer.oculus.com/licenses/sdk-3.5/
Unless required by applicable law or agreed to in writing, the Oculus SDK
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
************************************************************************************/
// Uncomment below to test access of read-only spatializer parameters
//#define TEST_READONLY_PARAMETERS
using UnityEngine;
using System;
using System.Collections;
using System.Runtime.InteropServices;
public class ONSPAudioSource : MonoBehaviour
{
#if TEST_READONLY_PARAMETERS
// Spatializer read-only system parameters (global)
static int readOnly_GlobalRelectionOn = 7;
static int readOnly_NumberOfUsedSpatializedVoices = 8;
#endif
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
static void OnBeforeSceneLoadRuntimeMethod()
{
OSP_SetGlobalVoiceLimit(ONSPSettings.Instance.voiceLimit);
}
// Import functions
public const string strONSPS = "AudioPluginOculusSpatializer";
[DllImport(strONSPS)]
private static extern void ONSP_GetGlobalRoomReflectionValues(ref bool reflOn, ref bool reverbOn,
ref float width, ref float height, ref float length);
// Public
[SerializeField]
private bool enableSpatialization = true;
public bool EnableSpatialization
{
get
{
return enableSpatialization;
}
set
{
enableSpatialization = value;
}
}
[SerializeField]
private float gain = 0.0f;
public float Gain
{
get
{
return gain;
}
set
{
gain = Mathf.Clamp(value, 0.0f, 24.0f);
}
}
[SerializeField]
private bool useInvSqr = false;
public bool UseInvSqr
{
get
{
return useInvSqr;
}
set
{
useInvSqr = value;
}
}
[SerializeField]
private float near = 0.25f;
public float Near
{
get
{
return near;
}
set
{
near = Mathf.Clamp(value, 0.0f, 1000000.0f);
}
}
[SerializeField]
private float far = 250.0f;
public float Far
{
get
{
return far;
}
set
{
far = Mathf.Clamp(value, 0.0f, 1000000.0f);
}
}
[SerializeField]
private float volumetricRadius = 0.0f;
public float VolumetricRadius
{
get
{
return volumetricRadius;
}
set
{
volumetricRadius = Mathf.Clamp(value, 0.0f, 1000.0f);
}
}
[SerializeField]
private float reverbSend = 0.0f;
public float ReverbSend
{
get
{
return reverbSend;
}
set
{
reverbSend = Mathf.Clamp(value, -60.0f, 20.0f);
}
}
[SerializeField]
private bool enableRfl = false;
public bool EnableRfl
{
get
{
return enableRfl;
}
set
{
enableRfl = value;
}
}
/// <summary>
/// Awake this instance.
/// </summary>
void Awake()
{
// We might iterate through multiple sources / game object
var source = GetComponent<AudioSource>();
SetParameters(ref source);
}
/// <summary>
/// Start this instance.
/// </summary>
void Start()
{
}
/// <summary>
/// Update this instance.
/// </summary>
void Update()
{
// We might iterate through multiple sources / game object
var source = GetComponent<AudioSource>();
// READ-ONLY PARAMETER TEST
#if TEST_READONLY_PARAMETERS
float rfl_enabled = 0.0f;
source.GetSpatializerFloat(readOnly_GlobalRelectionOn, out rfl_enabled);
float num_voices = 0.0f;
source.GetSpatializerFloat(readOnly_NumberOfUsedSpatializedVoices, out num_voices);
String readOnly = System.String.Format
("Read only values: refl enabled: {0:F0} num voices: {1:F0}", rfl_enabled, num_voices);
Debug.Log(readOnly);
#endif
// Check to see if we should disable spatializion
if ((Application.isPlaying == false) ||
(AudioListener.pause == true) ||
(source.isPlaying == false) ||
(source.isActiveAndEnabled == false)
)
{
source.spatialize = false;
return;
}
else
{
SetParameters(ref source);
}
}
enum Parameters : int
{
P_GAIN = 0,
P_USEINVSQR,
P_NEAR,
P_FAR,
P_RADIUS,
P_DISABLE_RFL,
P_AMBISTAT,
P_READONLY_GLOBAL_RFL_ENABLED, // READ-ONLY
P_READONLY_NUM_VOICES, // READ-ONLY
P_SENDLEVEL,
P_NUM
};
/// <summary>
/// Sets the parameters.
/// </summary>
/// <param name="source">Source.</param>
public void SetParameters(ref AudioSource source)
{
// See if we should enable spatialization
source.spatialize = enableSpatialization;
source.SetSpatializerFloat((int)Parameters.P_GAIN, gain);
// All inputs are floats; convert bool to 0.0 and 1.0
if(useInvSqr == true)
source.SetSpatializerFloat((int)Parameters.P_USEINVSQR, 1.0f);
else
source.SetSpatializerFloat((int)Parameters.P_USEINVSQR, 0.0f);
source.SetSpatializerFloat((int)Parameters.P_NEAR, near);
source.SetSpatializerFloat((int)Parameters.P_FAR, far);
source.SetSpatializerFloat((int)Parameters.P_RADIUS, volumetricRadius);
if(enableRfl == true)
source.SetSpatializerFloat((int)Parameters.P_DISABLE_RFL, 0.0f);
else
source.SetSpatializerFloat((int)Parameters.P_DISABLE_RFL, 1.0f);
source.SetSpatializerFloat((int)Parameters.P_SENDLEVEL, reverbSend);
}
private static ONSPAudioSource RoomReflectionGizmoAS = null;
/// <summary>
///
/// </summary>
void OnDrawGizmos()
{
// Are we the first one created? make sure to set our static ONSPAudioSource
// for drawing out room parameters once
if(RoomReflectionGizmoAS == null)
{
RoomReflectionGizmoAS = this;
}
Color c;
const float colorSolidAlpha = 0.1f;
// Draw the near/far spheres
// Near (orange)
c.r = 1.0f;
c.g = 0.5f;
c.b = 0.0f;
c.a = 1.0f;
Gizmos.color = c;
Gizmos.DrawWireSphere(transform.position, Near);
c.a = colorSolidAlpha;
Gizmos.color = c;
Gizmos.DrawSphere(transform.position, Near);
// Far (red)
c.r = 1.0f;
c.g = 0.0f;
c.b = 0.0f;
c.a = 1.0f;
Gizmos.color = Color.red;
Gizmos.DrawWireSphere(transform.position, Far);
c.a = colorSolidAlpha;
Gizmos.color = c;
Gizmos.DrawSphere(transform.position, Far);
// VolumetricRadius (purple)
c.r = 1.0f;
c.g = 0.0f;
c.b = 1.0f;
c.a = 1.0f;
Gizmos.color = c;
Gizmos.DrawWireSphere(transform.position, VolumetricRadius);
c.a = colorSolidAlpha;
Gizmos.color = c;
Gizmos.DrawSphere(transform.position, VolumetricRadius);
// Draw room parameters ONCE only, provided reflection engine is on
if (RoomReflectionGizmoAS == this)
{
// Get global room parameters (write new C api to get reflection values)
bool reflOn = false;
bool reverbOn = false;
float width = 1.0f;
float height = 1.0f;
float length = 1.0f;
ONSP_GetGlobalRoomReflectionValues(ref reflOn, ref reverbOn, ref width, ref height, ref length);
// TO DO: Get the room reflection values and render those out as well (like we do in the VST)
if((Camera.main != null) && (reflOn == true))
{
// Set color of cube (cyan is early reflections only, white is with reverb on)
if(reverbOn == true)
c = Color.white;
else
c = Color.cyan;
Gizmos.color = c;
Gizmos.DrawWireCube(Camera.main.transform.position, new Vector3(width, height, length));
c.a = colorSolidAlpha;
Gizmos.color = c;
Gizmos.DrawCube(Camera.main.transform.position, new Vector3(width, height, length));
}
}
}
/// <summary>
///
/// </summary>
void OnDestroy()
{
// We will null out single pointer instance
// of the room reflection gizmo since we are being destroyed.
// Any ONSPAS that is alive or born will re-set this pointer
// so that we only draw it once
if(RoomReflectionGizmoAS == this)
{
RoomReflectionGizmoAS = null;
}
}
[System.Runtime.InteropServices.DllImport("AudioPluginOculusSpatializer")]
private static extern int OSP_SetGlobalVoiceLimit(int VoiceLimit);
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: e503ea6418d27594caa33b93cac1b06a
timeCreated: 1442244775
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,56 @@
/************************************************************************************
Filename : ONSPProfiler.cs
Content : Use this to attach to the Oculus Audio Profiler tool
Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
Licensed under the Oculus SDK Version 3.5 (the "License");
you may not use the Oculus SDK except in compliance with the License,
which is provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
You may obtain a copy of the License at
https://developer.oculus.com/licenses/sdk-3.5/
Unless required by applicable law or agreed to in writing, the Oculus SDK
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
************************************************************************************/
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine;
using UnityEngine.Networking;
public class ONSPProfiler : MonoBehaviour
{
public bool profilerEnabled = false;
const int DEFAULT_PORT = 2121;
public int port = DEFAULT_PORT;
void Start()
{
Application.runInBackground = true;
}
void Update()
{
if (port < 0 || port > 65535)
{
port = DEFAULT_PORT;
}
ONSP_SetProfilerPort(port);
ONSP_SetProfilerEnabled(profilerEnabled);
}
// Import functions
public const string strONSPS = "AudioPluginOculusSpatializer";
[DllImport(strONSPS)]
private static extern int ONSP_SetProfilerEnabled(bool enabled);
[DllImport(strONSPS)]
private static extern int ONSP_SetProfilerPort(int port);
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: c02d0725e6d42214c99b03a3b162f0e8
timeCreated: 1504817842
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,680 @@
/************************************************************************************
Filename : ONSPPropagationGeometry.cs
Content : Geometry Functions
Attach to a game object with meshes and material scripts to create geometry
NOTE: ensure that Oculus Spatialization is enabled for AudioSource components
Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
Licensed under the Oculus SDK Version 3.5 (the "License");
you may not use the Oculus SDK except in compliance with the License,
which is provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
You may obtain a copy of the License at
https://developer.oculus.com/licenses/sdk-3.5/
Unless required by applicable law or agreed to in writing, the Oculus SDK
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
************************************************************************************/
#define INCLUDE_TERRAIN_TREES
using UnityEngine;
using System;
using System.Collections.Generic;
using Oculus.Spatializer.Propagation;
public class ONSPPropagationGeometry : MonoBehaviour
{
public static string GeometryAssetDirectory = "AudioGeometry";
public static string GeometryAssetPath { get { return Application.streamingAssetsPath + "/" + GeometryAssetDirectory; } }
//-------
// PUBLIC
/// The path to the serialized mesh file that holds the preprocessed mesh geometry.
public string filePathRelative = "";
public string filePath { get { return GeometryAssetPath + "/" + filePathRelative; } }
public bool fileEnabled = false;
public bool includeChildMeshes = true;
//-------
// PRIVATE
private IntPtr geometryHandle = IntPtr.Zero;
//-------
// PUBLIC STATIC
public static int OSPSuccess = 0;
public const string GEOMETRY_FILE_EXTENSION = "ovramesh";
private static string GetPath(Transform current)
{
if (current.parent == null)
return current.gameObject.scene.name + "/" + current.name;
return GetPath(current.parent) + "-" + current.name;
}
/// <summary>
/// If script is attached to a gameobject, it will try to create geometry
/// </summary>
void Awake()
{
CreatePropagationGeometry();
}
/// <summary>
/// Call this function to create geometry handle
/// </summary>
void CreatePropagationGeometry()
{
// Create Geometry
if (ONSPPropagation.Interface.CreateAudioGeometry(out geometryHandle) != OSPSuccess)
{
throw new Exception("Unable to create geometry handle");
}
// Upload Mesh
if (filePath != null && filePath.Length != 0 && fileEnabled && Application.isPlaying)
{
if (!ReadFile())
{
Debug.LogError("Failed to read file, attempting to regenerate audio geometry");
// We should not try to upload data dynamically if data already exists
UploadGeometry();
}
}
else
{
UploadGeometry();
}
}
/// <summary>
/// Update the world transform (TODO)
/// </summary>
private void Update()
{
if (geometryHandle == IntPtr.Zero)
return;
Matrix4x4 m = transform.localToWorldMatrix;
// Note: flip Z to convert from left-handed (+Z forward) to right-handed (+Z backward)
float[] matrix = { m[0,0], m[1,0], -m[2,0], m[3,0],
m[0,1], m[1,1], -m[2,1], m[3,1],
m[0,2], m[1,2], -m[2,2], m[3,2],
m[0,3], m[1,3], -m[2,3], m[3,3] };
ONSPPropagation.Interface.AudioGeometrySetTransform(geometryHandle, matrix);
}
/// <summary>
/// Call when destroyed
/// </summary>
private void OnDestroy()
{
// DESTROY GEOMETRY
if (geometryHandle != IntPtr.Zero && ONSPPropagation.Interface.DestroyAudioGeometry(geometryHandle) != OSPSuccess)
{
throw new Exception("Unable to destroy geometry");
}
geometryHandle = IntPtr.Zero;
}
//
// FUNCTIONS FOR UPLOADING MESHES VIA GAME OBJECT
//
static int terrainDecimation = 4;
private struct MeshMaterial
{
public MeshFilter meshFilter;
public ONSPPropagationMaterial[] materials;
}
private struct TerrainMaterial
{
public Terrain terrain;
public ONSPPropagationMaterial[] materials;
public Mesh[] treePrototypeMeshes;
}
private static void traverseMeshHierarchy(GameObject obj, ONSPPropagationMaterial[] currentMaterials, bool includeChildren,
List<MeshMaterial> meshMaterials, List<TerrainMaterial> terrainMaterials, bool ignoreStatic, ref int ignoredMeshCount)
{
if (!obj.activeInHierarchy)
return;
MeshFilter[] meshes = obj.GetComponents<MeshFilter>();
Terrain[] terrains = obj.GetComponents<Terrain>();
ONSPPropagationMaterial[] materials = obj.GetComponents<ONSPPropagationMaterial>();
// Initialize the current material array to a new array if there are any new materials.
if (materials != null && materials.Length > 0)
{
// Determine the length of the material array.
int maxLength = materials.Length;
if (currentMaterials != null)
maxLength = Math.Max(maxLength, currentMaterials.Length);
ONSPPropagationMaterial[] newMaterials = new ONSPPropagationMaterial[maxLength];
// Copy the previous materials into the new array.
if (currentMaterials != null)
{
for (int i = materials.Length; i < maxLength; i++)
newMaterials[i] = currentMaterials[i];
}
currentMaterials = newMaterials;
// Copy the current materials.
for (int i = 0; i < materials.Length; i++)
currentMaterials[i] = materials[i];
}
// Gather the meshes.
foreach (MeshFilter meshFilter in meshes)
{
Mesh mesh = meshFilter.sharedMesh;
if (mesh == null)
continue;
if (ignoreStatic && !mesh.isReadable)
{
Debug.LogWarning("Mesh: " + meshFilter.gameObject.name + " not readable, cannot be static.", meshFilter.gameObject);
++ignoredMeshCount;
continue;
}
MeshMaterial m = new MeshMaterial();
m.meshFilter = meshFilter;
m.materials = currentMaterials;
meshMaterials.Add(m);
}
// Gather the terrains.
foreach (Terrain terrain in terrains)
{
TerrainMaterial m = new TerrainMaterial();
m.terrain = terrain;
m.materials = currentMaterials;
terrainMaterials.Add(m);
}
// Traverse to the child objects.
if (includeChildren)
{
foreach (Transform child in obj.transform)
{
if (child.GetComponent<ONSPPropagationGeometry>() == null) // skip children which have their own component
traverseMeshHierarchy(child.gameObject, currentMaterials, includeChildren, meshMaterials, terrainMaterials, ignoreStatic, ref ignoredMeshCount);
}
}
}
//
// CALL THIS ON GAME OBJECT THAT HAS GEOMETRY ATTACHED TO IT
//
private int uploadMesh(IntPtr geometryHandle, GameObject meshObject, Matrix4x4 worldToLocal)
{
int unused = 0;
return uploadMesh(geometryHandle, meshObject, worldToLocal, false, ref unused);
}
private int uploadMesh(IntPtr geometryHandle, GameObject meshObject, Matrix4x4 worldToLocal, bool ignoreStatic, ref int ignoredMeshCount)
{
// Get the child mesh objects.
List<MeshMaterial> meshes = new List<MeshMaterial>();
List<TerrainMaterial> terrains = new List<TerrainMaterial>();
traverseMeshHierarchy(meshObject, null, includeChildMeshes, meshes, terrains, ignoreStatic, ref ignoredMeshCount);
//***********************************************************************
// Count the number of vertices and indices.
int totalVertexCount = 0;
uint totalIndexCount = 0;
int totalFaceCount = 0;
int totalMaterialCount = 0;
foreach (MeshMaterial m in meshes)
{
updateCountsForMesh(ref totalVertexCount, ref totalIndexCount, ref totalFaceCount, ref totalMaterialCount, m.meshFilter.sharedMesh);
}
// TODO: expose tree material
ONSPPropagationMaterial[] treeMaterials = new ONSPPropagationMaterial[1];
for (int i = 0; i < terrains.Count; ++i)
{
TerrainMaterial t = terrains[i];
TerrainData terrain = t.terrain.terrainData;
#if UNITY_2019_3_OR_NEWER
int w = terrain.heightmapResolution;
int h = terrain.heightmapResolution;
#else
int w = terrain.heightmapWidth;
int h = terrain.heightmapHeight;
#endif
int wRes = (w - 1) / terrainDecimation + 1;
int hRes = (h - 1) / terrainDecimation + 1;
int vertexCount = wRes * hRes;
int indexCount = (wRes - 1) * (hRes - 1) * 6;
totalMaterialCount++;
totalVertexCount += vertexCount;
totalIndexCount += (uint)indexCount;
totalFaceCount += indexCount / 3;
#if INCLUDE_TERRAIN_TREES
TreePrototype[] treePrototypes = terrain.treePrototypes;
if (treePrototypes.Length != 0)
{
if (treeMaterials[0] == null)
{
// Create the tree material
treeMaterials[0] = gameObject.AddComponent<ONSPPropagationMaterial>();
#if true
treeMaterials[0].SetPreset(ONSPPropagationMaterial.Preset.Foliage);
#else
// Custom material that is highly transmissive
treeMaterials[0].absorption.points = new List<ONSPPropagationMaterial.Point>{
new ONSPPropagationMaterial.Point(125f, .03f),
new ONSPPropagationMaterial.Point(250f, .06f),
new ONSPPropagationMaterial.Point(500f, .11f),
new ONSPPropagationMaterial.Point(1000f, .17f),
new ONSPPropagationMaterial.Point(2000f, .27f),
new ONSPPropagationMaterial.Point(4000f, .31f) };
treeMaterials[0].scattering.points = new List<ONSPPropagationMaterial.Point>{
new ONSPPropagationMaterial.Point(125f, .20f),
new ONSPPropagationMaterial.Point(250f, .3f),
new ONSPPropagationMaterial.Point(500f, .4f),
new ONSPPropagationMaterial.Point(1000f, .5f),
new ONSPPropagationMaterial.Point(2000f, .7f),
new ONSPPropagationMaterial.Point(4000f, .8f) };
treeMaterials[0].transmission.points = new List<ONSPPropagationMaterial.Point>(){
new ONSPPropagationMaterial.Point(125f, .95f),
new ONSPPropagationMaterial.Point(250f, .92f),
new ONSPPropagationMaterial.Point(500f, .87f),
new ONSPPropagationMaterial.Point(1000f, .81f),
new ONSPPropagationMaterial.Point(2000f, .71f),
new ONSPPropagationMaterial.Point(4000f, .67f) };
#endif
}
t.treePrototypeMeshes = new Mesh[treePrototypes.Length];
// assume the sharedMesh with the lowest vertex is the lowest LOD
for (int j = 0; j < treePrototypes.Length; ++j)
{
GameObject prefab = treePrototypes[j].prefab;
MeshFilter[] meshFilters = prefab.GetComponentsInChildren<MeshFilter>();
int minVertexCount = int.MaxValue;
int index = -1;
for (int k = 0; k < meshFilters.Length; ++k)
{
int count = meshFilters[k].sharedMesh.vertexCount;
if (count < minVertexCount)
{
minVertexCount = count;
index = k;
}
}
t.treePrototypeMeshes[j] = meshFilters[index].sharedMesh;
}
TreeInstance[] trees = terrain.treeInstances;
foreach (TreeInstance tree in trees)
{
updateCountsForMesh(ref totalVertexCount, ref totalIndexCount, ref totalFaceCount,
ref totalMaterialCount, t.treePrototypeMeshes[tree.prototypeIndex]);
}
terrains[i] = t;
}
#endif
}
//***********************************************************************
// Copy the mesh data.
List<Vector3> tempVertices = new List<Vector3>();
List<int> tempIndices = new List<int>();
MeshGroup[] groups = new MeshGroup[totalMaterialCount];
float[] vertices = new float[totalVertexCount * 3];
int[] indices = new int[totalIndexCount];
int vertexOffset = 0;
int indexOffset = 0;
int groupOffset = 0;
foreach (MeshMaterial m in meshes)
{
MeshFilter meshFilter = m.meshFilter;
// Compute the combined transform to go from mesh-local to geometry-local space.
Matrix4x4 matrix = worldToLocal * meshFilter.gameObject.transform.localToWorldMatrix;
uploadMeshFilter(tempVertices, tempIndices, groups, vertices, indices, ref vertexOffset, ref indexOffset, ref groupOffset, meshFilter.sharedMesh, m.materials, matrix);
}
foreach (TerrainMaterial t in terrains)
{
TerrainData terrain = t.terrain.terrainData;
// Compute the combined transform to go from mesh-local to geometry-local space.
Matrix4x4 matrix = worldToLocal * t.terrain.gameObject.transform.localToWorldMatrix;
#if UNITY_2019_3_OR_NEWER
int w = terrain.heightmapResolution;
int h = terrain.heightmapResolution;
#else
int w = terrain.heightmapWidth;
int h = terrain.heightmapHeight;
#endif
float[,] tData = terrain.GetHeights(0, 0, w, h);
Vector3 meshScale = terrain.size;
meshScale = new Vector3(meshScale.x / (w - 1) * terrainDecimation, meshScale.y, meshScale.z / (h - 1) * terrainDecimation);
int wRes = (w - 1) / terrainDecimation + 1;
int hRes = (h - 1) / terrainDecimation + 1;
int vertexCount = wRes * hRes;
int triangleCount = (wRes - 1) * (hRes - 1) * 2;
// Initialize the group.
groups[groupOffset].faceType = FaceType.TRIANGLES;
groups[groupOffset].faceCount = (UIntPtr)triangleCount;
groups[groupOffset].indexOffset = (UIntPtr)indexOffset;
if (t.materials != null && 0 < t.materials.Length)
{
t.materials[0].StartInternal();
groups[groupOffset].material = t.materials[0].materialHandle;
}
else
groups[groupOffset].material = IntPtr.Zero;
// Build vertices and UVs
for (int y = 0; y < hRes; y++)
{
for (int x = 0; x < wRes; x++)
{
int offset = (vertexOffset + y * wRes + x) * 3;
Vector3 v = matrix.MultiplyPoint3x4(Vector3.Scale(meshScale, new Vector3(y, tData[x * terrainDecimation, y * terrainDecimation], x)));
vertices[offset + 0] = v.x;
vertices[offset + 1] = v.y;
vertices[offset + 2] = v.z;
}
}
// Build triangle indices: 3 indices into vertex array for each triangle
for (int y = 0; y < hRes - 1; y++)
{
for (int x = 0; x < wRes - 1; x++)
{
// For each grid cell output two triangles
indices[indexOffset + 0] = (vertexOffset + (y * wRes) + x);
indices[indexOffset + 1] = (vertexOffset + ((y + 1) * wRes) + x);
indices[indexOffset + 2] = (vertexOffset + (y * wRes) + x + 1);
indices[indexOffset + 3] = (vertexOffset + ((y + 1) * wRes) + x);
indices[indexOffset + 4] = (vertexOffset + ((y + 1) * wRes) + x + 1);
indices[indexOffset + 5] = (vertexOffset + (y * wRes) + x + 1);
indexOffset += 6;
}
}
vertexOffset += vertexCount;
groupOffset++;
#if INCLUDE_TERRAIN_TREES
TreeInstance[] trees = terrain.treeInstances;
foreach (TreeInstance tree in trees)
{
Vector3 pos = Vector3.Scale(tree.position, terrain.size);
Matrix4x4 treeLocalToWorldMatrix = t.terrain.gameObject.transform.localToWorldMatrix;
treeLocalToWorldMatrix.SetColumn(3, treeLocalToWorldMatrix.GetColumn(3) + new Vector4(pos.x, pos.y, pos.z, 0.0f));
// TODO: tree rotation
Matrix4x4 treeMatrix = worldToLocal * treeLocalToWorldMatrix;
uploadMeshFilter(tempVertices, tempIndices, groups, vertices, indices, ref vertexOffset, ref indexOffset, ref groupOffset, t.treePrototypeMeshes[tree.prototypeIndex], treeMaterials, treeMatrix);
}
#endif
}
// Upload mesh data
return ONSPPropagation.Interface.AudioGeometryUploadMeshArrays(geometryHandle,
vertices, totalVertexCount,
indices, indices.Length,
groups, groups.Length);
}
private static void uploadMeshFilter(List<Vector3> tempVertices, List<int> tempIndices, MeshGroup[] groups, float[] vertices, int[] indices,
ref int vertexOffset, ref int indexOffset, ref int groupOffset, Mesh mesh, ONSPPropagationMaterial[] materials, Matrix4x4 matrix)
{
// Get the mesh vertices.
tempVertices.Clear();
mesh.GetVertices(tempVertices);
// Copy the Vector3 vertices into a packed array of floats for the API.
int meshVertexCount = tempVertices.Count;
for (int i = 0; i < meshVertexCount; i++)
{
// Transform into the parent space.
Vector3 v = matrix.MultiplyPoint3x4(tempVertices[i]);
int offset = (vertexOffset + i) * 3;
vertices[offset + 0] = v.x;
vertices[offset + 1] = v.y;
vertices[offset + 2] = v.z;
}
// Copy the data for each submesh.
for (int i = 0; i < mesh.subMeshCount; i++)
{
MeshTopology topology = mesh.GetTopology(i);
if (topology == MeshTopology.Triangles || topology == MeshTopology.Quads)
{
// Get the submesh indices.
tempIndices.Clear();
mesh.GetIndices(tempIndices, i);
int subMeshIndexCount = tempIndices.Count;
// Copy and adjust the indices.
for (int j = 0; j < subMeshIndexCount; j++)
indices[indexOffset + j] = tempIndices[j] + vertexOffset;
// Initialize the group.
if (topology == MeshTopology.Triangles)
{
groups[groupOffset + i].faceType = FaceType.TRIANGLES;
groups[groupOffset + i].faceCount = (UIntPtr)(subMeshIndexCount / 3);
}
else if (topology == MeshTopology.Quads)
{
groups[groupOffset + i].faceType = FaceType.QUADS;
groups[groupOffset + i].faceCount = (UIntPtr)(subMeshIndexCount / 4);
}
groups[groupOffset + i].indexOffset = (UIntPtr)indexOffset;
if (materials != null && materials.Length != 0)
{
int matIndex = i;
if (matIndex >= materials.Length)
matIndex = materials.Length - 1;
materials[matIndex].StartInternal();
groups[groupOffset + i].material = materials[matIndex].materialHandle;
}
else
groups[groupOffset + i].material = IntPtr.Zero;
indexOffset += subMeshIndexCount;
}
}
vertexOffset += meshVertexCount;
groupOffset += mesh.subMeshCount;
}
private static void updateCountsForMesh(ref int totalVertexCount, ref uint totalIndexCount, ref int totalFaceCount, ref int totalMaterialCount, Mesh mesh)
{
totalMaterialCount += mesh.subMeshCount;
totalVertexCount += mesh.vertexCount;
for (int i = 0; i < mesh.subMeshCount; i++)
{
MeshTopology topology = mesh.GetTopology(i);
if (topology == MeshTopology.Triangles || topology == MeshTopology.Quads)
{
uint meshIndexCount = mesh.GetIndexCount(i);
totalIndexCount += meshIndexCount;
if (topology == MeshTopology.Triangles)
totalFaceCount += (int)meshIndexCount / 3;
else if (topology == MeshTopology.Quads)
totalFaceCount += (int)meshIndexCount / 4;
}
}
}
//***********************************************************************
// UploadGeometry
public void UploadGeometry()
{
int ignoredMeshCount = 0;
if (uploadMesh(geometryHandle, gameObject, gameObject.transform.worldToLocalMatrix, true, ref ignoredMeshCount) != OSPSuccess)
throw new Exception("Unable to upload audio mesh geometry");
if (ignoredMeshCount != 0)
{
Debug.LogError("Failed to upload meshes, " + ignoredMeshCount + " static meshes ignored. Turn on \"File Enabled\" to process static meshes offline", gameObject);
}
}
#if UNITY_EDITOR
//***********************************************************************
// WriteFile - Write the serialized mesh file.
public bool WriteFile()
{
if (filePathRelative == "")
{
filePathRelative = GetPath(transform);
string modifier = "";
int counter = 0;
while (System.IO.File.Exists(filePath + modifier))
{
modifier = "-" + counter;
++counter;
if (counter > 10000)
{
// sanity check to prevent hang
throw new Exception("Unable to find sutiable file name");
}
}
filePathRelative = filePathRelative + modifier;
Debug.Log("No file path specified, autogenerated: " + filePathRelative);
}
// Create the directory
string directoryName = filePathRelative.Substring(0, filePathRelative.LastIndexOf('/'));
System.IO.Directory.CreateDirectory(GeometryAssetPath + "/" + directoryName);
// Create a temporary geometry.
IntPtr tempGeometryHandle = IntPtr.Zero;
if (ONSPPropagation.Interface.CreateAudioGeometry(out tempGeometryHandle) != OSPSuccess)
{
throw new Exception("Failed to create temp geometry handle");
}
// Upload the mesh geometry.
if (uploadMesh(tempGeometryHandle, gameObject, gameObject.transform.worldToLocalMatrix) != OSPSuccess)
{
Debug.LogError("Error uploading mesh " + gameObject.name);
return false;
}
// Write the mesh to a file.
if (ONSPPropagation.Interface.AudioGeometryWriteMeshFile(tempGeometryHandle, filePath) != OSPSuccess)
{
Debug.LogError("Error writing mesh file " + filePath);
return false;
}
// Destroy the geometry.
if (ONSPPropagation.Interface.DestroyAudioGeometry(tempGeometryHandle) != OSPSuccess)
{
throw new Exception("Failed to destroy temp geometry handle");
}
return true;
}
#endif
//***********************************************************************
// ReadFile - Read the serialized mesh file.
public bool ReadFile()
{
if (filePath == null || filePath.Length == 0)
{
Debug.LogError("Invalid mesh file path");
return false;
}
if (ONSPPropagation.Interface.AudioGeometryReadMeshFile(geometryHandle, filePath) != OSPSuccess)
{
Debug.LogError("Error reading mesh file " + filePath);
return false;
}
return true;
}
public bool WriteToObj()
{
// Create a temporary geometry.
IntPtr tempGeometryHandle = IntPtr.Zero;
if (ONSPPropagation.Interface.CreateAudioGeometry(out tempGeometryHandle) != OSPSuccess)
{
throw new Exception("Failed to create temp geometry handle");
}
// Upload the mesh geometry.
if (uploadMesh(tempGeometryHandle, gameObject, gameObject.transform.worldToLocalMatrix) != OSPSuccess)
{
Debug.LogError("Error uploading mesh " + gameObject.name);
return false;
}
// Write the mesh to a .obj file.
if (ONSPPropagation.Interface.AudioGeometryWriteMeshFileObj(tempGeometryHandle, filePath + ".obj") != OSPSuccess)
{
Debug.LogError("Error writing .obj file " + filePath + ".obj");
return false;
}
// Destroy the geometry.
if (ONSPPropagation.Interface.DestroyAudioGeometry(tempGeometryHandle) != OSPSuccess)
{
throw new Exception("Failed to destroy temp geometry handle");
}
return true;
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: abdaae8d2b81ba54498967f33610da0d
timeCreated: 1525731700
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,574 @@
/************************************************************************************
Filename : ONSPPropagationInterface.cs
Content : Interface into the Oculus Audio propagation functions
Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
Licensed under the Oculus SDK Version 3.5 (the "License");
you may not use the Oculus SDK except in compliance with the License,
which is provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
You may obtain a copy of the License at
https://developer.oculus.com/licenses/sdk-3.5/
Unless required by applicable law or agreed to in writing, the Oculus SDK
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
************************************************************************************/
using System;
using System.Runtime.InteropServices;
using UnityEngine;
using Oculus.Spatializer.Propagation;
namespace Oculus
{
namespace Spatializer
{
namespace Propagation
{
/***********************************************************************************/
// ENUMS and STRUCTS
/***********************************************************************************/
public enum FaceType : uint
{
TRIANGLES = 0,
QUADS
}
public enum MaterialProperty : uint
{
ABSORPTION = 0,
TRANSMISSION,
SCATTERING
}
// Matches internal mesh layout
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct MeshGroup
{
public UIntPtr indexOffset;
public UIntPtr faceCount;
[MarshalAs(UnmanagedType.U4)]
public FaceType faceType;
public IntPtr material;
}
}
}
}
class ONSPPropagation
{
static PropagationInterface CachedInterface;
public static PropagationInterface Interface { get { if (CachedInterface == null) CachedInterface = FindInterface(); return CachedInterface; } }
static PropagationInterface FindInterface()
{
IntPtr temp;
try
{
WwisePluginInterface.ovrAudio_GetPluginContext(out temp, ClientType.OVRA_CLIENT_TYPE_WWISE_UNKNOWN);
Debug.Log("Propagation initialized with Wwise Oculus Spatializer plugin");
return new WwisePluginInterface();
}
catch(System.DllNotFoundException)
{
// this is fine
}
try
{
FMODPluginInterface.ovrAudio_GetPluginContext(out temp, ClientType.OVRA_CLIENT_TYPE_FMOD);
Debug.Log("Propagation initialized with FMOD Oculus Spatializer plugin");
return new FMODPluginInterface();
}
catch (System.DllNotFoundException)
{
// this is fine
}
Debug.Log("Propagation initialized with Unity Oculus Spatializer plugin");
return new UnityNativeInterface();
}
public enum ovrAudioScalarType : uint
{
Int8,
UInt8,
Int16,
UInt16,
Int32,
UInt32,
Int64,
UInt64,
Float16,
Float32,
Float64
}
public class ClientType
{
// Copied from AudioSDK\OVRAudio\OVR_Audio_Internal.h
public const uint OVRA_CLIENT_TYPE_NATIVE = 0;
public const uint OVRA_CLIENT_TYPE_WWISE_2016 = 1;
public const uint OVRA_CLIENT_TYPE_WWISE_2017_1 = 2;
public const uint OVRA_CLIENT_TYPE_WWISE_2017_2 = 3;
public const uint OVRA_CLIENT_TYPE_WWISE_2018_1 = 4;
public const uint OVRA_CLIENT_TYPE_FMOD = 5;
public const uint OVRA_CLIENT_TYPE_UNITY = 6;
public const uint OVRA_CLIENT_TYPE_UE4 = 7;
public const uint OVRA_CLIENT_TYPE_VST = 8;
public const uint OVRA_CLIENT_TYPE_AAX = 9;
public const uint OVRA_CLIENT_TYPE_TEST = 10;
public const uint OVRA_CLIENT_TYPE_OTHER = 11;
public const uint OVRA_CLIENT_TYPE_WWISE_UNKNOWN = 12;
public const uint OVRA_CLIENT_TYPE_WWISE_2019_1 = 13;
public const uint OVRA_CLIENT_TYPE_WWISE_2019_2 = 14;
public const uint OVRA_CLIENT_TYPE_WWISE_2021_1 = 15;
}
public interface PropagationInterface
{
/***********************************************************************************/
// Settings API
int SetPropagationQuality(float quality);
int SetPropagationThreadAffinity(UInt64 cpuMask);
/***********************************************************************************/
// Geometry API
int CreateAudioGeometry(out IntPtr geometry);
int DestroyAudioGeometry(IntPtr geometry);
int AudioGeometryUploadMeshArrays(IntPtr geometry,
float[] vertices, int vertexCount,
int[] indices, int indexCount,
MeshGroup[] groups, int groupCount);
int AudioGeometrySetTransform(IntPtr geometry, float[] matrix4x4);
int AudioGeometryGetTransform(IntPtr geometry, out float[] matrix4x4);
int AudioGeometryWriteMeshFile(IntPtr geometry, string filePath);
int AudioGeometryReadMeshFile(IntPtr geometry, string filePath);
int AudioGeometryWriteMeshFileObj(IntPtr geometry, string filePath);
/***********************************************************************************/
// Material API
int AudioMaterialGetFrequency(IntPtr material, MaterialProperty property, float frequency, out float value);
int CreateAudioMaterial(out IntPtr material);
int DestroyAudioMaterial(IntPtr material);
int AudioMaterialSetFrequency(IntPtr material, MaterialProperty property, float frequency, float value);
int AudioMaterialReset(IntPtr material, MaterialProperty property);
}
/***********************************************************************************/
// UNITY NATIVE
/***********************************************************************************/
public class UnityNativeInterface : PropagationInterface
{
// The name used for the plugin DLL.
public const string strOSPS = "AudioPluginOculusSpatializer";
/***********************************************************************************/
// Context API: Required to create internal context if it does not exist yet
IntPtr context_ = IntPtr.Zero;
IntPtr context { get { if (context_ == IntPtr.Zero) { ovrAudio_GetPluginContext(out context_, ClientType.OVRA_CLIENT_TYPE_UNITY); } return context_; } }
[DllImport(strOSPS)]
public static extern int ovrAudio_GetPluginContext(out IntPtr context, uint clientType);
/***********************************************************************************/
// Settings API
[DllImport(strOSPS)]
private static extern int ovrAudio_SetPropagationQuality(IntPtr context, float quality);
public int SetPropagationQuality(float quality)
{
return ovrAudio_SetPropagationQuality(context, quality);
}
[DllImport(strOSPS)]
private static extern int ovrAudio_SetPropagationThreadAffinity(IntPtr context, UInt64 cpuMask);
public int SetPropagationThreadAffinity(UInt64 cpuMask)
{
return ovrAudio_SetPropagationThreadAffinity(context, cpuMask);
}
/***********************************************************************************/
// Geometry API
[DllImport(strOSPS)]
private static extern int ovrAudio_CreateAudioGeometry(IntPtr context, out IntPtr geometry);
public int CreateAudioGeometry(out IntPtr geometry)
{
return ovrAudio_CreateAudioGeometry(context, out geometry);
}
[DllImport(strOSPS)]
private static extern int ovrAudio_DestroyAudioGeometry(IntPtr geometry);
public int DestroyAudioGeometry(IntPtr geometry)
{
return ovrAudio_DestroyAudioGeometry(geometry);
}
[DllImport(strOSPS)]
private static extern int ovrAudio_AudioGeometryUploadMeshArrays(IntPtr geometry,
float[] vertices, UIntPtr verticesBytesOffset, UIntPtr vertexCount, UIntPtr vertexStride, ovrAudioScalarType vertexType,
int[] indices, UIntPtr indicesByteOffset, UIntPtr indexCount, ovrAudioScalarType indexType,
MeshGroup[] groups, UIntPtr groupCount);
public int AudioGeometryUploadMeshArrays(IntPtr geometry,
float[] vertices, int vertexCount,
int[] indices, int indexCount,
MeshGroup[] groups, int groupCount)
{
return ovrAudio_AudioGeometryUploadMeshArrays(geometry,
vertices, UIntPtr.Zero, (UIntPtr)vertexCount, UIntPtr.Zero, ovrAudioScalarType.Float32,
indices, UIntPtr.Zero, (UIntPtr)indexCount, ovrAudioScalarType.UInt32,
groups, (UIntPtr)groupCount);
}
[DllImport(strOSPS)]
private static extern int ovrAudio_AudioGeometrySetTransform(IntPtr geometry, float[] matrix4x4);
public int AudioGeometrySetTransform(IntPtr geometry, float[] matrix4x4)
{
return ovrAudio_AudioGeometrySetTransform(geometry, matrix4x4);
}
[DllImport(strOSPS)]
private static extern int ovrAudio_AudioGeometryGetTransform(IntPtr geometry, out float[] matrix4x4);
public int AudioGeometryGetTransform(IntPtr geometry, out float[] matrix4x4)
{
return ovrAudio_AudioGeometryGetTransform(geometry, out matrix4x4);
}
[DllImport(strOSPS)]
private static extern int ovrAudio_AudioGeometryWriteMeshFile(IntPtr geometry, string filePath);
public int AudioGeometryWriteMeshFile(IntPtr geometry, string filePath)
{
return ovrAudio_AudioGeometryWriteMeshFile(geometry, filePath);
}
[DllImport(strOSPS)]
private static extern int ovrAudio_AudioGeometryReadMeshFile(IntPtr geometry, string filePath);
public int AudioGeometryReadMeshFile(IntPtr geometry, string filePath)
{
return ovrAudio_AudioGeometryReadMeshFile(geometry, filePath);
}
[DllImport(strOSPS)]
private static extern int ovrAudio_AudioGeometryWriteMeshFileObj(IntPtr geometry, string filePath);
public int AudioGeometryWriteMeshFileObj(IntPtr geometry, string filePath)
{
return ovrAudio_AudioGeometryWriteMeshFileObj(geometry, filePath);
}
/***********************************************************************************/
// Material API
[DllImport(strOSPS)]
private static extern int ovrAudio_CreateAudioMaterial(IntPtr context, out IntPtr material);
public int CreateAudioMaterial(out IntPtr material)
{
return ovrAudio_CreateAudioMaterial(context, out material);
}
[DllImport(strOSPS)]
private static extern int ovrAudio_DestroyAudioMaterial(IntPtr material);
public int DestroyAudioMaterial(IntPtr material)
{
return ovrAudio_DestroyAudioMaterial(material);
}
[DllImport(strOSPS)]
private static extern int ovrAudio_AudioMaterialSetFrequency(IntPtr material, MaterialProperty property, float frequency, float value);
public int AudioMaterialSetFrequency(IntPtr material, MaterialProperty property, float frequency, float value)
{
return ovrAudio_AudioMaterialSetFrequency(material, property, frequency, value);
}
[DllImport(strOSPS)]
private static extern int ovrAudio_AudioMaterialGetFrequency(IntPtr material, MaterialProperty property, float frequency, out float value);
public int AudioMaterialGetFrequency(IntPtr material, MaterialProperty property, float frequency, out float value)
{
return ovrAudio_AudioMaterialGetFrequency(material, property, frequency, out value);
}
[DllImport(strOSPS)]
private static extern int ovrAudio_AudioMaterialReset(IntPtr material, MaterialProperty property);
public int AudioMaterialReset(IntPtr material, MaterialProperty property)
{
return ovrAudio_AudioMaterialReset(material, property);
}
}
/***********************************************************************************/
// WWISE
/***********************************************************************************/
public class WwisePluginInterface : PropagationInterface
{
// The name used for the plugin DLL.
public const string strOSPS = "OculusSpatializerWwise";
/***********************************************************************************/
// Context API: Required to create internal context if it does not exist yet
IntPtr context_ = IntPtr.Zero;
IntPtr context { get { if (context_ == IntPtr.Zero) { ovrAudio_GetPluginContext(out context_, ClientType.OVRA_CLIENT_TYPE_WWISE_UNKNOWN); } return context_; } }
[DllImport(strOSPS)]
public static extern int ovrAudio_GetPluginContext(out IntPtr context, uint clientType);
/***********************************************************************************/
// Settings API
[DllImport(strOSPS)]
private static extern int ovrAudio_SetPropagationQuality(IntPtr context, float quality);
public int SetPropagationQuality(float quality)
{
return ovrAudio_SetPropagationQuality(context, quality);
}
[DllImport(strOSPS)]
private static extern int ovrAudio_SetPropagationThreadAffinity(IntPtr context, UInt64 cpuMask);
public int SetPropagationThreadAffinity(UInt64 cpuMask)
{
return ovrAudio_SetPropagationThreadAffinity(context, cpuMask);
}
/***********************************************************************************/
// Geometry API
[DllImport(strOSPS)]
private static extern int ovrAudio_CreateAudioGeometry(IntPtr context, out IntPtr geometry);
public int CreateAudioGeometry(out IntPtr geometry)
{
return ovrAudio_CreateAudioGeometry(context, out geometry);
}
[DllImport(strOSPS)]
private static extern int ovrAudio_DestroyAudioGeometry(IntPtr geometry);
public int DestroyAudioGeometry(IntPtr geometry)
{
return ovrAudio_DestroyAudioGeometry(geometry);
}
[DllImport(strOSPS)]
private static extern int ovrAudio_AudioGeometryUploadMeshArrays(IntPtr geometry,
float[] vertices, UIntPtr verticesBytesOffset, UIntPtr vertexCount, UIntPtr vertexStride, ovrAudioScalarType vertexType,
int[] indices, UIntPtr indicesByteOffset, UIntPtr indexCount, ovrAudioScalarType indexType,
MeshGroup[] groups, UIntPtr groupCount);
public int AudioGeometryUploadMeshArrays(IntPtr geometry,
float[] vertices, int vertexCount,
int[] indices, int indexCount,
MeshGroup[] groups, int groupCount)
{
return ovrAudio_AudioGeometryUploadMeshArrays(geometry,
vertices, UIntPtr.Zero, (UIntPtr)vertexCount, UIntPtr.Zero, ovrAudioScalarType.Float32,
indices, UIntPtr.Zero, (UIntPtr)indexCount, ovrAudioScalarType.UInt32,
groups, (UIntPtr)groupCount);
}
[DllImport(strOSPS)]
private static extern int ovrAudio_AudioGeometrySetTransform(IntPtr geometry, float[] matrix4x4);
public int AudioGeometrySetTransform(IntPtr geometry, float[] matrix4x4)
{
return ovrAudio_AudioGeometrySetTransform(geometry, matrix4x4);
}
[DllImport(strOSPS)]
private static extern int ovrAudio_AudioGeometryGetTransform(IntPtr geometry, out float[] matrix4x4);
public int AudioGeometryGetTransform(IntPtr geometry, out float[] matrix4x4)
{
return ovrAudio_AudioGeometryGetTransform(geometry, out matrix4x4);
}
[DllImport(strOSPS)]
private static extern int ovrAudio_AudioGeometryWriteMeshFile(IntPtr geometry, string filePath);
public int AudioGeometryWriteMeshFile(IntPtr geometry, string filePath)
{
return ovrAudio_AudioGeometryWriteMeshFile(geometry, filePath);
}
[DllImport(strOSPS)]
private static extern int ovrAudio_AudioGeometryReadMeshFile(IntPtr geometry, string filePath);
public int AudioGeometryReadMeshFile(IntPtr geometry, string filePath)
{
return ovrAudio_AudioGeometryReadMeshFile(geometry, filePath);
}
[DllImport(strOSPS)]
private static extern int ovrAudio_AudioGeometryWriteMeshFileObj(IntPtr geometry, string filePath);
public int AudioGeometryWriteMeshFileObj(IntPtr geometry, string filePath)
{
return ovrAudio_AudioGeometryWriteMeshFileObj(geometry, filePath);
}
/***********************************************************************************/
// Material API
[DllImport(strOSPS)]
private static extern int ovrAudio_CreateAudioMaterial(IntPtr context, out IntPtr material);
public int CreateAudioMaterial(out IntPtr material)
{
return ovrAudio_CreateAudioMaterial(context, out material);
}
[DllImport(strOSPS)]
private static extern int ovrAudio_DestroyAudioMaterial(IntPtr material);
public int DestroyAudioMaterial(IntPtr material)
{
return ovrAudio_DestroyAudioMaterial(material);
}
[DllImport(strOSPS)]
private static extern int ovrAudio_AudioMaterialSetFrequency(IntPtr material, MaterialProperty property, float frequency, float value);
public int AudioMaterialSetFrequency(IntPtr material, MaterialProperty property, float frequency, float value)
{
return ovrAudio_AudioMaterialSetFrequency(material, property, frequency, value);
}
[DllImport(strOSPS)]
private static extern int ovrAudio_AudioMaterialGetFrequency(IntPtr material, MaterialProperty property, float frequency, out float value);
public int AudioMaterialGetFrequency(IntPtr material, MaterialProperty property, float frequency, out float value)
{
return ovrAudio_AudioMaterialGetFrequency(material, property, frequency, out value);
}
[DllImport(strOSPS)]
private static extern int ovrAudio_AudioMaterialReset(IntPtr material, MaterialProperty property);
public int AudioMaterialReset(IntPtr material, MaterialProperty property)
{
return ovrAudio_AudioMaterialReset(material, property);
}
}
/***********************************************************************************/
// FMOD
/***********************************************************************************/
public class FMODPluginInterface : PropagationInterface
{
// The name used for the plugin DLL.
public const string strOSPS = "OculusSpatializerFMOD";
/***********************************************************************************/
// Context API: Required to create internal context if it does not exist yet
IntPtr context_ = IntPtr.Zero;
IntPtr context { get { if (context_ == IntPtr.Zero) { ovrAudio_GetPluginContext(out context_, ClientType.OVRA_CLIENT_TYPE_FMOD); } return context_; } }
[DllImport(strOSPS)]
public static extern int ovrAudio_GetPluginContext(out IntPtr context, uint clientType);
/***********************************************************************************/
// Settings API
[DllImport(strOSPS)]
private static extern int ovrAudio_SetPropagationQuality(IntPtr context, float quality);
public int SetPropagationQuality(float quality)
{
return ovrAudio_SetPropagationQuality(context, quality);
}
[DllImport(strOSPS)]
private static extern int ovrAudio_SetPropagationThreadAffinity(IntPtr context, UInt64 cpuMask);
public int SetPropagationThreadAffinity(UInt64 cpuMask)
{
return ovrAudio_SetPropagationThreadAffinity(context, cpuMask);
}
/***********************************************************************************/
// Geometry API
[DllImport(strOSPS)]
private static extern int ovrAudio_CreateAudioGeometry(IntPtr context, out IntPtr geometry);
public int CreateAudioGeometry(out IntPtr geometry)
{
return ovrAudio_CreateAudioGeometry(context, out geometry);
}
[DllImport(strOSPS)]
private static extern int ovrAudio_DestroyAudioGeometry(IntPtr geometry);
public int DestroyAudioGeometry(IntPtr geometry)
{
return ovrAudio_DestroyAudioGeometry(geometry);
}
[DllImport(strOSPS)]
private static extern int ovrAudio_AudioGeometryUploadMeshArrays(IntPtr geometry,
float[] vertices, UIntPtr verticesBytesOffset, UIntPtr vertexCount, UIntPtr vertexStride, ovrAudioScalarType vertexType,
int[] indices, UIntPtr indicesByteOffset, UIntPtr indexCount, ovrAudioScalarType indexType,
MeshGroup[] groups, UIntPtr groupCount);
public int AudioGeometryUploadMeshArrays(IntPtr geometry,
float[] vertices, int vertexCount,
int[] indices, int indexCount,
MeshGroup[] groups, int groupCount)
{
return ovrAudio_AudioGeometryUploadMeshArrays(geometry,
vertices, UIntPtr.Zero, (UIntPtr)vertexCount, UIntPtr.Zero, ovrAudioScalarType.Float32,
indices, UIntPtr.Zero, (UIntPtr)indexCount, ovrAudioScalarType.UInt32,
groups, (UIntPtr)groupCount);
}
[DllImport(strOSPS)]
private static extern int ovrAudio_AudioGeometrySetTransform(IntPtr geometry, float[] matrix4x4);
public int AudioGeometrySetTransform(IntPtr geometry, float[] matrix4x4)
{
return ovrAudio_AudioGeometrySetTransform(geometry, matrix4x4);
}
[DllImport(strOSPS)]
private static extern int ovrAudio_AudioGeometryGetTransform(IntPtr geometry, out float[] matrix4x4);
public int AudioGeometryGetTransform(IntPtr geometry, out float[] matrix4x4)
{
return ovrAudio_AudioGeometryGetTransform(geometry, out matrix4x4);
}
[DllImport(strOSPS)]
private static extern int ovrAudio_AudioGeometryWriteMeshFile(IntPtr geometry, string filePath);
public int AudioGeometryWriteMeshFile(IntPtr geometry, string filePath)
{
return ovrAudio_AudioGeometryWriteMeshFile(geometry, filePath);
}
[DllImport(strOSPS)]
private static extern int ovrAudio_AudioGeometryReadMeshFile(IntPtr geometry, string filePath);
public int AudioGeometryReadMeshFile(IntPtr geometry, string filePath)
{
return ovrAudio_AudioGeometryReadMeshFile(geometry, filePath);
}
[DllImport(strOSPS)]
private static extern int ovrAudio_AudioGeometryWriteMeshFileObj(IntPtr geometry, string filePath);
public int AudioGeometryWriteMeshFileObj(IntPtr geometry, string filePath)
{
return ovrAudio_AudioGeometryWriteMeshFileObj(geometry, filePath);
}
/***********************************************************************************/
// Material API
[DllImport(strOSPS)]
private static extern int ovrAudio_CreateAudioMaterial(IntPtr context, out IntPtr material);
public int CreateAudioMaterial(out IntPtr material)
{
return ovrAudio_CreateAudioMaterial(context, out material);
}
[DllImport(strOSPS)]
private static extern int ovrAudio_DestroyAudioMaterial(IntPtr material);
public int DestroyAudioMaterial(IntPtr material)
{
return ovrAudio_DestroyAudioMaterial(material);
}
[DllImport(strOSPS)]
private static extern int ovrAudio_AudioMaterialSetFrequency(IntPtr material, MaterialProperty property, float frequency, float value);
public int AudioMaterialSetFrequency(IntPtr material, MaterialProperty property, float frequency, float value)
{
return ovrAudio_AudioMaterialSetFrequency(material, property, frequency, value);
}
[DllImport(strOSPS)]
private static extern int ovrAudio_AudioMaterialGetFrequency(IntPtr material, MaterialProperty property, float frequency, out float value);
public int AudioMaterialGetFrequency(IntPtr material, MaterialProperty property, float frequency, out float value)
{
return ovrAudio_AudioMaterialGetFrequency(material, property, frequency, out value);
}
[DllImport(strOSPS)]
private static extern int ovrAudio_AudioMaterialReset(IntPtr material, MaterialProperty property);
public int AudioMaterialReset(IntPtr material, MaterialProperty property)
{
return ovrAudio_AudioMaterialReset(material, property);
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: b604e1956166619468a5c9801f1b3756
timeCreated: 1525727421
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,616 @@
/************************************************************************************
Filename : ONSPPropagationMaterial.cs
Content : Propagation material class
Attach to geometry to define material properties
Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
Licensed under the Oculus SDK Version 3.5 (the "License");
you may not use the Oculus SDK except in compliance with the License,
which is provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
You may obtain a copy of the License at
https://developer.oculus.com/licenses/sdk-3.5/
Unless required by applicable law or agreed to in writing, the Oculus SDK
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
************************************************************************************/
using System;
using System.Linq;
using System.Collections.Generic;
using UnityEngine;
using Oculus.Spatializer.Propagation;
public sealed class ONSPPropagationMaterial : MonoBehaviour
{
public enum Preset
{
Custom,
AcousticTile,
Brick,
BrickPainted,
Carpet,
CarpetHeavy,
CarpetHeavyPadded,
CeramicTile,
Concrete,
ConcreteRough,
ConcreteBlock,
ConcreteBlockPainted,
Curtain,
Foliage,
Glass,
GlassHeavy,
Grass,
Gravel,
GypsumBoard,
PlasterOnBrick,
PlasterOnConcreteBlock,
Soil,
SoundProof,
Snow,
Steel,
Water,
WoodThin,
WoodThick,
WoodFloor,
WoodOnConcrete
}
[Serializable]
public sealed class Point
{
public float frequency;
public float data;
public Point( float frequency = 0, float data = 0 )
{
this.frequency = frequency;
this.data = data;
}
public static implicit operator Point(Vector2 v)
{
return new Point(v.x, v.y);
}
public static implicit operator Vector2(Point point)
{
return new Vector2(point.frequency, point.data);
}
}
[Serializable]
public sealed class Spectrum
{
public int selection = int.MaxValue;
public List<Point> points = new List<Point>();
public float this[float f]
{
get
{
if (points.Count > 0)
{
Point lower = new Point(float.MinValue);
Point upper = new Point(float.MaxValue);
foreach (Point point in points)
{
if (point.frequency < f)
{
if (point.frequency > lower.frequency)
lower = point;
}
else
{
if (point.frequency < upper.frequency)
upper = point;
}
}
if (lower.frequency == float.MinValue)
lower.data = points.OrderBy(p => p.frequency).First().data;
if (upper.frequency == float.MaxValue)
upper.data = points.OrderBy(p => p.frequency).Last().data;
return lower.data + (f - lower.frequency) *
(upper.data - lower.data) / (upper.frequency - lower.frequency);
}
return 0f;
}
}
}
//***********************************************************************
// Private Fields
public IntPtr materialHandle = IntPtr.Zero;
//***********************************************************************
// Public Fields
[Tooltip("Absorption")]
public Spectrum absorption = new Spectrum();
[Tooltip("Transmission")]
public Spectrum transmission = new Spectrum();
[Tooltip("Scattering")]
public Spectrum scattering = new Spectrum();
[SerializeField]
private Preset preset_ = Preset.Custom;
public Preset preset
{
get { return preset_; }
set
{
this.SetPreset( value );
preset_ = value;
}
}
//***********************************************************************
// Start / Destroy
/// Initialize the audio material. This is called after Awake() and before the first Update().
void Start()
{
StartInternal();
}
public void StartInternal()
{
// Ensure that the material is not initialized twice.
if ( materialHandle != IntPtr.Zero )
return;
// Create the internal material.
if (ONSPPropagation.Interface.CreateAudioMaterial( out materialHandle ) != ONSPPropagationGeometry.OSPSuccess)
throw new Exception("Unable to create internal audio material");
// Run the updates to initialize the material.
UploadMaterial();
}
/// Destroy the audio scene. This is called when the scene is deleted.
void OnDestroy()
{
DestroyInternal();
}
public void DestroyInternal()
{
if ( materialHandle != IntPtr.Zero )
{
// Destroy the material.
ONSPPropagation.Interface.DestroyAudioMaterial(materialHandle);
materialHandle = IntPtr.Zero;
}
}
//***********************************************************************
// Upload
public void UploadMaterial()
{
if ( materialHandle == IntPtr.Zero )
return;
// Absorption
ONSPPropagation.Interface.AudioMaterialReset(materialHandle, MaterialProperty.ABSORPTION);
foreach ( Point p in absorption.points )
ONSPPropagation.Interface.AudioMaterialSetFrequency(materialHandle, MaterialProperty.ABSORPTION,
p.frequency, p.data );
// Transmission
ONSPPropagation.Interface.AudioMaterialReset(materialHandle, MaterialProperty.TRANSMISSION);
foreach (Point p in transmission.points)
ONSPPropagation.Interface.AudioMaterialSetFrequency(materialHandle, MaterialProperty.TRANSMISSION,
p.frequency, p.data);
// Scattering
ONSPPropagation.Interface.AudioMaterialReset(materialHandle, MaterialProperty.SCATTERING);
foreach (Point p in scattering.points)
ONSPPropagation.Interface.AudioMaterialSetFrequency(materialHandle, MaterialProperty.SCATTERING,
p.frequency, p.data);
}
//***********************************************************************
public void SetPreset(Preset preset )
{
ONSPPropagationMaterial material = this;
switch ( preset )
{
case Preset.AcousticTile: AcousticTile(ref material); break;
case Preset.Brick: Brick(ref material); break;
case Preset.BrickPainted: BrickPainted(ref material); break;
case Preset.Carpet: Carpet(ref material); break;
case Preset.CarpetHeavy: CarpetHeavy(ref material); break;
case Preset.CarpetHeavyPadded: CarpetHeavyPadded(ref material); break;
case Preset.CeramicTile: CeramicTile(ref material); break;
case Preset.Concrete: Concrete(ref material); break;
case Preset.ConcreteRough: ConcreteRough(ref material); break;
case Preset.ConcreteBlock: ConcreteBlock(ref material); break;
case Preset.ConcreteBlockPainted: ConcreteBlockPainted(ref material); break;
case Preset.Curtain: Curtain(ref material); break;
case Preset.Foliage: Foliage(ref material); break;
case Preset.Glass: Glass(ref material); break;
case Preset.GlassHeavy: GlassHeavy(ref material); break;
case Preset.Grass: Grass(ref material); break;
case Preset.Gravel: Gravel(ref material); break;
case Preset.GypsumBoard: GypsumBoard(ref material); break;
case Preset.PlasterOnBrick: PlasterOnBrick(ref material); break;
case Preset.PlasterOnConcreteBlock: PlasterOnConcreteBlock(ref material); break;
case Preset.Soil: Soil(ref material); break;
case Preset.SoundProof: SoundProof(ref material); break;
case Preset.Snow: Snow(ref material); break;
case Preset.Steel: Steel(ref material); break;
case Preset.Water: Water(ref material); break;
case Preset.WoodThin: WoodThin(ref material); break;
case Preset.WoodThick: WoodThick(ref material); break;
case Preset.WoodFloor: WoodFloor(ref material); break;
case Preset.WoodOnConcrete: WoodOnConcrete(ref material); break;
case Preset.Custom:
break;
default:
break;
}
}
//***********************************************************************
private static void AcousticTile(ref ONSPPropagationMaterial material)
{
material.absorption.points = new List<Point>{
new Point(125f, .50f), new Point(250f, .70f), new Point(500f, .60f), new Point(1000f, .70f), new Point(2000f, .70f), new Point(4000f, .50f) };
material.scattering.points = new List<Point>{
new Point(125f, .10f), new Point(250f, .15f), new Point(500f, .20f), new Point(1000f, .20f), new Point(2000f, .25f), new Point(4000f, .30f) };
material.transmission.points = new List<Point>(){
new Point(125f, .05f), new Point(250f, .04f), new Point(500f, .03f), new Point(1000f, .02f), new Point(2000f, .005f), new Point(4000f, .002f) };
}
private static void Brick(ref ONSPPropagationMaterial material)
{
material.absorption.points = new List<Point>{
new Point(125f, .02f), new Point(250f, .02f), new Point(500f, .03f), new Point(1000f, .04f), new Point(2000f, .05f), new Point(4000f, .07f) };
material.scattering.points = new List<Point>{
new Point(125f, .20f), new Point(250f, .25f), new Point(500f, .30f), new Point(1000f, .35f), new Point(2000f, .40f), new Point(4000f, .45f) };
material.transmission.points = new List<Point>(){
new Point(125f, .025f), new Point(250f, .019f), new Point(500f, .01f), new Point(1000f, .0045f), new Point(2000f, .0018f), new Point(4000f, .00089f) };
}
private static void BrickPainted(ref ONSPPropagationMaterial material)
{
material.absorption.points = new List<Point>{
new Point(125f, .01f), new Point(250f, .01f), new Point(500f, .02f), new Point(1000f, .02f), new Point(2000f, .02f), new Point(4000f, .03f) };
material.scattering.points = new List<Point>{
new Point(125f, .15f), new Point(250f, .15f), new Point(500f, .20f), new Point(1000f, .20f), new Point(2000f, .20f), new Point(4000f, .25f) };
material.transmission.points = new List<Point>(){
new Point(125f, .025f), new Point(250f, .019f), new Point(500f, .01f), new Point(1000f, .0045f), new Point(2000f, .0018f), new Point(4000f, .00089f) };
}
private static void Carpet(ref ONSPPropagationMaterial material)
{
material.absorption.points = new List<Point>{
new Point(125f, .01f), new Point(250f, .05f), new Point(500f, .10f), new Point(1000f, .20f), new Point(2000f, .45f), new Point(4000f, .65f) };
material.scattering.points = new List<Point>{
new Point(125f, .10f), new Point(250f, .10f), new Point(500f, .15f), new Point(1000f, .20f), new Point(2000f, .30f), new Point(4000f, .45f) };
material.transmission.points = new List<Point>(){
new Point(125f, .004f), new Point(250f, .0079f), new Point(500f, .0056f), new Point(1000f, .0016f), new Point(2000f, .0014f), new Point(4000f, .0005f) };
}
private static void CarpetHeavy(ref ONSPPropagationMaterial material)
{
material.absorption.points = new List<Point>{
new Point(125f, .02f), new Point(250f, .06f), new Point(500f, .14f), new Point(1000f, .37f), new Point(2000f, .48f), new Point(4000f, .63f) };
material.scattering.points = new List<Point>{
new Point(125f, .10f), new Point(250f, .15f), new Point(500f, .20f), new Point(1000f, .25f), new Point(2000f, .35f), new Point(4000f, .50f) };
material.transmission.points = new List<Point>(){
new Point(125f, .004f), new Point(250f, .0079f), new Point(500f, .0056f), new Point(1000f, .0016f), new Point(2000f, .0014f), new Point(4000f, .0005f) };
}
private static void CarpetHeavyPadded(ref ONSPPropagationMaterial material)
{
material.absorption.points = new List<Point>{
new Point(125f, .08f), new Point(250f, .24f), new Point(500f, .57f), new Point(1000f, .69f), new Point(2000f, .71f), new Point(4000f, .73f) };
material.scattering.points = new List<Point>{
new Point(125f, .10f), new Point(250f, .15f), new Point(500f, .20f), new Point(1000f, .25f), new Point(2000f, .35f), new Point(4000f, .50f) };
material.transmission.points = new List<Point>(){
new Point(125f, .004f), new Point(250f, .0079f), new Point(500f, .0056f), new Point(1000f, .0016f), new Point(2000f, .0014f), new Point(4000f, .0005f) };
}
private static void CeramicTile(ref ONSPPropagationMaterial material)
{
material.absorption.points = new List<Point>{
new Point(125f, .01f), new Point(250f, .01f), new Point(500f, .01f), new Point(1000f, .01f), new Point(2000f, .02f), new Point(4000f, .02f) };
material.scattering.points = new List<Point>{
new Point(125f, .10f), new Point(250f, .12f), new Point(500f, .14f), new Point(1000f, .16f), new Point(2000f, .18f), new Point(4000f, .20f) };
material.transmission.points = new List<Point>(){
new Point(125f, .004f), new Point(250f, .0079f), new Point(500f, .0056f), new Point(1000f, .0016f), new Point(2000f, .0014f), new Point(4000f, .0005f) };
}
private static void Concrete(ref ONSPPropagationMaterial material)
{
material.absorption.points = new List<Point>{
new Point(125f, .01f), new Point(250f, .01f), new Point(500f, .02f), new Point(1000f, .02f), new Point(2000f, .02f), new Point(4000f, .02f) };
material.scattering.points = new List<Point>{
new Point(125f, .10f), new Point(250f, .11f), new Point(500f, .12f), new Point(1000f, .13f), new Point(2000f, .14f), new Point(4000f, .15f) };
material.transmission.points = new List<Point>(){
new Point(125f, .004f), new Point(250f, .0079f), new Point(500f, .0056f), new Point(1000f, .0016f), new Point(2000f, .0014f), new Point(4000f, .0005f) };
}
private static void ConcreteRough(ref ONSPPropagationMaterial material)
{
material.absorption.points = new List<Point>{
new Point(125f, .01f), new Point(250f, .02f), new Point(500f, .04f), new Point(1000f, .06f), new Point(2000f, .08f), new Point(4000f, .10f) };
material.scattering.points = new List<Point>{
new Point(125f, .10f), new Point(250f, .12f), new Point(500f, .15f), new Point(1000f, .20f), new Point(2000f, .25f), new Point(4000f, .30f) };
material.transmission.points = new List<Point>(){
new Point(125f, .004f), new Point(250f, .0079f), new Point(500f, .0056f), new Point(1000f, .0016f), new Point(2000f, .0014f), new Point(4000f, .0005f) };
}
private static void ConcreteBlock(ref ONSPPropagationMaterial material)
{
material.absorption.points = new List<Point>{
new Point(125f, .36f), new Point(250f, .44f), new Point(500f, .31f), new Point(1000f, .29f), new Point(2000f, .39f), new Point(4000f, .21f) };
material.scattering.points = new List<Point>{
new Point(125f, .10f), new Point(250f, .12f), new Point(500f, .15f), new Point(1000f, .20f), new Point(2000f, .30f), new Point(4000f, .40f) };
material.transmission.points = new List<Point>(){
new Point(125f, .02f), new Point(250f, .01f), new Point(500f, .0063f), new Point(1000f, .0035f), new Point(2000f, .00011f), new Point(4000f, .00063f) };
}
private static void ConcreteBlockPainted(ref ONSPPropagationMaterial material)
{
material.absorption.points = new List<Point>{
new Point(125f, .10f), new Point(250f, .05f), new Point(500f, .06f), new Point(1000f, .07f), new Point(2000f, .09f), new Point(4000f, .08f) };
material.scattering.points = new List<Point>{
new Point(125f, .10f), new Point(250f, .11f), new Point(500f, .13f), new Point(1000f, .15f), new Point(2000f, .16f), new Point(4000f, .20f) };
material.transmission.points = new List<Point>(){
new Point(125f, .02f), new Point(250f, .01f), new Point(500f, .0063f), new Point(1000f, .0035f), new Point(2000f, .00011f), new Point(4000f, .00063f) };
}
private static void Curtain(ref ONSPPropagationMaterial material)
{
material.absorption.points = new List<Point>{
new Point(125f, .07f), new Point(250f, .31f), new Point(500f, .49f), new Point(1000f, .75f), new Point(2000f, .70f), new Point(4000f, .60f) };
material.scattering.points = new List<Point>{
new Point(125f, .10f), new Point(250f, .15f), new Point(500f, .2f), new Point(1000f, .3f), new Point(2000f, .4f), new Point(4000f, .5f) };
material.transmission.points = new List<Point>(){
new Point(125f, .42f), new Point(250f, .39f), new Point(500f, .21f), new Point(1000f, .14f), new Point(2000f, .079f), new Point(4000f, .045f) };
}
private static void Foliage(ref ONSPPropagationMaterial material)
{
material.absorption.points = new List<Point>{
new Point(125f, .03f), new Point(250f, .06f), new Point(500f, .11f), new Point(1000f, .17f), new Point(2000f, .27f), new Point(4000f, .31f) };
material.scattering.points = new List<Point>{
new Point(125f, .20f), new Point(250f, .3f), new Point(500f, .4f), new Point(1000f, .5f), new Point(2000f, .7f), new Point(4000f, .8f) };
material.transmission.points = new List<Point>(){
new Point(125f, .9f), new Point(250f, .9f), new Point(500f, .9f), new Point(1000f, .8f), new Point(2000f, .5f), new Point(4000f, .3f) };
}
private static void Glass(ref ONSPPropagationMaterial material)
{
material.absorption.points = new List<Point>{
new Point(125f, .35f), new Point(250f, .25f), new Point(500f, .18f), new Point(1000f, .12f), new Point(2000f, .07f), new Point(4000f, .05f) };
material.scattering.points = new List<Point>{
new Point(125f, .05f), new Point(250f, .05f), new Point(500f, .05f), new Point(1000f, .05f), new Point(2000f, .05f), new Point(4000f, .05f) };
material.transmission.points = new List<Point>(){
new Point(125f, .125f), new Point(250f, .089f), new Point(500f, .05f), new Point(1000f, .028f), new Point(2000f, .022f), new Point(4000f, .079f) };
}
private static void GlassHeavy(ref ONSPPropagationMaterial material)
{
material.absorption.points = new List<Point>{
new Point(125f, .18f), new Point(250f, .06f), new Point(500f, .04f), new Point(1000f, .03f), new Point(2000f, .02f), new Point(4000f, .02f) };
material.scattering.points = new List<Point>{
new Point(125f, .05f), new Point(250f, .05f), new Point(500f, .05f), new Point(1000f, .05f), new Point(2000f, .05f), new Point(4000f, .05f) };
material.transmission.points = new List<Point>(){
new Point(125f, .056f), new Point(250f, .039f), new Point(500f, .028f), new Point(1000f, .02f), new Point(2000f, .032f), new Point(4000f, .014f) };
}
private static void Grass(ref ONSPPropagationMaterial material)
{
material.absorption.points = new List<Point>{
new Point(125f, .11f), new Point(250f, .26f), new Point(500f, .60f), new Point(1000f, .69f), new Point(2000f, .92f), new Point(4000f, .99f) };
material.scattering.points = new List<Point>{
new Point(125f, .30f), new Point(250f, .30f), new Point(500f, .40f), new Point(1000f, .50f), new Point(2000f, .60f), new Point(4000f, .70f) };
material.transmission.points = new List<Point>();
}
private static void Gravel(ref ONSPPropagationMaterial material)
{
material.absorption.points = new List<Point>{
new Point(125f, .25f), new Point(250f, .60f), new Point(500f, .65f), new Point(1000f, .70f), new Point(2000f, .75f), new Point(4000f, .80f) };
material.scattering.points = new List<Point>{
new Point(125f, .20f), new Point(250f, .30f), new Point(500f, .40f), new Point(1000f, .50f), new Point(2000f, .60f), new Point(4000f, .70f) };
material.transmission.points = new List<Point>();
}
private static void GypsumBoard(ref ONSPPropagationMaterial material)
{
material.absorption.points = new List<Point>{
new Point(125f, .29f), new Point(250f, .10f), new Point(500f, .05f), new Point(1000f, .04f), new Point(2000f, .07f), new Point(4000f, .09f) };
material.scattering.points = new List<Point>{
new Point(125f, .10f), new Point(250f, .11f), new Point(500f, .12f), new Point(1000f, .13f), new Point(2000f, .14f), new Point(4000f, .15f) };
material.transmission.points = new List<Point>(){
new Point(125f, .035f), new Point(250f, .0125f), new Point(500f, .0056f), new Point(1000f, .0025f), new Point(2000f, .0013f), new Point(4000f, .0032f) };
}
private static void PlasterOnBrick(ref ONSPPropagationMaterial material)
{
material.absorption.points = new List<Point>{
new Point(125f, .01f), new Point(250f, .02f), new Point(500f, .02f), new Point(1000f, .03f), new Point(2000f, .04f), new Point(4000f, .05f) };
material.scattering.points = new List<Point>{
new Point(125f, .20f), new Point(250f, .25f), new Point(500f, .30f), new Point(1000f, .35f), new Point(2000f, .40f), new Point(4000f, .45f) };
material.transmission.points = new List<Point>(){
new Point(125f, .025f), new Point(250f, .019f), new Point(500f, .01f), new Point(1000f, .0045f), new Point(2000f, .0018f), new Point(4000f, .00089f) };
}
private static void PlasterOnConcreteBlock(ref ONSPPropagationMaterial material)
{
material.absorption.points = new List<Point>{
new Point(125f, .12f), new Point(250f, .09f), new Point(500f, .07f), new Point(1000f, .05f), new Point(2000f, .05f), new Point(4000f, .04f) };
material.scattering.points = new List<Point>{
new Point(125f, .20f), new Point(250f, .25f), new Point(500f, .30f), new Point(1000f, .35f), new Point(2000f, .40f), new Point(4000f, .45f) };
material.transmission.points = new List<Point>(){
new Point(125f, .02f), new Point(250f, .01f), new Point(500f, .0063f), new Point(1000f, .0035f), new Point(2000f, .00011f), new Point(4000f, .00063f) };
}
private static void Soil(ref ONSPPropagationMaterial material)
{
material.absorption.points = new List<Point>{
new Point(125f, .15f), new Point(250f, .25f), new Point(500f, .40f), new Point(1000f, .55f), new Point(2000f, .60f), new Point(4000f, .60f) };
material.scattering.points = new List<Point>{
new Point(125f, .10f), new Point(250f, .20f), new Point(500f, .25f), new Point(1000f, .40f), new Point(2000f, .55f), new Point(4000f, .70f) };
material.transmission.points = new List<Point>();
}
private static void SoundProof(ref ONSPPropagationMaterial material)
{
material.absorption.points = new List<Point>{ new Point(1000f, 1.0f) };
material.scattering.points = new List<Point>{ new Point(1000f, 0.0f) };
material.transmission.points = new List<Point>();
}
private static void Snow(ref ONSPPropagationMaterial material)
{
material.absorption.points = new List<Point>{
new Point(125f, .45f), new Point(250f, .75f), new Point(500f, .90f), new Point(1000f, .95f), new Point(2000f, .95f), new Point(4000f, .95f) };
material.scattering.points = new List<Point>{
new Point(125f, .20f), new Point(250f, .30f), new Point(500f, .40f), new Point(1000f, .50f), new Point(2000f, .60f), new Point(4000f, .75f) };
material.transmission.points = new List<Point>();
}
private static void Steel(ref ONSPPropagationMaterial material)
{
material.absorption.points = new List<Point>{
new Point(125f, .05f), new Point(250f, .10f), new Point(500f, .10f), new Point(1000f, .10f), new Point(2000f, .07f), new Point(4000f, .02f) };
material.scattering.points = new List<Point>{
new Point(125f, .10f), new Point(250f, .10f), new Point(500f, .10f), new Point(1000f, .10f), new Point(2000f, .10f), new Point(4000f, .10f) };
material.transmission.points = new List<Point>(){
new Point(125f, .25f), new Point(250f, .2f), new Point(500f, .17f), new Point(1000f, .089f), new Point(2000f, .089f), new Point(4000f, .0056f) };
}
private static void Water(ref ONSPPropagationMaterial material)
{
material.absorption.points = new List<Point>{
new Point(125f, .01f), new Point(250f, .01f), new Point(500f, .01f), new Point(1000f, .02f), new Point(2000f, .02f), new Point(4000f, .03f) };
material.scattering.points = new List<Point>{
new Point(125f, .10f), new Point(250f, .10f), new Point(500f, .10f), new Point(1000f, .07f), new Point(2000f, .05f), new Point(4000f, .05f) };
material.transmission.points = new List<Point>(){
new Point(125f, .03f), new Point(250f, .03f), new Point(500f, .03f), new Point(1000f, .02f), new Point(2000f, .015f), new Point(4000f, .01f) };
}
private static void WoodThin(ref ONSPPropagationMaterial material)
{
material.absorption.points = new List<Point>{
new Point(125f, .42f), new Point(250f, .21f), new Point(500f, .10f), new Point(1000f, .08f), new Point(2000f, .06f), new Point(4000f, .06f) };
material.scattering.points = new List<Point>{
new Point(125f, .10f), new Point(250f, .10f), new Point(500f, .10f), new Point(1000f, .10f), new Point(2000f, .10f), new Point(4000f, .15f) };
material.transmission.points = new List<Point>(){
new Point(125f, .2f), new Point(250f, .125f), new Point(500f, .079f), new Point(1000f, .1f), new Point(2000f, .089f), new Point(4000f, .05f) };
}
private static void WoodThick(ref ONSPPropagationMaterial material)
{
material.absorption.points = new List<Point>{
new Point(125f, .19f), new Point(250f, .14f), new Point(500f, .09f), new Point(1000f, .06f), new Point(2000f, .06f), new Point(4000f, .05f) };
material.scattering.points = new List<Point>{
new Point(125f, .10f), new Point(250f, .10f), new Point(500f, .10f), new Point(1000f, .10f), new Point(2000f, .10f), new Point(4000f, .15f) };
material.transmission.points = new List<Point>(){
new Point(125f, .035f), new Point(250f, .028f), new Point(500f, .028f), new Point(1000f, .028f), new Point(2000f, .011f), new Point(4000f, .0071f) };
}
private static void WoodFloor(ref ONSPPropagationMaterial material)
{
material.absorption.points = new List<Point>{
new Point(125f, .15f), new Point(250f, .11f), new Point(500f, .10f), new Point(1000f, .07f), new Point(2000f, .06f), new Point(4000f, .07f) };
material.scattering.points = new List<Point>{
new Point(125f, .10f), new Point(250f, .10f), new Point(500f, .10f), new Point(1000f, .10f), new Point(2000f, .10f), new Point(4000f, .15f) };
material.transmission.points = new List<Point>(){
new Point(125f, .071f), new Point(250f, .025f), new Point(500f, .0158f), new Point(1000f, .0056f), new Point(2000f, .0035f), new Point(4000f, .0016f) };
}
private static void WoodOnConcrete(ref ONSPPropagationMaterial material)
{
material.absorption.points = new List<Point>{
new Point(125f, .04f), new Point(250f, .04f), new Point(500f, .07f), new Point(1000f, .06f), new Point(2000f, .06f), new Point(4000f, .07f) };
material.scattering.points = new List<Point>{
new Point(125f, .10f), new Point(250f, .10f), new Point(500f, .10f), new Point(1000f, .10f), new Point(2000f, .10f), new Point(4000f, .15f) };
material.transmission.points = new List<Point>(){
new Point(125f, .004f), new Point(250f, .0079f), new Point(500f, .0056f), new Point(1000f, .0016f), new Point(2000f, .0014f), new Point(4000f, .0005f) };
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 45fef2cb49a5b4b46a3d1cbeaec4c932
timeCreated: 1523481682
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,35 @@
/************************************************************************************
Filename : ONSPPropagationSettings.cs
Content : Exposes settings for Propagation
Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
Licensed under the Oculus SDK Version 3.5 (the "License");
you may not use the Oculus SDK except in compliance with the License,
which is provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
You may obtain a copy of the License at
https://developer.oculus.com/licenses/sdk-3.5/
Unless required by applicable law or agreed to in writing, the Oculus SDK
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
************************************************************************************/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ONSPPropagationSettings : MonoBehaviour
{
// quality as a percentage
public float quality = 100.0f;
void Update ()
{
ONSPPropagation.Interface.SetPropagationQuality(quality / 100.0f);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fef66f1ca6893fc449924f0e12b92357
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,47 @@
using UnityEngine;
using System.Collections;
#if UNITY_EDITOR
[UnityEditor.InitializeOnLoad]
#endif
public sealed class ONSPSettings : ScriptableObject
{
[SerializeField]
public int voiceLimit = 64;
private static ONSPSettings instance;
public static ONSPSettings Instance
{
get
{
if (instance == null)
{
instance = Resources.Load<ONSPSettings>("ONSPSettings");
// This can happen if the developer never input their App Id into the Unity Editor
// and therefore never created the OculusPlatformSettings.asset file
// Use a dummy object with defaults for the getters so we don't have a null pointer exception
if (instance == null)
{
instance = ScriptableObject.CreateInstance<ONSPSettings>();
#if UNITY_EDITOR
// Only in the editor should we save it to disk
string properPath = System.IO.Path.Combine(UnityEngine.Application.dataPath, "Resources");
if (!System.IO.Directory.Exists(properPath))
{
UnityEditor.AssetDatabase.CreateFolder("Assets", "Resources");
}
string fullPath = System.IO.Path.Combine(
System.IO.Path.Combine("Assets", "Resources"),
"ONSPSettings.asset");
UnityEditor.AssetDatabase.CreateAsset(instance, fullPath);
#endif
}
}
return instance;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ad074644ff568a14187a3690cfbd7534
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,63 @@
/************************************************************************************
Filename : ONSPVersion.cs
Content : Get version number of plug-in
Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
Licensed under the Oculus SDK Version 3.5 (the "License");
you may not use the Oculus SDK except in compliance with the License,
which is provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
You may obtain a copy of the License at
https://developer.oculus.com/licenses/sdk-3.5/
Unless required by applicable law or agreed to in writing, the Oculus SDK
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
************************************************************************************/
using UnityEngine;
using System;
using System.Runtime.InteropServices;
public class ONSPVersion : MonoBehaviour
{
// Import functions
public const string strONSPS = "AudioPluginOculusSpatializer";
[DllImport(strONSPS)]
private static extern void ONSP_GetVersion(ref int Major, ref int Minor, ref int Patch);
/// <summary>
/// Awake this instance.
/// </summary>
void Awake()
{
int major = 0;
int minor = 0;
int patch = 0;
ONSP_GetVersion(ref major, ref minor, ref patch);
String version = System.String.Format
("ONSP Version: {0:F0}.{1:F0}.{2:F0}", major, minor, patch);
Debug.Log(version);
}
/// <summary>
/// Start this instance.
/// </summary>
void Start()
{
}
/// <summary>
/// Update this instance.
/// </summary>
void Update()
{
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 46821b10458428648878b1b4a9113c40
timeCreated: 1459353580
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,343 @@
/************************************************************************************
Filename : OculusSpatializerUnity.cs
Content : Interface into real-time geometry reflection engine for native Unity
Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
Licensed under the Oculus SDK Version 3.5 (the "License");
you may not use the Oculus SDK except in compliance with the License,
which is provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
You may obtain a copy of the License at
https://developer.oculus.com/licenses/sdk-3.5/
Unless required by applicable law or agreed to in writing, the Oculus SDK
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
************************************************************************************/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Runtime.InteropServices;
using AOT;
public class OculusSpatializerUnity : MonoBehaviour
{
public LayerMask layerMask = -1;
public bool visualizeRoom = true;
bool roomVisualizationInitialized = false;
public int raysPerSecond = 256;
public float roomInterpSpeed = 0.9f;
public float maxWallDistance = 50.0f;
public int rayCacheSize = 512;
public bool dynamicReflectionsEnabled = true;
float particleSize = 0.2f;
float particleOffset = 0.1f;
GameObject room;
Renderer[] wallRenderer = new Renderer[6];
float[] dims = new float[3] { 1.0f, 1.0f, 1.0f };
float[] coefs = new float[6];
const int HIT_COUNT = 2048;
Vector3[] points = new Vector3[HIT_COUNT];
Vector3[] normals = new Vector3[HIT_COUNT];
ParticleSystem sys;
ParticleSystem.Particle[] particles = new ParticleSystem.Particle[HIT_COUNT];
static LayerMask gLayerMask = -1;
static Vector3 swapHandedness(Vector3 vec) { return new Vector3(vec.x, vec.y, -vec.z); }
[MonoPInvokeCallback(typeof(AudioRaycastCallback))]
static void AudioRaycast(Vector3 origin, Vector3 direction, out Vector3 point, out Vector3 normal, System.IntPtr data)
{
point = Vector3.zero;
normal = Vector3.zero;
RaycastHit hitInfo;
if (Physics.Raycast(swapHandedness(origin), swapHandedness(direction), out hitInfo, 1000.0f, gLayerMask.value))
{
point = swapHandedness(hitInfo.point);
normal = swapHandedness(hitInfo.normal);
}
}
void Start()
{
OSP_Unity_AssignRaycastCallback(AudioRaycast, System.IntPtr.Zero);
}
void OnDestroy()
{
OSP_Unity_AssignRaycastCallback(System.IntPtr.Zero, System.IntPtr.Zero);
}
void Update()
{
if (dynamicReflectionsEnabled)
{
OSP_Unity_AssignRaycastCallback(AudioRaycast, System.IntPtr.Zero);
}
else
{
OSP_Unity_AssignRaycastCallback(System.IntPtr.Zero, System.IntPtr.Zero);
}
OSP_Unity_SetDynamicRoomRaysPerSecond(raysPerSecond);
OSP_Unity_SetDynamicRoomInterpSpeed(roomInterpSpeed);
OSP_Unity_SetDynamicRoomMaxWallDistance(maxWallDistance);
OSP_Unity_SetDynamicRoomRaysRayCacheSize(rayCacheSize);
gLayerMask = layerMask;
OSP_Unity_UpdateRoomModel(1.0f);
if (visualizeRoom)
{
if (!roomVisualizationInitialized)
{
inititalizeRoomVisualization();
roomVisualizationInitialized = true;
}
Vector3 pos;
OSP_Unity_GetRoomDimensions(dims, coefs, out pos);
pos.z *= -1; // swap to left-handed
var size = new Vector3(dims[0], dims[1], dims[2]);
float magSqrd = size.sqrMagnitude;
if (!float.IsNaN(magSqrd) && 0.0f < magSqrd && magSqrd < 1000000.0f)
{
transform.localScale = size * 0.999f;
}
transform.position = pos;
OSP_Unity_GetRaycastHits(points, normals, HIT_COUNT);
for (int i = 0; i < HIT_COUNT; ++i)
{
if (points[i] == Vector3.zero)
points[i].y = -10000.0f; // hide it
// swap to left-handed
points[i].z *= -1;
normals[i].z *= -1;
particles[i].position = points[i] + normals[i] * particleOffset;
if (normals[i] != Vector3.zero)
particles[i].rotation3D = Quaternion.LookRotation(normals[i]).eulerAngles;
particles[i].startSize = particleSize;
particles[i].startColor = new Color(208 / 255f, 38 / 255f, 174 / 255f, 1.0f);
}
for (int wall = 0; wall < 6; ++wall)
{
var color = Color.Lerp(Color.red, Color.green, coefs[wall]);
wallRenderer[wall].material.SetColor("_TintColor", color);
}
sys.SetParticles(particles, particles.Length);
}
}
private void inititalizeRoomVisualization()
{
Debug.Log("Oculus Audio dynamic room estimation visualization enabled");
transform.position = Vector3.zero; // move to the origin otherwise things are displaced
// Create a particle system to visualize the ray cast hits
GameObject decalManager = new GameObject("DecalManager");
decalManager.transform.parent = transform;
sys = decalManager.AddComponent<ParticleSystem>();
{
var main = sys.main;
main.simulationSpace = ParticleSystemSimulationSpace.World;
main.loop = false;
main.playOnAwake = false;
var emission = sys.emission;
emission.enabled = false;
var shape = sys.shape;
shape.enabled = false;
var renderer = sys.GetComponent<ParticleSystemRenderer>();
renderer.renderMode = ParticleSystemRenderMode.Mesh;
renderer.material.shader = Shader.Find("Particles/Additive");
Texture2D decalTex;
{
const int SIZE = 64;
const int RING_COUNT = 2;
decalTex = new Texture2D(SIZE, SIZE);
const int HALF_SIZE = SIZE / 2;
for (int i = 0; i < SIZE / 2; ++i)
{
for (int j = 0; j < SIZE / 2; ++j)
{
// distance from center
float deltaX = (float)(HALF_SIZE - i);
float deltaY = (float)(HALF_SIZE - j);
float dist = Mathf.Sqrt((deltaX * deltaX) + (deltaY * deltaY));
float t = (RING_COUNT * dist) / HALF_SIZE;
float alpha = (dist < HALF_SIZE) ? Mathf.Clamp01(Mathf.Sin(Mathf.PI * 2.0f * t)) : 0.0f;
Color col = new Color(1.0f, 1.0f, 1.0f, alpha);
// Two way symmetry
decalTex.SetPixel(i, j, col);
decalTex.SetPixel(SIZE - i, j, col);
decalTex.SetPixel(i, SIZE - j, col);
decalTex.SetPixel(SIZE - i, SIZE - j, col);
}
}
decalTex.Apply();
}
renderer.material.mainTexture = decalTex;
// Make a quad
var m = new Mesh();
m.name = "ParticleQuad";
const float size = 0.5f;
m.vertices = new Vector3[] {
new Vector3(-size, -size, 0.0f),
new Vector3( size, -size, 0.0f),
new Vector3( size, size, 0.0f),
new Vector3(-size, size, 0.0f)
};
m.uv = new Vector2[] {
new Vector2(0, 0),
new Vector2(0, 1),
new Vector2(1, 1),
new Vector2(1, 0)
};
m.triangles = new int[] { 0, 1, 2, 0, 2, 3 };
m.RecalculateNormals();
renderer.mesh = m;
}
sys.Emit(HIT_COUNT);
// Construct the visual representation of the room
room = new GameObject("RoomVisualizer");
room.transform.parent = transform;
room.transform.localPosition = Vector3.zero;
Texture2D wallTex;
{
const int SIZE = 32;
wallTex = new Texture2D(SIZE, SIZE);
Color transparent = new Color(0.0f, 0.0f, 0.0f, 0.0f);
for (int i = 0; i < SIZE; ++i)
{
for (int j = 0; j < SIZE; ++j)
{
wallTex.SetPixel(i, j, transparent);
}
}
for (int i = 0; i < SIZE; ++i)
{
Color color1 = Color.white * 0.125f;
wallTex.SetPixel(SIZE / 4, i, color1);
wallTex.SetPixel(i, SIZE / 4, color1);
wallTex.SetPixel(3 * SIZE / 4, i, color1);
wallTex.SetPixel(i, 3 * SIZE / 4, color1);
color1 *= 2.0f;
wallTex.SetPixel(SIZE / 2, i, color1);
wallTex.SetPixel(i, SIZE / 2, color1);
color1 *= 2.0f;
wallTex.SetPixel(0, i, color1);
wallTex.SetPixel(i, 0, color1);
}
wallTex.Apply();
}
for (int wall = 0; wall < 6; ++wall)
{
var m = new Mesh();
m.name = "Plane" + wall;
const float size = 0.5f;
var verts = new Vector3[4];
int axis = wall / 2;
int sign = (wall % 2 == 0) ? 1 : -1;
for (int i = 0; i < 4; ++i)
{
verts[i][axis] = sign * size;
verts[i][(axis + 1) % 3] = size * ((i == 1 || i == 2) ? 1 : -1);
verts[i][(axis + 2) % 3] = size * ((i == 2 || i == 3) ? 1 : -1);
}
m.vertices = verts;
m.uv = new Vector2[]
{
new Vector2(0, 0),
new Vector2(0, 1),
new Vector2(1, 1),
new Vector2(1, 0)
};
m.triangles = new int[] { 0, 1, 2, 0, 2, 3 };
m.RecalculateNormals();
var go = new GameObject("Wall_" + wall);
go.AddComponent<MeshFilter>().mesh = m;
var renderer = go.AddComponent<MeshRenderer>();
wallRenderer[wall] = renderer;
renderer.material.shader = Shader.Find("Particles/Additive");
renderer.material.mainTexture = wallTex;
renderer.material.mainTextureScale = new Vector2(8, 8);
go.transform.parent = room.transform;
room.transform.localPosition = Vector3.zero;
}
}
// * * * * * * * * * * * * *
// Import functions
public delegate void AudioRaycastCallback(Vector3 origin, Vector3 direction,
out Vector3 point, out Vector3 normal,
System.IntPtr data);
private const string strOSP = "AudioPluginOculusSpatializer";
[DllImport(strOSP)]
private static extern int OSP_Unity_AssignRaycastCallback(AudioRaycastCallback callback, System.IntPtr data);
[DllImport(strOSP)]
private static extern int OSP_Unity_AssignRaycastCallback(System.IntPtr callback, System.IntPtr data);
[DllImport(strOSP)]
private static extern int OSP_Unity_SetDynamicRoomRaysPerSecond(int RaysPerSecond);
[DllImport(strOSP)]
private static extern int OSP_Unity_SetDynamicRoomInterpSpeed(float InterpSpeed);
[DllImport(strOSP)]
private static extern int OSP_Unity_SetDynamicRoomMaxWallDistance(float MaxWallDistance);
[DllImport(strOSP)]
private static extern int OSP_Unity_SetDynamicRoomRaysRayCacheSize(int RayCacheSize);
[DllImport(strOSP)]
private static extern int OSP_Unity_UpdateRoomModel(float wetLevel); // call from main thread!!
[DllImport(strOSP)]
private static extern int OSP_Unity_GetRoomDimensions(float[] roomDimensions, float[] reflectionsCoefs, out Vector3 position);
[DllImport(strOSP)]
private static extern int OSP_Unity_GetRaycastHits(Vector3[] points, Vector3[] normals, int length);
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 8e8aaaa0cd7804c469aa5f8dc3f42ee4
timeCreated: 1541979457
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 09f814575468d81448e92cb264792b5b
folderAsset: yes
timeCreated: 1479154551
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,164 @@
/************************************************************************************
Filename : ONSPReflectionZone.cs
Content : Add reflection zone volumes to set reflection parameters via snapshots.
Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
Licensed under the Oculus SDK Version 3.5 (the "License");
you may not use the Oculus SDK except in compliance with the License,
which is provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
You may obtain a copy of the License at
https://developer.oculus.com/licenses/sdk-3.5/
Unless required by applicable law or agreed to in writing, the Oculus SDK
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
************************************************************************************/
using UnityEngine;
using UnityEngine.Audio;
using System.Collections;
using System.Collections.Generic;
public struct ReflectionSnapshot
{
public AudioMixerSnapshot mixerSnapshot;
public float fadeTime;
}
public class ONSPReflectionZone : MonoBehaviour
{
public AudioMixerSnapshot mixerSnapshot = null;
public float fadeTime = 0.0f;
// Push/pop list
private static Stack<ReflectionSnapshot> snapshotList = new Stack<ReflectionSnapshot>();
private static ReflectionSnapshot currentSnapshot = new ReflectionSnapshot();
/// <summary>
/// Start this instance.
/// </summary>
void Start ()
{
}
/// <summary>
/// Update this instance.
/// </summary>
void Update ()
{
}
/// <summary>
/// Raises the trigger enter event.
/// </summary>
/// <param name="other">Other.</param>
void OnTriggerEnter(Collider other)
{
if(CheckForAudioListener(other.gameObject) == true)
{
PushCurrentMixerShapshot();
}
}
/// <summary>
/// Raises the trigger exit event.
/// </summary>
/// <param name="other">Other.</param>
void OnTriggerExit(Collider other)
{
if(CheckForAudioListener(other.gameObject) == true)
{
PopCurrentMixerSnapshot();
}
}
// * * * * * * * * * * * * *
// Private functions
/// <summary>
/// Checks for audio listener.
/// </summary>
/// <returns><c>true</c>, if for audio listener was checked, <c>false</c> otherwise.</returns>
/// <param name="gameObject">Game object.</param>
bool CheckForAudioListener(GameObject gameObject)
{
AudioListener al = gameObject.GetComponentInChildren<AudioListener>();
if(al != null)
return true;
return false;
}
/// <summary>
/// Pushs the current mixer snapshot onto the snapshot stack
/// </summary>
void PushCurrentMixerShapshot()
{
ReflectionSnapshot css = currentSnapshot;
snapshotList.Push(css);
// Set the zone reflection values
// NOTE: There will be conditions that might need resolution when dealing with volumes that
// overlap. Best practice is to never have volumes half-way inside other volumes; larger
// volumes should completely contain smaller volumes
SetReflectionValues();
}
/// <summary>
/// Pops the current reflection values from reflectionsList stack.
/// </summary>
void PopCurrentMixerSnapshot()
{
ReflectionSnapshot snapshot = snapshotList.Pop();
// Set the popped reflection values
SetReflectionValues(ref snapshot);
}
/// <summary>
/// Sets the reflection values. This is done when entering a zone (use zone values).
/// </summary>
void SetReflectionValues()
{
if (mixerSnapshot != null)
{
Debug.Log("Setting off snapshot " + mixerSnapshot.name);
mixerSnapshot.TransitionTo(fadeTime);
// Set the current snapshot to be equal to this one
currentSnapshot.mixerSnapshot = mixerSnapshot;
currentSnapshot.fadeTime = fadeTime;
}
else
{
Debug.Log("Mixer snapshot not set - Please ensure play area has at least one encompassing snapshot.");
}
}
/// <summary>
/// Sets the reflection values. This is done when exiting a zone (use popped values).
/// </summary>
/// <param name="rm">Rm.</param>
void SetReflectionValues(ref ReflectionSnapshot mss)
{
if(mss.mixerSnapshot != null)
{
Debug.Log("Setting off snapshot " + mss.mixerSnapshot.name);
mss.mixerSnapshot.TransitionTo(mss.fadeTime);
// Set the current snapshot to be equal to this one
currentSnapshot.mixerSnapshot = mss.mixerSnapshot;
currentSnapshot.fadeTime = mss.fadeTime;
}
else
{
Debug.Log("Mixer snapshot not set - Please ensure play area has at least one encompassing snapshot.");
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: cfc03cf517e91a64ba53fc31e61657ea
timeCreated: 1473375383
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: