Skip to content

Commit 94522d8

Browse files
committed
added lod support for .asset type meshes
1 parent 22d6008 commit 94522d8

2 files changed

Lines changed: 73 additions & 79 deletions

File tree

Basis/Packages/com.basis.sdk/Scripts/Editor/BasisBuildBlendshapeStripper.cs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,7 @@ public MeshRemapInfo(SkinnedMeshRenderer renderer, Mesh oldMesh, Mesh newMesh, I
5858
/// - Then we remap BasisAvatar indices to the new meshes.
5959
/// - Finally, callbacks fire so other systems can remap too.
6060
/// </summary>
61-
public static void StripForBuild(
62-
BasisAssetBundleObject settings,
63-
GameObject buildRoot,
64-
Basis.Scripts.BasisSdk.BasisAvatar avatarOnClone)
61+
public static void StripForBuild(BasisAssetBundleObject settings, GameObject buildRoot,Basis.Scripts.BasisSdk.BasisAvatar avatarOnClone)
6562
{
6663
if (buildRoot == null) throw new ArgumentNullException(nameof(buildRoot));
6764
if (avatarOnClone == null) throw new ArgumentNullException(nameof(avatarOnClone));
@@ -133,12 +130,12 @@ public static void StripForBuild(
133130
}
134131
catch (Exception ex)
135132
{
136-
Debug.LogException(ex);
133+
BasisDebug.LogError($"{ex.Message} {ex.StackTrace}");
137134
}
138135
}
139136

140137
AssetDatabase.SaveAssets();
141-
AssetDatabase.Refresh();
138+
AssetDatabase.Refresh( ImportAssetOptions.ForceSynchronousImport);
142139

143140
// Remap default avatar indices (by name)
144141
UpdateAvatarBlendshapeIndicesAfterStrip(
@@ -156,7 +153,7 @@ public static void StripForBuild(
156153
}
157154
catch (Exception ex)
158155
{
159-
Debug.LogException(ex);
156+
BasisDebug.LogError($"{ex.Message} {ex.StackTrace}");
160157
}
161158
}
162159

Basis/Packages/com.basis.sdk/Scripts/Editor/SDKInspector/BasisAvatarSDKInspector.cs

Lines changed: 69 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ public void SetupItems()
262262
faceVisemeMeshField.allowSceneObjects = true;
263263
AvatarIconField.allowSceneObjects = true;
264264

265-
// AvatarIconField.value = null;
265+
// AvatarIconField.value = null;
266266
animatorField.value = Avatar.Animator;
267267
faceBlinkMeshField.value = Avatar.FaceBlinkMesh;
268268
faceVisemeMeshField.value = Avatar.FaceVisemeMesh;
@@ -382,6 +382,8 @@ private async void EventCallbackAvatarBundle(List<BuildTarget> targets, Texture2
382382
// Add the result label to the UI
383383
uiElementsRoot.Add(resultLabel);
384384
// BuildReportViewerWindow.ShowWindow();
385+
386+
GameObject.Destroy(buildRoot);
385387
}
386388
else
387389
{
@@ -395,109 +397,104 @@ private async void EventCallbackAvatarBundle(List<BuildTarget> targets, Texture2
395397
}
396398
}
397399
}
398-
#if UNITY_6000_2_OR_NEWER
399-
/// <summary>
400-
/// Generate Mesh LODs via ModelImporter for all SkinnedMeshRenderers under the given root.
401-
/// Requires Unity 6000.2+ where ModelImporter.generateMeshLods exists.
402-
/// </summary>
403-
/// <param name="root">Root GameObject (e.g., your avatar/prefab in the scene or a prefab asset loaded in memory).</param>
404-
/// <param name="lodLimit">
405-
/// Maximum mesh LOD to generate. Use -1 to leave the current importer value unchanged.
406-
/// </param>
400+
#if UNITY_6000_2_OR_NEWER && UNITY_EDITOR
407401
public void GenerateMeshLODs(int lodLimit = -1)
408402
{
409403
var smrs = Avatar.GetComponentsInChildren<SkinnedMeshRenderer>(true);
410404
if (smrs == null || smrs.Length == 0)
411405
{
412-
Debug.LogWarning($"GenerateMeshLODs: No SkinnedMeshRenderer found under.");
406+
Debug.LogWarning("GenerateMeshLODs: No SkinnedMeshRenderer found under root.");
407+
return;
413408
}
414409

415-
// Collect unique importer asset paths (FBX/OBJ). Multiple meshes often come from the same file.
416-
var pathsNeedingReimport = new HashSet<string>();
410+
var modelPathsNeedingReimport = new HashSet<string>();
411+
var meshAssetsNeedingSave = new HashSet<Mesh>(); // for .asset meshes (and others without ModelImporter)
417412

418413
foreach (var smr in smrs)
419414
{
420-
if (smr == null || smr.sharedMesh == null)
421-
continue;
415+
if (smr == null || smr.sharedMesh == null) continue;
422416

423-
// Get the asset path for the mesh; for model sub-assets this is the FBX/OBJ path.
424-
string meshPath = AssetDatabase.GetAssetPath(smr.sharedMesh);
425-
if (string.IsNullOrEmpty(meshPath))
426-
continue;
417+
var mesh = smr.sharedMesh;
418+
string meshPath = AssetDatabase.GetAssetPath(mesh);
419+
if (string.IsNullOrEmpty(meshPath)) continue;
427420

428421
var importer = AssetImporter.GetAtPath(meshPath) as ModelImporter;
429-
if (importer == null)
430-
continue; // Not a model-imported mesh (e.g., .asset mesh), skip.
431-
432-
// Set importer flags
433-
bool changed = false;
434422

435-
if (!importer.generateMeshLods)
423+
if (importer != null)
436424
{
437-
importer.generateMeshLods = true;
438-
changed = true;
439-
}
425+
bool changed = false;
426+
427+
if (!importer.generateMeshLods)
428+
{
429+
importer.generateMeshLods = true;
430+
changed = true;
431+
}
440432

441-
if (lodLimit >= 0 && importer.maximumMeshLod != lodLimit)
433+
if (lodLimit >= 0 && importer.maximumMeshLod != lodLimit)
434+
{
435+
importer.maximumMeshLod = lodLimit;
436+
changed = true;
437+
}
438+
439+
if (changed)
440+
{
441+
modelPathsNeedingReimport.Add(meshPath);
442+
}
443+
}
444+
else
442445
{
443-
importer.maximumMeshLod = lodLimit;
444-
changed = true;
446+
// .asset Mesh (or otherwise not model-imported):
447+
// Generate Mesh LODs directly on the mesh asset.
448+
// meshLodLimit here = "max number of LOD levels to generate" (see docs).
449+
// 0 => generate none beyond original; negative => auto-stop at ~64 indices. :contentReference[oaicite:3]{index=3}
450+
int meshLodLimit = lodLimit; // reuse your parameter; adjust semantics if you want
451+
MeshLodUtility.GenerateMeshLods(mesh, meshLodLimit);
452+
453+
EditorUtility.SetDirty(mesh);
454+
meshAssetsNeedingSave.Add(mesh);
445455
}
446456

447-
if (changed)
448-
pathsNeedingReimport.Add(meshPath);
449-
450-
// Component-level preferences (do not require reimport)
457+
// Renderer-level knobs (work once mesh actually has Mesh LODs) :contentReference[oaicite:4]{index=4}
451458
smr.meshLodSelectionBias = 0f;
452459
smr.forceMeshLod = -1;
453460
}
454461

