Initial Commit

This commit is contained in:
2025-07-04 20:33:06 +03:00
commit 8f09347ae0
9219 changed files with 2447903 additions and 0 deletions
@@ -0,0 +1,571 @@
/*
* 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 : ONSPPropagationMaterialEditor.cs
* Content : Propagation material editor class
Attach to geometry to define material properties
***********************************************************************************/
using UnityEditor;
using UnityEngine;
using Spectrum = ONSPPropagationMaterial.Spectrum;
using Point = ONSPPropagationMaterial.Point;
[CustomEditor(typeof(ONSPPropagationMaterial))]
internal sealed class ONSPPropagationMaterialEditor : Editor{
private enum AxisScale{ Lin, Log, Sqr }
private sealed class SpectrumDrawer{
private const float cutoff = 20000f;
private static readonly Texture2D texture = EditorGUIUtility.whiteTexture;
private static readonly GUIStyle textStyle = new GUIStyle{
alignment = TextAnchor.MiddleLeft,
clipping = TextClipping.Overflow,
fontSize = 8,
fontStyle = FontStyle.Bold,
wordWrap = false,
normal = new GUIStyleState{ textColor = Color.grey },
focused = new GUIStyleState{ textColor = Color.grey }
};
private static int focus;
private readonly string label;
private readonly AxisScale scale;
private readonly Spectrum spectrum;
private bool dragInitiated;
private bool isDragging;
private bool displaySpectrum;
private bool displayPoints;
internal bool IsFocus{
get{
return focus == spectrum.GetHashCode();
}
}
internal SpectrumDrawer(string label, Spectrum spectrum, AxisScale scale){
this.label = label;
this.spectrum = spectrum;
this.scale = scale;
}
internal void Draw(Event e){
displaySpectrum = EditorGUILayout.Foldout(displaySpectrum, label);
if(displaySpectrum){
EditorGUI.indentLevel++;
DrawSpectrum(e);
displayPoints = EditorGUILayout.Foldout(displayPoints, "Points");
if(displayPoints){
EditorGUI.indentLevel++;
DrawPoints();
EditorGUI.indentLevel--;
}
EditorGUI.indentLevel--;
}
}
internal void LoadFoldoutState(){
displaySpectrum = EditorPrefs.GetBool(label + "Spectrum", true);
displayPoints = EditorPrefs.GetBool(label + "Points", false);
}
internal void SaveFoldoutState(){
EditorPrefs.SetBool(label + "Spectrum", displaySpectrum);
EditorPrefs.SetBool(label + "Points", displayPoints);
}
private void DrawSpectrum(Event e){
float height = 10 * EditorGUIUtility.singleLineHeight;
Rect r = EditorGUILayout.GetControlRect(true, height);
r.width -= rightMargin;
DrawDataTicks(r);
r = AudioCurveRendering.BeginCurveFrame(r);
AudioCurveRendering.DrawFilledCurve(r, EvaluateCurve, AudioCurveRendering.kAudioOrange);
DrawFrequencyTicks(r);
HandleEvent(r, e);
if(IsFocus) DrawSelected(r);
AudioCurveRendering.EndCurveFrame();
}
private void DrawPoints(){
var points = spectrum.points;
int lines = points.Count > 0 ? points.Count + 2 : 1;
float height = EditorGUIUtility.singleLineHeight * lines;
Rect r1 = EditorGUILayout.GetControlRect(true, height);
r1.width -= rightMargin;
r1.height = EditorGUIUtility.singleLineHeight;
{
int oldCount = points.Count;
int newCount = EditorGUI.DelayedIntField(r1, "Size", oldCount);
r1.y += r1.height;
if(newCount < points.Count){
points.RemoveRange(newCount, oldCount - newCount);
Undo.SetCurrentGroupName("Points Removed");
GUI.changed = true;
} else if(newCount > oldCount){
if(newCount > points.Capacity)
points.Capacity = newCount;
for(int i = oldCount; i < newCount; i++)
points.Add(new Point(125 * (1 << i)));
Undo.SetCurrentGroupName("Points Added");
GUI.changed = true;
}
}
if(points.Count > 0){
Rect r2 = new Rect(r1.xMax + 9, r1.y + r1.height * 1.125f, 24, r1.height * .75f);
r1.width /= 2;
EditorGUI.LabelField(r1, "Frequency");
r1.x += r1.width;
EditorGUI.LabelField(r1, "Data");
r1.x -= r1.width;
r1.y += r1.height;
for(int i = 0; i < points.Count; i++){
points[i].frequency = EditorGUI.FloatField(r1, points[i].frequency);
points[i].frequency = Mathf.Clamp(points[i].frequency, 0f, cutoff);
r1.x += r1.width;
points[i].data = EditorGUI.FloatField(r1, points[i].data);
points[i].data = Mathf.Clamp01(points[i].data);
r1.x -= r1.width;
r1.y += r1.height;
if(GUI.Button(r2, "")){
RemovePointAt(i);
break;
}
r2.y += r1.height;
}
}
}
private void DrawDataTicks(Rect r){
const int ticks = 10;
Rect label = new Rect(r.xMax + 9, r.y - r.height / (2 * ticks), 24, r.height / ticks);
Rect tick = new Rect(r.xMax + 2, r.y - 1, 4.5f, 2);
for(int i = 0; i <= ticks; i++){
float value = MapData(1 - (float)i / ticks, false);
EditorGUI.DrawRect(tick, textStyle.normal.textColor);
GUI.Label(label, value.ToString("0.000"), textStyle);
tick.y += label.height;
label.y += label.height;
}
}
private void DrawFrequencyTicks(Rect r){
Rect tick = new Rect(r.x, r.y, 1, r.height);
Rect label = new Rect(r.x, r.yMax - 1.5f * EditorGUIUtility.singleLineHeight, 32, EditorGUIUtility.singleLineHeight);
for(int i = 1; i < 30; i++){
float frequency;
if(MapFrequencyTick(i, out frequency)){
tick.x = MapFrequency(frequency) * r.width;
tick.height = label.y - r.y;
tick.width = 2;
EditorGUI.DrawRect(tick, textStyle.normal.textColor);
tick.y = label.yMax;
tick.height = r.yMax - label.yMax;
EditorGUI.DrawRect(tick, textStyle.normal.textColor);
label.x = tick.x - 2;
GUI.Label(label, FrequencyToString(frequency), textStyle);
tick.y = r.y;
tick.height = r.height;
tick.width = 1;
} else{
tick.x = MapFrequency(frequency) * r.width;
EditorGUI.DrawRect(tick, textStyle.normal.textColor);
}
}
}
private void DrawSelected(Rect r){
if(spectrum.points.Count > spectrum.selection){
const float radius = 12;
Vector2 position = MapPointPosition(r, spectrum.points[spectrum.selection]);
Vector2 size = new Vector2(radius, radius);
r = new Rect(position - size / 2, size);
#if UNITY_5
GUI.DrawTexture(r, texture, ScaleMode.StretchToFill, false, 0);
GUI.DrawTexture(r, texture, ScaleMode.StretchToFill, false, 0);
#else
GUI.DrawTexture(r, texture, ScaleMode.StretchToFill, false, 0, Color.white, 0, radius);
GUI.DrawTexture(r, texture, ScaleMode.StretchToFill, false, 0, Color.black, 2, radius);
#endif
}
}
private void HandleEvent(Rect r, Event e){
Vector2 position = e.mousePosition;
switch(e.type){
case EventType.MouseDown:
if(r.Contains(position)){
if(e.clickCount == 2){
spectrum.selection = spectrum.points.Count;
spectrum.points.Add(MapMouseEvent(r, position));
Undo.SetCurrentGroupName("Point Added");
GUI.changed = true;
} else{
int selection = spectrum.selection;
float minDistance = float.MaxValue;
for(int i = 0; i < spectrum.points.Count; i++){
float distance = Vector2.Distance(MapPointPosition(r, spectrum.points[i]), position);
if(distance < minDistance){
selection = i;
minDistance = distance;
}
}
if(selection != spectrum.selection){
spectrum.selection = selection;
Undo.SetCurrentGroupName("Point Selected");
GUI.changed = true;
}
}
focus = spectrum.GetHashCode();
dragInitiated = true;
} else{
isDragging = false;
focus = 0;
}
e.Use();
break;
case EventType.MouseDrag:
if(dragInitiated){
dragInitiated = false;
isDragging = true;
}
if(isDragging && spectrum.selection < spectrum.points.Count){
spectrum.points[spectrum.selection] = MapMouseEvent(r, position);
e.Use();
}
break;
case EventType.Ignore:
case EventType.MouseUp:
dragInitiated = false;
if(isDragging){
isDragging = false;
Undo.SetCurrentGroupName("Point Moved");
GUI.changed = true;
e.Use();
}
break;
case EventType.KeyDown:
switch(e.keyCode){
case KeyCode.Delete:
case KeyCode.Backspace:
if(spectrum.selection < spectrum.points.Count){
RemovePointAt(spectrum.selection);
e.Use();
}
break;
}
break;
}
}
private void RemovePointAt(int index){
spectrum.points.RemoveAt(index);
if(spectrum.selection == index)
spectrum.selection = spectrum.points.Count;
Undo.SetCurrentGroupName("Point Removed");
GUI.changed = true;
}
private float EvaluateCurve(float f){
return 2 * MapData(spectrum[MapFrequency(f, false)]) - 1;
}
private Vector2 MapPointPosition(Rect r, Point point){
return new Vector2{
x = r.x + r.width * MapFrequency(point.frequency),
y = r.y + r.height * (1 - MapData(point.data))
};
}
private Point MapMouseEvent(Rect r, Vector2 v){
return new Point{
frequency = v.x < r.xMin ? 0 : v.x > r.xMax ? cutoff : MapFrequency((v.x - r.x) / r.width, false),
data = v.y < r.yMin ? 1 : v.y > r.yMax ? 0 : MapData(1 - (v.y - r.y) / r.height, false)
};
}
private float MapData(float f, bool forward = true){
switch(scale){
case AxisScale.Log:
return forward ? f < 1e-3f ? 0 : 1 + Mathf.Log10(f) / 3 : Mathf.Pow(10, -3 * (1 - f));
case AxisScale.Sqr:
return forward ? Mathf.Sqrt(f) : f * f;
default:
case AxisScale.Lin:
return f;
}
}
public static bool MapFrequencyTick(int i, out float frequency){
int power = i / 9 + 1;
int multiplier = i % 9 + 1;
frequency = multiplier * Mathf.Pow(10, power);
return multiplier == 1;
}
public static float MapFrequency(float f, bool forward = true){
return forward ? f < 10 ? 0 : Mathf.Log(f / 10, cutoff / 10) : 10 * Mathf.Pow(cutoff / 10, f);
}
private static string FrequencyToString(float frequency){
if(frequency < 1000)
return string.Format("{0:F0} Hz", frequency);
else
return string.Format("{0:F0} kHz", frequency * .001f);
}
}
private const float rightMargin = 36;
private SpectrumDrawer absorption, scattering, transmission;
private void OnEnable(){
GetSpectra(out absorption, out scattering, out transmission);
absorption.LoadFoldoutState();
scattering.LoadFoldoutState();
transmission.LoadFoldoutState();
}
private void OnDisable(){
absorption.SaveFoldoutState();
scattering.SaveFoldoutState();
transmission.SaveFoldoutState();
}
public override void OnInspectorGUI(){
ONSPPropagationMaterial material = target as ONSPPropagationMaterial;
EditorGUI.BeginChangeCheck();
Rect r = EditorGUILayout.GetControlRect();
r.width -= rightMargin;
ONSPPropagationMaterial.Preset newPreset =
(ONSPPropagationMaterial.Preset)EditorGUI.EnumPopup(r, "Preset", material.preset);
Event e = Event.current;
EventType type = e.type;
absorption.Draw(e);
scattering.Draw(e);
transmission.Draw(e);
if(EditorGUI.EndChangeCheck()){
string groupName = Undo.GetCurrentGroupName();
Undo.RegisterCompleteObjectUndo(material, groupName);
if(groupName == "Point Added")
Undo.CollapseUndoOperations(Undo.GetCurrentGroup() - 1);
if(material.preset != newPreset)
material.preset = newPreset;
else
material.preset = ONSPPropagationMaterial.Preset.Custom;
if(Application.isPlaying)
material.UploadMaterial();
}
}
private void GetSpectra(out SpectrumDrawer absorption,
out SpectrumDrawer scattering,
out SpectrumDrawer transmission){
ONSPPropagationMaterial material = target as ONSPPropagationMaterial;
absorption = new SpectrumDrawer("Absorption", material.absorption, AxisScale.Sqr);
scattering = new SpectrumDrawer("Scattering", material.scattering, AxisScale.Lin);
transmission = new SpectrumDrawer("Transmission", material.transmission, AxisScale.Sqr);
}
}