Files
AR-Menu/Library/PackageCache/org.khronos.unitygltf@6b55d14e19c1/Runtime/Scripts/Plugins/LodsExport.cs
2025-11-30 08:35:03 +02:00

74 lines
2.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.Collections.Generic;
using System.Linq;
using GLTF.Schema;
using UnityEngine;
namespace UnityGLTF.Plugins
{
public class LodsExport : GLTFExportPlugin
{
public override string DisplayName => "MSFT_lod";
public override string Description => "Exports LODGroup components as MSFT_lod extension.";
public override GLTFExportPluginContext CreateInstance(ExportContext context)
{
return new MSFT_lods_Extension();
}
}
public class MSFT_lods_Extension: GLTFExportPluginContext
{
public override void AfterNodeExport(GLTFSceneExporter exporter, GLTFRoot gltfroot, Transform transform, Node node)
{
if (!transform) return;
var lodGroup = transform.GetComponent<LODGroup>();
if (!lodGroup) return;
var lods = lodGroup.GetLODs();
var usesCulling = lods[lods.Length - 1].renderers.Length == 0;
var nodeIds = new int[lods.Length - 1 - (usesCulling ? 1 : 0)];
var coverages = new float[nodeIds.Length + 1];
for (var index = 0; index < nodeIds.Length; index++)
{
var lod = lods[index + 1];
// TODO multiple renderers could be supported if the user ensures
// that all renderers in a LOD level are child of one node then we could export that node's ID
if (lod.renderers.Length != 1)
{
Debug.LogWarning("Can't export LODGroup with MSFT_lods with more than one renderer per LOD level. Skipping", lodGroup);
return;
}
var meshFilter = lod.renderers[0].GetComponent<MeshFilter>();
if (!meshFilter)
{
Debug.LogWarning("At least one renderer in LODGroup doesn't have a mesh. Skipping", lodGroup);
return;
}
var lodNode = exporter.ExportNode(lod.renderers[0].gameObject);
if (lodNode != null) nodeIds[index] = lodNode.Id;
coverages[index] = lod.screenRelativeTransitionHeight;
}
// if (usesCulling) coverages[coverages.Length - 1] = 0;
// TODO implement coverage export too
var ext = new MSFT_LODExtension(nodeIds.ToList());
// var coverageExt = new MSFT_LODExtension(coverages.ToList());
// for (int i = 0; i < ext.Hints.Length; i++)
// {
// ext.Hints[i] = new MSFT_lodsHint();
// ext.Hints[i].ScreenCoverage = lodGroup.GetLODs()[i].screenRelativeTransitionHeight;
// }
// TODO according to the MSFT_lod docs, nodes should be kicked out of the scene again
// to ensure that softwares that can't read MSFT_lods don't render them.
if (node.Extensions == null) node.Extensions = new Dictionary<string, IExtension>();
node.Extensions.Add(MSFT_LODExtensionFactory.EXTENSION_NAME, ext);
exporter.DeclareExtensionUsage(MSFT_LODExtensionFactory.EXTENSION_NAME, false);
}
}
}