Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Load default empty asset bundle #221

Closed
wants to merge 32 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
d938a4c
implemented profile get http request
lorux0 Dec 8, 2023
eac8b0f
pass json response to exception
lorux0 Dec 8, 2023
1dbf360
refactor of snapshot into url address
lorux0 Dec 9, 2023
8f12eb5
missing exception handling change
lorux0 Dec 9, 2023
2ce9da6
removed eyes, emote, skin extra allocations
lorux0 Dec 11, 2023
cea0337
Merge branch 'main' into feat/profiles
lorux0 Dec 11, 2023
bd72f64
fixes on processing profile from catalyst
lorux0 Dec 11, 2023
aa50636
implemented flow for updating the current avatar from the profile inf…
lorux0 Dec 13, 2023
e1615db
added urn note
lorux0 Dec 13, 2023
72639fd
improved allocations on urn shortening
lorux0 Dec 13, 2023
f4a7d81
implemented unique and shared wearables in the profile
lorux0 Dec 13, 2023
2ef36c2
minor rename refactor
lorux0 Dec 13, 2023
451f739
readonly properties in profile model
lorux0 Dec 13, 2023
7980d90
readonly properties on Emote
lorux0 Dec 13, 2023
cd220d9
refactor to save allocations on profile parsing
lorux0 Dec 13, 2023
bf15594
emotes as readonly dictionary
lorux0 Dec 13, 2023
8a3eb2d
refactor profiles into ecs for updating avatar from the debug menu
lorux0 Dec 14, 2023
4a8eec3
changed login order
lorux0 Dec 14, 2023
f01876b
fixed stucked profile promises
lorux0 Dec 15, 2023
b332a96
fixed avatar updating from resolved promise
lorux0 Dec 15, 2023
7b28aff
refactor of profile cache
lorux0 Dec 15, 2023
b18bf3b
always remove the promise either succeded or not
lorux0 Dec 15, 2023
e918298
improved profile parsing allocations
lorux0 Dec 16, 2023
b5bb12b
Merge branch 'main' into feat/profiles
lorux0 Dec 18, 2023
cca7184
fixed async test
lorux0 Dec 18, 2023
e7ed68d
Load empty default asset bundle
dalkia Dec 20, 2023
cbc4dc9
Code cleaning
dalkia Dec 20, 2023
7d0e676
Removed isDefaultEmptyWearableBool
dalkia Dec 21, 2023
4b5fba2
Fix test
dalkia Dec 21, 2023
cd6ebcf
Removed IsDefaultWearableFlag
dalkia Dec 21, 2023
744928c
Code cleaning
dalkia Dec 21, 2023
1ac8e96
Code cleaning
dalkia Dec 21, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ MonoBehaviour:
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
- m_GUID: 07f4f762821ea4a7e8740b3ac135b411
m_Address: EmptyDefaultWearable
m_ReadOnly: 0
m_SerializedLabels: []
FlaggedDuringContentUpdateRestriction: 0
m_ReadOnly: 0
m_Settings: {fileID: 11400000, guid: fc8a9d2b539788c47a5b305639fa8b34, type: 2}
m_SchemaSet:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@
"GUID:7f7d1af65c2641843945d409d28f2e20",
"GUID:3640f3c0b42946b0b8794a1ed8e06ca5",
"GUID:275e22790c04e9b47a5085d7b0c4432a",
"GUID:c80c82a8f4e04453b85fbab973d6774a"
"GUID:c80c82a8f4e04453b85fbab973d6774a",
"GUID:e56a0d6a94c144c784012e63b6043100",
"GUID:8322ea9340a544c59ddc56d4793eac74"
],
"includePlatforms": [],
"excludePlatforms": [],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,15 +126,10 @@ private AvatarCustomSkinningComponent InstantiateAvatar(ref AvatarShapeComponent
continue;
}

