VR4RoboticArm2/VR4RoboticArm/Library/PackageCache/com.meta.xr.sdk.audio/Runtime/scripts/MetaXRAcousticMaterial.cs
IonutMocanu d7aba243a2 Main
2025-09-08 11:04:02 +03:00

207 lines
7.1 KiB
C#

/*
* 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 : MetaXRAcousticMaterial.cs
* Content : Acoustic material class
***********************************************************************************/
using Meta.XR.Acoustics;
using System;
using System.Linq;
using UnityEngine;
using Native = MetaXRAcousticNativeInterface;
/// \brief This class is used for to create or edit an Acoustic Material
public sealed class MetaXRAcousticMaterial : MonoBehaviour, Meta.XR.Acoustics.IMaterialDataProvider
{
//***********************************************************************
// Public Fields
/// \brief The properties of this material
/// \see MetaXRAcousticMaterialProperties
[SerializeField]
private MetaXRAcousticMaterialProperties properties;
internal MetaXRAcousticMaterialProperties Properties
{
get => properties;
set => properties = value;
}
/// \brief If true the user has edited the properties beyond the default presets
[SerializeField]
private bool hasCustomData = false;
/// \brief This is a reference to the material properties the user has edited
[SerializeField]
internal Meta.XR.Acoustics.MaterialData customData = null;
/// \brief This holds either a material preset or the user's custom material data
public Meta.XR.Acoustics.MaterialData Data => hasCustomData ? customData : properties?.Data;
internal Color Color => Data != null ? Data.color : Color.magenta;
internal void CopyPresetToCustomData(MetaXRAcousticMaterialProperties.BuiltinPreset preset)
{
if (!hasCustomData)
{
Debug.LogError("Material doesn't have custom data", gameObject);
return;
}
MetaXRAcousticMaterialProperties.SetPreset(preset, ref customData);
}
#if UNITY_EDITOR
internal void AppendHash(ref Hash128 hash)
{
if (!hasCustomData && properties == null)
return;
foreach (Meta.XR.Acoustics.Spectrum.Point p in Data.absorption.points)
{
hash.Append(p.frequency);
hash.Append(p.data);
}
foreach (Meta.XR.Acoustics.Spectrum.Point p in Data.transmission.points)
{
hash.Append(p.frequency);
hash.Append(p.data);
}
foreach (Meta.XR.Acoustics.Spectrum.Point p in Data.scattering.points)
{
hash.Append(p.frequency);
hash.Append(p.data);
}
}
#endif
//***********************************************************************
// Private Fields
[NonSerialized]
private IntPtr materialHandle = IntPtr.Zero;
//***********************************************************************
// Start / Destroy
/// Initialize the audio material. This is called after Awake() and before the first Update().
void Start()
{
if (!gameObject.isStatic)
StartInternal();
}
internal bool StartInternal()
{
// Ensure that the material is not initialized twice.
if (materialHandle != IntPtr.Zero)
return true; // already initialized
// Create the internal material.
materialHandle = CreateMaterialNativeHandle(Data);
return true;
}
/// Destroy the audio scene. This is called when the scene is deleted.
void OnDestroy()
{
DestroyInternal();
}
internal void DestroyInternal()
{
if (materialHandle != IntPtr.Zero)
{
DestroyMaterialNativeHandle(materialHandle);
materialHandle = IntPtr.Zero;
}
}
//***********************************************************************
// Upload
internal bool ApplyMaterialProperties()
{
return ApplyPropertiesToNative(materialHandle, Data);
}
internal static IntPtr CreateMaterialNativeHandle(Meta.XR.Acoustics.MaterialData data = null)
{
IntPtr handle = IntPtr.Zero;
if (Native.Interface.CreateAudioMaterial(out handle) != MetaXRAcousticGeometry.Success)
{
Debug.LogError("Unable to create internal audio material");
return handle;
}
if (data != null)
ApplyPropertiesToNative(handle, data);
return handle;
}
internal static void DestroyMaterialNativeHandle(IntPtr handle)
{
// Destroy the material.
Native.Interface.DestroyAudioMaterial(handle);
}
private static bool ApplyPropertiesToNative(IntPtr handle, Meta.XR.Acoustics.MaterialData data)
{
return ApplyPropertiesToNative(handle, data, null);
}
private static bool ApplyPropertiesToNative(IntPtr handle, Meta.XR.Acoustics.MaterialData data, GameObject gameObject)
{
if (handle == IntPtr.Zero || data == null)
{
if (gameObject != null)
{
string path = ((gameObject.scene != null) ? gameObject.scene.name : "") + ":" + string.Join("/", gameObject.GetComponentsInParent<Transform>().Select(t => t.name).Reverse().ToArray());
Debug.LogWarning($"Acoustic Material configured with empty properties: {path}", gameObject);
}
return false;
}
// Absorption
Native.Interface.AudioMaterialReset(handle, MaterialProperty.ABSORPTION);
foreach (Meta.XR.Acoustics.Spectrum.Point p in data.absorption.points)
{
Native.Interface.AudioMaterialSetFrequency(handle, MaterialProperty.ABSORPTION,
p.frequency, p.data);
}
// Transmission
Native.Interface.AudioMaterialReset(handle, MaterialProperty.TRANSMISSION);
foreach (Meta.XR.Acoustics.Spectrum.Point p in data.transmission.points)
{
Native.Interface.AudioMaterialSetFrequency(handle, MaterialProperty.TRANSMISSION,
p.frequency, p.data);
}
// Scattering
Native.Interface.AudioMaterialReset(handle, MaterialProperty.SCATTERING);
foreach (Meta.XR.Acoustics.Spectrum.Point p in data.scattering.points)
{
Native.Interface.AudioMaterialSetFrequency(handle, MaterialProperty.SCATTERING,
p.frequency, p.data);
}
return true;
}
}