455-
if (pathsNeedingReimport.Count == 0)
462+
// Reimport model files (FBX/OBJ)
463+
if (modelPathsNeedingReimport.Count > 0)
456464
{
457-
Debug.Log("GenerateMeshLODs: No importer changes detected.");
458-
return;
459-
}
460-
461-
try
462-
{
463-
AssetDatabase.StartAssetEditing();
464-
465-
int i = 0;
466-
int total = pathsNeedingReimport.Count;
467-
foreach (var path in pathsNeedingReimport)
465+
try
468466
{
469-
if (EditorUtility.DisplayCancelableProgressBar(
470-
"Reimporting Models (LODs)",
471-
$"{i + 1}/{total}: {path}",
472-
(float)i / total))
473-
{
474-
Debug.LogWarning("GenerateMeshLODs: Canceled by user.");
475-
break;
476-
}
467+
AssetDatabase.StartAssetEditing();
468+
int i = 0, total = modelPathsNeedingReimport.Count;
477469

478-
var importer = AssetImporter.GetAtPath(path) as ModelImporter;
479-
if (importer != null)
470+
foreach (var path in modelPathsNeedingReimport)
480471
{
481-
// Write settings and reimport this asset immediately.
482-
// Either approach works; SaveAndReimport is the simplest.
483-
importer.SaveAndReimport();
484-
// Alternatively:
485-
// AssetDatabase.WriteImportSettingsIfDirty(path);
486-
// AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);
472+
if (EditorUtility.DisplayCancelableProgressBar(
473+
"Reimporting Models (Mesh LODs)",
474+
$"{i + 1}/{total}: {path}",
475+
(float)i / total))
476+
{
477+
Debug.LogWarning("GenerateMeshLODs: Canceled by user.");
478+
break;
479+
}
480+
481+
var mi = AssetImporter.GetAtPath(path) as ModelImporter;
482+
if (mi != null) mi.SaveAndReimport();
483+
i++;
487484
}
488-
489-
i++;
485+
}
486+
finally
487+
{
488+
EditorUtility.ClearProgressBar();
489+
AssetDatabase.StopAssetEditing();
490490
}
491491
}
492-
finally
493-
{
494-
EditorUtility.ClearProgressBar();
495-
AssetDatabase.StopAssetEditing();
492+
493+
// Save modified .asset meshes
494+
if (meshAssetsNeedingSave.Count > 0)
496495
AssetDatabase.SaveAssets();
497-
// No need for AssetDatabase.Refresh(); reimports were explicit.
498-
}
499496

500-
Debug.Log($"GenerateMeshLODs: Reimported {pathsNeedingReimport.Count} model asset(s).");
497+
Debug.Log($"GenerateMeshLODs: Reimported {modelPathsNeedingReimport.Count} model asset(s), updated {meshAssetsNeedingSave.Count} mesh asset(s).");
501498
}
502499
#endif
503500
public void AvatarTestInEditorClickFunction()

0 commit comments

Comments
 (0)