public IEnumerator FetchTextures(TexturesFetched onTextureFetched) { if (texturesRetreived) { onTextureFetched?.Invoke(mainTexture, maskTexture); yield break; } var representation = wearable.GetRepresentation(bodyShapeType); string mainTextureName = representation.contents.FirstOrDefault(x => !x.file.ToLower().Contains("_mask.png"))?.hash; string maskName = representation.contents.FirstOrDefault(x => x.file.ToLower().Contains("_mask.png"))?.hash; if (!string.IsNullOrEmpty(mainTextureName)) { yield return(Utils.FetchTexture(wearable.baseUrl + mainTextureName, (tex) => { tex.Compress(false); mainTexture = tex; })); } if (!string.IsNullOrEmpty(maskName)) { yield return(Utils.FetchTexture(wearable.baseUrl + maskName, (tex) => { tex.Compress(false); maskTexture = tex; })); } texturesRetreived = true; onTextureFetched?.Invoke(mainTexture, maskTexture); }
public virtual void Load(Transform parent, Action <WearableController> onSuccess, Action <WearableController> onFail) { bonesRetargeted = false; var representation = wearable.GetRepresentation(bodyShapeType); var provider = wearable.GetContentProvider(bodyShapeType); loader = new RendereableAssetLoadHelper(provider, wearable.baseUrlBundles); loader.settings.forceNewInstance = true; loader.settings.initialLocalPosition = Vector3.up * 0.75f; loader.settings.cachingFlags = MaterialCachingHelper.Mode.CACHE_SHADERS; loader.settings.visibleFlags = AssetPromiseSettings_Rendering.VisibleFlags.INVISIBLE; loader.settings.parent = parent; loader.OnSuccessEvent += (x) => { PrepareWearable(x); onSuccess.Invoke(this); }; loader.OnFailEvent += () => onFail.Invoke(this); loader.Load(representation.mainFile); }
public virtual void Load(string bodyShapeId, Transform parent, Action <WearableController> onSuccess, Action <WearableController> onFail) { if (isReady) { return; } boneRetargetingDirty = true; var representation = wearable.GetRepresentation(bodyShapeId); if (representation == null) { onFail?.Invoke(this); return; } var provider = wearable.GetContentProvider(bodyShapeId); loader = new RendereableAssetLoadHelper(provider, wearable.baseUrlBundles); loader.settings.forceNewInstance = false; loader.settings.initialLocalPosition = Vector3.up * 0.75f; loader.settings.cachingFlags = MaterialCachingHelper.Mode.CACHE_SHADERS; loader.settings.visibleFlags = AssetPromiseSettings_Rendering.VisibleFlags.INVISIBLE; loader.settings.parent = parent; assetRenderers = null; void OnSuccessWrapper(GameObject gameObject) { if (loader != null) { loader.OnSuccessEvent -= OnSuccessWrapper; } assetRenderers = gameObject.GetComponentsInChildren <Renderer>(); PrepareWearable(gameObject); onSuccess?.Invoke(this); } loader.OnSuccessEvent += OnSuccessWrapper; void OnFailEventWrapper() { if (loader != null) { loader.OnFailEvent -= OnFailEventWrapper; loader.ClearEvents(); lastMainFileLoaded = null; loader = null; } onFail?.Invoke(this); } loader.OnFailEvent += OnFailEventWrapper; lastMainFileLoaded = representation.mainFile; loader.Load(representation.mainFile); }
public IEnumerator FetchTextures() { if (mainTexturePromise != null) { AssetPromiseKeeper_Texture.i.Forget(mainTexturePromise); } if (maskTexturePromise != null) { AssetPromiseKeeper_Texture.i.Forget(maskTexturePromise); } mainTexture = null; maskTexture = null; var representation = wearableItem.GetRepresentation(bodyShape.bodyShapeId); string mainTextureHash = representation?.contents?.FirstOrDefault(x => x.key == representation?.mainFile)?.hash; if (mainTextureHash == null) { mainTextureHash = representation?.contents?.FirstOrDefault(x => !x.key.ToLower().Contains("_mask.png"))?.hash; } string maskhash = representation?.contents?.FirstOrDefault(x => x.key.ToLower().Contains("_mask.png"))?.hash; if (!string.IsNullOrEmpty(mainTextureHash)) { mainTexturePromise = new AssetPromise_Texture(wearableItem.baseUrl + mainTextureHash); mainTexturePromise.OnSuccessEvent += (x) => mainTexture = x.texture; mainTexturePromise.OnFailEvent += (x) => mainTexture = null; AssetPromiseKeeper_Texture.i.Keep(mainTexturePromise); } if (!string.IsNullOrEmpty(maskhash)) { maskTexturePromise = new AssetPromise_Texture(wearableItem.baseUrl + maskhash); maskTexturePromise.OnSuccessEvent += (x) => maskTexture = x.texture; maskTexturePromise.OnFailEvent += (x) => maskTexture = null; AssetPromiseKeeper_Texture.i.Keep(maskTexturePromise); } yield return(mainTexturePromise); yield return(maskTexturePromise); PrepareWearable(); }
private IEnumerator LoadAvatar() { yield return(new WaitUntil(() => gameObject.activeSelf)); bool loadSoftFailed = false; WearableItem resolvedBody = null; Helpers.Promise <WearableItem> avatarBodyPromise = null; if (!string.IsNullOrEmpty(model.bodyShape)) { avatarBodyPromise = CatalogController.RequestWearable(model.bodyShape); } else { OnFailEvent?.Invoke(true); yield break; } List <WearableItem> resolvedWearables = new List <WearableItem>(); List <Helpers.Promise <WearableItem> > avatarWearablePromises = new List <Helpers.Promise <WearableItem> >(); if (model.wearables != null) { for (int i = 0; i < model.wearables.Count; i++) { avatarWearablePromises.Add(CatalogController.RequestWearable(model.wearables[i])); } } // In this point, all the requests related to the avatar's wearables have been collected and sent to the CatalogController to be sent to kernel as a unique request. // From here we wait for the response of the requested wearables and process them. if (avatarBodyPromise != null) { yield return(avatarBodyPromise); if (!string.IsNullOrEmpty(avatarBodyPromise.error)) { Debug.LogError(avatarBodyPromise.error); loadSoftFailed = true; } else { resolvedBody = avatarBodyPromise.value; wearablesInUse.Add(avatarBodyPromise.value.id); } } if (resolvedBody == null) { isLoading = false; OnFailEvent?.Invoke(true); yield break; } List <Helpers.Promise <WearableItem> > replacementPromises = new List <Helpers.Promise <WearableItem> >(); foreach (var avatarWearablePromise in avatarWearablePromises) { yield return(avatarWearablePromise); if (!string.IsNullOrEmpty(avatarWearablePromise.error)) { Debug.LogError(avatarWearablePromise.error); loadSoftFailed = true; } else { WearableItem wearableItem = avatarWearablePromise.value; wearablesInUse.Add(wearableItem.id); if (wearableItem.GetRepresentation(model.bodyShape) != null) { resolvedWearables.Add(wearableItem); } else { model.wearables.Remove(wearableItem.id); string defaultReplacement = DefaultWearables.GetDefaultWearable(model.bodyShape, wearableItem.data.category); if (!string.IsNullOrEmpty(defaultReplacement)) { model.wearables.Add(defaultReplacement); replacementPromises.Add(CatalogController.RequestWearable(defaultReplacement)); } } } } foreach (var wearablePromise in replacementPromises) { yield return(wearablePromise); if (!string.IsNullOrEmpty(wearablePromise.error)) { Debug.LogError(wearablePromise.error); loadSoftFailed = true; } else { WearableItem wearableItem = wearablePromise.value; wearablesInUse.Add(wearableItem.id); resolvedWearables.Add(wearableItem); } } bool bodyIsDirty = false; if (bodyShapeController != null && bodyShapeController.id != model?.bodyShape) { bodyShapeController.CleanUp(); bodyShapeController = null; bodyIsDirty = true; } if (bodyShapeController == null) { HideAll(); bodyShapeController = new BodyShapeController(resolvedBody); eyesController = FacialFeatureController.CreateDefaultFacialFeature(bodyShapeController.bodyShapeId, Categories.EYES, eyeMaterial); eyebrowsController = FacialFeatureController.CreateDefaultFacialFeature(bodyShapeController.bodyShapeId, Categories.EYEBROWS, eyebrowMaterial); mouthController = FacialFeatureController.CreateDefaultFacialFeature(bodyShapeController.bodyShapeId, Categories.MOUTH, mouthMaterial); } else { //If bodyShape is downloading will call OnWearableLoadingSuccess (and therefore SetupDefaultMaterial) once ready if (bodyShapeController.isReady) { bodyShapeController.SetupDefaultMaterial(defaultMaterial, model.skinColor, model.hairColor); } } bool wearablesIsDirty = false; HashSet <string> unusedCategories = new HashSet <string>(Categories.ALL); int wearableCount = resolvedWearables.Count; for (int index = 0; index < wearableCount; index++) { WearableItem wearable = resolvedWearables[index]; if (wearable == null) { continue; } unusedCategories.Remove(wearable.data.category); if (wearableControllers.ContainsKey(wearable)) { if (wearableControllers[wearable].IsLoadedForBodyShape(bodyShapeController.bodyShapeId)) { UpdateWearableController(wearable); } else { wearableControllers[wearable].CleanUp(); } } else { AddWearableController(wearable); if (wearable.data.category != Categories.EYES && wearable.data.category != Categories.MOUTH && wearable.data.category != Categories.EYEBROWS) { wearablesIsDirty = true; } } } foreach (var category in unusedCategories) { switch (category) { case Categories.EYES: eyesController = FacialFeatureController.CreateDefaultFacialFeature(bodyShapeController.bodyShapeId, Categories.EYES, eyeMaterial); break; case Categories.MOUTH: mouthController = FacialFeatureController.CreateDefaultFacialFeature(bodyShapeController.bodyShapeId, Categories.MOUTH, mouthMaterial); break; case Categories.EYEBROWS: eyebrowsController = FacialFeatureController.CreateDefaultFacialFeature(bodyShapeController.bodyShapeId, Categories.EYEBROWS, eyebrowMaterial); break; } } HashSet <string> hiddenList = WearableItem.CompoundHidesList(bodyShapeController.bodyShapeId, resolvedWearables); if (!bodyShapeController.isReady) { bodyShapeController.Load(bodyShapeController.bodyShapeId, transform, OnWearableLoadingSuccess, OnBodyShapeLoadingFail); } foreach (WearableController wearable in wearableControllers.Values) { if (bodyIsDirty) { wearable.boneRetargetingDirty = true; } wearable.Load(bodyShapeController.bodyShapeId, transform, OnWearableLoadingSuccess, x => OnWearableLoadingFail(x)); yield return(null); } yield return(new WaitUntil(() => bodyShapeController.isReady && wearableControllers.Values.All(x => x.isReady))); eyesController?.Load(bodyShapeController, model.eyeColor); eyebrowsController?.Load(bodyShapeController, model.hairColor); mouthController?.Load(bodyShapeController, model.skinColor); yield return(new WaitUntil(() => (eyebrowsController == null || (eyebrowsController != null && eyebrowsController.isReady)) && (eyesController == null || (eyesController != null && eyesController.isReady)) && (mouthController == null || (mouthController != null && mouthController.isReady)))); if (bodyIsDirty || wearablesIsDirty) { OnVisualCue?.Invoke(VisualCue.Loaded); } bodyShapeController.SetActiveParts(unusedCategories.Contains(Categories.LOWER_BODY), unusedCategories.Contains(Categories.UPPER_BODY), unusedCategories.Contains(Categories.FEET)); bodyShapeController.SetFacialFeaturesVisible(facialFeaturesVisible); bodyShapeController.UpdateVisibility(hiddenList); foreach (WearableController wearableController in wearableControllers.Values) { wearableController.UpdateVisibility(hiddenList); } CleanUpUnusedItems(); isLoading = false; SetWearableBones(); UpdateExpressions(model.expressionTriggerId, model.expressionTriggerTimestamp); if (lastStickerTimestamp != model.stickerTriggerTimestamp && model.stickerTriggerId != null) { lastStickerTimestamp = model.stickerTriggerTimestamp; stickersController?.PlayEmote(model.stickerTriggerId); } if (loadSoftFailed) { OnFailEvent?.Invoke(false); } else { OnSuccessEvent?.Invoke(); } }