Initialer Upload neues Unity-Projekt
This commit is contained in:
147
Assets/Oculus/Spatializer/scripts/ONSPAmbisonicsNative.cs
Normal file
147
Assets/Oculus/Spatializer/scripts/ONSPAmbisonicsNative.cs
Normal 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
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bb001ad917b86f148a2c85acdd0d5c6a
|
||||
timeCreated: 1479161980
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
373
Assets/Oculus/Spatializer/scripts/ONSPAudioSource.cs
Normal file
373
Assets/Oculus/Spatializer/scripts/ONSPAudioSource.cs
Normal 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);
|
||||
}
|
||||
12
Assets/Oculus/Spatializer/scripts/ONSPAudioSource.cs.meta
Normal file
12
Assets/Oculus/Spatializer/scripts/ONSPAudioSource.cs.meta
Normal 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:
|
||||
61
Assets/Oculus/Spatializer/scripts/ONSPProfiler.cs
Normal file
61
Assets/Oculus/Spatializer/scripts/ONSPProfiler.cs
Normal 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);
|
||||
}
|
||||
12
Assets/Oculus/Spatializer/scripts/ONSPProfiler.cs.meta
Normal file
12
Assets/Oculus/Spatializer/scripts/ONSPProfiler.cs.meta
Normal 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:
|
||||
708
Assets/Oculus/Spatializer/scripts/ONSPPropagationGeometry.cs
Normal file
708
Assets/Oculus/Spatializer/scripts/ONSPPropagationGeometry.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: abdaae8d2b81ba54498967f33610da0d
|
||||
timeCreated: 1525731700
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
579
Assets/Oculus/Spatializer/scripts/ONSPPropagationInterface.cs
Normal file
579
Assets/Oculus/Spatializer/scripts/ONSPPropagationInterface.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b604e1956166619468a5c9801f1b3756
|
||||
timeCreated: 1525727421
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
621
Assets/Oculus/Spatializer/scripts/ONSPPropagationMaterial.cs
Normal file
621
Assets/Oculus/Spatializer/scripts/ONSPPropagationMaterial.cs
Normal 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) };
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 45fef2cb49a5b4b46a3d1cbeaec4c932
|
||||
timeCreated: 1523481682
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
39
Assets/Oculus/Spatializer/scripts/ONSPPropagationSettings.cs
Normal file
39
Assets/Oculus/Spatializer/scripts/ONSPPropagationSettings.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fef66f1ca6893fc449924f0e12b92357
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
47
Assets/Oculus/Spatializer/scripts/ONSPSettings.cs
Normal file
47
Assets/Oculus/Spatializer/scripts/ONSPSettings.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Oculus/Spatializer/scripts/ONSPSettings.cs.meta
Normal file
11
Assets/Oculus/Spatializer/scripts/ONSPSettings.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ad074644ff568a14187a3690cfbd7534
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
68
Assets/Oculus/Spatializer/scripts/ONSPVersion.cs
Normal file
68
Assets/Oculus/Spatializer/scripts/ONSPVersion.cs
Normal 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()
|
||||
{
|
||||
}
|
||||
}
|
||||
12
Assets/Oculus/Spatializer/scripts/ONSPVersion.cs.meta
Normal file
12
Assets/Oculus/Spatializer/scripts/ONSPVersion.cs.meta
Normal 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:
|
||||
348
Assets/Oculus/Spatializer/scripts/OculusSpatializerUnity.cs
Normal file
348
Assets/Oculus/Spatializer/scripts/OculusSpatializerUnity.cs
Normal 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);
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8e8aaaa0cd7804c469aa5f8dc3f42ee4
|
||||
timeCreated: 1541979457
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
9
Assets/Oculus/Spatializer/scripts/helpers.meta
Normal file
9
Assets/Oculus/Spatializer/scripts/helpers.meta
Normal file
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 09f814575468d81448e92cb264792b5b
|
||||
folderAsset: yes
|
||||
timeCreated: 1479154551
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
169
Assets/Oculus/Spatializer/scripts/helpers/ONSPReflectionZone.cs
Normal file
169
Assets/Oculus/Spatializer/scripts/helpers/ONSPReflectionZone.cs
Normal 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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cfc03cf517e91a64ba53fc31e61657ea
|
||||
timeCreated: 1473375383
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user