Building your catalog
Catalogs define what assets your users may use in order to customize their avatars. By default, MSquared provides an extensive library of parts to get you started, however, you may want to build your own catalog for a custom experience.
Catalogs are hosted json files which the Avatar Editor ingests and presents to the user so they can pick the assets they desire. At its root, a catalog is defined as a set of skin and bodyTypes configurations. How to set up each section is outlined below.
{
skin: Skin;
bodyTypes: BodyTypes;
}Skin
By default the Avatar Creator supports 7 skin tones. If you need more skin tones please reach out to the MSquared Team. Any parts which are skin dependent will require a variation to be created for each skin color.
{
name: string;
index: number;
}For most projects, the following skin setup can be used:
"skin": [
{
"name": "01",
"index": 1
},
{
"name": "02",
"index": 2
},
{
"name": "03",
"index": 3
},
{
"name": "04",
"index": 4
},
{
"name": "05",
"index": 5
},
{
"name": "06",
"index": 6
},
{
"name": "07",
"index": 7
}
],
Body Types
By default, the Avatar Creator supports 2 body types (bodyA and bodyB). If you need more body types please reach out to the MSquared Team. Every catalog should define parts for both bodyA and bodyB.
A body type is composed of body, head, hair, top, bottom, and shoes - each containing a list of parts.
body:{
torsoArms: string;
arms: string;
legsFeet: string;
legs: string;
};
head: {
list: HeadPart[];
};
hair: {
list: HairPart[]
};
top: {
list: TopPart[]
};
bottom: {
list: BottomPart[]
};
shoes: {
list: ShoesPart[]
};Defining a body
The base body parts must be provided, which the user's chosen assets will be placed on top of. All fields which make up the body are skin dependent.
Defining a part
A part is composed of the following fields:
fileRequired for every part
References the thumbnail and model by appending
.webpand.glbrespectively to the provided URI
secondaryOptionally provided to
TopPartandBottomPartLoads an additional glb for the slot
File referenced in the same way as the primary file but no thumbnail is required
torsoOptional field on
TopPartIf value is
truethen the torso will be renderedFor example, this may be needed for shirts but a hoodie covers the whole torso so by default it will not need to render the torso
legsOptional field on
BottomPartIf value is
truethen the legs will be renderedFor example, this may be needed for shorts but a pair of jeans covers the whole legs so by default it will not need to render the legs
Additionally, the head slot is skin dependent.
Example Catalog
This minimal example only has one body type configured; selecting the other body type in the editor with this will cause an error
{
"skin": [
{
"name": "01",
"index": 1
},
{
"name": "02",
"index": 2
}
],
"bodyTypes": {
"bodyA": { ...omitted... },
"bodyB": {
"body": {
"torsoArms": "https://storage.googleapis.com/glb-content-bucket/parts/Body_B_BodyTorsoHeadless",
"arms": "https://storage.googleapis.com/glb-content-bucket/parts/Body_B_BodyArmsHeadless",
"legsFeet": "https://storage.googleapis.com/glb-content-bucket/parts/Body_B_BodyLegsFeet",
"legs": "https://storage.googleapis.com/glb-content-bucket/parts/Body_B_BodyLegs"
},
"head": {
"list": [
{
"file": "https://storage.googleapis.com/glb-content-bucket/parts/Head_B_Mixed_B"
},
{
"file": "https://storage.googleapis.com/glb-content-bucket/parts/Head_B_Mixed_A"
}
]
},
"hair": {
"list": [
{
"file": "https://storage.googleapis.com/glb-content-bucket/parts/Hair_B_NatalieHair_Brown_01"
},
{
"file": "https://storage.googleapis.com/glb-content-bucket/parts/Hair_B_NatalieHair_Extra_01"
}
]
},
"top": {
"list": [
{
"file": "https://storage.googleapis.com/glb-content-bucket/parts/Top_B_Hoodie_WindbreakerBlackWhite_01"
},
{
"file": "https://storage.googleapis.com/glb-content-bucket/parts/Top_B_RockJacket_VinylWhite_01",
"secondary": "https://storage.googleapis.com/glb-content-bucket/parts/Top_B_RockTopLong_White_01",
"torso": true
},
{
"file": "https://storage.googleapis.com/glb-content-bucket/parts/Top_B_FlannelShirt_CheckerdRed_01",
"secondary": "https://storage.googleapis.com/glb-content-bucket/parts/Top_B_BaseballJersey_BlackRed_01"
}
]
},
"bottom": {
"list": [
{
"file": "https://storage.googleapis.com/glb-content-bucket/parts/Bottom_B_TightJoggers_TanJeans_01"
},
{
"file": "https://storage.googleapis.com/glb-content-bucket/parts/Bottom_B_PleatedSkirt_TweedWhite_01",
"secondary": "https://storage.googleapis.com/glb-content-bucket/parts/Bottom_B_StockingsGarterRibbon_White_01",
"legs": true
}
]
},
"shoes": {
"list": [
{
"file": "https://storage.googleapis.com/glb-content-bucket/parts/Shoes_B_HighTops_WhitePink_01"
},
{
"file": "https://storage.googleapis.com/glb-content-bucket/parts/Shoes_B_HighTops_RunningBlue_01"
}
]
}
}
}
}
Asset Files
Assets, including the thumbnail and model, should be hosted using a high-availability, high-throughput CDN to avoid bottlenecks. Additionally, configure your CDN with aggressive caching to minimize network requests and speed up downloads. The files must be publicly downloadable.
Files referenced in the below catalog do not have a file extension included. This is so they can reference both the thumbnail and model by simply appending .webp and .glb respectively.
A common issue encountered when configuring asset files is the bucket hosting the assets does not have the correct CORS configuration, leading to the Avatar Creator UI not being able to fetch the content. Please ensure that whatever bucket is used for hosting content allows cross-origin requests.
Skin Dependent Parts
Additionally, some parts are marked as skin dependent. These will have the skin index, (preceded by an underscore), appended before the extension so specific parts can be set based off of the skin color
Example files
Given the base file reference:
example.com/my-storage/body-partIt would be expected that it would be possible to publicly access both
example.com/my-storage/body-part.webp // The thumbnail.
example.com/my-storage/body-part.glb // The model.Furthermore, if the part was skin dependent the following should be accessible:
example.com/my-storage/body-part_01.webp // The thumbnail for skin tone 01.
example.com/my-storage/body-part_01.glb // The model for skin tone 01.
example.com/my-storage/body-part_02.webp // The thumbnail for skin tone 02.
example.com/my-storage/body-part_02.glb // The model for skin tone 02.
...
example.com/my-storage/body-part_07.webp // The thumbnail for skin tone 07.
example.com/my-storage/body-part_07.glb // The model for skin tone 07.Last updated
Was this helpful?

