roavatar-renderer 1.6.3 → 1.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -5
- package/dist/index.d.ts +25 -2
- package/dist/index.js +316 -285
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -27,6 +27,7 @@ Basic example on how to load an avatar using OutfitRenderer (to make it simpler)
|
|
|
27
27
|
FLAGS.RIG_PATH = chrome.runtime.getURL("assets/")
|
|
28
28
|
}
|
|
29
29
|
//if layered assets dont work set this to false (workers improve performance)
|
|
30
|
+
//or set FLAGS.GET_WORKER_FUNC to a working function, check source for example
|
|
30
31
|
FLAGS.USE_WORKERS = true
|
|
31
32
|
|
|
32
33
|
//setup RBXRenderer
|
|
@@ -44,19 +45,20 @@ Basic example on how to load an avatar using OutfitRenderer (to make it simpler)
|
|
|
44
45
|
//add renderer to document
|
|
45
46
|
document.body.appendChild(RBXRenderer.getRendererElement())
|
|
46
47
|
|
|
47
|
-
//get
|
|
48
|
-
const
|
|
49
|
-
if (!(
|
|
48
|
+
//get the OutfitModel for the user with id 1
|
|
49
|
+
const outfitModel = await API.Avatar.GetUserAvatarModel(1)
|
|
50
|
+
if (!(outfitModel instanceof OutfitModel)) throw new Error("Failed to get outfitModel")
|
|
50
51
|
|
|
51
52
|
//create renderer for outfit
|
|
52
53
|
//used by api
|
|
53
54
|
const auth = new Authentication()
|
|
54
55
|
//manages outfit rendering for you
|
|
55
|
-
const outfitRenderer = new OutfitRenderer(auth,
|
|
56
|
+
const outfitRenderer = new OutfitRenderer(auth, outfitModel)
|
|
56
57
|
outfitRenderer.startAnimating()
|
|
57
58
|
outfitRenderer.setMainAnimation("idle")
|
|
58
59
|
```
|
|
59
60
|
**RESULT:**
|
|
60
61
|
<img src="https://devforum-uploads.s3.dualstack.us-east-2.amazonaws.com/uploads/original/5X/9/f/a/d/9fadf25d9770b63e8a2e480369930cad94ad04aa.png">
|
|
61
62
|
|
|
62
|
-
|
|
63
|
+
For more examples check out the OutfitRenderer, BackgroundRenderer, RoAvatar (avatarPreview.tsx) or RoValra (ItemRender.ts) source code
|
|
64
|
+
There is also a discord server you can ask for help in: https://discord.gg/PHa5Vgtbva
|
package/dist/index.d.ts
CHANGED
|
@@ -404,6 +404,7 @@ export declare const API: {
|
|
|
404
404
|
GetUserLooks: (userId: number, cursor?: string) => Promise<Response | UserLooks_Result>;
|
|
405
405
|
CreateLook: (auth: Authentication, outfit: Outfit, name: string, description: string) => Promise<Response>;
|
|
406
406
|
DeleteLook: (auth: Authentication, lookId: string) => Promise<Response>;
|
|
407
|
+
PatchLook: (auth: Authentication, lookId: string, data: Partial<Look_Result["look"]>) => Promise<Response>;
|
|
407
408
|
};
|
|
408
409
|
PremiumFeatures: {
|
|
409
410
|
GetSubscription: (userId: number) => Promise<Response | GetSubscription_Result>;
|
|
@@ -685,6 +686,10 @@ export declare function awaitTimeout<T>(promise: Promise<T>, time?: number): Pro
|
|
|
685
686
|
*/
|
|
686
687
|
export declare function awaitTimeoutThrows<T>(promise: Promise<T>, time?: number): Promise<T>;
|
|
687
688
|
|
|
689
|
+
/**
|
|
690
|
+
* Used internally by OutfitRenderer to render backgrounds
|
|
691
|
+
* @category Renderer
|
|
692
|
+
*/
|
|
688
693
|
export declare class BackgroundRenderer {
|
|
689
694
|
auth: Authentication;
|
|
690
695
|
avatarCyclorama?: Instance;
|
|
@@ -1576,6 +1581,8 @@ export declare const FLAGS: {
|
|
|
1576
1581
|
API_REQUEST_RETRY: boolean;
|
|
1577
1582
|
/**the fetch function the api will use */
|
|
1578
1583
|
FETCH_FUNC: ((input: URL | RequestInfo, init?: RequestInit) => Promise<Response>) | undefined;
|
|
1584
|
+
/**a function all image urls will go through before being loaded, the return value is the new image url */
|
|
1585
|
+
IMAGE_FUNC: ((input: string) => Promise<string>) | undefined;
|
|
1579
1586
|
/**loads assets from assetdelivery instead of local files */
|
|
1580
1587
|
ONLINE_ASSETS: boolean;
|
|
1581
1588
|
/**path to rbxasset:// local files*/
|
|
@@ -1739,6 +1746,14 @@ export declare function gaussian_rbf(v0: Vec3, v1: Vec3, sigma?: number): number
|
|
|
1739
1746
|
*/
|
|
1740
1747
|
export declare function generateModelThumbnail(auth: Authentication, renderScene: RBXRendererScene, model: Instance, size?: Vec2, type?: ThumbnailType, quality?: number, gltfAutoDownload?: boolean, includeAnimations?: boolean): Promise<ThumbnailResult>;
|
|
1741
1748
|
|
|
1749
|
+
/**
|
|
1750
|
+
* @deprecated This has the exact same behavior as generateOutfitThumbnail which also supports outfitModels
|
|
1751
|
+
* @category ThumbnailGenerator
|
|
1752
|
+
* @param auth
|
|
1753
|
+
* @param outfitModel
|
|
1754
|
+
* @param options
|
|
1755
|
+
* @returns
|
|
1756
|
+
*/
|
|
1742
1757
|
export declare function generateOutfitModelThumbnail(auth: Authentication, outfitModel: OutfitModel, options: Partial<OutfitModelThumbnailOptions>): Promise<ThumbnailResult>;
|
|
1743
1758
|
|
|
1744
1759
|
/**
|
|
@@ -1751,7 +1766,6 @@ export declare function generateOutfitModelThumbnail(auth: Authentication, outfi
|
|
|
1751
1766
|
* @param gltfAutoDownload Automatically download gltf file
|
|
1752
1767
|
* @returns ThumbnailResult, always a string for 2d thumbnails, 3d can be ArrayBuffer (glb, binary) or {[key: string]: unknown} (gltf, json)
|
|
1753
1768
|
*
|
|
1754
|
-
* @deprecated Use new Thumbnails category instead
|
|
1755
1769
|
* @category ThumbnailGenerator
|
|
1756
1770
|
*
|
|
1757
1771
|
* @example
|
|
@@ -2892,6 +2906,8 @@ export declare function offsetMesh(mesh: FileMesh, cframe: CFrame): void;
|
|
|
2892
2906
|
export declare function offsetMeshWithRotation(mesh: FileMesh, cframe: CFrame): void;
|
|
2893
2907
|
|
|
2894
2908
|
/**
|
|
2909
|
+
* It is recommended to use an OutfitModel that contains an Outfit instead of using an Outfit directly as they cannot contain things such as avatar backgrounds
|
|
2910
|
+
*
|
|
2895
2911
|
* Usually obtained from API
|
|
2896
2912
|
* @category Outfit
|
|
2897
2913
|
*/
|
|
@@ -2955,7 +2971,7 @@ export declare class Outfit {
|
|
|
2955
2971
|
getNextOrder(order: number): number;
|
|
2956
2972
|
addAssetId(assetId: number, auth: Authentication): Promise<boolean>;
|
|
2957
2973
|
addAssetIdEconomy(assetId: number): Promise<boolean>;
|
|
2958
|
-
addBundleId(bundleId: number): Promise<boolean>;
|
|
2974
|
+
addBundleId(bundleId: number, auth?: Authentication): Promise<boolean>;
|
|
2959
2975
|
getAssetId(assetId: number): Asset | undefined;
|
|
2960
2976
|
fromLook(look: Look_Result["look"], auth: Authentication): Promise<boolean>;
|
|
2961
2977
|
fromBuffer(buffer: ArrayBuffer, auth: Authentication): Promise<Response | Outfit>;
|
|
@@ -2979,6 +2995,10 @@ export declare type OutfitJson = {
|
|
|
2979
2995
|
scales?: ScaleJson;
|
|
2980
2996
|
};
|
|
2981
2997
|
|
|
2998
|
+
/**
|
|
2999
|
+
* Usually obtained from API, not to be confused with Outfit which cannot contain things such as backgrounds
|
|
3000
|
+
* @category Outfit
|
|
3001
|
+
*/
|
|
2982
3002
|
export declare class OutfitModel {
|
|
2983
3003
|
outfit: Outfit;
|
|
2984
3004
|
emotes: Map<number, Asset>;
|
|
@@ -3985,6 +4005,9 @@ declare type ThreePoseCorrective = Vec3;
|
|
|
3985
4005
|
* @category ThumbnailGenerator */
|
|
3986
4006
|
export declare type ThumbnailCameraType = "default" | "avatarHeadshot" | "avatarFullbody" | "fullbody";
|
|
3987
4007
|
|
|
4008
|
+
/**
|
|
4009
|
+
* @category Outfit
|
|
4010
|
+
*/
|
|
3988
4011
|
export declare class ThumbnailCustomization {
|
|
3989
4012
|
thumbnailType: number;
|
|
3990
4013
|
emoteAssetId: number;
|
package/dist/index.js
CHANGED
|
@@ -22,6 +22,275 @@ function cloneSearch_Payload(data) {
|
|
|
22
22
|
return newData;
|
|
23
23
|
}
|
|
24
24
|
const AllAvatarModelOutfitUpdateTypes = ["UpdateBodyColors", "UpdateAssets", "UpdateAvatarType", "UpdateScales", "UpdateBackground"];
|
|
25
|
+
const AssetTypes = [
|
|
26
|
+
"",
|
|
27
|
+
"Image",
|
|
28
|
+
"TShirt",
|
|
29
|
+
"Audio",
|
|
30
|
+
"Mesh",
|
|
31
|
+
"Lua",
|
|
32
|
+
"HTML",
|
|
33
|
+
"Text",
|
|
34
|
+
"Hat",
|
|
35
|
+
"Place",
|
|
36
|
+
"Model",
|
|
37
|
+
"Shirt",
|
|
38
|
+
"Pants",
|
|
39
|
+
"Decal",
|
|
40
|
+
"",
|
|
41
|
+
"",
|
|
42
|
+
"Avatar",
|
|
43
|
+
"Head",
|
|
44
|
+
"Face",
|
|
45
|
+
"Gear",
|
|
46
|
+
"",
|
|
47
|
+
"Badge",
|
|
48
|
+
"GroupEmblem",
|
|
49
|
+
"",
|
|
50
|
+
"Animation",
|
|
51
|
+
"Arms",
|
|
52
|
+
"Legs",
|
|
53
|
+
"Torso",
|
|
54
|
+
"RightArm",
|
|
55
|
+
"LeftArm",
|
|
56
|
+
"LeftLeg",
|
|
57
|
+
"RightLeg",
|
|
58
|
+
"Package",
|
|
59
|
+
"YouTubeVideo",
|
|
60
|
+
"GamePass",
|
|
61
|
+
"App",
|
|
62
|
+
"",
|
|
63
|
+
"Code",
|
|
64
|
+
"Plugin",
|
|
65
|
+
"SolidModel",
|
|
66
|
+
"MeshPart",
|
|
67
|
+
"HairAccessory",
|
|
68
|
+
"FaceAccessory",
|
|
69
|
+
"NeckAccessory",
|
|
70
|
+
"ShoulderAccessory",
|
|
71
|
+
"FrontAccessory",
|
|
72
|
+
"BackAccessory",
|
|
73
|
+
"WaistAccessory",
|
|
74
|
+
"ClimbAnimation",
|
|
75
|
+
"DeathAnimation",
|
|
76
|
+
"FallAnimation",
|
|
77
|
+
"IdleAnimation",
|
|
78
|
+
"JumpAnimation",
|
|
79
|
+
"RunAnimation",
|
|
80
|
+
"SwimAnimation",
|
|
81
|
+
"WalkAnimation",
|
|
82
|
+
"PoseAnimation",
|
|
83
|
+
"",
|
|
84
|
+
"",
|
|
85
|
+
"LocalizationTableManifest",
|
|
86
|
+
"LocalizationTableTranslation",
|
|
87
|
+
"EmoteAnimation",
|
|
88
|
+
"Video",
|
|
89
|
+
"TexturePack",
|
|
90
|
+
"TShirtAccessory",
|
|
91
|
+
"ShirtAccessory",
|
|
92
|
+
"PantsAccessory",
|
|
93
|
+
"JacketAccessory",
|
|
94
|
+
"SweaterAccessory",
|
|
95
|
+
"ShortsAccessory",
|
|
96
|
+
"LeftShoeAccessory",
|
|
97
|
+
"RightShoeAccessory",
|
|
98
|
+
"DressSkirtAccessory",
|
|
99
|
+
"FontFamily",
|
|
100
|
+
"FontFace",
|
|
101
|
+
"MeshHiddenSurfaceRemoval",
|
|
102
|
+
"EyebrowAccessory",
|
|
103
|
+
"EyelashAccessory",
|
|
104
|
+
"MoodAnimation",
|
|
105
|
+
"DynamicHead",
|
|
106
|
+
//79
|
|
107
|
+
"CodeSnippet",
|
|
108
|
+
"AdsVideo",
|
|
109
|
+
"OtaUpdate",
|
|
110
|
+
"Screenshot",
|
|
111
|
+
"RuntimePropertySet",
|
|
112
|
+
"StorePreviewVideo",
|
|
113
|
+
"GamePreviewVideo",
|
|
114
|
+
"CreatorExperienceConfig",
|
|
115
|
+
"FaceMakeup",
|
|
116
|
+
"LipMakeup",
|
|
117
|
+
"EyeMakeup",
|
|
118
|
+
"VoxelFragment",
|
|
119
|
+
"AvatarBackground",
|
|
120
|
+
"TextDocument"
|
|
121
|
+
];
|
|
122
|
+
const WearableAssetTypes = [
|
|
123
|
+
"TShirt",
|
|
124
|
+
"Hat",
|
|
125
|
+
"Shirt",
|
|
126
|
+
"Pants",
|
|
127
|
+
"Head",
|
|
128
|
+
"Face",
|
|
129
|
+
"Gear",
|
|
130
|
+
"Torso",
|
|
131
|
+
"RightArm",
|
|
132
|
+
"LeftArm",
|
|
133
|
+
"LeftLeg",
|
|
134
|
+
"RightLeg",
|
|
135
|
+
"HairAccessory",
|
|
136
|
+
"FaceAccessory",
|
|
137
|
+
"NeckAccessory",
|
|
138
|
+
"ShoulderAccessory",
|
|
139
|
+
"FrontAccessory",
|
|
140
|
+
"BackAccessory",
|
|
141
|
+
"WaistAccessory",
|
|
142
|
+
"ClimbAnimation",
|
|
143
|
+
"FallAnimation",
|
|
144
|
+
"IdleAnimation",
|
|
145
|
+
"JumpAnimation",
|
|
146
|
+
"RunAnimation",
|
|
147
|
+
"SwimAnimation",
|
|
148
|
+
"WalkAnimation",
|
|
149
|
+
"TShirtAccessory",
|
|
150
|
+
"ShirtAccessory",
|
|
151
|
+
"PantsAccessory",
|
|
152
|
+
"JacketAccessory",
|
|
153
|
+
"SweaterAccessory",
|
|
154
|
+
"ShortsAccessory",
|
|
155
|
+
"LeftShoeAccessory",
|
|
156
|
+
"RightShoeAccessory",
|
|
157
|
+
"DressSkirtAccessory",
|
|
158
|
+
"EyebrowAccessory",
|
|
159
|
+
"EyelashAccessory",
|
|
160
|
+
"MoodAnimation",
|
|
161
|
+
"DynamicHead",
|
|
162
|
+
"FaceMakeup",
|
|
163
|
+
"LipMakeup",
|
|
164
|
+
"EyeMakeup",
|
|
165
|
+
"PoseAnimation",
|
|
166
|
+
"EarAccessory",
|
|
167
|
+
"EyeAccessory",
|
|
168
|
+
"DeathAnimation"
|
|
169
|
+
];
|
|
170
|
+
const AccessoryAssetTypes = [
|
|
171
|
+
"Hat",
|
|
172
|
+
"HairAccessory",
|
|
173
|
+
"FaceAccessory",
|
|
174
|
+
"NeckAccessory",
|
|
175
|
+
"ShoulderAccessory",
|
|
176
|
+
"FrontAccessory",
|
|
177
|
+
"BackAccessory",
|
|
178
|
+
"WaistAccessory"
|
|
179
|
+
];
|
|
180
|
+
const LayeredAssetTypes = [
|
|
181
|
+
"TShirtAccessory",
|
|
182
|
+
"ShirtAccessory",
|
|
183
|
+
"PantsAccessory",
|
|
184
|
+
"JacketAccessory",
|
|
185
|
+
"SweaterAccessory",
|
|
186
|
+
"ShortsAccessory",
|
|
187
|
+
"LeftShoeAccessory",
|
|
188
|
+
"RightShoeAccessory",
|
|
189
|
+
"DressSkirtAccessory",
|
|
190
|
+
"EyebrowAccessory",
|
|
191
|
+
"EyelashAccessory",
|
|
192
|
+
"HairAccessory",
|
|
193
|
+
"FaceMakeup",
|
|
194
|
+
"LipMakeup",
|
|
195
|
+
"EyeMakeup"
|
|
196
|
+
];
|
|
197
|
+
const SpecialLayeredAssetTypes = [
|
|
198
|
+
"EyebrowAccessory",
|
|
199
|
+
"EyelashAccessory",
|
|
200
|
+
"HairAccessory"
|
|
201
|
+
];
|
|
202
|
+
const MaxOneOfAssetTypes = [
|
|
203
|
+
"TShirt",
|
|
204
|
+
"Shirt",
|
|
205
|
+
"Pants",
|
|
206
|
+
"Head",
|
|
207
|
+
"Face",
|
|
208
|
+
"Gear",
|
|
209
|
+
"Torso",
|
|
210
|
+
"RightArm",
|
|
211
|
+
"LeftArm",
|
|
212
|
+
"LeftLeg",
|
|
213
|
+
"RightLeg",
|
|
214
|
+
"ClimbAnimation",
|
|
215
|
+
"DeathAnimation",
|
|
216
|
+
"FallAnimation",
|
|
217
|
+
"IdleAnimation",
|
|
218
|
+
"JumpAnimation",
|
|
219
|
+
"RunAnimation",
|
|
220
|
+
"SwimAnimation",
|
|
221
|
+
"WalkAnimation",
|
|
222
|
+
"PoseAnimation",
|
|
223
|
+
"MoodAnimation",
|
|
224
|
+
"DynamicHead",
|
|
225
|
+
"EyebrowAccessory",
|
|
226
|
+
"EyelashAccessory"
|
|
227
|
+
];
|
|
228
|
+
const ToRemoveBeforeBundleType = {
|
|
229
|
+
"DynamicHead": ["MoodAnimation", "DynamicHead", "EyebrowAccessory", "EyelashAccessory", "Head"],
|
|
230
|
+
"Shoes": ["LeftShoeAccessory", "RightShoeAccessory"],
|
|
231
|
+
"AnimationPack": [
|
|
232
|
+
"ClimbAnimation",
|
|
233
|
+
"DeathAnimation",
|
|
234
|
+
"FallAnimation",
|
|
235
|
+
"IdleAnimation",
|
|
236
|
+
"JumpAnimation",
|
|
237
|
+
"RunAnimation",
|
|
238
|
+
"SwimAnimation",
|
|
239
|
+
"WalkAnimation",
|
|
240
|
+
"PoseAnimation",
|
|
241
|
+
"MoodAnimation"
|
|
242
|
+
],
|
|
243
|
+
"Character": [
|
|
244
|
+
"DynamicHead",
|
|
245
|
+
"Head",
|
|
246
|
+
"Torso",
|
|
247
|
+
"LeftArm",
|
|
248
|
+
"RightArm",
|
|
249
|
+
"LeftLeg",
|
|
250
|
+
"RightLeg"
|
|
251
|
+
],
|
|
252
|
+
"MakeupLook": [
|
|
253
|
+
"FaceMakeup",
|
|
254
|
+
"EyeMakeup",
|
|
255
|
+
"LipMakeup",
|
|
256
|
+
"EyebrowAccessory",
|
|
257
|
+
"EyelashAccessory"
|
|
258
|
+
]
|
|
259
|
+
};
|
|
260
|
+
const AssetTypeNameToId = /* @__PURE__ */ new Map();
|
|
261
|
+
for (let i = 0; i < AssetTypes.length; i++) {
|
|
262
|
+
const name = AssetTypes[i];
|
|
263
|
+
AssetTypeNameToId.set(name, i);
|
|
264
|
+
}
|
|
265
|
+
const ActualBundleTypes = [
|
|
266
|
+
//names used by Roblox
|
|
267
|
+
"",
|
|
268
|
+
"Avatar",
|
|
269
|
+
//traditional bundle
|
|
270
|
+
"DynamicHead",
|
|
271
|
+
"Avatar",
|
|
272
|
+
//outfit
|
|
273
|
+
"Shoes",
|
|
274
|
+
"Avatar"
|
|
275
|
+
//animation pack
|
|
276
|
+
];
|
|
277
|
+
const BundleTypes = [
|
|
278
|
+
"",
|
|
279
|
+
"Character",
|
|
280
|
+
"DynamicHead",
|
|
281
|
+
"Outfit",
|
|
282
|
+
"Shoes",
|
|
283
|
+
"AnimationPack",
|
|
284
|
+
"",
|
|
285
|
+
"MakeupLook"
|
|
286
|
+
];
|
|
287
|
+
const CatalogBundleTypes = [
|
|
288
|
+
"",
|
|
289
|
+
"Character",
|
|
290
|
+
"AnimationPack",
|
|
291
|
+
"Shoes",
|
|
292
|
+
"DynamicHead"
|
|
293
|
+
];
|
|
25
294
|
const BrickColors = {
|
|
26
295
|
1: "#F2F3F3",
|
|
27
296
|
2: "#A1A5A2",
|
|
@@ -338,7 +607,9 @@ const MaxPerAsset = {
|
|
|
338
607
|
"WalkAnimation": 1,
|
|
339
608
|
"LayeredClothing": 5,
|
|
340
609
|
//group type
|
|
341
|
-
"MoodAnimation": 1
|
|
610
|
+
"MoodAnimation": 1,
|
|
611
|
+
"EyebrowAccessory": 1,
|
|
612
|
+
"EyelashAccessory": 1
|
|
342
613
|
};
|
|
343
614
|
const OutfitOrigin = {
|
|
344
615
|
"WebAvatar": "WebAvatar",
|
|
@@ -32408,7 +32679,7 @@ function nearestSearch(node, target, best = { dist: Infinity, index: -1 }) {
|
|
|
32408
32679
|
}
|
|
32409
32680
|
return best;
|
|
32410
32681
|
}
|
|
32411
|
-
const jsContent = '(function() {\n "use strict";\n new TextDecoder();\n new TextDecoder();\n const FullBodyColorPalette = [\n {\n "brickColorId": 361,\n "hexColor": "#564236",\n "name": "Dirt brown"\n },\n {\n "brickColorId": 192,\n "hexColor": "#694028",\n "name": "Reddish brown"\n },\n {\n "brickColorId": 217,\n "hexColor": "#7C5C46",\n "name": "Brown"\n },\n {\n "brickColorId": 153,\n "hexColor": "#957977",\n "name": "Sand red"\n },\n {\n "brickColorId": 359,\n "hexColor": "#AF9483",\n "name": "Linen"\n },\n {\n "brickColorId": 352,\n "hexColor": "#C7AC78",\n "name": "Burlap"\n },\n {\n "brickColorId": 5,\n "hexColor": "#D7C59A",\n "name": "Brick yellow"\n },\n {\n "brickColorId": 101,\n "hexColor": "#DA867A",\n "name": "Medium red"\n },\n {\n "brickColorId": 1007,\n "hexColor": "#A34B4B",\n "name": "Dusty Rose"\n },\n {\n "brickColorId": 1014,\n "hexColor": "#AA5500",\n "name": "CGA brown"\n },\n {\n "brickColorId": 38,\n "hexColor": "#A05F35",\n "name": "Dark orange"\n },\n {\n "brickColorId": 18,\n "hexColor": "#CC8E69",\n "name": "Nougat"\n },\n {\n "brickColorId": 125,\n "hexColor": "#EAB892",\n "name": "Light orange"\n },\n {\n "brickColorId": 1030,\n "hexColor": "#FFCC99",\n "name": "Pastel brown"\n },\n {\n "brickColorId": 133,\n "hexColor": "#D5733D",\n "name": "Neon orange"\n },\n {\n "brickColorId": 106,\n "hexColor": "#DA8541",\n "name": "Bright orange"\n },\n {\n "brickColorId": 105,\n "hexColor": "#E29B40",\n "name": "Br. yellowish orange"\n },\n {\n "brickColorId": 1017,\n "hexColor": "#FFAF00",\n "name": "Deep orange"\n },\n {\n "brickColorId": 24,\n "hexColor": "#F5CD30",\n "name": "Bright yellow"\n },\n {\n "brickColorId": 334,\n "hexColor": "#F8D96D",\n "name": "Daisy orange"\n },\n {\n "brickColorId": 226,\n "hexColor": "#FDEA8D",\n "name": "Cool yellow"\n },\n {\n "brickColorId": 141,\n "hexColor": "#27462D",\n "name": "Earth green"\n },\n {\n "brickColorId": 1021,\n "hexColor": "#3A7D15",\n "name": "Camo"\n },\n {\n "brickColorId": 28,\n "hexColor": "#287F47",\n "name": "Dark green"\n },\n {\n "brickColorId": 37,\n "hexColor": "#4B974B",\n "name": "Bright green"\n },\n {\n "brickColorId": 310,\n "hexColor": "#5B9A4C",\n "name": "Shamrock"\n },\n {\n "brickColorId": 317,\n "hexColor": "#7C9C6B",\n "name": "Moss"\n },\n {\n "brickColorId": 119,\n "hexColor": "#A4BD47",\n "name": "Br. yellowish green"\n },\n {\n "brickColorId": 1011,\n "hexColor": "#002060",\n "name": "Navy blue"\n },\n {\n "brickColorId": 1012,\n "hexColor": "#2154B9",\n "name": "Deep blue"\n },\n {\n "brickColorId": 1010,\n "hexColor": "#0000FF",\n "name": "Really blue"\n },\n {\n "brickColorId": 23,\n "hexColor": "#0D69AC",\n "name": "Bright blue"\n },\n {\n "brickColorId": 305,\n "hexColor": "#527CAE",\n "name": "Steel blue"\n },\n {\n "brickColorId": 102,\n "hexColor": "#6E99CA",\n "name": "Medium blue"\n },\n {\n "brickColorId": 45,\n "hexColor": "#B4D2E4",\n "name": "Light blue"\n },\n {\n "brickColorId": 107,\n "hexColor": "#008F9C",\n "name": "Bright bluish green"\n },\n {\n "brickColorId": 1018,\n "hexColor": "#12EED4",\n "name": "Teal"\n },\n {\n "brickColorId": 1027,\n "hexColor": "#9FF3E9",\n "name": "Pastel blue-green"\n },\n {\n "brickColorId": 1019,\n "hexColor": "#00FFFF",\n "name": "Toothpaste"\n },\n {\n "brickColorId": 1013,\n "hexColor": "#04AFEC",\n "name": "Cyan"\n },\n {\n "brickColorId": 11,\n "hexColor": "#80BBDC",\n "name": "Pastel Blue"\n },\n {\n "brickColorId": 1024,\n "hexColor": "#AFDDFF",\n "name": "Pastel light blue"\n },\n {\n "brickColorId": 104,\n "hexColor": "#6B327C",\n "name": "Bright violet"\n },\n {\n "brickColorId": 1023,\n "hexColor": "#8C5B9F",\n "name": "Lavender"\n },\n {\n "brickColorId": 321,\n "hexColor": "#A75E9B",\n "name": "Lilac"\n },\n {\n "brickColorId": 1015,\n "hexColor": "#AA00AA",\n "name": "Magenta"\n },\n {\n "brickColorId": 1031,\n "hexColor": "#6225D1",\n "name": "Royal purple"\n },\n {\n "brickColorId": 1006,\n "hexColor": "#B480FF",\n "name": "Alder"\n },\n {\n "brickColorId": 1026,\n "hexColor": "#B1A7FF",\n "name": "Pastel violet"\n },\n {\n "brickColorId": 21,\n "hexColor": "#C4281C",\n "name": "Bright red"\n },\n {\n "brickColorId": 1004,\n "hexColor": "#FF0000",\n "name": "Really red"\n },\n {\n "brickColorId": 1032,\n "hexColor": "#FF00BF",\n "name": "Hot pink"\n },\n {\n "brickColorId": 1016,\n "hexColor": "#FF66CC",\n "name": "Pink"\n },\n {\n "brickColorId": 330,\n "hexColor": "#FF98DC",\n "name": "Carnation pink"\n },\n {\n "brickColorId": 9,\n "hexColor": "#E8BAC8",\n "name": "Light reddish violet"\n },\n {\n "brickColorId": 1025,\n "hexColor": "#FFC9C9",\n "name": "Pastel orange"\n },\n {\n "brickColorId": 364,\n "hexColor": "#5A4C42",\n "name": "Dark taupe"\n },\n {\n "brickColorId": 351,\n "hexColor": "#BC9B5D",\n "name": "Cork"\n },\n {\n "brickColorId": 1008,\n "hexColor": "#C1BE42",\n "name": "Olive"\n },\n {\n "brickColorId": 29,\n "hexColor": "#A1C48C",\n "name": "Medium green"\n },\n {\n "brickColorId": 1022,\n "hexColor": "#7F8E64",\n "name": "Grime"\n },\n {\n "brickColorId": 151,\n "hexColor": "#789082",\n "name": "Sand green"\n },\n {\n "brickColorId": 135,\n "hexColor": "#74869D",\n "name": "Sand blue"\n },\n {\n "brickColorId": 1020,\n "hexColor": "#00FF00",\n "name": "Lime green"\n },\n {\n "brickColorId": 1028,\n "hexColor": "#CCFFCC",\n "name": "Pastel green"\n },\n {\n "brickColorId": 1009,\n "hexColor": "#FFFF00",\n "name": "New Yeller"\n },\n {\n "brickColorId": 1029,\n "hexColor": "#FFFFCC",\n "name": "Pastel yellow"\n },\n {\n "brickColorId": 1003,\n "hexColor": "#111111",\n "name": "Really black"\n },\n {\n "brickColorId": 26,\n "hexColor": "#1B2A35",\n "name": "Black"\n },\n {\n "brickColorId": 199,\n "hexColor": "#635F62",\n "name": "Dark stone grey"\n },\n {\n "brickColorId": 194,\n "hexColor": "#A3A2A5",\n "name": "Medium stone grey"\n },\n {\n "brickColorId": 1002,\n "hexColor": "#CDCDCD",\n "name": "Mid gray"\n },\n {\n "brickColorId": 208,\n "hexColor": "#E5E4DF",\n "name": "Light stone grey"\n },\n {\n "brickColorId": 1,\n "hexColor": "#F2F3F3",\n "name": "White"\n },\n {\n "brickColorId": 1001,\n "hexColor": "#F8F8F8",\n "name": "Institutional white"\n }\n ];\n const RegularBodyColors = [\n "5A4C42",\n "7C5C46",\n "AF9483",\n "CC8E69",\n "EAB892",\n "564236",\n "694028",\n "BC9B5D",\n "c7ac78",\n "d7c59a",\n "957977",\n "a34b4b",\n "da867a",\n "ffc9c9",\n "ff98dc",\n "74869d",\n "527cae",\n "80bbdc",\n "b1a7ff",\n "a75e9b",\n "008f9c",\n "5b9a4c",\n "7c9c6b",\n "a1c48c",\n "e29b40",\n "f5cd30",\n "f8d96d",\n "635f62",\n "cdcdcd",\n "f8f8f8"\n ];\n for (let i = 0; i < RegularBodyColors.length; i++) {\n const color = RegularBodyColors[i];\n RegularBodyColors[i] = color.toUpperCase();\n }\n const FullBodyColors = [];\n for (const colorDetails of FullBodyColorPalette) {\n FullBodyColors.push(colorDetails.hexColor.substring(1));\n }\n function calculateMagnitude3D(x, y, z) {\n return Math.sqrt(x * x + y * y + z * z);\n }\n function magnitude(v) {\n return calculateMagnitude3D(v[0], v[1], v[2]);\n }\n function minus(v0, v1) {\n return [v0[0] - v1[0], v0[1] - v1[1], v0[2] - v1[2]];\n }\n function distance(v0, v1) {\n return magnitude(minus(v1, v0));\n }\n class KDNode {\n point;\n index;\n axis;\n left = null;\n right = null;\n constructor(point, index, axis) {\n this.point = point;\n this.index = index;\n this.axis = axis;\n }\n }\n function buildKDTree(points, indices, depth = 0) {\n if (points.length === 0) return null;\n const axis = depth % 3;\n const sorted = points.map((p, i) => ({ p, index: indices[i] })).sort((a, b) => a.p[axis] - b.p[axis]);\n const mid = Math.floor(sorted.length / 2);\n const node = new KDNode(sorted[mid].p, sorted[mid].index, axis);\n const leftPoints = sorted.slice(0, mid).map((x) => x.p);\n const leftIndices = sorted.slice(0, mid).map((x) => x.index);\n const rightPoints = sorted.slice(mid + 1).map((x) => x.p);\n const rightIndices = sorted.slice(mid + 1).map((x) => x.index);\n node.left = buildKDTree(leftPoints, leftIndices, depth + 1);\n node.right = buildKDTree(rightPoints, rightIndices, depth + 1);\n return node;\n }\n function siftUp(heap, i) {\n while (i > 0) {\n const p = i - 1 >> 1;\n if (heap[p].dist >= heap[i].dist) break;\n const tmp = heap[p];\n heap[p] = heap[i];\n heap[i] = tmp;\n i = p;\n }\n }\n function siftDown(heap, i) {\n const n = heap.length;\n while (true) {\n let largest = i;\n const l = (i << 1) + 1;\n const r = l + 1;\n if (l < n && heap[l].dist > heap[largest].dist) largest = l;\n if (r < n && heap[r].dist > heap[largest].dist) largest = r;\n if (largest === i) break;\n const tmp = heap[i];\n heap[i] = heap[largest];\n heap[largest] = tmp;\n i = largest;\n }\n }\n function heapPushMax(heap, item, k) {\n if (heap.length < k) {\n heap.push(item);\n siftUp(heap, heap.length - 1);\n return;\n }\n if (item.dist >= heap[0].dist) return;\n heap[0] = item;\n siftDown(heap, 0);\n }\n function distSq(a, b) {\n const dx = a[0] - b[0];\n const dy = a[1] - b[1];\n const dz = a[2] - b[2];\n return dx * dx + dy * dy + dz * dz;\n }\n function knnSearch(node, target, k, heap = []) {\n if (!node) return heap;\n const axis = node.axis;\n const dist = distSq(target, node.point);\n heapPushMax(heap, { dist, index: node.index }, k);\n const diff = target[axis] - node.point[axis];\n const primary = diff < 0 ? node.left : node.right;\n const secondary = diff < 0 ? node.right : node.left;\n knnSearch(primary, target, k, heap);\n const worstDist = heap.length < k ? Infinity : heap[0].dist;\n if (diff * diff < worstDist) {\n knnSearch(secondary, target, k, heap);\n }\n if (node === null) {\n heap.sort((a, b) => a.dist - b.dist);\n }\n return heap;\n }\n function nearestSearch(node, target, best = { dist: Infinity, index: -1 }) {\n if (!node) return best;\n const dist = distance(target, node.point);\n if (dist < best.dist) {\n best = { dist, index: node.index };\n }\n const axis = node.axis;\n const diff = target[axis] - node.point[axis];\n const primary = diff < 0 ? node.left : node.right;\n const secondary = diff < 0 ? node.right : node.left;\n best = nearestSearch(primary, target, best);\n if (Math.abs(diff) < best.dist) {\n best = nearestSearch(secondary, target, best);\n }\n return best;\n }\n function luDecompose(A) {\n const n = A.length;\n const LU = A;\n const P = new Int32Array(n);\n for (let i = 0; i < n; i++) P[i] = i;\n for (let k = 0; k < n; k++) {\n let pivot = k;\n for (let i = k + 1; i < n; i++) {\n if (Math.abs(LU[i][k]) > Math.abs(LU[pivot][k])) {\n pivot = i;\n }\n }\n if (pivot !== k) {\n const tmpRow = LU[k];\n LU[k] = LU[pivot];\n LU[pivot] = tmpRow;\n const tmpP = P[k];\n P[k] = P[pivot];\n P[pivot] = tmpP;\n }\n const pivotVal = LU[k][k];\n for (let i = k + 1; i < n; i++) {\n LU[i][k] /= pivotVal;\n const mult = LU[i][k];\n const rowI = LU[i];\n const rowK = LU[k];\n for (let j = k + 1; j < n; j++) {\n rowI[j] -= mult * rowK[j];\n }\n }\n }\n return { LU, P };\n }\n function luSolve({ LU, P }, b) {\n const n = LU.length;\n const x = new Float32Array(n);\n for (let i = 0; i < n; i++) {\n x[i] = b[P[i]];\n }\n for (let i = 0; i < n; i++) {\n const row = LU[i];\n let sum = x[i];\n for (let j = 0; j < i; j++) {\n sum -= row[j] * x[j];\n }\n x[i] = sum;\n }\n for (let i = n - 1; i >= 0; i--) {\n const row = LU[i];\n let sum = x[i];\n for (let j = i + 1; j < n; j++) {\n sum -= row[j] * x[j];\n }\n x[i] = sum / row[i];\n }\n return x;\n }\n function patchRBFWorkerFunc([_A, _bx, _by, _bz]) {\n const A = _A.map((r) => new Float32Array(r));\n const bx = new Float32Array(_bx);\n const by = new Float32Array(_by);\n const bz = new Float32Array(_bz);\n const LU = luDecompose(A);\n const wx = luSolve(LU, bx);\n const wy = luSolve(LU, by);\n const wz = luSolve(LU, bz);\n const n = wx.length;\n const result = new Float32Array(n * 3);\n for (let i = 0; i < n; i++) {\n result[i * 3 + 0] = wx[i];\n result[i * 3 + 1] = wy[i];\n result[i * 3 + 2] = wz[i];\n }\n return result.buffer;\n }\n function RBFDeformerSolveAsync([patchCount, detailsCount, epsilon, importantIndicesBuf, refVertsBuf, distVertsBuf, meshVertsBuf, meshBonesBuf]) {\n const importantIndices = new Uint16Array(importantIndicesBuf);\n const refVerts = new Float32Array(refVertsBuf);\n const distVerts = new Float32Array(distVertsBuf);\n const meshVerts = new Float32Array(meshVertsBuf);\n const meshBones = new Float32Array(meshBonesBuf);\n const refCount = refVerts.length / 3;\n const meshVertCount = meshVerts.length / 3;\n const meshBoneCount = meshBones.length / 3;\n const points = new Array(refCount);\n const indices = new Array(refCount);\n for (let i = 0; i < refCount; i++) {\n const refPos = [refVerts[i * 3 + 0], refVerts[i * 3 + 1], refVerts[i * 3 + 2]];\n points[i] = refPos;\n indices[i] = i;\n }\n const controlKD = buildKDTree(points, indices);\n const step = Math.max(1, Math.floor(refCount / patchCount));\n const patchCenters = [];\n for (let i = 0; i < refCount; i += step) {\n const refPos = [refVerts[i * 3 + 0], refVerts[i * 3 + 1], refVerts[i * 3 + 2]];\n patchCenters.push(refPos);\n if (patchCenters.length >= patchCount) break;\n }\n const neighborIndices = new Array(patchCenters.length);\n const weights = new Array(patchCenters.length);\n const patchIndices = patchCenters.map((_, i) => i);\n const patchKD = buildKDTree(patchCenters, patchIndices);\n const isUsedArr = new Array(patchCenters.length).fill(false);\n const nearestPatch = new Uint16Array(meshVertCount + meshBoneCount);\n for (let i = 0; i < meshVertCount; i++) {\n const vec = [meshVerts[i * 3 + 0], meshVerts[i * 3 + 1], meshVerts[i * 3 + 2]];\n const nearestPatchNode = nearestSearch(patchKD, vec);\n isUsedArr[nearestPatchNode.index] = true;\n nearestPatch[i] = nearestPatchNode.index;\n }\n for (let i = 0; i < meshBoneCount; i++) {\n const vec = [meshBones[i * 3 + 0], meshBones[i * 3 + 1], meshBones[i * 3 + 2]];\n const nearestPatchNode = nearestSearch(patchKD, vec);\n isUsedArr[nearestPatchNode.index] = true;\n nearestPatch[i + meshVertCount] = nearestPatchNode.index;\n }\n for (let i = 0; i < patchCenters.length; i++) {\n if (!isUsedArr[i]) {\n continue;\n }\n const centerPos = patchCenters[i];\n const neighbors = knnSearch(controlKD, centerPos, detailsCount);\n const foundNeighborIndices = neighbors.map((n) => n.index);\n for (const important of importantIndices) {\n if (!foundNeighborIndices.includes(important)) {\n foundNeighborIndices.push(important);\n }\n }\n neighborIndices[i] = new Uint16Array(foundNeighborIndices);\n }\n const A_array = new Array(patchCenters.length);\n for (let p = 0; p < patchCenters.length; p++) {\n const patchNeighborIndices = neighborIndices[p];\n if (!patchNeighborIndices) continue;\n const K = patchNeighborIndices.length;\n const positions = new Array(patchNeighborIndices.length);\n for (let i = 0; i < patchNeighborIndices.length; i++) {\n const j = patchNeighborIndices[i];\n const refPos = [refVerts[j * 3 + 0], refVerts[j * 3 + 1], refVerts[j * 3 + 2]];\n positions[i] = refPos;\n }\n const A = new Array(K);\n for (let i = 0; i < K; i++) {\n A[i] = new Float32Array(K);\n }\n for (let i = 0; i < K; i++) {\n const [pix, piy, piz] = positions[i];\n for (let j = i + 1; j < K; j++) {\n const [pjx, pjy, pjz] = positions[j];\n const dist = Math.sqrt((pix - pjx) * (pix - pjx) + (piy - pjy) * (piy - pjy) + (piz - pjz) * (piz - pjz));\n A[i][j] = dist;\n A[j][i] = dist;\n }\n A[i][i] = epsilon;\n }\n A_array[p] = A;\n }\n for (let p = 0; p < patchCenters.length; p++) {\n if (!isUsedArr[p]) {\n continue;\n }\n const patchNeighborIndices = neighborIndices[p];\n const K = patchNeighborIndices.length;\n const usedRef = new Array(K);\n const usedDist = new Array(K);\n for (let i = 0; i < K; i++) {\n const idx = patchNeighborIndices[i];\n const j = idx;\n const refPos = [refVerts[j * 3 + 0], refVerts[j * 3 + 1], refVerts[j * 3 + 2]];\n const distPos = [distVerts[j * 3 + 0], distVerts[j * 3 + 1], distVerts[j * 3 + 2]];\n usedRef[i] = refPos;\n usedDist[i] = distPos;\n }\n const A = A_array[p];\n const bx = new Float32Array(K);\n const by = new Float32Array(K);\n const bz = new Float32Array(K);\n for (let i = 0; i < K; i++) {\n const dr = usedDist[i];\n const rr = usedRef[i];\n bx[i] = dr[0] - rr[0];\n by[i] = dr[1] - rr[1];\n bz[i] = dr[2] - rr[2];\n }\n const Abuffers = A.map((r) => r.buffer);\n weights[p] = new Float32Array(patchRBFWorkerFunc([Abuffers, bx.buffer, by.buffer, bz.buffer]));\n }\n const neighborIndicesBuf = neighborIndices.map((a) => {\n return a.buffer;\n });\n const weightsBuf = weights.map((a) => {\n return a.buffer;\n });\n return [neighborIndicesBuf, weightsBuf, nearestPatch.buffer];\n }\n const WorkerTypeToFunction = {\n "patchRBF": patchRBFWorkerFunc,\n "RBFDeformerSolveAsync": RBFDeformerSolveAsync\n };\n function getWorkerOnMessage() {\n return function(event) {\n const [id, type, data] = event.data;\n const func = WorkerTypeToFunction[type];\n self.postMessage([id, func(data)]);\n };\n }\n onmessage = getWorkerOnMessage();\n})();\n';
|
|
32682
|
+
const jsContent = '(function() {\n "use strict";\n new TextDecoder();\n new TextDecoder();\n const AssetTypes = [\n "",\n "Image",\n "TShirt",\n "Audio",\n "Mesh",\n "Lua",\n "HTML",\n "Text",\n "Hat",\n "Place",\n "Model",\n "Shirt",\n "Pants",\n "Decal",\n "",\n "",\n "Avatar",\n "Head",\n "Face",\n "Gear",\n "",\n "Badge",\n "GroupEmblem",\n "",\n "Animation",\n "Arms",\n "Legs",\n "Torso",\n "RightArm",\n "LeftArm",\n "LeftLeg",\n "RightLeg",\n "Package",\n "YouTubeVideo",\n "GamePass",\n "App",\n "",\n "Code",\n "Plugin",\n "SolidModel",\n "MeshPart",\n "HairAccessory",\n "FaceAccessory",\n "NeckAccessory",\n "ShoulderAccessory",\n "FrontAccessory",\n "BackAccessory",\n "WaistAccessory",\n "ClimbAnimation",\n "DeathAnimation",\n "FallAnimation",\n "IdleAnimation",\n "JumpAnimation",\n "RunAnimation",\n "SwimAnimation",\n "WalkAnimation",\n "PoseAnimation",\n "",\n "",\n "LocalizationTableManifest",\n "LocalizationTableTranslation",\n "EmoteAnimation",\n "Video",\n "TexturePack",\n "TShirtAccessory",\n "ShirtAccessory",\n "PantsAccessory",\n "JacketAccessory",\n "SweaterAccessory",\n "ShortsAccessory",\n "LeftShoeAccessory",\n "RightShoeAccessory",\n "DressSkirtAccessory",\n "FontFamily",\n "FontFace",\n "MeshHiddenSurfaceRemoval",\n "EyebrowAccessory",\n "EyelashAccessory",\n "MoodAnimation",\n "DynamicHead",\n //79\n "CodeSnippet",\n "AdsVideo",\n "OtaUpdate",\n "Screenshot",\n "RuntimePropertySet",\n "StorePreviewVideo",\n "GamePreviewVideo",\n "CreatorExperienceConfig",\n "FaceMakeup",\n "LipMakeup",\n "EyeMakeup",\n "VoxelFragment",\n "AvatarBackground",\n "TextDocument"\n ];\n const AssetTypeNameToId = /* @__PURE__ */ new Map();\n for (let i = 0; i < AssetTypes.length; i++) {\n const name = AssetTypes[i];\n AssetTypeNameToId.set(name, i);\n }\n const FullBodyColorPalette = [\n {\n "brickColorId": 361,\n "hexColor": "#564236",\n "name": "Dirt brown"\n },\n {\n "brickColorId": 192,\n "hexColor": "#694028",\n "name": "Reddish brown"\n },\n {\n "brickColorId": 217,\n "hexColor": "#7C5C46",\n "name": "Brown"\n },\n {\n "brickColorId": 153,\n "hexColor": "#957977",\n "name": "Sand red"\n },\n {\n "brickColorId": 359,\n "hexColor": "#AF9483",\n "name": "Linen"\n },\n {\n "brickColorId": 352,\n "hexColor": "#C7AC78",\n "name": "Burlap"\n },\n {\n "brickColorId": 5,\n "hexColor": "#D7C59A",\n "name": "Brick yellow"\n },\n {\n "brickColorId": 101,\n "hexColor": "#DA867A",\n "name": "Medium red"\n },\n {\n "brickColorId": 1007,\n "hexColor": "#A34B4B",\n "name": "Dusty Rose"\n },\n {\n "brickColorId": 1014,\n "hexColor": "#AA5500",\n "name": "CGA brown"\n },\n {\n "brickColorId": 38,\n "hexColor": "#A05F35",\n "name": "Dark orange"\n },\n {\n "brickColorId": 18,\n "hexColor": "#CC8E69",\n "name": "Nougat"\n },\n {\n "brickColorId": 125,\n "hexColor": "#EAB892",\n "name": "Light orange"\n },\n {\n "brickColorId": 1030,\n "hexColor": "#FFCC99",\n "name": "Pastel brown"\n },\n {\n "brickColorId": 133,\n "hexColor": "#D5733D",\n "name": "Neon orange"\n },\n {\n "brickColorId": 106,\n "hexColor": "#DA8541",\n "name": "Bright orange"\n },\n {\n "brickColorId": 105,\n "hexColor": "#E29B40",\n "name": "Br. yellowish orange"\n },\n {\n "brickColorId": 1017,\n "hexColor": "#FFAF00",\n "name": "Deep orange"\n },\n {\n "brickColorId": 24,\n "hexColor": "#F5CD30",\n "name": "Bright yellow"\n },\n {\n "brickColorId": 334,\n "hexColor": "#F8D96D",\n "name": "Daisy orange"\n },\n {\n "brickColorId": 226,\n "hexColor": "#FDEA8D",\n "name": "Cool yellow"\n },\n {\n "brickColorId": 141,\n "hexColor": "#27462D",\n "name": "Earth green"\n },\n {\n "brickColorId": 1021,\n "hexColor": "#3A7D15",\n "name": "Camo"\n },\n {\n "brickColorId": 28,\n "hexColor": "#287F47",\n "name": "Dark green"\n },\n {\n "brickColorId": 37,\n "hexColor": "#4B974B",\n "name": "Bright green"\n },\n {\n "brickColorId": 310,\n "hexColor": "#5B9A4C",\n "name": "Shamrock"\n },\n {\n "brickColorId": 317,\n "hexColor": "#7C9C6B",\n "name": "Moss"\n },\n {\n "brickColorId": 119,\n "hexColor": "#A4BD47",\n "name": "Br. yellowish green"\n },\n {\n "brickColorId": 1011,\n "hexColor": "#002060",\n "name": "Navy blue"\n },\n {\n "brickColorId": 1012,\n "hexColor": "#2154B9",\n "name": "Deep blue"\n },\n {\n "brickColorId": 1010,\n "hexColor": "#0000FF",\n "name": "Really blue"\n },\n {\n "brickColorId": 23,\n "hexColor": "#0D69AC",\n "name": "Bright blue"\n },\n {\n "brickColorId": 305,\n "hexColor": "#527CAE",\n "name": "Steel blue"\n },\n {\n "brickColorId": 102,\n "hexColor": "#6E99CA",\n "name": "Medium blue"\n },\n {\n "brickColorId": 45,\n "hexColor": "#B4D2E4",\n "name": "Light blue"\n },\n {\n "brickColorId": 107,\n "hexColor": "#008F9C",\n "name": "Bright bluish green"\n },\n {\n "brickColorId": 1018,\n "hexColor": "#12EED4",\n "name": "Teal"\n },\n {\n "brickColorId": 1027,\n "hexColor": "#9FF3E9",\n "name": "Pastel blue-green"\n },\n {\n "brickColorId": 1019,\n "hexColor": "#00FFFF",\n "name": "Toothpaste"\n },\n {\n "brickColorId": 1013,\n "hexColor": "#04AFEC",\n "name": "Cyan"\n },\n {\n "brickColorId": 11,\n "hexColor": "#80BBDC",\n "name": "Pastel Blue"\n },\n {\n "brickColorId": 1024,\n "hexColor": "#AFDDFF",\n "name": "Pastel light blue"\n },\n {\n "brickColorId": 104,\n "hexColor": "#6B327C",\n "name": "Bright violet"\n },\n {\n "brickColorId": 1023,\n "hexColor": "#8C5B9F",\n "name": "Lavender"\n },\n {\n "brickColorId": 321,\n "hexColor": "#A75E9B",\n "name": "Lilac"\n },\n {\n "brickColorId": 1015,\n "hexColor": "#AA00AA",\n "name": "Magenta"\n },\n {\n "brickColorId": 1031,\n "hexColor": "#6225D1",\n "name": "Royal purple"\n },\n {\n "brickColorId": 1006,\n "hexColor": "#B480FF",\n "name": "Alder"\n },\n {\n "brickColorId": 1026,\n "hexColor": "#B1A7FF",\n "name": "Pastel violet"\n },\n {\n "brickColorId": 21,\n "hexColor": "#C4281C",\n "name": "Bright red"\n },\n {\n "brickColorId": 1004,\n "hexColor": "#FF0000",\n "name": "Really red"\n },\n {\n "brickColorId": 1032,\n "hexColor": "#FF00BF",\n "name": "Hot pink"\n },\n {\n "brickColorId": 1016,\n "hexColor": "#FF66CC",\n "name": "Pink"\n },\n {\n "brickColorId": 330,\n "hexColor": "#FF98DC",\n "name": "Carnation pink"\n },\n {\n "brickColorId": 9,\n "hexColor": "#E8BAC8",\n "name": "Light reddish violet"\n },\n {\n "brickColorId": 1025,\n "hexColor": "#FFC9C9",\n "name": "Pastel orange"\n },\n {\n "brickColorId": 364,\n "hexColor": "#5A4C42",\n "name": "Dark taupe"\n },\n {\n "brickColorId": 351,\n "hexColor": "#BC9B5D",\n "name": "Cork"\n },\n {\n "brickColorId": 1008,\n "hexColor": "#C1BE42",\n "name": "Olive"\n },\n {\n "brickColorId": 29,\n "hexColor": "#A1C48C",\n "name": "Medium green"\n },\n {\n "brickColorId": 1022,\n "hexColor": "#7F8E64",\n "name": "Grime"\n },\n {\n "brickColorId": 151,\n "hexColor": "#789082",\n "name": "Sand green"\n },\n {\n "brickColorId": 135,\n "hexColor": "#74869D",\n "name": "Sand blue"\n },\n {\n "brickColorId": 1020,\n "hexColor": "#00FF00",\n "name": "Lime green"\n },\n {\n "brickColorId": 1028,\n "hexColor": "#CCFFCC",\n "name": "Pastel green"\n },\n {\n "brickColorId": 1009,\n "hexColor": "#FFFF00",\n "name": "New Yeller"\n },\n {\n "brickColorId": 1029,\n "hexColor": "#FFFFCC",\n "name": "Pastel yellow"\n },\n {\n "brickColorId": 1003,\n "hexColor": "#111111",\n "name": "Really black"\n },\n {\n "brickColorId": 26,\n "hexColor": "#1B2A35",\n "name": "Black"\n },\n {\n "brickColorId": 199,\n "hexColor": "#635F62",\n "name": "Dark stone grey"\n },\n {\n "brickColorId": 194,\n "hexColor": "#A3A2A5",\n "name": "Medium stone grey"\n },\n {\n "brickColorId": 1002,\n "hexColor": "#CDCDCD",\n "name": "Mid gray"\n },\n {\n "brickColorId": 208,\n "hexColor": "#E5E4DF",\n "name": "Light stone grey"\n },\n {\n "brickColorId": 1,\n "hexColor": "#F2F3F3",\n "name": "White"\n },\n {\n "brickColorId": 1001,\n "hexColor": "#F8F8F8",\n "name": "Institutional white"\n }\n ];\n const RegularBodyColors = [\n "5A4C42",\n "7C5C46",\n "AF9483",\n "CC8E69",\n "EAB892",\n "564236",\n "694028",\n "BC9B5D",\n "c7ac78",\n "d7c59a",\n "957977",\n "a34b4b",\n "da867a",\n "ffc9c9",\n "ff98dc",\n "74869d",\n "527cae",\n "80bbdc",\n "b1a7ff",\n "a75e9b",\n "008f9c",\n "5b9a4c",\n "7c9c6b",\n "a1c48c",\n "e29b40",\n "f5cd30",\n "f8d96d",\n "635f62",\n "cdcdcd",\n "f8f8f8"\n ];\n for (let i = 0; i < RegularBodyColors.length; i++) {\n const color = RegularBodyColors[i];\n RegularBodyColors[i] = color.toUpperCase();\n }\n const FullBodyColors = [];\n for (const colorDetails of FullBodyColorPalette) {\n FullBodyColors.push(colorDetails.hexColor.substring(1));\n }\n function calculateMagnitude3D(x, y, z) {\n return Math.sqrt(x * x + y * y + z * z);\n }\n function magnitude(v) {\n return calculateMagnitude3D(v[0], v[1], v[2]);\n }\n function minus(v0, v1) {\n return [v0[0] - v1[0], v0[1] - v1[1], v0[2] - v1[2]];\n }\n function distance(v0, v1) {\n return magnitude(minus(v1, v0));\n }\n class KDNode {\n point;\n index;\n axis;\n left = null;\n right = null;\n constructor(point, index, axis) {\n this.point = point;\n this.index = index;\n this.axis = axis;\n }\n }\n function buildKDTree(points, indices, depth = 0) {\n if (points.length === 0) return null;\n const axis = depth % 3;\n const sorted = points.map((p, i) => ({ p, index: indices[i] })).sort((a, b) => a.p[axis] - b.p[axis]);\n const mid = Math.floor(sorted.length / 2);\n const node = new KDNode(sorted[mid].p, sorted[mid].index, axis);\n const leftPoints = sorted.slice(0, mid).map((x) => x.p);\n const leftIndices = sorted.slice(0, mid).map((x) => x.index);\n const rightPoints = sorted.slice(mid + 1).map((x) => x.p);\n const rightIndices = sorted.slice(mid + 1).map((x) => x.index);\n node.left = buildKDTree(leftPoints, leftIndices, depth + 1);\n node.right = buildKDTree(rightPoints, rightIndices, depth + 1);\n return node;\n }\n function siftUp(heap, i) {\n while (i > 0) {\n const p = i - 1 >> 1;\n if (heap[p].dist >= heap[i].dist) break;\n const tmp = heap[p];\n heap[p] = heap[i];\n heap[i] = tmp;\n i = p;\n }\n }\n function siftDown(heap, i) {\n const n = heap.length;\n while (true) {\n let largest = i;\n const l = (i << 1) + 1;\n const r = l + 1;\n if (l < n && heap[l].dist > heap[largest].dist) largest = l;\n if (r < n && heap[r].dist > heap[largest].dist) largest = r;\n if (largest === i) break;\n const tmp = heap[i];\n heap[i] = heap[largest];\n heap[largest] = tmp;\n i = largest;\n }\n }\n function heapPushMax(heap, item, k) {\n if (heap.length < k) {\n heap.push(item);\n siftUp(heap, heap.length - 1);\n return;\n }\n if (item.dist >= heap[0].dist) return;\n heap[0] = item;\n siftDown(heap, 0);\n }\n function distSq(a, b) {\n const dx = a[0] - b[0];\n const dy = a[1] - b[1];\n const dz = a[2] - b[2];\n return dx * dx + dy * dy + dz * dz;\n }\n function knnSearch(node, target, k, heap = []) {\n if (!node) return heap;\n const axis = node.axis;\n const dist = distSq(target, node.point);\n heapPushMax(heap, { dist, index: node.index }, k);\n const diff = target[axis] - node.point[axis];\n const primary = diff < 0 ? node.left : node.right;\n const secondary = diff < 0 ? node.right : node.left;\n knnSearch(primary, target, k, heap);\n const worstDist = heap.length < k ? Infinity : heap[0].dist;\n if (diff * diff < worstDist) {\n knnSearch(secondary, target, k, heap);\n }\n if (node === null) {\n heap.sort((a, b) => a.dist - b.dist);\n }\n return heap;\n }\n function nearestSearch(node, target, best = { dist: Infinity, index: -1 }) {\n if (!node) return best;\n const dist = distance(target, node.point);\n if (dist < best.dist) {\n best = { dist, index: node.index };\n }\n const axis = node.axis;\n const diff = target[axis] - node.point[axis];\n const primary = diff < 0 ? node.left : node.right;\n const secondary = diff < 0 ? node.right : node.left;\n best = nearestSearch(primary, target, best);\n if (Math.abs(diff) < best.dist) {\n best = nearestSearch(secondary, target, best);\n }\n return best;\n }\n function luDecompose(A) {\n const n = A.length;\n const LU = A;\n const P = new Int32Array(n);\n for (let i = 0; i < n; i++) P[i] = i;\n for (let k = 0; k < n; k++) {\n let pivot = k;\n for (let i = k + 1; i < n; i++) {\n if (Math.abs(LU[i][k]) > Math.abs(LU[pivot][k])) {\n pivot = i;\n }\n }\n if (pivot !== k) {\n const tmpRow = LU[k];\n LU[k] = LU[pivot];\n LU[pivot] = tmpRow;\n const tmpP = P[k];\n P[k] = P[pivot];\n P[pivot] = tmpP;\n }\n const pivotVal = LU[k][k];\n for (let i = k + 1; i < n; i++) {\n LU[i][k] /= pivotVal;\n const mult = LU[i][k];\n const rowI = LU[i];\n const rowK = LU[k];\n for (let j = k + 1; j < n; j++) {\n rowI[j] -= mult * rowK[j];\n }\n }\n }\n return { LU, P };\n }\n function luSolve({ LU, P }, b) {\n const n = LU.length;\n const x = new Float32Array(n);\n for (let i = 0; i < n; i++) {\n x[i] = b[P[i]];\n }\n for (let i = 0; i < n; i++) {\n const row = LU[i];\n let sum = x[i];\n for (let j = 0; j < i; j++) {\n sum -= row[j] * x[j];\n }\n x[i] = sum;\n }\n for (let i = n - 1; i >= 0; i--) {\n const row = LU[i];\n let sum = x[i];\n for (let j = i + 1; j < n; j++) {\n sum -= row[j] * x[j];\n }\n x[i] = sum / row[i];\n }\n return x;\n }\n function patchRBFWorkerFunc([_A, _bx, _by, _bz]) {\n const A = _A.map((r) => new Float32Array(r));\n const bx = new Float32Array(_bx);\n const by = new Float32Array(_by);\n const bz = new Float32Array(_bz);\n const LU = luDecompose(A);\n const wx = luSolve(LU, bx);\n const wy = luSolve(LU, by);\n const wz = luSolve(LU, bz);\n const n = wx.length;\n const result = new Float32Array(n * 3);\n for (let i = 0; i < n; i++) {\n result[i * 3 + 0] = wx[i];\n result[i * 3 + 1] = wy[i];\n result[i * 3 + 2] = wz[i];\n }\n return result.buffer;\n }\n function RBFDeformerSolveAsync([patchCount, detailsCount, epsilon, importantIndicesBuf, refVertsBuf, distVertsBuf, meshVertsBuf, meshBonesBuf]) {\n const importantIndices = new Uint16Array(importantIndicesBuf);\n const refVerts = new Float32Array(refVertsBuf);\n const distVerts = new Float32Array(distVertsBuf);\n const meshVerts = new Float32Array(meshVertsBuf);\n const meshBones = new Float32Array(meshBonesBuf);\n const refCount = refVerts.length / 3;\n const meshVertCount = meshVerts.length / 3;\n const meshBoneCount = meshBones.length / 3;\n const points = new Array(refCount);\n const indices = new Array(refCount);\n for (let i = 0; i < refCount; i++) {\n const refPos = [refVerts[i * 3 + 0], refVerts[i * 3 + 1], refVerts[i * 3 + 2]];\n points[i] = refPos;\n indices[i] = i;\n }\n const controlKD = buildKDTree(points, indices);\n const step = Math.max(1, Math.floor(refCount / patchCount));\n const patchCenters = [];\n for (let i = 0; i < refCount; i += step) {\n const refPos = [refVerts[i * 3 + 0], refVerts[i * 3 + 1], refVerts[i * 3 + 2]];\n patchCenters.push(refPos);\n if (patchCenters.length >= patchCount) break;\n }\n const neighborIndices = new Array(patchCenters.length);\n const weights = new Array(patchCenters.length);\n const patchIndices = patchCenters.map((_, i) => i);\n const patchKD = buildKDTree(patchCenters, patchIndices);\n const isUsedArr = new Array(patchCenters.length).fill(false);\n const nearestPatch = new Uint16Array(meshVertCount + meshBoneCount);\n for (let i = 0; i < meshVertCount; i++) {\n const vec = [meshVerts[i * 3 + 0], meshVerts[i * 3 + 1], meshVerts[i * 3 + 2]];\n const nearestPatchNode = nearestSearch(patchKD, vec);\n isUsedArr[nearestPatchNode.index] = true;\n nearestPatch[i] = nearestPatchNode.index;\n }\n for (let i = 0; i < meshBoneCount; i++) {\n const vec = [meshBones[i * 3 + 0], meshBones[i * 3 + 1], meshBones[i * 3 + 2]];\n const nearestPatchNode = nearestSearch(patchKD, vec);\n isUsedArr[nearestPatchNode.index] = true;\n nearestPatch[i + meshVertCount] = nearestPatchNode.index;\n }\n for (let i = 0; i < patchCenters.length; i++) {\n if (!isUsedArr[i]) {\n continue;\n }\n const centerPos = patchCenters[i];\n const neighbors = knnSearch(controlKD, centerPos, detailsCount);\n const foundNeighborIndices = neighbors.map((n) => n.index);\n for (const important of importantIndices) {\n if (!foundNeighborIndices.includes(important)) {\n foundNeighborIndices.push(important);\n }\n }\n neighborIndices[i] = new Uint16Array(foundNeighborIndices);\n }\n const A_array = new Array(patchCenters.length);\n for (let p = 0; p < patchCenters.length; p++) {\n const patchNeighborIndices = neighborIndices[p];\n if (!patchNeighborIndices) continue;\n const K = patchNeighborIndices.length;\n const positions = new Array(patchNeighborIndices.length);\n for (let i = 0; i < patchNeighborIndices.length; i++) {\n const j = patchNeighborIndices[i];\n const refPos = [refVerts[j * 3 + 0], refVerts[j * 3 + 1], refVerts[j * 3 + 2]];\n positions[i] = refPos;\n }\n const A = new Array(K);\n for (let i = 0; i < K; i++) {\n A[i] = new Float32Array(K);\n }\n for (let i = 0; i < K; i++) {\n const [pix, piy, piz] = positions[i];\n for (let j = i + 1; j < K; j++) {\n const [pjx, pjy, pjz] = positions[j];\n const dist = Math.sqrt((pix - pjx) * (pix - pjx) + (piy - pjy) * (piy - pjy) + (piz - pjz) * (piz - pjz));\n A[i][j] = dist;\n A[j][i] = dist;\n }\n A[i][i] = epsilon;\n }\n A_array[p] = A;\n }\n for (let p = 0; p < patchCenters.length; p++) {\n if (!isUsedArr[p]) {\n continue;\n }\n const patchNeighborIndices = neighborIndices[p];\n const K = patchNeighborIndices.length;\n const usedRef = new Array(K);\n const usedDist = new Array(K);\n for (let i = 0; i < K; i++) {\n const idx = patchNeighborIndices[i];\n const j = idx;\n const refPos = [refVerts[j * 3 + 0], refVerts[j * 3 + 1], refVerts[j * 3 + 2]];\n const distPos = [distVerts[j * 3 + 0], distVerts[j * 3 + 1], distVerts[j * 3 + 2]];\n usedRef[i] = refPos;\n usedDist[i] = distPos;\n }\n const A = A_array[p];\n const bx = new Float32Array(K);\n const by = new Float32Array(K);\n const bz = new Float32Array(K);\n for (let i = 0; i < K; i++) {\n const dr = usedDist[i];\n const rr = usedRef[i];\n bx[i] = dr[0] - rr[0];\n by[i] = dr[1] - rr[1];\n bz[i] = dr[2] - rr[2];\n }\n const Abuffers = A.map((r) => r.buffer);\n weights[p] = new Float32Array(patchRBFWorkerFunc([Abuffers, bx.buffer, by.buffer, bz.buffer]));\n }\n const neighborIndicesBuf = neighborIndices.map((a) => {\n return a.buffer;\n });\n const weightsBuf = weights.map((a) => {\n return a.buffer;\n });\n return [neighborIndicesBuf, weightsBuf, nearestPatch.buffer];\n }\n const WorkerTypeToFunction = {\n "patchRBF": patchRBFWorkerFunc,\n "RBFDeformerSolveAsync": RBFDeformerSolveAsync\n };\n function getWorkerOnMessage() {\n return function(event) {\n const [id, type, data] = event.data;\n const func = WorkerTypeToFunction[type];\n self.postMessage([id, func(data)]);\n };\n }\n onmessage = getWorkerOnMessage();\n})();\n';
|
|
32412
32683
|
const blob = typeof self !== "undefined" && self.Blob && new Blob(["(self.URL || self.webkitURL).revokeObjectURL(self.location.href);", jsContent], { type: "text/javascript;charset=utf-8" });
|
|
32413
32684
|
function WorkerWrapper(options) {
|
|
32414
32685
|
let objURL;
|
|
@@ -32664,6 +32935,7 @@ const FLAGS = {
|
|
|
32664
32935
|
INCLUDE_REQUEST_CREDENTIALS_OVERRIDE: "include",
|
|
32665
32936
|
API_REQUEST_RETRY: true,
|
|
32666
32937
|
FETCH_FUNC: void 0,
|
|
32938
|
+
IMAGE_FUNC: void 0,
|
|
32667
32939
|
//assets
|
|
32668
32940
|
ONLINE_ASSETS: false,
|
|
32669
32941
|
ASSETS_PATH: "../assets/rbxasset/",
|
|
@@ -35126,275 +35398,6 @@ function toVecXYZ(vec) {
|
|
|
35126
35398
|
Z: vec.z
|
|
35127
35399
|
};
|
|
35128
35400
|
}
|
|
35129
|
-
const AssetTypes = [
|
|
35130
|
-
"",
|
|
35131
|
-
"Image",
|
|
35132
|
-
"TShirt",
|
|
35133
|
-
"Audio",
|
|
35134
|
-
"Mesh",
|
|
35135
|
-
"Lua",
|
|
35136
|
-
"HTML",
|
|
35137
|
-
"Text",
|
|
35138
|
-
"Hat",
|
|
35139
|
-
"Place",
|
|
35140
|
-
"Model",
|
|
35141
|
-
"Shirt",
|
|
35142
|
-
"Pants",
|
|
35143
|
-
"Decal",
|
|
35144
|
-
"",
|
|
35145
|
-
"",
|
|
35146
|
-
"Avatar",
|
|
35147
|
-
"Head",
|
|
35148
|
-
"Face",
|
|
35149
|
-
"Gear",
|
|
35150
|
-
"",
|
|
35151
|
-
"Badge",
|
|
35152
|
-
"GroupEmblem",
|
|
35153
|
-
"",
|
|
35154
|
-
"Animation",
|
|
35155
|
-
"Arms",
|
|
35156
|
-
"Legs",
|
|
35157
|
-
"Torso",
|
|
35158
|
-
"RightArm",
|
|
35159
|
-
"LeftArm",
|
|
35160
|
-
"LeftLeg",
|
|
35161
|
-
"RightLeg",
|
|
35162
|
-
"Package",
|
|
35163
|
-
"YouTubeVideo",
|
|
35164
|
-
"GamePass",
|
|
35165
|
-
"App",
|
|
35166
|
-
"",
|
|
35167
|
-
"Code",
|
|
35168
|
-
"Plugin",
|
|
35169
|
-
"SolidModel",
|
|
35170
|
-
"MeshPart",
|
|
35171
|
-
"HairAccessory",
|
|
35172
|
-
"FaceAccessory",
|
|
35173
|
-
"NeckAccessory",
|
|
35174
|
-
"ShoulderAccessory",
|
|
35175
|
-
"FrontAccessory",
|
|
35176
|
-
"BackAccessory",
|
|
35177
|
-
"WaistAccessory",
|
|
35178
|
-
"ClimbAnimation",
|
|
35179
|
-
"DeathAnimation",
|
|
35180
|
-
"FallAnimation",
|
|
35181
|
-
"IdleAnimation",
|
|
35182
|
-
"JumpAnimation",
|
|
35183
|
-
"RunAnimation",
|
|
35184
|
-
"SwimAnimation",
|
|
35185
|
-
"WalkAnimation",
|
|
35186
|
-
"PoseAnimation",
|
|
35187
|
-
"",
|
|
35188
|
-
"",
|
|
35189
|
-
"LocalizationTableManifest",
|
|
35190
|
-
"LocalizationTableTranslation",
|
|
35191
|
-
"EmoteAnimation",
|
|
35192
|
-
"Video",
|
|
35193
|
-
"TexturePack",
|
|
35194
|
-
"TShirtAccessory",
|
|
35195
|
-
"ShirtAccessory",
|
|
35196
|
-
"PantsAccessory",
|
|
35197
|
-
"JacketAccessory",
|
|
35198
|
-
"SweaterAccessory",
|
|
35199
|
-
"ShortsAccessory",
|
|
35200
|
-
"LeftShoeAccessory",
|
|
35201
|
-
"RightShoeAccessory",
|
|
35202
|
-
"DressSkirtAccessory",
|
|
35203
|
-
"FontFamily",
|
|
35204
|
-
"FontFace",
|
|
35205
|
-
"MeshHiddenSurfaceRemoval",
|
|
35206
|
-
"EyebrowAccessory",
|
|
35207
|
-
"EyelashAccessory",
|
|
35208
|
-
"MoodAnimation",
|
|
35209
|
-
"DynamicHead",
|
|
35210
|
-
//79
|
|
35211
|
-
"CodeSnippet",
|
|
35212
|
-
"AdsVideo",
|
|
35213
|
-
"OtaUpdate",
|
|
35214
|
-
"Screenshot",
|
|
35215
|
-
"RuntimePropertySet",
|
|
35216
|
-
"StorePreviewVideo",
|
|
35217
|
-
"GamePreviewVideo",
|
|
35218
|
-
"CreatorExperienceConfig",
|
|
35219
|
-
"FaceMakeup",
|
|
35220
|
-
"LipMakeup",
|
|
35221
|
-
"EyeMakeup",
|
|
35222
|
-
"VoxelFragment",
|
|
35223
|
-
"AvatarBackground",
|
|
35224
|
-
"TextDocument"
|
|
35225
|
-
];
|
|
35226
|
-
const WearableAssetTypes = [
|
|
35227
|
-
"TShirt",
|
|
35228
|
-
"Hat",
|
|
35229
|
-
"Shirt",
|
|
35230
|
-
"Pants",
|
|
35231
|
-
"Head",
|
|
35232
|
-
"Face",
|
|
35233
|
-
"Gear",
|
|
35234
|
-
"Torso",
|
|
35235
|
-
"RightArm",
|
|
35236
|
-
"LeftArm",
|
|
35237
|
-
"LeftLeg",
|
|
35238
|
-
"RightLeg",
|
|
35239
|
-
"HairAccessory",
|
|
35240
|
-
"FaceAccessory",
|
|
35241
|
-
"NeckAccessory",
|
|
35242
|
-
"ShoulderAccessory",
|
|
35243
|
-
"FrontAccessory",
|
|
35244
|
-
"BackAccessory",
|
|
35245
|
-
"WaistAccessory",
|
|
35246
|
-
"ClimbAnimation",
|
|
35247
|
-
"FallAnimation",
|
|
35248
|
-
"IdleAnimation",
|
|
35249
|
-
"JumpAnimation",
|
|
35250
|
-
"RunAnimation",
|
|
35251
|
-
"SwimAnimation",
|
|
35252
|
-
"WalkAnimation",
|
|
35253
|
-
"TShirtAccessory",
|
|
35254
|
-
"ShirtAccessory",
|
|
35255
|
-
"PantsAccessory",
|
|
35256
|
-
"JacketAccessory",
|
|
35257
|
-
"SweaterAccessory",
|
|
35258
|
-
"ShortsAccessory",
|
|
35259
|
-
"LeftShoeAccessory",
|
|
35260
|
-
"RightShoeAccessory",
|
|
35261
|
-
"DressSkirtAccessory",
|
|
35262
|
-
"EyebrowAccessory",
|
|
35263
|
-
"EyelashAccessory",
|
|
35264
|
-
"MoodAnimation",
|
|
35265
|
-
"DynamicHead",
|
|
35266
|
-
"FaceMakeup",
|
|
35267
|
-
"LipMakeup",
|
|
35268
|
-
"EyeMakeup",
|
|
35269
|
-
"PoseAnimation",
|
|
35270
|
-
"EarAccessory",
|
|
35271
|
-
"EyeAccessory",
|
|
35272
|
-
"DeathAnimation"
|
|
35273
|
-
];
|
|
35274
|
-
const AccessoryAssetTypes = [
|
|
35275
|
-
"Hat",
|
|
35276
|
-
"HairAccessory",
|
|
35277
|
-
"FaceAccessory",
|
|
35278
|
-
"NeckAccessory",
|
|
35279
|
-
"ShoulderAccessory",
|
|
35280
|
-
"FrontAccessory",
|
|
35281
|
-
"BackAccessory",
|
|
35282
|
-
"WaistAccessory"
|
|
35283
|
-
];
|
|
35284
|
-
const LayeredAssetTypes = [
|
|
35285
|
-
"TShirtAccessory",
|
|
35286
|
-
"ShirtAccessory",
|
|
35287
|
-
"PantsAccessory",
|
|
35288
|
-
"JacketAccessory",
|
|
35289
|
-
"SweaterAccessory",
|
|
35290
|
-
"ShortsAccessory",
|
|
35291
|
-
"LeftShoeAccessory",
|
|
35292
|
-
"RightShoeAccessory",
|
|
35293
|
-
"DressSkirtAccessory",
|
|
35294
|
-
"EyebrowAccessory",
|
|
35295
|
-
"EyelashAccessory",
|
|
35296
|
-
"HairAccessory",
|
|
35297
|
-
"FaceMakeup",
|
|
35298
|
-
"LipMakeup",
|
|
35299
|
-
"EyeMakeup"
|
|
35300
|
-
];
|
|
35301
|
-
const SpecialLayeredAssetTypes = [
|
|
35302
|
-
"EyebrowAccessory",
|
|
35303
|
-
"EyelashAccessory",
|
|
35304
|
-
"HairAccessory"
|
|
35305
|
-
];
|
|
35306
|
-
const MaxOneOfAssetTypes = [
|
|
35307
|
-
"TShirt",
|
|
35308
|
-
"Shirt",
|
|
35309
|
-
"Pants",
|
|
35310
|
-
"Head",
|
|
35311
|
-
"Face",
|
|
35312
|
-
"Gear",
|
|
35313
|
-
"Torso",
|
|
35314
|
-
"RightArm",
|
|
35315
|
-
"LeftArm",
|
|
35316
|
-
"LeftLeg",
|
|
35317
|
-
"RightLeg",
|
|
35318
|
-
"ClimbAnimation",
|
|
35319
|
-
"DeathAnimation",
|
|
35320
|
-
"FallAnimation",
|
|
35321
|
-
"IdleAnimation",
|
|
35322
|
-
"JumpAnimation",
|
|
35323
|
-
"RunAnimation",
|
|
35324
|
-
"SwimAnimation",
|
|
35325
|
-
"WalkAnimation",
|
|
35326
|
-
"PoseAnimation",
|
|
35327
|
-
"MoodAnimation",
|
|
35328
|
-
"DynamicHead",
|
|
35329
|
-
"EyebrowAccessory",
|
|
35330
|
-
"EyelashAccessory"
|
|
35331
|
-
];
|
|
35332
|
-
const ToRemoveBeforeBundleType = {
|
|
35333
|
-
"DynamicHead": ["MoodAnimation", "DynamicHead", "EyebrowAccessory", "EyelashAccessory", "Head"],
|
|
35334
|
-
"Shoes": ["LeftShoeAccessory", "RightShoeAccessory"],
|
|
35335
|
-
"AnimationPack": [
|
|
35336
|
-
"ClimbAnimation",
|
|
35337
|
-
"DeathAnimation",
|
|
35338
|
-
"FallAnimation",
|
|
35339
|
-
"IdleAnimation",
|
|
35340
|
-
"JumpAnimation",
|
|
35341
|
-
"RunAnimation",
|
|
35342
|
-
"SwimAnimation",
|
|
35343
|
-
"WalkAnimation",
|
|
35344
|
-
"PoseAnimation",
|
|
35345
|
-
"MoodAnimation"
|
|
35346
|
-
],
|
|
35347
|
-
"Character": [
|
|
35348
|
-
"DynamicHead",
|
|
35349
|
-
"Head",
|
|
35350
|
-
"Torso",
|
|
35351
|
-
"LeftArm",
|
|
35352
|
-
"RightArm",
|
|
35353
|
-
"LeftLeg",
|
|
35354
|
-
"RightLeg"
|
|
35355
|
-
],
|
|
35356
|
-
"MakeupLook": [
|
|
35357
|
-
"FaceMakeup",
|
|
35358
|
-
"EyeMakeup",
|
|
35359
|
-
"LipMakeup",
|
|
35360
|
-
"EyebrowAccessory",
|
|
35361
|
-
"EyelashAccessory"
|
|
35362
|
-
]
|
|
35363
|
-
};
|
|
35364
|
-
const AssetTypeNameToId = /* @__PURE__ */ new Map();
|
|
35365
|
-
for (let i = 0; i < AssetTypes.length; i++) {
|
|
35366
|
-
const name = AssetTypes[i];
|
|
35367
|
-
AssetTypeNameToId.set(name, i);
|
|
35368
|
-
}
|
|
35369
|
-
const ActualBundleTypes = [
|
|
35370
|
-
//names used by Roblox
|
|
35371
|
-
"",
|
|
35372
|
-
"Avatar",
|
|
35373
|
-
//traditional bundle
|
|
35374
|
-
"DynamicHead",
|
|
35375
|
-
"Avatar",
|
|
35376
|
-
//outfit
|
|
35377
|
-
"Shoes",
|
|
35378
|
-
"Avatar"
|
|
35379
|
-
//animation pack
|
|
35380
|
-
];
|
|
35381
|
-
const BundleTypes = [
|
|
35382
|
-
"",
|
|
35383
|
-
"Character",
|
|
35384
|
-
"DynamicHead",
|
|
35385
|
-
"Outfit",
|
|
35386
|
-
"Shoes",
|
|
35387
|
-
"AnimationPack",
|
|
35388
|
-
"",
|
|
35389
|
-
"MakeupLook"
|
|
35390
|
-
];
|
|
35391
|
-
const CatalogBundleTypes = [
|
|
35392
|
-
"",
|
|
35393
|
-
"Character",
|
|
35394
|
-
"AnimationPack",
|
|
35395
|
-
"Shoes",
|
|
35396
|
-
"DynamicHead"
|
|
35397
|
-
];
|
|
35398
35401
|
class ItemInfo {
|
|
35399
35402
|
itemType;
|
|
35400
35403
|
type;
|
|
@@ -36037,7 +36040,7 @@ class Outfit {
|
|
|
36037
36040
|
});
|
|
36038
36041
|
}
|
|
36039
36042
|
}
|
|
36040
|
-
if (LayeredAssetTypes.includes(asset.assetType.name) && !MakeupAssetTypes.includes(asset.assetType.name)) {
|
|
36043
|
+
if (LayeredAssetTypes.includes(asset.assetType.name) && !MakeupAssetTypes.includes(asset.assetType.name) && !MaxOneOfAssetTypes.includes(asset.assetType.name)) {
|
|
36041
36044
|
totalLayered += 1;
|
|
36042
36045
|
if (totalLayered > 10) {
|
|
36043
36046
|
issues.push({
|
|
@@ -36491,7 +36494,7 @@ class Outfit {
|
|
|
36491
36494
|
this.addAsset(assetId, assetDetails.AssetTypeId, assetDetails.Name);
|
|
36492
36495
|
return true;
|
|
36493
36496
|
}
|
|
36494
|
-
async addBundleId(bundleId) {
|
|
36497
|
+
async addBundleId(bundleId, auth) {
|
|
36495
36498
|
const bundleDetails = await API.Catalog.GetBundleDetails(bundleId);
|
|
36496
36499
|
if (!(bundleDetails instanceof Response)) {
|
|
36497
36500
|
const bundleType = CatalogBundleTypes[bundleDetails.bundleType];
|
|
@@ -36510,6 +36513,18 @@ class Outfit {
|
|
|
36510
36513
|
break;
|
|
36511
36514
|
}
|
|
36512
36515
|
}
|
|
36516
|
+
if (!bundleDetails.bundledItems.find((v) => {
|
|
36517
|
+
return v.type === "UserOutfit";
|
|
36518
|
+
})) {
|
|
36519
|
+
const promises = [];
|
|
36520
|
+
for (const item of bundleDetails.bundledItems) {
|
|
36521
|
+
if (item.type !== "Asset") continue;
|
|
36522
|
+
const promise = auth ? this.addAssetId(item.id, auth) : this.addAssetIdEconomy(item.id);
|
|
36523
|
+
promises.push(promise);
|
|
36524
|
+
}
|
|
36525
|
+
await Promise.all(promises);
|
|
36526
|
+
return true;
|
|
36527
|
+
}
|
|
36513
36528
|
} else {
|
|
36514
36529
|
warn(true, "Failed to get bundleDetails", bundleDetails);
|
|
36515
36530
|
}
|
|
@@ -39061,7 +39076,13 @@ const API = {
|
|
|
39061
39076
|
CACHE.Image.set(cacheURL, void 0);
|
|
39062
39077
|
};
|
|
39063
39078
|
image.crossOrigin = "anonymous";
|
|
39064
|
-
|
|
39079
|
+
if (FLAGS.IMAGE_FUNC) {
|
|
39080
|
+
FLAGS.IMAGE_FUNC(fetchStr).then((str) => {
|
|
39081
|
+
image.src = str;
|
|
39082
|
+
});
|
|
39083
|
+
} else {
|
|
39084
|
+
image.src = fetchStr;
|
|
39085
|
+
}
|
|
39065
39086
|
});
|
|
39066
39087
|
}));
|
|
39067
39088
|
}
|
|
@@ -39206,13 +39227,19 @@ const API = {
|
|
|
39206
39227
|
if (response.status !== 200) return response;
|
|
39207
39228
|
const body = await response.json();
|
|
39208
39229
|
const outfitModel = new OutfitModel().fromJson(body);
|
|
39230
|
+
outfitModel.outfit.creatorId = userId;
|
|
39231
|
+
outfitModel.outfit.origin = OutfitOrigin.WebAvatar;
|
|
39209
39232
|
return outfitModel;
|
|
39210
39233
|
},
|
|
39211
39234
|
GetAvatarModel: async function() {
|
|
39235
|
+
const userInfoPromise = API.Users.GetUserInfo();
|
|
39212
39236
|
const response = await RBLXGet("https://avatar.roblox.com/v4/avatar?selectionTypes=0&selectionTypes=1&selectionTypes=2&selectionTypes=3&selectionTypes=4&selectionTypes=5&selectionTypes=6");
|
|
39213
39237
|
if (response.status !== 200) return response;
|
|
39214
39238
|
const body = await response.json();
|
|
39215
39239
|
const outfitModel = new OutfitModel().fromJson(body);
|
|
39240
|
+
const userInfo = await userInfoPromise;
|
|
39241
|
+
if (userInfo) outfitModel.outfit.creatorId = userInfo.id;
|
|
39242
|
+
outfitModel.outfit.origin = OutfitOrigin.WebAvatar;
|
|
39216
39243
|
return outfitModel;
|
|
39217
39244
|
},
|
|
39218
39245
|
UpdateAvatarModel: async function(auth, model, updateTypes = AllAvatarModelOutfitUpdateTypes) {
|
|
@@ -39464,7 +39491,11 @@ const API = {
|
|
|
39464
39491
|
if (response instanceof ArrayBuffer) {
|
|
39465
39492
|
const buffer2 = response;
|
|
39466
39493
|
const rbx = new RBX();
|
|
39467
|
-
|
|
39494
|
+
try {
|
|
39495
|
+
rbx.fromBuffer(buffer2);
|
|
39496
|
+
} catch {
|
|
39497
|
+
return new Response();
|
|
39498
|
+
}
|
|
39468
39499
|
if (FLAGS.ENABLE_API_CACHE && FLAGS.ENABLE_API_RBX_CACHE) {
|
|
39469
39500
|
CACHE.RBX.set(cacheStr, rbx.clone());
|
|
39470
39501
|
}
|
|
@@ -39676,7 +39707,7 @@ const API = {
|
|
|
39676
39707
|
},
|
|
39677
39708
|
"Users": {
|
|
39678
39709
|
GetUserInfo: async function() {
|
|
39679
|
-
if (CACHE.UserInfo) {
|
|
39710
|
+
if (CACHE.UserInfo !== void 0) {
|
|
39680
39711
|
return CACHE.UserInfo;
|
|
39681
39712
|
}
|
|
39682
39713
|
const response = await RBLXGet("https://users.roblox.com/v1/users/authenticated");
|
|
@@ -39856,6 +39887,10 @@ const API = {
|
|
|
39856
39887
|
DeleteLook: async function(auth, lookId) {
|
|
39857
39888
|
const response = await RBLXDelete(`https://apis.roblox.com/look-api/v1/looks/${lookId}`, auth, {});
|
|
39858
39889
|
return response;
|
|
39890
|
+
},
|
|
39891
|
+
PatchLook: async function(auth, lookId, data) {
|
|
39892
|
+
const response = await RBLXPatch(`https://apis.roblox.com/look-api/v1/looks/${lookId}`, auth, data);
|
|
39893
|
+
return response;
|
|
39859
39894
|
}
|
|
39860
39895
|
},
|
|
39861
39896
|
"PremiumFeatures": {
|
|
@@ -52774,11 +52809,11 @@ class LightDesc extends RenderDesc {
|
|
|
52774
52809
|
if (light instanceof PointLight || light instanceof SpotLight) {
|
|
52775
52810
|
light.decay = 0.4;
|
|
52776
52811
|
light.visible = this.enabled;
|
|
52777
|
-
light.intensity = this.brightness;
|
|
52812
|
+
light.intensity = this.brightness * 4;
|
|
52778
52813
|
light.distance = this.range + 0.5;
|
|
52779
52814
|
light.castShadow = this.shadows;
|
|
52780
52815
|
light.shadow.intensity = 0.5;
|
|
52781
|
-
light.color = new Color().setRGB(this.color.R, this.color.G, this.color.B);
|
|
52816
|
+
light.color = new Color().setRGB(this.color.R, this.color.G, this.color.B, SRGBColorSpace);
|
|
52782
52817
|
const resultCF = this.cframe;
|
|
52783
52818
|
const targetCF = new CFrame();
|
|
52784
52819
|
if (light instanceof SpotLight) {
|
|
@@ -59383,7 +59418,7 @@ class OutfitRenderer {
|
|
|
59383
59418
|
if (animatorW) {
|
|
59384
59419
|
animatorW.data.forceTransitionTime = 0;
|
|
59385
59420
|
}
|
|
59386
|
-
if (!this.outfit.containsAssetType("Gear")) {
|
|
59421
|
+
if (!this.outfit.containsAssetType("Gear") || this.outfit.playerAvatarType === AvatarType.R15 && !this.hasAnimationSetAnimation("pose")) {
|
|
59387
59422
|
if (this.outfit.playerAvatarType === AvatarType.R15) {
|
|
59388
59423
|
if (this.hasAnimationSetAnimation("pose")) {
|
|
59389
59424
|
this.setMainAnimation("pose").then(() => {
|
|
@@ -59556,12 +59591,8 @@ async function generateOutfitThumbnail(auth, outfit, size = [150, 150], type = "
|
|
|
59556
59591
|
}
|
|
59557
59592
|
if (outfitRenderer.backgroundRenderer.backgroundId) {
|
|
59558
59593
|
renderScene.directionalLight.castShadow = true;
|
|
59559
|
-
renderScene.directionalLight.position.set(
|
|
59560
|
-
|
|
59561
|
-
}));
|
|
59562
|
-
renderScene.directionalLight2.position.set(...renderScene.directionalLight2.position.toArray().map((v, i) => {
|
|
59563
|
-
return i === 2 ? -v : v;
|
|
59564
|
-
}));
|
|
59594
|
+
renderScene.directionalLight.position.set(-0.55828 * 10, 0.72756 * 10, -0.39873 * 10);
|
|
59595
|
+
renderScene.directionalLight2.position.set(0.55828 * 10, -0.72756 * 10, 0.39873 * 10);
|
|
59565
59596
|
}
|
|
59566
59597
|
if (outfitRenderer.currentRig) {
|
|
59567
59598
|
let cameraCFrame = new CFrame();
|