Files
AR-Menu/Library/PackageCache/com.needle.engine-exporter@8c046140a1d9/Gltf/Runtime/Experimental/progressive/NeedleCompressionSettings.cs
2025-11-30 08:35:03 +02:00

189 lines
7.9 KiB
C#

using UnityEditor;
using UnityEngine;
using UnityEngine.Serialization;
#if UNITY_EDITOR
using Needle.Engine.Editors;
#endif
namespace Needle.Engine.Gltf.Experimental.progressive
{
// [EditorBrowsable(EditorBrowsableState.Never)]
// [Obsolete("ProgressiveTexturesSettings has been deprecated. Use ProgressiveLoadingSettings instead. (UnityUpgradable) -> ProgressiveLoadingSettings")]
[ExecuteAlways]
[HelpURL("http://docs.needle.tools/compression")]
[AddComponentMenu("Needle Engine/Optimization/Compression and LOD Settings (Needle Engine)" +
Constants.NeedleComponentTags +
" progressiveloading progressivemeshes settings generate meshes textures optimization build loading deferred lods autolod")]
public class NeedleCompressionSettings : MonoBehaviour
{
// Textures
#if UNITY_EDITOR
public TextureCompressionMode DefaultTextureFormat = TextureCompressionMode.Automatic;
#endif
public int TextureMaxSize = 8192;
public bool GenerateTextureLODs = true;
public bool UseMaxSize = true;
[FormerlySerializedAs("MaxSize")]
[Tooltip(
"This is the max resolution for textures in the glb that is loaded at start - high-res textures with the original resolution will be loaded on demand.")]
public int LODsMaxSize = 128;
// Meshes
public MeshCompressionType MeshCompression = MeshCompressionType.Draco;
[FormerlySerializedAs("GenerateLODs")]
[Tooltip(
"When enabled LODs will be generated for the meshes. When disabled no LODs will be generated.")]
public bool GenerateMeshLODs = true;
}
#if UNITY_EDITOR
[CustomEditor(typeof(NeedleCompressionSettings))]
internal class NeedleCompressionSettingsEditor : Editor
{
[InitializeOnLoadMethod]
private static void Init()
{
ExportInfoEditor.Enabled += (exp) =>
{
if (exp && !exp.TryGetComponent<NeedleCompressionSettings>(out _))
{
// First check if the scene already HAS an compression settings component and IF so move it to the ExportInfo
var existing = FindAnyObjectByType<NeedleCompressionSettings>();
if (existing && exp.gameObject != existing.gameObject && !exp.gameObject.TryGetComponent(typeof(NeedleCompressionSettings), out _))
{
var newInstance = Undo.AddComponent(exp.gameObject, typeof(NeedleCompressionSettings));
UnityEditorInternal.ComponentUtility.CopyComponent(existing);
UnityEditorInternal.ComponentUtility.PasteComponentValues(newInstance);
Undo.DestroyObjectImmediate(existing);
Selection.activeGameObject = newInstance.gameObject;
Debug.Log(
$"Moved {nameof(NeedleCompressionSettings)} to the root GameObject of the scene. This component should only be present once in the scene.", newInstance);
}
// Ensure ExportInfo has a NeedleCompressionSettings
else
{
Undo.AddComponent<NeedleCompressionSettings>(exp.gameObject);
}
}
};
}
private SerializedProperty allowProgressiveLoading, useMaxSize, maxSize, generateTextureLODs, generateMeshLODs;
private SerializedProperty meshCompression, defaultTextureFormat, textureMaxSize;
private void OnEnable()
{
useMaxSize = serializedObject.FindProperty(nameof(NeedleCompressionSettings.UseMaxSize));
maxSize = serializedObject.FindProperty(nameof(NeedleCompressionSettings.LODsMaxSize));
generateTextureLODs = serializedObject.FindProperty(nameof(NeedleCompressionSettings.GenerateTextureLODs));
defaultTextureFormat =
serializedObject.FindProperty(nameof(NeedleCompressionSettings.DefaultTextureFormat));
meshCompression = serializedObject.FindProperty(nameof(NeedleCompressionSettings.MeshCompression));
generateMeshLODs = serializedObject.FindProperty(nameof(NeedleCompressionSettings.GenerateMeshLODs));
}
public override void OnInspectorGUI()
{
// ReSharper disable once LocalVariableHidesMember
var target = (NeedleCompressionSettings)this.target;
var change = new EditorGUI.ChangeCheckScope();
// EditorGUILayout.PropertyField(allowProgressiveLoading, new GUIContent("Allow Progressive Loading"));
using (new GUILayout.HorizontalScope())
{
GUILayout.FlexibleSpace();
if (GUILayout.Button("Documentation", GUILayout.MaxWidth(100)))
{
Application.OpenURL("https://docs.needle.tools/compression");
}
}
// using (new EditorGUI.DisabledScope(target.AllowProgressiveLoading == false))
{
GUILayout.Space(5);
EditorGUILayout.LabelField(new GUIContent("Textures"), EditorStyles.boldLabel);
target.TextureMaxSize = EditorGUILayout.IntPopup(new GUIContent("Max Texture Size", "The maximum texture size. Textures larger than this will be downscaled. It is usually not necessary to change this settings when texture LODs are enabled."),
target.TextureMaxSize, NeedleTextureSettings.maxSizesLabels, NeedleTextureSettings.maxSizes);
using (new GUILayout.HorizontalScope())
{
EditorGUILayout.PropertyField(defaultTextureFormat, new GUIContent("Default Texture Format"));
}
var textureFormatHint = default(string);
var messageType = MessageType.None;
switch (target.DefaultTextureFormat)
{
case TextureCompressionMode.None:
textureFormatHint = "Texture compression is disabled. Not recommend: large file size, large GPU memory usage";
messageType = MessageType.Warning;
break;
case TextureCompressionMode.Automatic:
textureFormatHint = "Automatic texture format: Ideal for most use cases. The texture format will be selected based on how the texture is used in the scene.";
break;
case TextureCompressionMode.Product:
textureFormatHint = "Product texture format: Ideal for 3D product use cases.";
break;
case TextureCompressionMode.World:
textureFormatHint = "World texture format: Ideal for 3D world use cases.";
break;
case TextureCompressionMode.WebP:
textureFormatHint =
"WebP texture format: Override all textures to use WebP. Low file size, large GPU memory usage, high quality";
break;
case TextureCompressionMode.ETC1S:
textureFormatHint =
"ETC1S texture format: Override all textures to use ETC1S. Low file size, low GPU memory usage, medium quality";
break;
case TextureCompressionMode.UASTC:
textureFormatHint =
"UASTC texture format: Override all textures to use UASTC. Low file size, low GPU memory usage, high quality";
break;
}
if (!string.IsNullOrWhiteSpace(textureFormatHint))
{
EditorGUILayout.HelpBox(textureFormatHint, messageType);
}
GUILayout.Space(5);
EditorGUILayout.LabelField(new GUIContent("Meshes"), EditorStyles.boldLabel);
EditorGUILayout.PropertyField(meshCompression, new GUIContent("Mesh Compression"));
GUILayout.Space(5);
EditorGUILayout.LabelField(new GUIContent("LOD Settings"), EditorStyles.boldLabel);
// var messageType = allowProgressiveLoading.boolValue ? MessageType.None : MessageType.Warning;
EditorGUILayout.HelpBox(
"Generate LODs for textures or meshes project wide to improve load- and runtime performance",
MessageType.None);
EditorGUILayout.PropertyField(generateMeshLODs, new GUIContent("Generate Mesh LODs"));
EditorGUILayout.PropertyField(generateTextureLODs, new GUIContent("Generate Texture LODs"));
using (new EditorGUI.DisabledScope(!target.GenerateTextureLODs))
using (new GUILayout.HorizontalScope())
{
EditorGUILayout.PropertyField(useMaxSize,
new GUIContent("Texture LODs Root Size",
"When disabled the default max size will be used (usually 256px)"));
using (new EditorGUI.DisabledScope(target.UseMaxSize == false))
{
EditorGUILayout.PropertyField(maxSize, new GUIContent());
}
}
// GUILayout.Space(5);
// EditorGUILayout.HelpBox("Tip: You can append '?debugprogressive' in the browser URL to debug LODs. Texture and Mesh LODs can then be toggled using P.", MessageType.None);
}
if (change.changed) serializedObject.ApplyModifiedProperties();
}
}
#endif
}