if (resultWearable.isFacialFeature())
{
//TODO: Facial Features. They are textures that should be applied on the body shape, not gameobjects to instantiate.
//We need the asset bundle to have access to the texture
}
else
{
WearableAsset originalAsset = resultWearable.GetOriginalAsset(avatarShapeComponent.BodyShape);
WearableAsset originalAsset = resultWearable.GetOriginalAsset(avatarShapeComponent.BodyShape);

if (originalAsset.GameObject != null)
{
CachedWearable instantiatedWearable =
wearableAssetsCache.InstantiateWearable(originalAsset, avatarBase.transform);

Expand All @@ -145,6 +140,18 @@ private AvatarCustomSkinningComponent InstantiateAvatar(ref AvatarShapeComponent
if (resultWearable.IsBodyShape())
bodyShape = instantiatedWearable;
}
else
{
if (resultWearable.IsFacialFeature())
{
//TODO: Facial Features. They are textures that should be applied on the body shape, not gameobjects to instantiate.
//We need the asset bundle to have access to the texture
}

//TODO: There are rare cases where the wearable should be a gameobject, but the asset bundle did not bring it
//This happened to me with bafkreiejnil6fhcb6s2pjbuvbwb6s7bo4flz4o4wosjjqrtd4gjuyht45u (aviator style eyewear)
//We should handle it
}
}

AvatarWearableHide.HideBodyShape(bodyShape, wearablesToHide, usedCategories);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,13 @@
using DCL.AvatarRendering.Wearables.Helpers;
using DCL.Diagnostics;
using DCL.ECSComponents;
using DCL.Profiles;
using Decentraland.Common;
using ECS.Abstract;
using ECS.Prioritization.Components;
using ECS.Unity.ColorComponent;
using UnityEngine;
using Entity = Arch.Core.Entity;
using Promise = ECS.StreamableLoading.Common.AssetPromise<
DCL.AvatarRendering.Wearables.Components.IWearable[],
DCL.AvatarRendering.Wearables.Components.Intentions.GetWearablesByPointersIntention>;
Expand All @@ -23,10 +27,12 @@ internal AvatarLoaderSystem(World world) : base(world) { }

protected override void Update(float t)
{
UpdateAvatarByProfileQuery(World);
LoadNewAvatarQuery(World);
UpdateAvatarQuery(World);
}

// TODO: remove PBAvatarShape as middleware, instead use Profile directly
[Query]
[None(typeof(AvatarShapeComponent))]
private void LoadNewAvatar(in Entity entity, ref PBAvatarShape pbAvatarShape, ref PartitionComponent partition)
Expand All @@ -36,6 +42,7 @@ private void LoadNewAvatar(in Entity entity, ref PBAvatarShape pbAvatarShape, re
World.Add(entity, new AvatarShapeComponent(pbAvatarShape.Name, pbAvatarShape.Id, pbAvatarShape, wearablePromise, pbAvatarShape.SkinColor.ToUnityColor(), pbAvatarShape.HairColor.ToUnityColor()));
}

// TODO: remove PBAvatarShape as middleware, instead use Profile directly
[Query]
private void UpdateAvatar(ref PBAvatarShape pbAvatarShape, ref AvatarShapeComponent avatarShapeComponent, ref PartitionComponent partition)
{
Expand All @@ -53,6 +60,37 @@ private void UpdateAvatar(ref PBAvatarShape pbAvatarShape, ref AvatarShapeCompon
pbAvatarShape.IsDirty = false;
}

// TODO: remove PBAvatarShape as middleware, instead use Profile directly
[Query]
private void UpdateAvatarByProfile(in Entity entity, ref Profile profile, ref PBAvatarShape pbAvatarShape, ref PartitionComponent partition)
{
Color avatarSkinColor = profile.Avatar.SkinColor;
Color avatarHairColor = profile.Avatar.HairColor;

World.Set(entity, new PBAvatarShape
{
Id = profile.UserId,
BodyShape = profile.Avatar.BodyShape,
Wearables = { profile.Avatar.SharedWearables },
Name = profile.Name,
SkinColor = new Color3
{
R = avatarSkinColor.r,
B = avatarSkinColor.b,
G = avatarSkinColor.g,
},
HairColor = new Color3
{
R = avatarHairColor.r,
B = avatarHairColor.b,
G = avatarHairColor.g,
},
IsDirty = true,
});

World.Remove<Profile>(entity);
}

private Promise CreateWearablePromise(PBAvatarShape pbAvatarShape, PartitionComponent partition) =>
Promise.Create(World,
WearableComponentsUtils.CreateGetWearablesByPointersIntention(pbAvatarShape, pbAvatarShape.Wearables),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
using Arch.Core;
using Arch.SystemGroups;
using Arch.SystemGroups.DefaultSystemGroups;
using DCL.DebugUtilities;
using DCL.DebugUtilities.UIBindings;
using DCL.Diagnostics;
using DCL.Profiles;
using ECS;
using ECS.Abstract;
using ECS.Prioritization.Components;
using ECS.StreamableLoading.Common.Components;
using System.Threading;
using Promise = ECS.StreamableLoading.Common.AssetPromise<
DCL.Profiles.Profile,
DCL.Profiles.GetProfileIntention>;

namespace DCL.AvatarRendering.AvatarShape.Systems
{
[UpdateInGroup(typeof(PresentationSystemGroup))]
[LogCategory(ReportCategory.AVATAR)]
public partial class OwnAvatarLoaderFromDebugMenuSystem : BaseUnityLoopSystem
{
private readonly Entity ownPlayerEntity;
private readonly IRealmData realmData;
private readonly DebugWidgetVisibilityBinding widgetVisibility;

private CancellationTokenSource fetchProfileCancellationToken;

public OwnAvatarLoaderFromDebugMenuSystem(
World world,
Entity ownPlayerEntity,
IDebugContainerBuilder debugContainerBuilder,
IRealmData realmData)
: base(world)
{
this.ownPlayerEntity = ownPlayerEntity;
this.realmData = realmData;

debugContainerBuilder.AddWidget("Profile: Avatar Shape")
.SetVisibilityBinding(widgetVisibility = new DebugWidgetVisibilityBinding(false))
.AddStringFieldWithConfirmation("0x..", "Set Address", UpdateProfileForOwnAvatar);
}

protected override void Update(float t)
{
widgetVisibility.SetVisible(realmData.Configured);
}

private void UpdateProfileForOwnAvatar(string profileId)
{
const int VERSION = 0;

var promise = Promise.Create(World,
new GetProfileIntention(profileId, VERSION,
new CommonLoadingArguments($"profiles/{profileId}?version={VERSION}")),
PartitionComponent.TOP_PRIORITY);

World.Add(ownPlayerEntity, promise);
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &1300342356663069903
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 6132992296668838597}
m_Layer: 0
m_Name: EmptyDefaultWearable
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &6132992296668838597
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1300342356663069903}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 10
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,6 @@ public interface IWearable

WearableDTO.WearableMetadataDto.DataDto GetData();

bool isFacialFeature();
bool IsFacialFeature();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ public void GetHidingList(string bodyShapeType, HashSet<string> hideListResult)
public WearableDTO.WearableMetadataDto.DataDto GetData() =>
WearableDTO.Asset.metadata.data;

public bool isFacialFeature() =>
public bool IsFacialFeature() =>
WearablesConstants.FACIAL_FEATURES.Contains(GetCategory());

public bool IsCompatibleWithBodyShape(string bodyShape)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ namespace DCL.AvatarRendering.Wearables.Helpers
{
public interface IWearableAssetsCache
{
int WearablesAssesCount { get; }
int WearablesAssetsCount { get; }

bool TryGet(WearableAsset asset, out CachedWearable instance);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ public interface IWearableCatalog
/// Retrieves a wearable by its DTO or adds a new one if it doesn't exist.
/// </summary>
/// <param name="wearableDto">The wearable DTO</param>
/// <param name="addToCache">If true, the wearable will be added to the cache.</param>
/// <returns>An instance of the <see cref="IWearable" /> type.</returns>
IWearable GetOrAddWearableByDTO(WearableDTO wearableDto);
IWearable GetOrAddWearableByDTO(WearableDTO wearableDto, bool addToCache = true);

/// <summary>
/// Adds an empty wearable to the catalog.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public void Dispose()
disposed = true;

RENDERER_INFO_POOL.Release(rendererInfos);
assetBundleData.Dereference();
assetBundleData?.Dereference();

if (ReferenceCount > 0)
ProfilingCounters.WearablesAssetsReferencedAmount.Value--;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public class WearableAssetsCache : IWearableAssetsCache, IDisposable
private readonly Transform parentContainer;
private readonly SimplePriorityQueue<WearableAsset, long> unloadQueue = new ();

public int WearablesAssesCount => cache.Count;
public int WearablesAssetsCount => cache.Keys.Count;

internal Dictionary<WearableAsset, List<CachedWearable>> cache { get; }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,24 @@ public partial class WearableCatalog : IWearableCatalog

internal Dictionary<string, IWearable> wearablesCache { get; } = new ();

public IWearable GetOrAddWearableByDTO(WearableDTO wearableDto) =>
public IWearable GetOrAddWearableByDTO(WearableDTO wearableDto, bool addToCache = true) =>
TryGetWearable(wearableDto.metadata.id, out IWearable existingWearable)
? existingWearable
: AddWearable(wearableDto.metadata.id, new Wearable
{
WearableDTO = new StreamableLoadingResult<WearableDTO>(wearableDto),
IsLoading = false,
});
}, addToCache);

public void AddEmptyWearable(string loadingIntentionPointer) =>
AddWearable(loadingIntentionPointer, new Wearable());

internal IWearable AddWearable(string loadingIntentionPointer, IWearable wearable)
internal IWearable AddWearable(string loadingIntentionPointer, IWearable wearable, bool addToCache = true)
{
wearablesCache.Add(loadingIntentionPointer, wearable);
cacheKeysDictionary[loadingIntentionPointer] = listedCacheKeys.AddLast((loadingIntentionPointer, MultithreadingUtility.FrameCount));

if (addToCache)
cacheKeysDictionary[loadingIntentionPointer] = listedCacheKeys.AddLast((loadingIntentionPointer, MultithreadingUtility.FrameCount));

return wearable;
}
Expand All @@ -44,14 +46,6 @@ public bool TryGetWearable(string wearableURN, out IWearable wearable)
return false;
}

public IWearable GetDefaultWearable(BodyShape bodyShape, string category)
{
string wearableURN = WearablesConstants.DefaultWearables.GetDefaultWearable(bodyShape, category);

UpdateListedCachePriority(@for: wearableURN);
return wearablesCache[wearableURN];
}

private void UpdateListedCachePriority(string @for)
{
if (cacheKeysDictionary.TryGetValue(@for, out LinkedListNode<(string key, long lastUsedFrame)> node))
Expand All @@ -76,6 +70,9 @@ public void Unload(IConcurrentBudgetProvider frameTimeBudgetProvider)
}
}

public IWearable GetDefaultWearable(BodyShape bodyShape, string category) =>
wearablesCache[WearablesConstants.DefaultWearables.GetDefaultWearable(bodyShape, category)];

private static bool TryUnloadAllWearableAssets(IWearable wearable)
{
var countNullOrEmpty = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ namespace DCL.AvatarRendering.Wearables.Helpers
{
public static class WearablesConstants
{
public const string EMPTY_DEFAULT_WEARABLE = "EMPTY_DEFAULT_WEARABLE";

//Used for hiding algorithm
public static readonly IList<string> CATEGORIES_PRIORITY = new List<string>
{
Expand Down Expand Up @@ -96,9 +98,12 @@ private static readonly Color[] DEFAULT_SKIN_COLORS
new (1.00f, 0.86f, 0.67f),
};

private static Color GetRandomSkinColor() =>
public static Color GetRandomSkinColor() =>
DEFAULT_SKIN_COLORS[Random.Range(0, DEFAULT_SKIN_COLORS.Length)];

public static Color GetRandomHairColor() =>
Random.ColorHSV();

public static Color3 GetRandomSkinColor3()
{
Color randomColor = GetRandomSkinColor();
Expand Down Expand Up @@ -146,7 +151,7 @@ public static string[] GetDefaultWearablesForBodyShape(string bodyShapeId) =>
public static string GetDefaultWearable(BodyShape bodyShapeId, string category)
{
if (!DEFAULT_WEARABLES.ContainsKey((bodyShapeId, category)))
return null;
return EMPTY_DEFAULT_WEARABLE;

return DEFAULT_WEARABLES[(bodyShapeId, category)];
}
Expand Down
Loading