Initialer Upload neues Unity-Projekt

This commit is contained in:
Daniel Ocks
2025-07-21 09:11:14 +02:00
commit eeca72985b
14558 changed files with 1508140 additions and 0 deletions

View File

@ -0,0 +1,147 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* Licensed under the Oculus SDK License Agreement (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/oculussdk/
*
* 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.
*/
/************************************************************************************
* Filename : ONSPAmbisonicsNative.cs
* Content : Native interface into the Oculus Ambisonics
***********************************************************************************/
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,373 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* Licensed under the Oculus SDK License Agreement (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/oculussdk/
*
* 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.
*/
/************************************************************************************
* Filename : ONSPAudioSource.cs
* Content : Interface into the Oculus Native Spatializer Plugin
***********************************************************************************/
// Uncomment below to test access of read-only spatializer parameters
//#define TEST_READONLY_PARAMETERS
#if !(UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN || UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX || (UNITY_ANDROID && !UNITY_EDITOR))
#define ONSP_UNSUPPORTED_PLATFORM
#endif
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()
{
#if !ONSP_UNSUPPORTED_PLATFORM
OSP_SetGlobalVoiceLimit(ONSPSettings.Instance.voiceLimit);
#endif
}
// 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,61 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* Licensed under the Oculus SDK License Agreement (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/oculussdk/
*
* 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.
*/
/************************************************************************************
* Filename : ONSPProfiler.cs
* Content : Use this to attach to the Oculus Audio Profiler tool
***********************************************************************************/
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,708 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* Licensed under the Oculus SDK License Agreement (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/oculussdk/
*
* 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.
*/
/************************************************************************************
* 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
***********************************************************************************/
#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;
// Check for LOD. If present, use only the highest LOD and don't recurse to children.
// Without this, we can accidentally get all LODs merged together.
LODGroup lodGroup = obj.GetComponent(typeof(LODGroup)) as LODGroup;
if ( lodGroup != null )
{
LOD [] lods = lodGroup.GetLODs();
if ( lods.Length > 0 )
{
// Get renderers for highest LOD.
Renderer [] lodRenderers = lods[0].renderers;
if ( lodRenderers.Length > 0 )
{
// Use the rendered game object to get the mesh instead, and don't go to children.
obj = lodRenderers[0].gameObject;
includeChildren = false;
}
}
}
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
int directoriesEnd = filePathRelative.LastIndexOf('/');
if ( directoriesEnd >= 0 )
{
string directoryName = filePathRelative.Substring(0, directoriesEnd);
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,579 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* Licensed under the Oculus SDK License Agreement (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/oculussdk/
*
* 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.
*/
/************************************************************************************
* Filename : ONSPPropagationInterface.cs
* Content : Interface into the Oculus Audio propagation functions
***********************************************************************************/
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,621 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* Licensed under the Oculus SDK License Agreement (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/oculussdk/
*
* 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.
*/
/************************************************************************************
* Filename : ONSPPropagationMaterial.cs
* Content : Propagation material class
Attach to geometry to define material properties
***********************************************************************************/
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,39 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* Licensed under the Oculus SDK License Agreement (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/oculussdk/
*
* 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.
*/
/************************************************************************************
* Filename : ONSPPropagationSettings.cs
* Content : Exposes settings for Propagation
***********************************************************************************/
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,68 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* Licensed under the Oculus SDK License Agreement (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/oculussdk/
*
* 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.
*/
/************************************************************************************
* Filename : ONSPVersion.cs
* Content : Get version number of plug-in
***********************************************************************************/
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,348 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* Licensed under the Oculus SDK License Agreement (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/oculussdk/
*
* 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.
*/
/************************************************************************************
* Filename : OculusSpatializerUnity.cs
* Content : Interface into real-time geometry reflection engine for native Unity
***********************************************************************************/
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,169 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* Licensed under the Oculus SDK License Agreement (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/oculussdk/
*
* 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.
*/
/************************************************************************************
* Filename : ONSPReflectionZone.cs
* Content : Add reflection zone volumes to set reflection parameters via snapshots.
***********************************************************************************/
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: