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 it's root a catalog is defined as a set of skin
and bodyTypes
configurations. How to setup 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:
file
Required for every part
References the thumbnail and model by appending
.webp
and.glb
respectively to the provided URI
secondary
Optionally provided to
TopPart
andBottomPart
Loads an additional glb for the slot
File referenced in the same way as the primary file but no thumbnail is required
torso
Optional field on
TopPart
If value is
true
then 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
legs
Optional field on
BottomPart
If value is
true
then 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 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 ran into 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 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-part
It 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?