From 48fc55aabdd5dc31b1c1c51b3c612e85433de15b Mon Sep 17 00:00:00 2001 From: Toys0125 Date: Fri, 27 Mar 2026 01:46:43 -0500 Subject: [PATCH 1/2] Added sphere Previews and have it off by default. --- .../BasisUI/BasisSettingsDefaults.cs | 3 + .../SettingsProviderStorage.cs | 6 + .../Drivers/Common/BasisAvatarDriver.cs | 155 +++-- .../ContentShare/BasisContentSphere.cs | 641 ++++++++++++++++-- .../com.basis.sdk/Meshes/AvatarOrb.fbx | Bin 43692 -> 47084 bytes .../com.basis.sdk/Prefabs/AvatarOrb.prefab | 26 +- 6 files changed, 708 insertions(+), 123 deletions(-) diff --git a/Basis/Packages/com.basis.framework/BasisUI/BasisSettingsDefaults.cs b/Basis/Packages/com.basis.framework/BasisUI/BasisSettingsDefaults.cs index cd314fab5f..221befad43 100644 --- a/Basis/Packages/com.basis.framework/BasisUI/BasisSettingsDefaults.cs +++ b/Basis/Packages/com.basis.framework/BasisUI/BasisSettingsDefaults.cs @@ -150,6 +150,8 @@ public static class BasisSettingsDefaults public static BasisSettingsBinding CacheMaxSizeGB = new("cachemaxsizegb", new BasisPlatformDefault(128)); + public static BasisSettingsBinding SharedContentPreviews = new("sharedcontentpreviews", new BasisPlatformDefault(false)); + public static BasisSettingsBinding AvatarMeshLOD = new("avatarmeshlod", new BasisPlatformDefault { windows = 0.05f, @@ -631,6 +633,7 @@ public static void LoadAll() // LOD / Download limits AvatarDownloadSize.LoadBindingValue(); CacheMaxSizeGB.LoadBindingValue(); + SharedContentPreviews.LoadBindingValue(); AvatarMeshLOD.LoadBindingValue(); GlobalMeshLOD.LoadBindingValue(); diff --git a/Basis/Packages/com.basis.framework/BasisUI/Menus/Main Menu Providers/SettingsProviderParts/SettingsProviderStorage.cs b/Basis/Packages/com.basis.framework/BasisUI/Menus/Main Menu Providers/SettingsProviderParts/SettingsProviderStorage.cs index a2bef94658..0d752afa47 100644 --- a/Basis/Packages/com.basis.framework/BasisUI/Menus/Main Menu Providers/SettingsProviderParts/SettingsProviderStorage.cs +++ b/Basis/Packages/com.basis.framework/BasisUI/Menus/Main Menu Providers/SettingsProviderParts/SettingsProviderStorage.cs @@ -24,6 +24,11 @@ public static PanelTabPage StorageTab(PanelTabGroup tabGroup) PanelSlider.SliderSettings.Advanced("Avatar Download Size", 5, 1024, false, 0, ValueDisplayMode.MemorySize), BasisSettingsDefaults.AvatarDownloadSize); + PanelToggle sharedPreviewToggle = PanelToggle.CreateNewEntry(downloadGroup.ContentParent); + sharedPreviewToggle.Descriptor.SetTitle("Load Shared Content Previews"); + sharedPreviewToggle.Descriptor.SetDescription("Downloads shared content in the background and renders a fitted LOD3-style preview inside the share sphere."); + sharedPreviewToggle.AssignBinding(BasisSettingsDefaults.SharedContentPreviews); + // Cache size limit slider (lightweight, no file I/O) PanelElementDescriptor limitGroup = PanelElementDescriptor.CreateNew(PanelElementDescriptor.ElementStyles.Group, container); @@ -137,5 +142,6 @@ private static void ResetStorageDefaults() { BasisSettingsDefaults.AvatarDownloadSize.ResetToDefault(); BasisSettingsDefaults.CacheMaxSizeGB.ResetToDefault(); + BasisSettingsDefaults.SharedContentPreviews.ResetToDefault(); } } diff --git a/Basis/Packages/com.basis.framework/Drivers/Common/BasisAvatarDriver.cs b/Basis/Packages/com.basis.framework/Drivers/Common/BasisAvatarDriver.cs index 2cb67f6c7c..d62d4dcb47 100644 --- a/Basis/Packages/com.basis.framework/Drivers/Common/BasisAvatarDriver.cs +++ b/Basis/Packages/com.basis.framework/Drivers/Common/BasisAvatarDriver.cs @@ -548,98 +548,115 @@ public static bool TryGetTextureWithScaleAndOffset(Material mat, string property result = new BasisTexTransform(tex, scale, offset); return true; } - public static void MaterialCorrection(SkinnedMeshRenderer renderer, Shader fallbackUrpShader) + private static bool TryCreateFallbackMaterial(Material mat, Shader fallbackUrpShader, out Material fixedMat) { - if (renderer == null) + fixedMat = null; + + if (mat == null) { - return; + return false; } - var materials = renderer.sharedMaterials; - if (materials == null || materials.Length == 0) + var shader = mat.shader; + if (shader == null) { - return; + return false; } if (fallbackUrpShader == null) { Debug.LogWarning("MaterialCorrection: fallbackUrpShader is null, cannot swap shaders."); - return; + return false; } - bool anyChanged = false; - - for (int mi = 0; mi < materials.Length; mi++) + bool shaderBroken = !shader.isSupported || (!string.IsNullOrEmpty(shader.name) && shader.name.Contains("InternalErrorShader")); + if (!shaderBroken) { - var mat = materials[mi]; - if (mat == null) - { - continue; - } + return false; + } - var shader = mat.shader; - if (shader == null) - { - continue; - } + bool hasAlbedo = TryGetFirstTextureWithScaleAndOffset(mat, AlbedoProps, out BasisTexTransform albedo, out _); + bool hasNormal = TryGetFirstTextureWithScaleAndOffset(mat, NormalProps, out BasisTexTransform normal, out _); + bool hasMetal = TryGetFirstTextureWithScaleAndOffset(mat, MetallicProps, out BasisTexTransform metal, out _); + bool hasOcc = TryGetFirstTextureWithScaleAndOffset(mat, OcclusionProps, out BasisTexTransform occ, out _); + bool hasColor = TryGetFirstColor(mat, out Color baseColor, out _); + fixedMat = new Material(fallbackUrpShader) + { + name = mat.name + " (Fixed)" + }; + if (hasAlbedo) + { + fixedMat.SetTexture("_BaseMap", albedo.texture); + fixedMat.SetTextureScale("_BaseMap", albedo.scale); + fixedMat.SetTextureOffset("_BaseMap", albedo.offset); + } + if (hasColor) + { + fixedMat.SetColor("_BaseColor", baseColor); + } + if (hasNormal) + { + fixedMat.EnableKeyword("_NORMALMAP"); + fixedMat.SetTexture("_BumpMap", normal.texture); + fixedMat.SetTextureScale("_BumpMap", normal.scale); + fixedMat.SetTextureOffset("_BumpMap", normal.offset); + fixedMat.SetFloat("_BumpScale", 0.2f); + } + if (hasMetal) + { + fixedMat.EnableKeyword("_METALLICSPECGLOSSMAP"); + fixedMat.SetTexture("_MetallicGlossMap", metal.texture); + fixedMat.SetTextureScale("_MetallicGlossMap", metal.scale); + fixedMat.SetTextureOffset("_MetallicGlossMap", metal.offset); + } + fixedMat.SetFloat("_Metallic", 0.2f); + fixedMat.SetFloat("_Smoothness", 0.2f); + if (hasOcc) + { + fixedMat.SetTexture("_OcclusionMap", occ.texture); + fixedMat.SetTextureScale("_OcclusionMap", occ.scale); + fixedMat.SetTextureOffset("_OcclusionMap", occ.offset); + fixedMat.SetFloat("_OcclusionStrength", 0.2f); + } + return true; + } + public static void MaterialCorrection(Renderer renderer, Shader fallbackUrpShader, List createdMaterials = null) + { + if (renderer == null) + { + return; + } - bool shaderBroken = !shader.isSupported || (!string.IsNullOrEmpty(shader.name) && shader.name.Contains("InternalErrorShader")); + var materials = renderer.sharedMaterials; + if (materials == null || materials.Length == 0) + { + return; + } - if (!shaderBroken) - { - continue; - } - bool hasAlbedo = TryGetFirstTextureWithScaleAndOffset(mat, AlbedoProps, out BasisTexTransform albedo, out string albedoProp); - bool hasNormal = TryGetFirstTextureWithScaleAndOffset(mat, NormalProps, out BasisTexTransform normal, out string normalProp); - bool hasMetal = TryGetFirstTextureWithScaleAndOffset(mat, MetallicProps, out BasisTexTransform metal, out string metalProp); - bool hasOcc = TryGetFirstTextureWithScaleAndOffset(mat, OcclusionProps, out BasisTexTransform occ, out string occProp); - bool hasColor = TryGetFirstColor(mat, out Color baseColor, out string colorProp); - var fixedMat = new Material(fallbackUrpShader) - { - name = mat.name + " (Fixed)" - }; - if (hasAlbedo) - { - fixedMat.SetTexture("_BaseMap", albedo.texture); - fixedMat.SetTextureScale("_BaseMap", albedo.scale); - fixedMat.SetTextureOffset("_BaseMap", albedo.offset); - } - if (hasColor) - { - fixedMat.SetColor("_BaseColor", baseColor); - } - if (hasNormal) - { - fixedMat.EnableKeyword("_NORMALMAP"); - fixedMat.SetTexture("_BumpMap", normal.texture); - fixedMat.SetTextureScale("_BumpMap", normal.scale); - fixedMat.SetTextureOffset("_BumpMap", normal.offset); - fixedMat.SetFloat("_BumpScale", 0.2f); - } - if (hasMetal) - { - fixedMat.EnableKeyword("_METALLICSPECGLOSSMAP"); - fixedMat.SetTexture("_MetallicGlossMap", metal.texture); - fixedMat.SetTextureScale("_MetallicGlossMap", metal.scale); - fixedMat.SetTextureOffset("_MetallicGlossMap", metal.offset); - } - fixedMat.SetFloat("_Metallic", 0.2f); - fixedMat.SetFloat("_Smoothness", 0.2f); - if (hasOcc) + bool anyChanged = false; + for (int mi = 0; mi < materials.Length; mi++) + { + if (TryCreateFallbackMaterial(materials[mi], fallbackUrpShader, out Material fixedMat)) { - fixedMat.SetTexture("_OcclusionMap", occ.texture); - fixedMat.SetTextureScale("_OcclusionMap", occ.scale); - fixedMat.SetTextureOffset("_OcclusionMap", occ.offset); - - fixedMat.SetFloat("_OcclusionStrength", 0.2f); + materials[mi] = fixedMat; + createdMaterials?.Add(fixedMat); + anyChanged = true; } - materials[mi] = fixedMat; - anyChanged = true; } + if (anyChanged) { renderer.sharedMaterials = materials; } } + public static void MaterialCorrection(SkinnedMeshRenderer renderer, Shader fallbackUrpShader) + { + if (renderer == null) + { + return; + } + + MaterialCorrection((Renderer)renderer, fallbackUrpShader, null); + } } } diff --git a/Basis/Packages/com.basis.framework/Networking/ContentShare/BasisContentSphere.cs b/Basis/Packages/com.basis.framework/Networking/ContentShare/BasisContentSphere.cs index b800d34c71..60be3660d8 100644 --- a/Basis/Packages/com.basis.framework/Networking/ContentShare/BasisContentSphere.cs +++ b/Basis/Packages/com.basis.framework/Networking/ContentShare/BasisContentSphere.cs @@ -1,9 +1,11 @@ using Basis.BasisUI; +using Basis.Scripts.Drivers; using Basis.Scripts.BasisSdk.Interactions; using Basis.Scripts.Device_Management.Devices; using Basis.Scripts.TransformBinders.BoneControl; using Basis.Scripts.UI.UI_Panels; using System; +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using TMPro; @@ -30,6 +32,13 @@ public class BasisContentSphere : BasisInteractableObject private float _bobPhase; private Vector3 _restPosition; private CancellationTokenSource _metaLoadCts; + private CancellationTokenSource _previewLoadCts; + private BasisTrackedBundleWrapper _previewBundleWrapper; + private Transform _previewRoot; + private GameObject _previewInstance; + private readonly List _previewMaterials = new(); + private const float PreviewFitPadding = 0.9f; + private const int PreviewLodIndex = 3; public TextMeshPro Label; public Renderer Renderer; public int MaterialIndex; @@ -45,10 +54,18 @@ public void Initialize(string sphereNetID, string contentURL, string unlockPassw ContentType = contentType; CreatorPlayerID = creatorPlayerID; InteractRange = 2f; - - _metaLoadCts = new CancellationTokenSource(); - _ = LoadMetadataImageAsync(_metaLoadCts.Token); Label.text = GetContentTypeName(); + + if (BasisSettingsDefaults.SharedContentPreviews.RawValue) + { + _previewLoadCts = new CancellationTokenSource(); + _ = LoadLivePreviewAsync(_previewLoadCts.Token); + } + else + { + _metaLoadCts = new CancellationTokenSource(); + _ = LoadMetadataImageAsync(_metaLoadCts.Token); + } } private void Start() @@ -71,51 +88,12 @@ private async Task LoadMetadataImageAsync(CancellationToken cancellationToken) { try { - BasisTrackedBundleWrapper wrapper = new BasisTrackedBundleWrapper - { - LoadableBundle = ToLoadableBundle() - }; - + BasisTrackedBundleWrapper wrapper = new BasisTrackedBundleWrapper { LoadableBundle = ToLoadableBundle() }; BasisProgressReport report = new BasisProgressReport(); await BasisBeeManagement.HandleMetaOnlyLoad(wrapper, report, cancellationToken); if (cancellationToken.IsCancellationRequested || this == null) return; - - Color typeColor = GetTypeColor(); - if (wrapper.LoadableBundle.BasisBundleConnector.ImageBase64 != null) - { - texture = BasisTextureCompression.FromPngBytes(wrapper.LoadableBundle.BasisBundleConnector.ImageBase64); - - // Blend 50% type color with 50% texture - Color[] pixels = texture.GetPixels(); - for (int i = 0; i < pixels.Length; i++) - { - pixels[i] = Color.Lerp(typeColor, pixels[i], 0.5f); - } - texture.SetPixels(pixels); - texture.Apply(); - - // Update label with bundle name if available - string bundleName = wrapper.LoadableBundle.BasisBundleConnector.BasisBundleDescription?.AssetBundleName; - if (!string.IsNullOrEmpty(bundleName) && Label != null) - { - Label.text = $"{GetContentTypeName()}\n{bundleName}"; - } - } - else - { - texture = new Texture2D(1, 1); - texture.SetPixel(0, 0, typeColor); - texture.Apply(); - } - if (Renderer != null) - { - MaterialPropertyBlock block = new MaterialPropertyBlock(); - Renderer.GetPropertyBlock(block, MaterialIndex); - block.SetTexture("_MainTex", texture); - block.SetTexture("_EmissionMap", texture); - Renderer.SetPropertyBlock(block, MaterialIndex); - } + ApplyMetadataFromConnector(wrapper.LoadableBundle.BasisBundleConnector); } catch (OperationCanceledException) { } catch (Exception e) @@ -128,6 +106,10 @@ public override void OnDestroy() GameObject.Destroy(texture); _metaLoadCts?.Cancel(); _metaLoadCts?.Dispose(); + _previewLoadCts?.Cancel(); + _previewLoadCts?.Dispose(); + ReleasePreviewBundle(); + DestroyPreview(); base.OnDestroy(); } @@ -230,6 +212,577 @@ public string GetContentTypeName() } } + private async Task LoadLivePreviewAsync(CancellationToken cancellationToken) + { + GameObject stagedInstance = null; + List stagedMaterials = new(); + BasisTrackedBundleWrapper wrapper = null; + try + { + wrapper = await RetainPreviewBundleAsync(cancellationToken); + cancellationToken.ThrowIfCancellationRequested(); + ApplyMetadataFromConnector(wrapper.LoadableBundle.BasisBundleConnector); + + GameObject previewPrefab = await LoadPreviewPrefabAsync(wrapper, cancellationToken); + if (previewPrefab == null) + { + BasisDebug.LogWarning($"Shared content preview missing loadable GameObject for sphere {SphereNetID} ({ContentURL})."); + return; + } + + if (this == null || gameObject == null) + { + return; + } + + EnsurePreviewRoot(); + stagedInstance = GameObject.Instantiate(previewPrefab, _previewRoot, false); + stagedInstance.name = $"{previewPrefab.name}_SharePreview"; + stagedInstance.transform.localPosition = Vector3.zero; + stagedInstance.transform.localRotation = Quaternion.identity; + stagedInstance.transform.localScale = Vector3.one; + + SanitizePreviewInstance(stagedInstance); + ApplyPreviewOrientation(stagedInstance); + ForcePreviewLods(stagedInstance); + ApplyPreviewFallbackMaterials(stagedInstance, stagedMaterials); + + if (!TryFitPreviewToSphere(stagedInstance, wrapper.LoadableBundle.BasisBundleConnector.Bounds)) + { + CleanupStagedPreview(stagedInstance, stagedMaterials); + BasisDebug.LogWarning($"Shared content preview had no render bounds for sphere {SphereNetID} ({ContentURL})."); + return; + } + + cancellationToken.ThrowIfCancellationRequested(); + DestroyPreview(); + ReleasePreviewBundle(); + _previewBundleWrapper = wrapper; + _previewMaterials.AddRange(stagedMaterials); + _previewInstance = stagedInstance; + wrapper = null; + stagedInstance = null; + HideMetadataPreviewLayer(); + } + catch (OperationCanceledException) + { + CleanupStagedPreview(stagedInstance, stagedMaterials); + ReleasePreviewBundle(wrapper); + } + catch (Exception ex) + { + CleanupStagedPreview(stagedInstance, stagedMaterials); + ReleasePreviewBundle(wrapper); + BasisDebug.LogWarning($"Shared content preview failed for sphere {SphereNetID} ({ContentURL}): {ex.Message}"); + } + } + + private async Task RetainPreviewBundleAsync(CancellationToken cancellationToken) + { + string remoteUrl = ContentURL; + BasisProgressReport report = new BasisProgressReport(); + + while (true) + { + if (BasisLoadHandler.LoadedBundles.TryGetValue(remoteUrl, out BasisTrackedBundleWrapper existingWrapper)) + { + existingWrapper.Increment(); + try + { + await existingWrapper.WaitForBundleLoadAsync(); + cancellationToken.ThrowIfCancellationRequested(); + if (existingWrapper.AssetBundle == null) + { + throw new Exception("Bundle load did not produce an AssetBundle."); + } + + return existingWrapper; + } + catch + { + existingWrapper.DeIncrement(); + throw; + } + } + + BasisTrackedBundleWrapper newWrapper = new BasisTrackedBundleWrapper + { + LoadableBundle = ToLoadableBundle() + }; + + if (!BasisLoadHandler.LoadedBundles.TryAdd(remoteUrl, newWrapper)) + { + continue; + } + + newWrapper.Increment(); + try + { + await BasisBeeManagement.HandleBundleAndMetaLoading(newWrapper, report, cancellationToken); + cancellationToken.ThrowIfCancellationRequested(); + if (newWrapper.AssetBundle == null) + { + throw new Exception("Bundle load did not produce an AssetBundle."); + } + + return newWrapper; + } + catch + { + newWrapper.DeIncrement(); + BasisLoadHandler.LoadedBundles.TryRemove(remoteUrl, out _); + if (newWrapper.AssetBundle != null) + { + newWrapper.AssetBundle.Unload(true); + } + throw; + } + } + } + + private async Task LoadPreviewPrefabAsync(BasisTrackedBundleWrapper wrapper, CancellationToken cancellationToken) + { + if (wrapper?.AssetBundle == null) + { + return null; + } + + BasisBundleGenerated generated = null; + BasisBundleConnector connector = wrapper.LoadableBundle?.BasisBundleConnector; + if (connector != null) + { + connector.GetPlatform(out generated); + } + + string preferredAssetName = generated?.AssetToLoadName; + if (!string.IsNullOrEmpty(preferredAssetName)) + { + GameObject preferred = await LoadAssetAsGameObjectAsync(wrapper.AssetBundle, preferredAssetName, cancellationToken); + if (preferred != null) + { + return preferred; + } + } + + string[] assetNames = wrapper.AssetBundle.GetAllAssetNames(); + for (int index = 0; index < assetNames.Length; index++) + { + cancellationToken.ThrowIfCancellationRequested(); + GameObject fallback = await LoadAssetAsGameObjectAsync(wrapper.AssetBundle, assetNames[index], cancellationToken); + if (fallback != null) + { + return fallback; + } + } + + return null; + } + + private static async Task LoadAssetAsGameObjectAsync(AssetBundle assetBundle, string assetName, CancellationToken cancellationToken) + { + if (assetBundle == null || string.IsNullOrEmpty(assetName)) + { + return null; + } + + string[] candidateNames = + { + assetName, + assetName.Replace(".bundle", ".prefab") + }; + + for (int index = 0; index < candidateNames.Length; index++) + { + string candidate = candidateNames[index]; + if (string.IsNullOrEmpty(candidate)) + { + continue; + } + + AssetBundleRequest request = assetBundle.LoadAssetAsync(candidate); + while (!request.isDone) + { + cancellationToken.ThrowIfCancellationRequested(); + await Task.Yield(); + } + + if (request.asset is GameObject gameObject) + { + return gameObject; + } + } + + return null; + } + + private void ApplyMetadataFromConnector(BasisBundleConnector connector) + { + if (this == null || connector == null) + { + return; + } + + Texture2D nextTexture = BuildMetadataTexture(connector); + if (texture != null) + { + GameObject.Destroy(texture); + } + texture = nextTexture; + + string bundleName = connector.BasisBundleDescription?.AssetBundleName; + if (!string.IsNullOrEmpty(bundleName) && Label != null) + { + Label.text = $"{GetContentTypeName()}\n{bundleName}"; + } + + if (Renderer != null) + { + MaterialPropertyBlock block = new MaterialPropertyBlock(); + Renderer.GetPropertyBlock(block, MaterialIndex); + block.SetTexture("_MainTex", texture); + block.SetTexture("_EmissionMap", texture); + Renderer.SetPropertyBlock(block, MaterialIndex); + } + } + + private Texture2D BuildMetadataTexture(BasisBundleConnector connector) + { + Color typeColor = GetTypeColor(); + if (connector.ImageBase64 != null) + { + Texture2D previewTexture = BasisTextureCompression.FromPngBytes(connector.ImageBase64); + Color[] pixels = previewTexture.GetPixels(); + for (int i = 0; i < pixels.Length; i++) + { + pixels[i] = Color.Lerp(typeColor, pixels[i], 0.5f); + } + previewTexture.SetPixels(pixels); + previewTexture.Apply(); + return previewTexture; + } + + Texture2D fallbackTexture = new Texture2D(1, 1); + fallbackTexture.SetPixel(0, 0, typeColor); + fallbackTexture.Apply(); + return fallbackTexture; + } + + private void EnsurePreviewRoot() + { + if (_previewRoot != null) + { + return; + } + + GameObject previewRoot = new GameObject("Shared Content Preview"); + previewRoot.transform.SetParent(transform, false); + previewRoot.transform.localPosition = Vector3.zero; + previewRoot.transform.localRotation = Quaternion.identity; + previewRoot.transform.localScale = Vector3.one; + _previewRoot = previewRoot.transform; + } + + private void SanitizePreviewInstance(GameObject instance) + { + if (instance == null) + { + return; + } + + foreach (Collider collider in instance.GetComponentsInChildren(true)) + { + collider.enabled = false; + } + + foreach (Rigidbody rigidbody in instance.GetComponentsInChildren(true)) + { + rigidbody.isKinematic = true; + rigidbody.detectCollisions = false; + } + + foreach (AudioSource audioSource in instance.GetComponentsInChildren(true)) + { + audioSource.enabled = false; + } + + foreach (Animator animator in instance.GetComponentsInChildren(true)) + { + animator.enabled = false; + } + + foreach (ParticleSystem particleSystem in instance.GetComponentsInChildren(true)) + { + particleSystem.Stop(true, ParticleSystemStopBehavior.StopEmittingAndClear); + particleSystem.gameObject.SetActive(false); + } + + foreach (BasisInteractableObject interactable in instance.GetComponentsInChildren(true)) + { + interactable.enabled = false; + } + + foreach (MonoBehaviour monoBehaviour in instance.GetComponentsInChildren(true)) + { + if (monoBehaviour == null) + { + continue; + } + + if (monoBehaviour is BasisInteractableObject) + { + continue; + } + + monoBehaviour.enabled = false; + } + } + + private void ApplyPreviewFallbackMaterials(GameObject instance, List createdMaterials) + { + if (instance == null || BundledContentHolder.Instance == null) + { + return; + } + + Shader fallbackShader = BundledContentHolder.Instance.UrpShader; + if (fallbackShader == null) + { + return; + } + + foreach (Renderer childRenderer in instance.GetComponentsInChildren(true)) + { + if (childRenderer == null) + { + continue; + } + + BasisAvatarDriver.MaterialCorrection(childRenderer, fallbackShader, createdMaterials); + } + } + + private void ForcePreviewLods(GameObject instance) + { + if (instance == null) + { + return; + } + + foreach (Renderer childRenderer in instance.GetComponentsInChildren(true)) + { + if (childRenderer == null) + { + continue; + } + + childRenderer.forceMeshLod = PreviewLodIndex; + } + + foreach (LODGroup lodGroup in instance.GetComponentsInChildren(true)) + { + if (lodGroup == null) + { + continue; + } + + int lodCount = lodGroup.GetLODs().Length; + if (lodCount <= 0) + { + continue; + } + + lodGroup.RecalculateBounds(); + lodGroup.ForceLOD(Mathf.Min(PreviewLodIndex, lodCount - 1)); + } + } + + private void ApplyPreviewOrientation(GameObject instance) + { + if (instance == null) + { + return; + } + + if (ContentType == ContentShareType.Avatar) + { + instance.transform.localRotation = Quaternion.Euler(90f, 0f, 0f); + } + } + + private void HideMetadataPreviewLayer() + { + if (Renderer == null) + { + return; + } + Renderer.enabled = false; + } + + private bool TryFitPreviewToSphere(GameObject instance, BasisBounds fallbackBounds) + { + if (instance == null || _previewRoot == null) + { + return false; + } + + if (!TryGetCombinedRendererBounds(instance, out Bounds previewBounds)) + { + if (fallbackBounds.size == Vector3.zero) + { + return false; + } + + previewBounds = new Bounds(instance.transform.position + fallbackBounds.center, fallbackBounds.size); + } + + float targetDiameter = 1f; + Vector3 targetCenter = transform.position; + if (TryGetShellBounds(out Bounds shellBounds)) + { + targetDiameter = Mathf.Min(shellBounds.size.x, shellBounds.size.y, shellBounds.size.z) * PreviewFitPadding; + targetCenter = shellBounds.center; + } + + float previewMaxSize = Mathf.Max(previewBounds.size.x, previewBounds.size.y, previewBounds.size.z); + if (previewMaxSize <= Mathf.Epsilon) + { + return false; + } + + float scaleFactor = targetDiameter / previewMaxSize; + instance.transform.localScale = instance.transform.localScale * scaleFactor; + + if (!TryGetCombinedRendererBounds(instance, out previewBounds)) + { + previewBounds = new Bounds(instance.transform.position + fallbackBounds.center, fallbackBounds.size * scaleFactor); + } + + Vector3 centerOffset = targetCenter - previewBounds.center; + instance.transform.position += centerOffset; + return true; + } + + private bool TryGetShellBounds(out Bounds bounds) + { + Renderer[] shellRenderers = GetComponentsInChildren(true); + bounds = default; + bool hasBounds = false; + + for (int index = 0; index < shellRenderers.Length; index++) + { + Renderer shellRenderer = shellRenderers[index]; + if (shellRenderer == null || !shellRenderer.enabled) + { + continue; + } + + if (_previewRoot != null && shellRenderer.transform.IsChildOf(_previewRoot)) + { + continue; + } + + if (Label != null && shellRenderer.transform.IsChildOf(Label.transform)) + { + continue; + } + + if (!hasBounds) + { + bounds = shellRenderer.bounds; + hasBounds = true; + } + else + { + bounds.Encapsulate(shellRenderer.bounds); + } + } + + return hasBounds; + } + + private static bool TryGetCombinedRendererBounds(GameObject instance, out Bounds bounds) + { + Renderer[] renderers = instance.GetComponentsInChildren(true); + bounds = default; + bool hasBounds = false; + for (int index = 0; index < renderers.Length; index++) + { + Renderer childRenderer = renderers[index]; + if (childRenderer == null || !childRenderer.enabled) + { + continue; + } + + if (!hasBounds) + { + bounds = childRenderer.bounds; + hasBounds = true; + } + else + { + bounds.Encapsulate(childRenderer.bounds); + } + } + + return hasBounds; + } + + private void DestroyPreview() + { + if (_previewInstance != null) + { + GameObject.Destroy(_previewInstance); + _previewInstance = null; + } + + for (int index = 0; index < _previewMaterials.Count; index++) + { + if (_previewMaterials[index] != null) + { + GameObject.Destroy(_previewMaterials[index]); + } + } + _previewMaterials.Clear(); + } + + private void ReleasePreviewBundle() + { + if (_previewBundleWrapper == null) + { + return; + } + + ReleasePreviewBundle(_previewBundleWrapper); + _previewBundleWrapper = null; + } + + private static void ReleasePreviewBundle(BasisTrackedBundleWrapper wrapper) + { + if (wrapper?.LoadableBundle?.BasisRemoteBundleEncrypted?.RemoteBeeFileLocation == null) + { + return; + } + + _ = BasisLoadHandler.RequestDeIncrementOfBundle(wrapper.LoadableBundle); + } + + private static void CleanupStagedPreview(GameObject stagedInstance, List stagedMaterials) + { + if (stagedInstance != null) + { + GameObject.Destroy(stagedInstance); + } + + for (int index = 0; index < stagedMaterials.Count; index++) + { + if (stagedMaterials[index] != null) + { + GameObject.Destroy(stagedMaterials[index]); + } + } + stagedMaterials.Clear(); + } + #region BasisInteractableObject Implementation public override bool CanHover(BasisInput input) diff --git a/Basis/Packages/com.basis.sdk/Meshes/AvatarOrb.fbx b/Basis/Packages/com.basis.sdk/Meshes/AvatarOrb.fbx index 14fa0afb29fe6570ca729c3e4d43c571aeee8cbc..1543235e5f1b5f9b495403afdf712198452174cd 100644 GIT binary patch delta 30402 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 delta 27952 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 diff --git a/Basis/Packages/com.basis.sdk/Prefabs/AvatarOrb.prefab b/Basis/Packages/com.basis.sdk/Prefabs/AvatarOrb.prefab index f30ebefa2d..d284ab0d3d 100644 --- a/Basis/Packages/com.basis.sdk/Prefabs/AvatarOrb.prefab +++ b/Basis/Packages/com.basis.sdk/Prefabs/AvatarOrb.prefab @@ -191,15 +191,15 @@ PrefabInstance: m_Modifications: - target: {fileID: -8679921383154817045, guid: f0d1d5c0f7212e445a8a6b048a795747, type: 3} propertyPath: m_LocalPosition.x - value: -0.272 + value: -0.49324 objectReference: {fileID: 0} - target: {fileID: -8679921383154817045, guid: f0d1d5c0f7212e445a8a6b048a795747, type: 3} propertyPath: m_LocalPosition.y - value: 0 + value: -1.55 objectReference: {fileID: 0} - target: {fileID: -8679921383154817045, guid: f0d1d5c0f7212e445a8a6b048a795747, type: 3} propertyPath: m_LocalPosition.z - value: -29.593 + value: 4.62343 objectReference: {fileID: 0} - target: {fileID: -8679921383154817045, guid: f0d1d5c0f7212e445a8a6b048a795747, type: 3} propertyPath: m_LocalRotation.w @@ -232,11 +232,15 @@ PrefabInstance: - target: {fileID: -7511558181221131132, guid: f0d1d5c0f7212e445a8a6b048a795747, type: 3} propertyPath: 'm_Materials.Array.data[0]' value: - objectReference: {fileID: 2100000, guid: 89d91b9e307208f41b092716806fbe14, type: 2} + objectReference: {fileID: 2100000, guid: 98c6e28597211dc4ca46b1232906f316, type: 2} - target: {fileID: -7511558181221131132, guid: f0d1d5c0f7212e445a8a6b048a795747, type: 3} propertyPath: 'm_Materials.Array.data[1]' value: objectReference: {fileID: 2100000, guid: 98c6e28597211dc4ca46b1232906f316, type: 2} + - target: {fileID: -3089726251873171878, guid: f0d1d5c0f7212e445a8a6b048a795747, type: 3} + propertyPath: 'm_Materials.Array.data[0]' + value: + objectReference: {fileID: 2100000, guid: 89d91b9e307208f41b092716806fbe14, type: 2} - target: {fileID: -3089726251873171878, guid: f0d1d5c0f7212e445a8a6b048a795747, type: 3} propertyPath: 'm_Materials.Array.data[1]' value: @@ -262,6 +266,11 @@ PrefabInstance: insertIndex: -1 addedObject: {fileID: 2587787579263692451} m_SourcePrefab: {fileID: 100100000, guid: f0d1d5c0f7212e445a8a6b048a795747, type: 3} +--- !u!23 &1885848445302283906 stripped +MeshRenderer: + m_CorrespondingSourceObject: {fileID: -3089726251873171878, guid: f0d1d5c0f7212e445a8a6b048a795747, type: 3} + m_PrefabInstance: {fileID: 5707458702514165976} + m_PrefabAsset: {fileID: 0} --- !u!1 &4896994591437006217 stripped GameObject: m_CorrespondingSourceObject: {fileID: 919132149155446097, guid: f0d1d5c0f7212e445a8a6b048a795747, type: 3} @@ -301,8 +310,10 @@ MonoBehaviour: m_PersistentCalls: m_Calls: [] InteractRange: 1 + AllowDirectGrab: 1 + GrabRadius: 0.15 Label: {fileID: 8452803495268253739} - Renderer: {fileID: 6410138300982690908} + Renderer: {fileID: 1885848445302283906} MaterialIndex: 0 texture: {fileID: 0} --- !u!54 &3357315586662725574 @@ -358,8 +369,3 @@ Transform: m_CorrespondingSourceObject: {fileID: -8679921383154817045, guid: f0d1d5c0f7212e445a8a6b048a795747, type: 3} m_PrefabInstance: {fileID: 5707458702514165976} m_PrefabAsset: {fileID: 0} ---- !u!23 &6410138300982690908 stripped -MeshRenderer: - m_CorrespondingSourceObject: {fileID: -7511558181221131132, guid: f0d1d5c0f7212e445a8a6b048a795747, type: 3} - m_PrefabInstance: {fileID: 5707458702514165976} - m_PrefabAsset: {fileID: 0} From 26891bc06e0f43bc496f02367ec3aa3235791164 Mon Sep 17 00:00:00 2001 From: Toys0125 Date: Fri, 27 Mar 2026 02:03:01 -0500 Subject: [PATCH 2/2] Fix Label Preview for share content. --- .../ContentShare/BasisContentSphere.cs | 39 +++++++++++++++++- .../com.basis.sdk/Meshes/AvatarOrb.fbx | Bin 47084 -> 47004 bytes 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/Basis/Packages/com.basis.framework/Networking/ContentShare/BasisContentSphere.cs b/Basis/Packages/com.basis.framework/Networking/ContentShare/BasisContentSphere.cs index 60be3660d8..dd4d2e664a 100644 --- a/Basis/Packages/com.basis.framework/Networking/ContentShare/BasisContentSphere.cs +++ b/Basis/Packages/com.basis.framework/Networking/ContentShare/BasisContentSphere.cs @@ -6,6 +6,7 @@ using Basis.Scripts.UI.UI_Panels; using System; using System.Collections.Generic; +using System.IO; using System.Threading; using System.Threading.Tasks; using TMPro; @@ -54,7 +55,7 @@ public void Initialize(string sphereNetID, string contentURL, string unlockPassw ContentType = contentType; CreatorPlayerID = creatorPlayerID; InteractRange = 2f; - Label.text = GetContentTypeName(); + SetInitialLabel(); if (BasisSettingsDefaults.SharedContentPreviews.RawValue) { @@ -212,6 +213,42 @@ public string GetContentTypeName() } } + private void SetInitialLabel() + { + if (Label == null) + { + return; + } + + string typeName = GetContentTypeName(); + string bundleName = TryGetBundleNameFromUrl(); + Label.text = string.IsNullOrEmpty(bundleName) ? typeName : $"{typeName}\n{bundleName}"; + } + + private string TryGetBundleNameFromUrl() + { + if (string.IsNullOrEmpty(ContentURL)) + { + return string.Empty; + } + + try + { + string path = ContentURL; + if (Uri.TryCreate(ContentURL, UriKind.Absolute, out Uri uri)) + { + path = uri.LocalPath; + } + + string fileName = Path.GetFileNameWithoutExtension(path); + return string.IsNullOrWhiteSpace(fileName) ? string.Empty : fileName; + } + catch + { + return string.Empty; + } + } + private async Task LoadLivePreviewAsync(CancellationToken cancellationToken) { GameObject stagedInstance = null; diff --git a/Basis/Packages/com.basis.sdk/Meshes/AvatarOrb.fbx b/Basis/Packages/com.basis.sdk/Meshes/AvatarOrb.fbx index 1543235e5f1b5f9b495403afdf712198452174cd..84fa34841be06701dbf278bfaf086e27552b588a 100644 GIT binary patch delta 753 zcmZvXTSyd99EbP(!FxuQlB;wvO2SYqNz-M$M_RfSnwA>5>1K4UP`M)mfXsxp%{QQoXaM$LU_%w2*d%6(`WSa`+SL_(xk!OwXZT zVJ+=&RA3J=Gj@hDL|rAj8@vy@3MCByb!`k!r8 zGHh8m@3GPak72vSZ8trbRkCQrV+@q4817hXl5MOBt@24W1fN_+Uu7)G^=vOnyrs;6 zYu<92^kT|uqZKcbe5EWO$9*N__F*(oL9cyy<2%LTkfF4)67(rnx~k~O7(MwIGs+%{ zDn>C^)r+*tk7T)?1V7qj8wLDOefW>R2feBpqmeK5lk=-27vs4?v312b0 zi;+MjeG2GV+N~l}X^0bNypnU2$y`RExzAF7>Wv%#DaYTtCD`L4?(pfQ=wHLF= z3L3HE8kb!%W&ImUt{v*P7}|7wdX2PwcEci3Z))w;^%#t2YS=p~7P(?}3KP~tq~yTb zw#9!GS1fT-4mODxu8tPC2#2j>2jWR8y86W6l=pv}4)X!N!nhSF#uAvS-qY9XdXj5*-qdF1x}XXvVy~i9NwC zM>E9;Vc;=A0ma*_@2(C?@u0Jw(awx}#D({UQM|@H3Za3?-h5@Z^AbhF;ta?pU?8jsGIV}3JvtolHa$_Xcn2bh! zx5Z#Gny(_{PfH2uy9y<~&ZTi0W5Z-SjIcKY)4v&V