roavatar-renderer 1.5.16 → 1.5.18

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.
Files changed (3) hide show
  1. package/dist/index.d.ts +122 -16
  2. package/dist/index.js +913 -353
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,3 +1,26 @@
1
+ function cloneSearch_Payload(data) {
2
+ const newData = {
3
+ taxonomy: data.taxonomy,
4
+ salesTypeFilter: data.salesTypeFilter,
5
+ categoryFilter: data.categoryFilter,
6
+ sortType: data.sortType,
7
+ keyword: data.keyword,
8
+ topics: void 0,
9
+ creatorName: data.creatorName,
10
+ minPrice: data.minPrice,
11
+ maxPrice: data.maxPrice,
12
+ includeNotForSale: data.includeNotForSale,
13
+ limit: data.limit
14
+ };
15
+ if (data.topics) {
16
+ newData.topics = [];
17
+ for (const topic of data.topics) {
18
+ newData.topics.push(topic);
19
+ }
20
+ }
21
+ return newData;
22
+ }
23
+ const AllAvatarModelOutfitUpdateTypes = ["UpdateBodyColors", "UpdateAssets", "UpdateScales", "UpdateBackground"];
1
24
  const BrickColors = {
2
25
  1: "#F2F3F3",
3
26
  2: "#A1A5A2",
@@ -31497,6 +31520,16 @@ class CFrame {
31497
31520
  lookVector.applyQuaternion(quat);
31498
31521
  return lookVector.toArray();
31499
31522
  }
31523
+ upVector() {
31524
+ const matrix = this.getTHREEMatrix();
31525
+ const pos = new Vector3$1();
31526
+ const quat = new Quaternion();
31527
+ const scale = new Vector3$1();
31528
+ matrix.decompose(pos, quat, scale);
31529
+ const upVector = new Vector3$1(0, 1, 0);
31530
+ upVector.applyQuaternion(quat);
31531
+ return upVector.toArray();
31532
+ }
31500
31533
  static lookAt(eye, target, up = [0, 1, 0]) {
31501
31534
  const matrix = new Matrix4().lookAt(new Vector3$1(...eye), new Vector3$1(...target), new Vector3$1(...up));
31502
31535
  const newCFrame = new CFrame();
@@ -31637,6 +31670,9 @@ class Instance {
31637
31670
  get name() {
31638
31671
  return this.Prop("Name");
31639
31672
  }
31673
+ get Parent() {
31674
+ return this.parent;
31675
+ }
31640
31676
  createWrapper() {
31641
31677
  const wrapper = GetWrapperForInstance(this);
31642
31678
  if (wrapper && !this._hasWrappered) {
@@ -31747,6 +31783,9 @@ class Instance {
31747
31783
  if (value && value.toLowerCase().includes(FLAGS.SEARCH_FOR_STRING)) {
31748
31784
  log(true, this.GetFullName());
31749
31785
  log(true, value);
31786
+ if (value.length > 1e4) {
31787
+ download(this.GetFullName(), value);
31788
+ }
31750
31789
  }
31751
31790
  }
31752
31791
  }
@@ -33438,7 +33477,8 @@ const AssetTypes = [
33438
33477
  "LipMakeup",
33439
33478
  "EyeMakeup",
33440
33479
  "VoxelFragment",
33441
- "AvatarBackground"
33480
+ "AvatarBackground",
33481
+ "TextDocument"
33442
33482
  ];
33443
33483
  const WearableAssetTypes = [
33444
33484
  "TShirt",
@@ -33931,6 +33971,18 @@ class BodyColor3s {
33931
33971
  this.rightLegColor3 = bodyColorsJson.rightLegColor3;
33932
33972
  if (bodyColorsJson.leftLegColor3)
33933
33973
  this.leftLegColor3 = bodyColorsJson.leftLegColor3;
33974
+ if (bodyColorsJson.headColor)
33975
+ this.headColor3 = bodyColorsJson.headColor;
33976
+ if (bodyColorsJson.torsoColor)
33977
+ this.torsoColor3 = bodyColorsJson.torsoColor;
33978
+ if (bodyColorsJson.rightArmColor)
33979
+ this.rightArmColor3 = bodyColorsJson.rightArmColor;
33980
+ if (bodyColorsJson.leftArmColor)
33981
+ this.leftArmColor3 = bodyColorsJson.leftArmColor;
33982
+ if (bodyColorsJson.rightLegColor)
33983
+ this.rightLegColor3 = bodyColorsJson.rightLegColor;
33984
+ if (bodyColorsJson.leftLegColor)
33985
+ this.leftLegColor3 = bodyColorsJson.leftLegColor;
33934
33986
  }
33935
33987
  }
33936
33988
  class BodyColors {
@@ -34106,6 +34158,15 @@ class Outfit {
34106
34158
  ogJson.collections = void 0;
34107
34159
  return ogJson;
34108
34160
  }
34161
+ toCleanJsonV4(removeNotOwnedAssets = false) {
34162
+ const ogJson = this.toJson(removeNotOwnedAssets);
34163
+ ogJson.creatorId = void 0;
34164
+ ogJson.outfitType = void 0;
34165
+ ogJson.collections = void 0;
34166
+ ogJson.bodyColor3s = void 0;
34167
+ ogJson.bodyColors = this.bodyColors.toHexJson();
34168
+ return ogJson;
34169
+ }
34109
34170
  fromJson(outfitJson) {
34110
34171
  this.scale = new Scale();
34111
34172
  if (outfitJson.scale) {
@@ -34114,7 +34175,7 @@ class Outfit {
34114
34175
  this.scale.fromJson(outfitJson.scales);
34115
34176
  }
34116
34177
  const bodyColorsJson = outfitJson.bodyColors;
34117
- if (bodyColorsJson && !("headColor3" in bodyColorsJson)) {
34178
+ if (bodyColorsJson && !("headColor3" in bodyColorsJson) && !("headColor" in bodyColorsJson)) {
34118
34179
  const oldBodyColors = new BodyColors();
34119
34180
  oldBodyColors.fromJson(bodyColorsJson);
34120
34181
  if (FLAGS.BODYCOLOR3) {
@@ -34864,7 +34925,7 @@ class Outfit {
34864
34925
  staticFacialAnimation = true;
34865
34926
  }
34866
34927
  let meta = void 0;
34867
- if (assetOrder !== void 0 || assetPos || assetRot || assetScale || assetHeadShape !== void 0) {
34928
+ if (assetOrder !== void 0 || assetPos || assetRot || assetScale || assetHeadShape !== void 0 || staticFacialAnimation !== void 0) {
34868
34929
  meta = new AssetMeta();
34869
34930
  meta.order = assetOrder;
34870
34931
  meta.position = assetPos;
@@ -35068,6 +35129,92 @@ class Outfit {
35068
35129
  return view.buffer;
35069
35130
  }
35070
35131
  }
35132
+ class ThumbnailCustomization {
35133
+ thumbnailType;
35134
+ emoteAssetId = 0;
35135
+ fieldOfViewDeg = 28.751935958862305;
35136
+ yRotDeg = 0;
35137
+ distanceScale = 1;
35138
+ constructor(thumbnailType) {
35139
+ this.thumbnailType = thumbnailType;
35140
+ }
35141
+ fromJson(json) {
35142
+ this.emoteAssetId = json.emoteAssetId;
35143
+ this.fieldOfViewDeg = json.camera.fieldOfViewDeg;
35144
+ this.yRotDeg = json.camera.yRotDeg;
35145
+ this.distanceScale = json.camera.distanceScale;
35146
+ return this;
35147
+ }
35148
+ toJson() {
35149
+ return {
35150
+ thumbnailType: this.thumbnailType,
35151
+ emoteAssetId: this.emoteAssetId,
35152
+ camera: {
35153
+ fieldOfViewDeg: this.fieldOfViewDeg,
35154
+ yRotDeg: this.yRotDeg,
35155
+ distanceScale: this.distanceScale
35156
+ }
35157
+ };
35158
+ }
35159
+ clone() {
35160
+ const copy = new ThumbnailCustomization(this.thumbnailType);
35161
+ copy.emoteAssetId = this.emoteAssetId;
35162
+ copy.fieldOfViewDeg = this.fieldOfViewDeg;
35163
+ copy.yRotDeg = this.yRotDeg;
35164
+ copy.distanceScale = this.distanceScale;
35165
+ return copy;
35166
+ }
35167
+ }
35168
+ class OutfitModel {
35169
+ outfit = new Outfit();
35170
+ emotes = /* @__PURE__ */ new Map();
35171
+ background;
35172
+ thumbnailCustomizations;
35173
+ profileFrame;
35174
+ fromJson(outfitModel) {
35175
+ const config = "avatarConfigurations" in outfitModel ? outfitModel.avatarConfigurations : outfitModel.outfitConfigurations;
35176
+ this.outfit.fromJson("avatarModel" in outfitModel ? outfitModel.avatarModel : outfitModel.outfitModel);
35177
+ if (config) {
35178
+ if (config.emotes) {
35179
+ for (const emote of config.emotes) {
35180
+ const asset = new Asset();
35181
+ asset.id = emote.assetId;
35182
+ asset.name = emote.assetName;
35183
+ this.emotes.set(emote.position, asset);
35184
+ }
35185
+ }
35186
+ if (config.background) {
35187
+ const asset = new Asset();
35188
+ asset.fromJson(config.background.backgroundAsset);
35189
+ this.background = asset;
35190
+ }
35191
+ if (config.thumbnailCustomizations) {
35192
+ this.thumbnailCustomizations = [];
35193
+ for (const json of config.thumbnailCustomizations) {
35194
+ this.thumbnailCustomizations.push(new ThumbnailCustomization(json.thumbnailType).fromJson(json));
35195
+ }
35196
+ }
35197
+ }
35198
+ return this;
35199
+ }
35200
+ clone() {
35201
+ const copy = new OutfitModel();
35202
+ copy.outfit = this.outfit.clone();
35203
+ copy.emotes = /* @__PURE__ */ new Map();
35204
+ for (const key of this.emotes.keys()) {
35205
+ copy.emotes.set(key, this.emotes.get(key));
35206
+ }
35207
+ copy.background = this.background?.clone();
35208
+ if (this.thumbnailCustomizations) {
35209
+ copy.thumbnailCustomizations = [];
35210
+ for (const customization of this.thumbnailCustomizations) {
35211
+ copy.thumbnailCustomizations.push(customization.clone());
35212
+ }
35213
+ }
35214
+ copy.profileFrame = this.profileFrame;
35215
+ return copy;
35216
+ }
35217
+ }
35071
35218
  class LocalOutfit {
35072
35219
  name;
35073
35220
  id;
@@ -35075,6 +35222,7 @@ class LocalOutfit {
35075
35222
  date;
35076
35223
  image;
35077
35224
  buffer;
35225
+ bg = 0;
35078
35226
  constructor(outfit) {
35079
35227
  this.name = outfit.name;
35080
35228
  this.id = outfit.id;
@@ -35089,7 +35237,8 @@ class LocalOutfit {
35089
35237
  creator: this.creator,
35090
35238
  date: this.date,
35091
35239
  image: this.image,
35092
- buffer: this.buffer
35240
+ buffer: this.buffer,
35241
+ bg: this.bg
35093
35242
  };
35094
35243
  }
35095
35244
  fromJson(data) {
@@ -35098,12 +35247,16 @@ class LocalOutfit {
35098
35247
  this.creator = data.creator;
35099
35248
  this.image = data.image;
35100
35249
  this.buffer = data.buffer;
35250
+ this.bg = data.bg || 0;
35101
35251
  return this;
35102
35252
  }
35103
35253
  update(outfit) {
35104
35254
  this.buffer = arrayBufferToBase64(outfit.toBuffer());
35105
35255
  this.image = void 0;
35106
35256
  }
35257
+ /**
35258
+ * @deprecated Use toOutfitModel() instead
35259
+ */
35107
35260
  async toOutfit(auth) {
35108
35261
  const outfit = new Outfit();
35109
35262
  outfit.name = this.name;
@@ -35112,6 +35265,26 @@ class LocalOutfit {
35112
35265
  await outfit.fromBuffer(base64ToArrayBuffer(this.buffer), auth);
35113
35266
  return outfit;
35114
35267
  }
35268
+ async toOutfitModel(auth) {
35269
+ const outfitModel = new OutfitModel();
35270
+ const outfit = outfitModel.outfit;
35271
+ outfit.name = this.name;
35272
+ outfit.id = this.id;
35273
+ outfit.creatorId = this.creator;
35274
+ await outfit.fromBuffer(base64ToArrayBuffer(this.buffer), auth);
35275
+ if (this.bg) {
35276
+ await outfit.addAssetId(this.bg, auth);
35277
+ const assetIndex = outfit.assets.findIndex((v) => {
35278
+ return v.id === this.bg;
35279
+ });
35280
+ if (assetIndex >= 0) {
35281
+ const asset = outfit.assets[assetIndex];
35282
+ outfitModel.background = asset;
35283
+ outfit.removeAsset(this.bg);
35284
+ }
35285
+ }
35286
+ return outfitModel;
35287
+ }
35115
35288
  }
35116
35289
  class ItemSort {
35117
35290
  subType;
@@ -35271,6 +35444,9 @@ const CategoryDictionary = {
35271
35444
  "Swim": new SortInfo([new ItemSort(54)]),
35272
35445
  "Climb": new SortInfo([new ItemSort(48)]),
35273
35446
  "Mood": new SortInfo([new ItemSort(AssetTypeNameToId.get("MoodAnimation") || 0)], "inventory")
35447
+ },
35448
+ "Profile": {
35449
+ "Backgrounds": new SortInfo([new ItemSort(AssetTypeNameToId.get("AvatarBackground") || 0)])
35274
35450
  }
35275
35451
  }
35276
35452
  };
@@ -37022,6 +37198,7 @@ function createContentMap() {
37022
37198
  }
37023
37199
  ContentMap.set("roavatar://AvatarEditorScene.rbxm", "74148511291027");
37024
37200
  ContentMap.set("roavatar://AvatarSceneNew.rbxm", "130507237273896");
37201
+ ContentMap.set("roavatar://AvatarCyclorama.rbxm", "79116945688799");
37025
37202
  }
37026
37203
  let CachedRoAvatarData = void 0;
37027
37204
  let ThumbnailsToBatch = [];
@@ -37278,6 +37455,64 @@ const API = {
37278
37455
  return response;
37279
37456
  }
37280
37457
  },
37458
+ GetAvatarModel: async function() {
37459
+ const response = await RBLXGet("https://avatar.roblox.com/v4/avatar?selectionTypes=0&selectionTypes=1&selectionTypes=2&selectionTypes=3&selectionTypes=4&selectionTypes=5");
37460
+ if (response.status !== 200) return response;
37461
+ const body = await response.json();
37462
+ const outfitModel = new OutfitModel().fromJson(body);
37463
+ return outfitModel;
37464
+ },
37465
+ UpdateAvatarModel: async function(auth, model, updateTypes = AllAvatarModelOutfitUpdateTypes) {
37466
+ const response = await RBLXPatch("https://avatar.roblox.com/v4/avatar", auth, {
37467
+ updateTypes,
37468
+ avatarDefinition: {
37469
+ updateAvatarConfig: {
37470
+ backgroundRequestModel: {
37471
+ id: model.background?.id || 0
37472
+ }
37473
+ },
37474
+ updateAvatarModel: model.outfit.toCleanJson()
37475
+ }
37476
+ });
37477
+ return response;
37478
+ },
37479
+ GetOutfitModel: async function(id, creatorId) {
37480
+ const response = await RBLXGet(`https://avatar.roblox.com/v4/outfits/${id}/details`);
37481
+ if (response.status !== 200) return response;
37482
+ const body = await response.json();
37483
+ const outfitModel = new OutfitModel().fromJson(body);
37484
+ outfitModel.outfit.origin = OutfitOrigin.WebOutfit;
37485
+ outfitModel.outfit.id = Number(id);
37486
+ outfitModel.outfit.creatorId = creatorId;
37487
+ return outfitModel;
37488
+ },
37489
+ CreateOutfitModel: async function(auth, model) {
37490
+ const response = await RBLXPost("https://avatar.roblox.com/v4/outfits/create", auth, {
37491
+ outfitDefinition: {
37492
+ updateOutfitConfig: {
37493
+ backgroundRequestModel: {
37494
+ id: model.background?.id || 0
37495
+ }
37496
+ },
37497
+ updateOutfitModel: model.outfit.toCleanJsonV4()
37498
+ }
37499
+ });
37500
+ return response;
37501
+ },
37502
+ UpdateOutfitModel: async function(auth, model, id, updateTypes = AllAvatarModelOutfitUpdateTypes) {
37503
+ const response = await RBLXPatch(`https://avatar.roblox.com/v4/outfits/${id}`, auth, {
37504
+ updateTypes,
37505
+ outfitDefinition: {
37506
+ updateOutfitConfig: {
37507
+ backgroundRequestModel: {
37508
+ id: model.background?.id || 0
37509
+ }
37510
+ },
37511
+ updateOutfitModel: model.outfit.toCleanJsonV4()
37512
+ }
37513
+ });
37514
+ return response;
37515
+ },
37281
37516
  GetHeadShapes: async function(pageToken) {
37282
37517
  const itemSort = new ItemSort(1, "headshape");
37283
37518
  return API.Avatar.GetAvatarInventory("1", pageToken, [itemSort]);
@@ -37315,6 +37550,9 @@ const API = {
37315
37550
  return result;
37316
37551
  }
37317
37552
  },
37553
+ /**
37554
+ * @deprecated Use GetOutfitModel instead
37555
+ */
37318
37556
  GetOutfitDetails: async function(outfitId, userId) {
37319
37557
  let requestUrl = "https://avatar.roblox.com/v1/outfits/";
37320
37558
  if (FLAGS.BODYCOLOR3) {
@@ -37332,6 +37570,9 @@ const API = {
37332
37570
  return response;
37333
37571
  }
37334
37572
  },
37573
+ /**
37574
+ * @deprecated Use CreateOutfitModel instead
37575
+ */
37335
37576
  SaveOutfit: async function(auth, outfit) {
37336
37577
  const requestUrl = `https://avatar.roblox.com/${FLAGS.BODYCOLOR3 ? "v3" : "v2"}/outfits/create`;
37337
37578
  const response = await RBLXPost(requestUrl, auth, outfit.toCleanJson());
@@ -37345,6 +37586,9 @@ const API = {
37345
37586
  return response2;
37346
37587
  }
37347
37588
  },
37589
+ /**
37590
+ * @deprecated Use UpdateOutfitModel instead
37591
+ */
37348
37592
  UpdateOutfit: async function(auth, outfitId, newOutfit) {
37349
37593
  let requestUrl = "https://avatar.roblox.com/v1/outfits/";
37350
37594
  if (FLAGS.BODYCOLOR3) {
@@ -37354,6 +37598,9 @@ const API = {
37354
37598
  const response = RBLXPatch(requestUrl, auth, JSON.stringify(newOutfit.toCleanJson()));
37355
37599
  return response;
37356
37600
  },
37601
+ /**
37602
+ * @deprecated Use UpdateOutfitModel instead
37603
+ */
37357
37604
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
37358
37605
  PatchOutfit: async function(auth, outfitId, patchData) {
37359
37606
  let requestUrl = "https://avatar.roblox.com/v1/outfits/";
@@ -37492,11 +37739,15 @@ const API = {
37492
37739
  if (response instanceof ArrayBuffer) {
37493
37740
  const buffer2 = response;
37494
37741
  const mesh = new FileMesh();
37495
- await mesh.fromBuffer(buffer2);
37496
- if (FLAGS.ENABLE_API_CACHE && FLAGS.ENABLE_API_MESH_CACHE) {
37497
- CACHE.Mesh.set(cacheStr, mesh.clone());
37742
+ try {
37743
+ await mesh.fromBuffer(buffer2);
37744
+ if (FLAGS.ENABLE_API_CACHE && FLAGS.ENABLE_API_MESH_CACHE) {
37745
+ CACHE.Mesh.set(cacheStr, mesh.clone());
37746
+ }
37747
+ return mesh;
37748
+ } catch {
37749
+ return new Response();
37498
37750
  }
37499
- return mesh;
37500
37751
  } else {
37501
37752
  return response;
37502
37753
  }
@@ -37715,7 +37966,8 @@ const API = {
37715
37966
  type,
37716
37967
  id,
37717
37968
  size,
37718
- headShape
37969
+ headShape,
37970
+ includeBackground: type === "Outfit"
37719
37971
  };
37720
37972
  const cachedThumbnail = CACHE.Thumbnails.get(requestIdFromThumbnailInfo(thisThumbnailInfo));
37721
37973
  if (CACHE.Thumbnails.has(requestIdFromThumbnailInfo(thisThumbnailInfo))) {
@@ -37739,7 +37991,8 @@ const API = {
37739
37991
  resolves: [resolve],
37740
37992
  attempt: 0,
37741
37993
  lastTryTimestamp: 0,
37742
- headShape
37994
+ headShape,
37995
+ includeBackground: type === "Outfit"
37743
37996
  });
37744
37997
  });
37745
37998
  },
@@ -37748,7 +38001,8 @@ const API = {
37748
38001
  type,
37749
38002
  id,
37750
38003
  size,
37751
- headShape
38004
+ headShape,
38005
+ includeBackground: type === "Outfit"
37752
38006
  };
37753
38007
  CACHE.Thumbnails.delete(requestIdFromThumbnailInfo(thisThumbnailInfo));
37754
38008
  },
@@ -37880,6 +38134,9 @@ function requestIdFromThumbnailInfo(thumbnailInfo) {
37880
38134
  if (thumbnailInfo.headShape) {
37881
38135
  requestId += `:${thumbnailInfo.headShape}`;
37882
38136
  }
38137
+ if (thumbnailInfo.includeBackground) {
38138
+ requestId += `:${thumbnailInfo.includeBackground}`;
38139
+ }
37883
38140
  return requestId;
37884
38141
  }
37885
38142
  function PurgeFailedThumbnails() {
@@ -37910,7 +38167,8 @@ function BatchThumbnails() {
37910
38167
  "size": thumbnailInfo.size,
37911
38168
  "targetId": thumbnailInfo.id,
37912
38169
  "type": thumbnailInfo.type,
37913
- "headShape": thumbnailInfo.headShape
38170
+ "headShape": thumbnailInfo.headShape,
38171
+ "includeBackground": thumbnailInfo.includeBackground
37914
38172
  });
37915
38173
  auth = thumbnailInfo.auth;
37916
38174
  thumbnailInfo.lastTryTimestamp = Date.now() / 1e3;
@@ -37958,28 +38216,6 @@ function startBatchThumbnails() {
37958
38216
  }
37959
38217
  }, 10);
37960
38218
  }
37961
- function cloneSearch_Payload(data) {
37962
- const newData = {
37963
- taxonomy: data.taxonomy,
37964
- salesTypeFilter: data.salesTypeFilter,
37965
- categoryFilter: data.categoryFilter,
37966
- sortType: data.sortType,
37967
- keyword: data.keyword,
37968
- topics: void 0,
37969
- creatorName: data.creatorName,
37970
- minPrice: data.minPrice,
37971
- maxPrice: data.maxPrice,
37972
- includeNotForSale: data.includeNotForSale,
37973
- limit: data.limit
37974
- };
37975
- if (data.topics) {
37976
- newData.topics = [];
37977
- for (const topic of data.topics) {
37978
- newData.topics.push(topic);
37979
- }
37980
- }
37981
- return newData;
37982
- }
37983
38219
  function browserSendMessage(data) {
37984
38220
  return (chrome || browser).runtime.sendMessage(data);
37985
38221
  }
@@ -45574,6 +45810,8 @@ class MaterialDesc {
45574
45810
  dirty = false;
45575
45811
  //result
45576
45812
  createdTextures = [];
45813
+ noTextureTransparency = false;
45814
+ result;
45577
45815
  isSame(other) {
45578
45816
  if (this.dirty || other.dirty) return false;
45579
45817
  const propertiesSame = this.isDecal === other.isDecal && this.transparent === other.transparent && Math.round(this.transparency * 100) === Math.round(other.transparency * 100) && this.doubleSided === other.doubleSided && this.visible === other.visible && this.canHaveMipmaps === other.canHaveMipmaps;
@@ -45589,6 +45827,21 @@ class MaterialDesc {
45589
45827
  }
45590
45828
  return propertiesSame && layersSame;
45591
45829
  }
45830
+ needsRegeneration(other) {
45831
+ if (this.dirty || other.dirty) return true;
45832
+ const propertiesSame = this.isDecal === other.isDecal && this.doubleSided === other.doubleSided && this.visible === other.visible && this.canHaveMipmaps === other.canHaveMipmaps;
45833
+ let layersSame = true;
45834
+ if (this.layers.length !== other.layers.length) {
45835
+ layersSame = false;
45836
+ } else {
45837
+ for (let i = 0; i < this.layers.length; i++) {
45838
+ const thisLayer = this.layers[i];
45839
+ const otherLayer = other.layers[i];
45840
+ layersSame = layersSame && thisLayer.isSame(otherLayer);
45841
+ }
45842
+ }
45843
+ return !propertiesSame || !layersSame;
45844
+ }
45592
45845
  getTexturesOfType(textureType) {
45593
45846
  const urls = [];
45594
45847
  for (const layer of this.layers) {
@@ -46030,6 +46283,16 @@ class MaterialDesc {
46030
46283
  return this.compileTexture_DirectCompose(textureType);
46031
46284
  }
46032
46285
  }
46286
+ hasTransparency() {
46287
+ let hasTransparency = this.transparent;
46288
+ if (this.noTextureTransparency) {
46289
+ hasTransparency = false;
46290
+ }
46291
+ if (this.transparency > 0.01) {
46292
+ hasTransparency = true;
46293
+ }
46294
+ return hasTransparency;
46295
+ }
46033
46296
  async compileMaterial(meshDesc) {
46034
46297
  const colorTexturePromise = this.compileTexture("color", meshDesc);
46035
46298
  const normalTexturePromise = this.compileTexture("normal", meshDesc);
@@ -46043,11 +46306,10 @@ class MaterialDesc {
46043
46306
  let metalnessTexture = void 0;
46044
46307
  let emissiveTexture = void 0;
46045
46308
  let hasEmissive = false;
46046
- let hasTransparency = this.transparent;
46047
46309
  if (colorTextureInfo) {
46048
46310
  colorTexture = colorTextureInfo[0];
46049
46311
  if (!colorTextureInfo[1]) {
46050
- hasTransparency = false;
46312
+ this.noTextureTransparency = true;
46051
46313
  }
46052
46314
  }
46053
46315
  if (normalTextureInfo) {
@@ -46065,9 +46327,7 @@ class MaterialDesc {
46065
46327
  hasEmissive = true;
46066
46328
  }
46067
46329
  }
46068
- if (this.transparency > 0.01) {
46069
- hasTransparency = true;
46070
- }
46330
+ const hasTransparency = this.hasTransparency();
46071
46331
  let material = void 0;
46072
46332
  const textureTemplate = {};
46073
46333
  if (colorTexture) textureTemplate.map = colorTexture;
@@ -46108,8 +46368,27 @@ class MaterialDesc {
46108
46368
  depthWrite: this.transparency > 0 ? false : true
46109
46369
  });
46110
46370
  }
46371
+ this.result = material;
46111
46372
  return material;
46112
46373
  }
46374
+ fromMaterialDesc(other) {
46375
+ this.transparency = other.transparency;
46376
+ this.transparent = other.transparent;
46377
+ }
46378
+ updateTransparency() {
46379
+ if (this.result) {
46380
+ const ogHasTransparency = this.result.transparent;
46381
+ this.result.transparent = this.hasTransparency();
46382
+ this.result.opacity = 1 - this.transparency;
46383
+ this.result.depthWrite = this.transparency > 0 ? false : true;
46384
+ if (ogHasTransparency !== this.result.transparent) {
46385
+ this.result.needsUpdate = true;
46386
+ }
46387
+ }
46388
+ }
46389
+ updateResult() {
46390
+ this.updateTransparency();
46391
+ }
46113
46392
  addClothingLayers(parent) {
46114
46393
  const pants = parent.FindFirstChildOfClass("Pants");
46115
46394
  if (pants) {
@@ -46816,12 +47095,13 @@ class ObjectDesc extends RenderDesc {
46816
47095
  if (this.meshDesc.layerDesc && Date.now() / 1e3 - this.meshDesc.compilationTimestamp < FLAGS.LAYERED_CLOTHING_COOLDOWN) {
46817
47096
  return false;
46818
47097
  }
46819
- return !this.meshDesc.isSame(other.meshDesc) || !this.materialDesc.isSame(other.materialDesc);
47098
+ return !this.meshDesc.isSame(other.meshDesc) || this.materialDesc.needsRegeneration(other.materialDesc);
46820
47099
  }
46821
47100
  virtualFromRenderDesc(other) {
46822
47101
  this.cframe = other.cframe;
46823
47102
  this.size = other.size;
46824
47103
  this.isBodyPart = other.isBodyPart;
47104
+ this.materialDesc.fromMaterialDesc(other.materialDesc);
46825
47105
  }
46826
47106
  fromInstance(child) {
46827
47107
  this.instance = child;
@@ -47001,6 +47281,9 @@ class ObjectDesc extends RenderDesc {
47001
47281
  }
47002
47282
  }
47003
47283
  }
47284
+ if (this.materialDesc.result) {
47285
+ this.materialDesc.updateResult();
47286
+ }
47004
47287
  }
47005
47288
  static shouldRenderInstance(instance) {
47006
47289
  const isDecal = instance.className === "Decal";
@@ -50292,307 +50575,6 @@ const __vite_glob_0_20 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.de
50292
50575
  __proto__: null,
50293
50576
  PartWrapper
50294
50577
  }, Symbol.toStringTag, { value: "Module" }));
50295
- class SoundWrapperData {
50296
- audioContext;
50297
- gainNode;
50298
- buffer;
50299
- playingSource;
50300
- }
50301
- class SoundWrapper extends InstanceWrapper {
50302
- static className = "Sound";
50303
- static requiredProperties = ["Name", "Looped", "Playing", "Volume", "_data"];
50304
- setup() {
50305
- if (!this.instance.HasProperty("Name")) this.instance.addProperty(new Property("Name", DataType.String), this.instance.className);
50306
- if (!this.instance.HasProperty("Looped")) this.instance.addProperty(new Property("Looped", DataType.Bool), false);
50307
- if (!this.instance.HasProperty("Playing")) this.instance.addProperty(new Property("Playing", DataType.Bool), false);
50308
- if (!this.instance.HasProperty("Volume")) this.instance.addProperty(new Property("Volume", DataType.Float32), false);
50309
- if (!this.instance.HasProperty("_data")) this.instance.addProperty(new Property("_data", DataType.NonSerializable), new SoundWrapperData());
50310
- }
50311
- get data() {
50312
- return this.instance.Prop("_data");
50313
- }
50314
- created() {
50315
- if (this.instance.Prop("Playing")) {
50316
- this.Play();
50317
- }
50318
- this.instance.Destroying.Connect(() => {
50319
- if (this.data.playingSource) {
50320
- this.Stop();
50321
- }
50322
- this.data.audioContext = void 0;
50323
- this.data.gainNode = void 0;
50324
- this.data.buffer = void 0;
50325
- });
50326
- }
50327
- _updateVolume() {
50328
- if (this.data.gainNode) {
50329
- if (this.instance.HasProperty("Volume")) {
50330
- const volume = this.instance.Prop("Volume");
50331
- this.data.gainNode.gain.value = volume;
50332
- }
50333
- }
50334
- }
50335
- setPlaying(value) {
50336
- this.instance.setProperty("Playing", value);
50337
- }
50338
- playSource() {
50339
- if (!this.data.audioContext || !this.data.gainNode || !this.data.buffer) return;
50340
- this.data.playingSource = this.data.audioContext.createBufferSource();
50341
- this.data.playingSource.buffer = this.data.buffer;
50342
- this.data.playingSource.connect(this.data.gainNode);
50343
- this.data.gainNode.connect(this.data.audioContext.destination);
50344
- this._updateVolume();
50345
- this.data.playingSource.start(0);
50346
- this.data.playingSource.onended = (() => {
50347
- if (this.instance.Prop("Looped")) {
50348
- this.Play();
50349
- } else {
50350
- this.Stop();
50351
- }
50352
- });
50353
- }
50354
- Play() {
50355
- if (!FLAGS.AUDIO_ENABLED) return;
50356
- this.Stop();
50357
- this.setPlaying(true);
50358
- if (!this.data.audioContext) {
50359
- this.data.audioContext = new AudioContext();
50360
- }
50361
- if (!this.data.gainNode) {
50362
- this.data.gainNode = this.data.audioContext.createGain();
50363
- }
50364
- if (!this.data.buffer) {
50365
- let audioUrl = void 0;
50366
- if (this.instance.HasProperty("SoundId")) {
50367
- audioUrl = this.instance.Prop("SoundId");
50368
- } else if (this.instance.HasProperty("AudioContent")) {
50369
- audioUrl = this.instance.Prop("AudioContent").uri;
50370
- }
50371
- if (audioUrl && audioUrl.length > 0) {
50372
- API.Asset.GetAssetBuffer(audioUrl).then((responseBuffer) => {
50373
- if (responseBuffer instanceof Response || !this.data.audioContext) return;
50374
- const buffer2 = responseBuffer.slice(0);
50375
- this.data.audioContext.decodeAudioData(buffer2).then((decodedData) => {
50376
- if (!this.data.audioContext || !this.data.gainNode) return;
50377
- this.data.buffer = decodedData;
50378
- this.playSource();
50379
- });
50380
- });
50381
- }
50382
- } else if (this.data.buffer) {
50383
- this.playSource();
50384
- }
50385
- }
50386
- Stop() {
50387
- this.setPlaying(false);
50388
- if (this.data.playingSource) {
50389
- this.data.playingSource.stop();
50390
- this.data.playingSource = void 0;
50391
- }
50392
- }
50393
- }
50394
- const __vite_glob_0_22 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
50395
- __proto__: null,
50396
- SoundWrapper
50397
- }, Symbol.toStringTag, { value: "Module" }));
50398
- class ScriptWrapperData {
50399
- shouldStop = false;
50400
- }
50401
- class ScriptWrapper extends InstanceWrapper {
50402
- static className = "Script";
50403
- static requiredProperties = ["Name", "_data"];
50404
- setup() {
50405
- if (!this.instance.HasProperty("Name")) this.instance.addProperty(new Property("Name", DataType.String), this.instance.className);
50406
- if (!this.instance.HasProperty("_data")) this.instance.addProperty(new Property("_data", DataType.NonSerializable), new ScriptWrapperData());
50407
- }
50408
- get data() {
50409
- return this.instance.Prop("_data");
50410
- }
50411
- created() {
50412
- this.Run();
50413
- }
50414
- Run() {
50415
- switch (this.instance.Prop("Name")) {
50416
- case "ChickenSounds":
50417
- case "HarmonicaSounds":
50418
- case "SoundPlayer":
50419
- this.SoundPlayer(this.instance);
50420
- break;
50421
- }
50422
- }
50423
- //Scripts
50424
- async SoundPlayer(script) {
50425
- let Handle = void 0;
50426
- if (script.parent && script.parent.Prop("Name") === "Handle") {
50427
- Handle = script.parent;
50428
- } else if (script.parent && script.parent.FindFirstChild("Handle")) {
50429
- Handle = script.parent.FindFirstChild("Handle");
50430
- }
50431
- if (!Handle) return;
50432
- const Hat = Handle.parent;
50433
- if (!Hat) return;
50434
- const Sounds = [];
50435
- for (const child of Handle.GetDescendants()) {
50436
- if (child.className === "Sound") {
50437
- Sounds.push(child);
50438
- }
50439
- }
50440
- function IsBeingWorn() {
50441
- return Hat?.parent?.FindFirstChild("Humanoid");
50442
- }
50443
- let maxTime = 20;
50444
- if (script.Prop("Name") === "SoundPlayer") {
50445
- maxTime = 15;
50446
- }
50447
- while (true) {
50448
- await Wait(mathRandom(5, maxTime));
50449
- if (this.instance.destroyed || this.data.shouldStop) return;
50450
- if (IsBeingWorn()) {
50451
- const index = mathRandom(0, Sounds.length - 1);
50452
- const Sound = Sounds[index];
50453
- const soundWrapper = new SoundWrapper(Sound);
50454
- soundWrapper.Play();
50455
- }
50456
- }
50457
- }
50458
- }
50459
- const __vite_glob_0_21 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
50460
- __proto__: null,
50461
- ScriptWrapper
50462
- }, Symbol.toStringTag, { value: "Module" }));
50463
- class ToolWrapper extends InstanceWrapper {
50464
- static className = "Tool";
50465
- static requiredProperties = [
50466
- "Name",
50467
- "Grip"
50468
- ];
50469
- setup() {
50470
- if (!this.instance.HasProperty("Name")) this.instance.addProperty(new Property("Name", DataType.String), this.instance.className);
50471
- if (!this.instance.HasProperty("Grip")) this.instance.addProperty(new Property("Grip", DataType.CFrame), new CFrame());
50472
- }
50473
- created() {
50474
- this.instance.AncestryChanged.Connect(() => {
50475
- this.createWeld();
50476
- });
50477
- }
50478
- //doing this is actually inaccurate because tools dont create welds, but its easier
50479
- createWeld() {
50480
- const handle = this.instance.FindFirstChild("Handle");
50481
- const rig = this.instance.parent;
50482
- const grip = this.instance.PropOrDefault("Grip", new CFrame()).clone();
50483
- if (handle) {
50484
- const oldToolWeld = handle.FindFirstChild("ToolWeld_GripRoAvatar");
50485
- if (oldToolWeld) {
50486
- oldToolWeld.Destroy();
50487
- }
50488
- }
50489
- const humanoid = rig?.FindFirstChildOfClass("Humanoid");
50490
- if (handle && rig && rig.className === "Model" && humanoid) {
50491
- const rightHand = rig.FindFirstChild("RightHand") || rig.FindFirstChild("Right Arm");
50492
- if (rightHand) {
50493
- for (const child of rightHand.GetDescendants()) {
50494
- if (child.Prop("Name") === "RightGripAttachment") {
50495
- const rightGripAttCF = child.PropOrDefault("CFrame", new CFrame()).clone();
50496
- if (humanoid.Prop("RigType") === HumanoidRigType.R6) {
50497
- rightGripAttCF.Orientation[0] -= 90;
50498
- }
50499
- const weld = new Instance("Weld");
50500
- weld.addProperty(new Property("Name", DataType.String), "ToolWeld_GripRoAvatar");
50501
- weld.addProperty(new Property("Archivable", DataType.Bool), true);
50502
- weld.addProperty(new Property("C0", DataType.CFrame), rightGripAttCF);
50503
- weld.addProperty(new Property("C1", DataType.CFrame), grip);
50504
- weld.addProperty(new Property("Part0", DataType.Referent), child.parent);
50505
- weld.addProperty(new Property("Part1", DataType.Referent), handle);
50506
- weld.addProperty(new Property("Active", DataType.Bool), true);
50507
- weld.addProperty(new Property("Enabled", DataType.Bool), false);
50508
- weld.setParent(handle);
50509
- weld.setProperty("Enabled", true);
50510
- }
50511
- }
50512
- }
50513
- }
50514
- }
50515
- }
50516
- const __vite_glob_0_23 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
50517
- __proto__: null,
50518
- ToolWrapper
50519
- }, Symbol.toStringTag, { value: "Module" }));
50520
- class WedgePartWrapper extends BasePartWrapper {
50521
- static className = "WedgePart";
50522
- }
50523
- const __vite_glob_0_24 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
50524
- __proto__: null,
50525
- WedgePartWrapper
50526
- }, Symbol.toStringTag, { value: "Module" }));
50527
- class WeldWrapper extends JointInstanceWrapper {
50528
- static className = "Weld";
50529
- }
50530
- const __vite_glob_0_25 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
50531
- __proto__: null,
50532
- WeldWrapper
50533
- }, Symbol.toStringTag, { value: "Module" }));
50534
- const modules$1 = /* @__PURE__ */ Object.assign({ "./instance/Accessory.ts": __vite_glob_0_0$1, "./instance/AccessoryDescription.ts": __vite_glob_0_1$1, "./instance/AnimationConstraint.ts": __vite_glob_0_2$1, "./instance/Animator.ts": __vite_glob_0_3, "./instance/Attachment.ts": __vite_glob_0_4, "./instance/BasePart.ts": __vite_glob_0_5, "./instance/BodyColors.ts": __vite_glob_0_6, "./instance/BodyPartDescription.ts": __vite_glob_0_7, "./instance/Bone.ts": __vite_glob_0_8, "./instance/Constraint.ts": __vite_glob_0_9, "./instance/Decal.ts": __vite_glob_0_10, "./instance/FaceControls.ts": __vite_glob_0_11, "./instance/HumanoidDescription.ts": __vite_glob_0_12, "./instance/InstanceWrapper.ts": __vite_glob_0_13, "./instance/JointInstance.ts": __vite_glob_0_14, "./instance/MakeupDescription.ts": __vite_glob_0_15, "./instance/ManualWeld.ts": __vite_glob_0_16, "./instance/MeshPart.ts": __vite_glob_0_17, "./instance/Model.ts": __vite_glob_0_18, "./instance/Motor6D.ts": __vite_glob_0_19, "./instance/Part.ts": __vite_glob_0_20, "./instance/Script.ts": __vite_glob_0_21, "./instance/Sound.ts": __vite_glob_0_22, "./instance/Tool.ts": __vite_glob_0_23, "./instance/WedgePart.ts": __vite_glob_0_24, "./instance/Weld.ts": __vite_glob_0_25 });
50535
- function RegisterWrappers() {
50536
- for (const module of Object.values(modules$1)) {
50537
- for (const exprt of Object.values(module)) {
50538
- let prototype = Object.getPrototypeOf(exprt);
50539
- while (prototype) {
50540
- if (prototype === InstanceWrapper) {
50541
- exprt.register();
50542
- break;
50543
- }
50544
- prototype = Object.getPrototypeOf(prototype);
50545
- }
50546
- }
50547
- }
50548
- }
50549
- const attachmentGeometry = new SphereGeometry(0.125, 16, 8);
50550
- class AttachmentDesc extends RenderDesc {
50551
- static classTypes = ["Attachment"];
50552
- visible = false;
50553
- cframe = new CFrame();
50554
- isSame(other) {
50555
- return this.visible === other.visible && this.cframe.isSame(other.cframe);
50556
- }
50557
- needsRegeneration(other) {
50558
- return this.visible !== other.visible;
50559
- }
50560
- virtualFromRenderDesc(other) {
50561
- this.cframe = other.cframe.clone();
50562
- }
50563
- fromInstance(child) {
50564
- const attachmentW = new AttachmentWrapper(child);
50565
- this.cframe = attachmentW.getWorldCFrame();
50566
- this.visible = child.PropOrDefault("Visible", this.visible) || FLAGS.ALWAYS_SHOW_ATTACHMENTS;
50567
- }
50568
- async compileResults() {
50569
- this.results = [];
50570
- if (this.visible) {
50571
- const mesh = new Mesh(attachmentGeometry, new MeshLambertMaterial({ color: 65280 }));
50572
- mesh.name = this.instance ? this.instance.PropOrDefault("Name", "Unknown") + "_Att" : "Unknown_Att";
50573
- this.results.push(mesh);
50574
- }
50575
- this.updateResults();
50576
- return this.results;
50577
- }
50578
- updateResults() {
50579
- if (!this.results) return;
50580
- for (const attachment of this.results) {
50581
- const resultCF = this.cframe;
50582
- setTHREEObjectCF(attachment, resultCF);
50583
- }
50584
- }
50585
- dispose(_renderer, scene) {
50586
- if (!this.results) return;
50587
- for (const result of this.results) {
50588
- scene.remove(result);
50589
- }
50590
- }
50591
- }
50592
- const __vite_glob_0_0 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
50593
- __proto__: null,
50594
- AttachmentDesc
50595
- }, Symbol.toStringTag, { value: "Module" }));
50596
50578
  const particle_vertexShader = (
50597
50579
  /*glsl*/
50598
50580
  `
@@ -51050,8 +51032,8 @@ class EmitterDesc extends DisposableDesc {
51050
51032
  }
51051
51033
  return this.result;
51052
51034
  }
51053
- emit(groupDesc) {
51054
- if (this.particles.length >= this.maxCount || groupDesc.enabled === false) {
51035
+ emit(groupDesc, force = false) {
51036
+ if (this.particles.length >= this.maxCount || groupDesc.enabled === false && !force) {
51055
51037
  return;
51056
51038
  }
51057
51039
  const speed = randomBetween(this.speed.Min, this.speed.Max);
@@ -51249,6 +51231,7 @@ class EmitterGroupDesc extends RenderDesc {
51249
51231
  this.lowerBound = other.lowerBound;
51250
51232
  this.higherBound = other.higherBound;
51251
51233
  this.emitterDir = other.emitterDir;
51234
+ this.enabled = other.enabled;
51252
51235
  for (let i = 0; i < this.emitterDescs.length; i++) {
51253
51236
  this.emitterDescs[i].fromEmitterDesc(other.emitterDescs[i]);
51254
51237
  }
@@ -51490,6 +51473,524 @@ const __vite_glob_0_1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.def
51490
51473
  __proto__: null,
51491
51474
  EmitterGroupDesc
51492
51475
  }, Symbol.toStringTag, { value: "Module" }));
51476
+ class ParticleEmitterWrapper extends InstanceWrapper {
51477
+ static className = "ParticleEmitter";
51478
+ static requiredProperties = [
51479
+ "Name"
51480
+ ];
51481
+ setup() {
51482
+ if (!this.instance.HasProperty("Name")) this.instance.addProperty(new Property("Name", DataType.String), this.instance.className);
51483
+ }
51484
+ Emit(count = 16) {
51485
+ const renderDescs = RBXRenderer.getRenderDescs(this.instance);
51486
+ for (const renderDesc of renderDescs) {
51487
+ if (renderDesc instanceof EmitterGroupDesc) {
51488
+ for (const emitterDesc of renderDesc.emitterDescs) {
51489
+ for (let i = 0; i < count; i++) {
51490
+ emitterDesc.emit(renderDesc, true);
51491
+ }
51492
+ }
51493
+ }
51494
+ }
51495
+ }
51496
+ }
51497
+ const __vite_glob_0_21 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
51498
+ __proto__: null,
51499
+ ParticleEmitterWrapper
51500
+ }, Symbol.toStringTag, { value: "Module" }));
51501
+ class SoundWrapperData {
51502
+ audioContext;
51503
+ gainNode;
51504
+ buffer;
51505
+ playingSource;
51506
+ }
51507
+ class SoundWrapper extends InstanceWrapper {
51508
+ static className = "Sound";
51509
+ static requiredProperties = ["Name", "Looped", "Playing", "Volume", "_data"];
51510
+ setup() {
51511
+ if (!this.instance.HasProperty("Name")) this.instance.addProperty(new Property("Name", DataType.String), this.instance.className);
51512
+ if (!this.instance.HasProperty("Looped")) this.instance.addProperty(new Property("Looped", DataType.Bool), false);
51513
+ if (!this.instance.HasProperty("Playing")) this.instance.addProperty(new Property("Playing", DataType.Bool), false);
51514
+ if (!this.instance.HasProperty("Volume")) this.instance.addProperty(new Property("Volume", DataType.Float32), false);
51515
+ if (!this.instance.HasProperty("_data")) this.instance.addProperty(new Property("_data", DataType.NonSerializable), new SoundWrapperData());
51516
+ }
51517
+ get data() {
51518
+ return this.instance.Prop("_data");
51519
+ }
51520
+ created() {
51521
+ if (this.instance.Prop("Playing")) {
51522
+ this.Play();
51523
+ }
51524
+ this.instance.Destroying.Connect(() => {
51525
+ if (this.data.playingSource) {
51526
+ this.Stop();
51527
+ }
51528
+ this.data.audioContext = void 0;
51529
+ this.data.gainNode = void 0;
51530
+ this.data.buffer = void 0;
51531
+ });
51532
+ this.instance.Changed.Connect(() => {
51533
+ this._updateVolume();
51534
+ });
51535
+ }
51536
+ _updateVolume() {
51537
+ if (this.data.gainNode) {
51538
+ if (this.instance.HasProperty("Volume")) {
51539
+ const volume = this.instance.Prop("Volume");
51540
+ this.data.gainNode.gain.value = volume;
51541
+ }
51542
+ }
51543
+ }
51544
+ setPlaying(value) {
51545
+ this.instance.setProperty("Playing", value);
51546
+ }
51547
+ playSource() {
51548
+ if (!this.data.audioContext || !this.data.gainNode || !this.data.buffer) return;
51549
+ this.data.playingSource = this.data.audioContext.createBufferSource();
51550
+ this.data.playingSource.buffer = this.data.buffer;
51551
+ this.data.playingSource.connect(this.data.gainNode);
51552
+ this.data.gainNode.connect(this.data.audioContext.destination);
51553
+ this._updateVolume();
51554
+ this.data.playingSource.start(0);
51555
+ this.data.playingSource.onended = (() => {
51556
+ if (this.instance.Prop("Looped")) {
51557
+ this.Play();
51558
+ } else {
51559
+ this.Stop();
51560
+ }
51561
+ });
51562
+ }
51563
+ Play() {
51564
+ if (!FLAGS.AUDIO_ENABLED) return;
51565
+ this.Stop();
51566
+ this.setPlaying(true);
51567
+ if (!this.data.audioContext) {
51568
+ this.data.audioContext = new AudioContext();
51569
+ }
51570
+ if (!this.data.gainNode) {
51571
+ this.data.gainNode = this.data.audioContext.createGain();
51572
+ }
51573
+ if (!this.data.buffer) {
51574
+ let audioUrl = void 0;
51575
+ if (this.instance.HasProperty("SoundId")) {
51576
+ audioUrl = this.instance.Prop("SoundId");
51577
+ } else if (this.instance.HasProperty("AudioContent")) {
51578
+ audioUrl = this.instance.Prop("AudioContent").uri;
51579
+ }
51580
+ if (audioUrl && audioUrl.length > 0) {
51581
+ API.Asset.GetAssetBuffer(audioUrl).then((responseBuffer) => {
51582
+ if (responseBuffer instanceof Response || !this.data.audioContext) return;
51583
+ const buffer2 = responseBuffer.slice(0);
51584
+ this.data.audioContext.decodeAudioData(buffer2).then((decodedData) => {
51585
+ if (!this.data.audioContext || !this.data.gainNode) return;
51586
+ this.data.buffer = decodedData;
51587
+ this.playSource();
51588
+ });
51589
+ });
51590
+ }
51591
+ } else if (this.data.buffer) {
51592
+ this.playSource();
51593
+ }
51594
+ }
51595
+ Stop() {
51596
+ this.setPlaying(false);
51597
+ if (this.data.playingSource) {
51598
+ this.data.playingSource.stop();
51599
+ this.data.playingSource = void 0;
51600
+ }
51601
+ }
51602
+ }
51603
+ const __vite_glob_0_23 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
51604
+ __proto__: null,
51605
+ SoundWrapper
51606
+ }, Symbol.toStringTag, { value: "Module" }));
51607
+ class ScriptWrapperData {
51608
+ shouldStop = false;
51609
+ }
51610
+ class ScriptWrapper extends InstanceWrapper {
51611
+ static className = "Script";
51612
+ static requiredProperties = ["Name", "_data"];
51613
+ setup() {
51614
+ if (!this.instance.HasProperty("Name")) this.instance.addProperty(new Property("Name", DataType.String), this.instance.className);
51615
+ if (!this.instance.HasProperty("_data")) this.instance.addProperty(new Property("_data", DataType.NonSerializable), new ScriptWrapperData());
51616
+ }
51617
+ get data() {
51618
+ return this.instance.Prop("_data");
51619
+ }
51620
+ created() {
51621
+ this.Run();
51622
+ }
51623
+ Run() {
51624
+ switch (this.instance.Prop("Name")) {
51625
+ case "ChickenSounds":
51626
+ case "HarmonicaSounds":
51627
+ case "SoundPlayer":
51628
+ this.SoundPlayer(this.instance);
51629
+ break;
51630
+ case "HatScript2.0":
51631
+ this.HatScript20(this.instance);
51632
+ break;
51633
+ }
51634
+ }
51635
+ //Scripts
51636
+ async SoundPlayer(script) {
51637
+ let Handle = void 0;
51638
+ if (script.parent && script.parent.Prop("Name") === "Handle") {
51639
+ Handle = script.parent;
51640
+ } else if (script.parent && script.parent.FindFirstChild("Handle")) {
51641
+ Handle = script.parent.FindFirstChild("Handle");
51642
+ }
51643
+ if (!Handle) return;
51644
+ const Hat = Handle.parent;
51645
+ if (!Hat) return;
51646
+ const Sounds = [];
51647
+ for (const child of Handle.GetDescendants()) {
51648
+ if (child.className === "Sound") {
51649
+ Sounds.push(child);
51650
+ }
51651
+ }
51652
+ function IsBeingWorn() {
51653
+ return Hat?.parent?.FindFirstChild("Humanoid");
51654
+ }
51655
+ let maxTime = 20;
51656
+ if (script.Prop("Name") === "SoundPlayer") {
51657
+ maxTime = 15;
51658
+ }
51659
+ while (true) {
51660
+ await Wait(mathRandom(5, maxTime));
51661
+ if (this.instance.destroyed || this.data.shouldStop) return;
51662
+ if (IsBeingWorn()) {
51663
+ const index = mathRandom(0, Sounds.length - 1);
51664
+ const Sound = Sounds[index];
51665
+ const soundWrapper = new SoundWrapper(Sound);
51666
+ soundWrapper.Play();
51667
+ }
51668
+ }
51669
+ }
51670
+ async HatScript20(script) {
51671
+ const now = /* @__PURE__ */ new Date();
51672
+ const month = now.getMonth();
51673
+ const day = now.getDay();
51674
+ const data = this.data;
51675
+ let hw;
51676
+ let tg;
51677
+ let xm;
51678
+ let bd;
51679
+ let pt;
51680
+ let vt;
51681
+ let af;
51682
+ if (month == 10 && day > 21) {
51683
+ hw = true;
51684
+ } else if (month == 11 && day > 19) {
51685
+ tg = true;
51686
+ } else if (month == 12 && day > 17 && day < 28) {
51687
+ xm = true;
51688
+ } else if (month == 9 && day == 1) {
51689
+ bd = true;
51690
+ } else if (month == 3 && day > 11 && day < 20) {
51691
+ pt = true;
51692
+ } else if (month == 2 && day > 8 && day < 17) {
51693
+ vt = true;
51694
+ } else if (month == 4 && day == 1) {
51695
+ af = true;
51696
+ }
51697
+ let emitter = script.parent?.Child("ParticleEmitter");
51698
+ const burst = script.parent?.Child("Burst");
51699
+ async function snowBlower() {
51700
+ const snow1 = script.parent?.Child("Snowflake1");
51701
+ const snow2 = script.parent?.Child("Snowflake2");
51702
+ while (true) {
51703
+ await Wait(Math.random() * 5);
51704
+ if (script.destroyed || data.shouldStop) return;
51705
+ snow1?.setProperty("Enabled", false);
51706
+ snow2?.setProperty("Enabled", true);
51707
+ await Wait(Math.random() * 5);
51708
+ if (script.destroyed || data.shouldStop) return;
51709
+ snow1?.setProperty("Enabled", true);
51710
+ snow2?.setProperty("Enabled", false);
51711
+ if (Math.random() > 0.97) {
51712
+ snow1?.setProperty("Enabled", false);
51713
+ await Wait(4);
51714
+ if (script.destroyed || data.shouldStop) return;
51715
+ (snow1?.w).Emit(22);
51716
+ await Wait(Math.random());
51717
+ if (script.destroyed || data.shouldStop) return;
51718
+ (snow2?.w).Emit(22);
51719
+ await Wait(2);
51720
+ if (script.destroyed || data.shouldStop) return;
51721
+ }
51722
+ }
51723
+ }
51724
+ async function leafBlower() {
51725
+ const leaf1 = script.parent?.Child("Leaf1");
51726
+ const leaf2 = script.parent?.Child("Leaf2");
51727
+ while (true) {
51728
+ await Wait(Math.random() * 5);
51729
+ if (script.destroyed || data.shouldStop) return;
51730
+ leaf1?.setProperty("Enabled", false);
51731
+ leaf2?.setProperty("Enabled", true);
51732
+ await Wait(Math.random() * 5);
51733
+ if (script.destroyed || data.shouldStop) return;
51734
+ leaf1?.setProperty("Enabled", true);
51735
+ leaf2?.setProperty("Enabled", false);
51736
+ if (Math.random() > 0.97) {
51737
+ leaf1?.setProperty("Enabled", false);
51738
+ await Wait(4);
51739
+ if (script.destroyed || data.shouldStop) return;
51740
+ (leaf1?.w).Emit(22);
51741
+ await Wait(Math.random());
51742
+ if (script.destroyed || data.shouldStop) return;
51743
+ (leaf2?.w).Emit(22);
51744
+ await Wait(2);
51745
+ if (script.destroyed || data.shouldStop) return;
51746
+ }
51747
+ }
51748
+ }
51749
+ async function cloverBlower() {
51750
+ const leaf1 = script.parent?.Child("Clover1");
51751
+ const leaf2 = script.parent?.Child("Clover2");
51752
+ while (true) {
51753
+ await Wait(Math.random() * 5);
51754
+ if (script.destroyed || data.shouldStop) return;
51755
+ leaf1?.setProperty("Enabled", false);
51756
+ leaf2?.setProperty("Enabled", true);
51757
+ await Wait(Math.random() * 5);
51758
+ if (script.destroyed || data.shouldStop) return;
51759
+ leaf1?.setProperty("Enabled", true);
51760
+ leaf2?.setProperty("Enabled", false);
51761
+ if (Math.random() > 0.97) {
51762
+ leaf1?.setProperty("Enabled", false);
51763
+ await Wait(4);
51764
+ if (script.destroyed || data.shouldStop) return;
51765
+ (leaf1?.w).Emit(22);
51766
+ await Wait(Math.random());
51767
+ if (script.destroyed || data.shouldStop) return;
51768
+ (leaf2?.w).Emit(22);
51769
+ await Wait(2);
51770
+ if (script.destroyed || data.shouldStop) return;
51771
+ }
51772
+ }
51773
+ }
51774
+ if (hw) {
51775
+ emitter?.setProperty("Enabled", false);
51776
+ emitter = script.parent?.Child("Hallow");
51777
+ if (script.parent?.parent?.IsA("MeshPart")) {
51778
+ script.parent?.parent?.setProperty("TextureID", "rbxassetid://6991166143");
51779
+ } else {
51780
+ script.parent?.parent?.Child("Mesh")?.setProperty("TextureId", "rbxassetid://6991166143");
51781
+ }
51782
+ } else if (tg) {
51783
+ if (script.parent?.parent?.IsA("MeshPart")) {
51784
+ script.parent?.parent?.setProperty("TextureID", "rbxassetid://6991393806");
51785
+ } else {
51786
+ script.parent?.parent?.Child("Mesh")?.setProperty("TextureId", "rbxassetid://6991393806");
51787
+ }
51788
+ leafBlower();
51789
+ } else if (xm) {
51790
+ emitter?.setProperty("Enabled", false);
51791
+ emitter = script.parent?.Child("Snowflake3");
51792
+ snowBlower();
51793
+ } else if (bd) {
51794
+ emitter?.setProperty("Enabled", false);
51795
+ emitter = script.parent?.Child("Confetti");
51796
+ if (script.parent?.parent?.IsA("MeshPart")) {
51797
+ script.parent?.parent?.setProperty("TextureID", "rbxassetid://2399316028");
51798
+ } else {
51799
+ script.parent?.parent?.Child("Mesh")?.setProperty("TextureId", "rbxassetid://2399316028");
51800
+ }
51801
+ } else if (pt) {
51802
+ if (script.Parent?.Parent?.IsA("MeshPart")) {
51803
+ script.parent?.parent?.setProperty("TextureID", "rbxassetid://2399447918");
51804
+ } else {
51805
+ script.parent?.parent?.Child("Mesh")?.setProperty("TextureId", "rbxassetid://2399447918");
51806
+ }
51807
+ cloverBlower();
51808
+ } else if (vt) {
51809
+ emitter?.setProperty("Enabled", false);
51810
+ emitter = script.Parent?.Child("Heart");
51811
+ if (script.Parent?.Parent?.IsA("MeshPart")) {
51812
+ script.parent?.parent?.setProperty("TextureID", "rbxassetid://2399448372");
51813
+ } else {
51814
+ script.parent?.parent?.Child("Mesh")?.setProperty("TextureId", "rbxassetid://2399448372");
51815
+ }
51816
+ } else if (af) {
51817
+ emitter?.setProperty("Enabled", false);
51818
+ emitter = script.Parent?.Child("Hats");
51819
+ script.Parent?.Child("Smokescreen")?.setProperty("Enabled", true);
51820
+ script.Parent?.Parent?.setProperty("Transparency", 1);
51821
+ }
51822
+ while (true) {
51823
+ await Wait(1.3);
51824
+ if (script.destroyed || data.shouldStop) return;
51825
+ emitter?.setProperty("Enabled", false);
51826
+ await Wait(0.8);
51827
+ if (script.destroyed || data.shouldStop) return;
51828
+ emitter?.setProperty("Enabled", true);
51829
+ const rando = Math.random();
51830
+ if (rando > 0.97) {
51831
+ emitter?.setProperty("Enabled", false);
51832
+ await Wait(4);
51833
+ if (script.destroyed || data.shouldStop) return;
51834
+ burst?.setProperty("Enabled", true);
51835
+ await Wait(2);
51836
+ if (script.destroyed || data.shouldStop) return;
51837
+ burst?.setProperty("Enabled", false);
51838
+ emitter?.setProperty("Enabled", true);
51839
+ } else if (rando > 0.969) {
51840
+ emitter?.setProperty("Enabled", false);
51841
+ await Wait(4);
51842
+ if (script.destroyed || data.shouldStop) return;
51843
+ for (const v of script.Parent?.GetChildren() || []) {
51844
+ if (v.IsA("ParticleEmitter")) {
51845
+ v.w.Emit(mathRandom(6, 10));
51846
+ await Wait(0.5);
51847
+ if (script.destroyed || data.shouldStop) return;
51848
+ }
51849
+ }
51850
+ await Wait(2);
51851
+ if (script.destroyed || data.shouldStop) return;
51852
+ emitter?.setProperty("Enabled", true);
51853
+ }
51854
+ }
51855
+ }
51856
+ }
51857
+ const __vite_glob_0_22 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
51858
+ __proto__: null,
51859
+ ScriptWrapper
51860
+ }, Symbol.toStringTag, { value: "Module" }));
51861
+ class ToolWrapper extends InstanceWrapper {
51862
+ static className = "Tool";
51863
+ static requiredProperties = [
51864
+ "Name",
51865
+ "Grip"
51866
+ ];
51867
+ setup() {
51868
+ if (!this.instance.HasProperty("Name")) this.instance.addProperty(new Property("Name", DataType.String), this.instance.className);
51869
+ if (!this.instance.HasProperty("Grip")) this.instance.addProperty(new Property("Grip", DataType.CFrame), new CFrame());
51870
+ }
51871
+ created() {
51872
+ this.instance.AncestryChanged.Connect(() => {
51873
+ this.createWeld();
51874
+ });
51875
+ }
51876
+ //doing this is actually inaccurate because tools dont create welds, but its easier
51877
+ createWeld() {
51878
+ const handle = this.instance.FindFirstChild("Handle");
51879
+ const rig = this.instance.parent;
51880
+ const grip = this.instance.PropOrDefault("Grip", new CFrame()).clone();
51881
+ if (handle) {
51882
+ const oldToolWeld = handle.FindFirstChild("ToolWeld_GripRoAvatar");
51883
+ if (oldToolWeld) {
51884
+ oldToolWeld.Destroy();
51885
+ }
51886
+ }
51887
+ const humanoid = rig?.FindFirstChildOfClass("Humanoid");
51888
+ if (handle && rig && rig.className === "Model" && humanoid) {
51889
+ const rightHand = rig.FindFirstChild("RightHand") || rig.FindFirstChild("Right Arm");
51890
+ if (rightHand) {
51891
+ for (const child of rightHand.GetDescendants()) {
51892
+ if (child.Prop("Name") === "RightGripAttachment") {
51893
+ const rightGripAttCF = child.PropOrDefault("CFrame", new CFrame()).clone();
51894
+ if (humanoid.Prop("RigType") === HumanoidRigType.R6) {
51895
+ rightGripAttCF.Orientation[0] -= 90;
51896
+ }
51897
+ const weld = new Instance("Weld");
51898
+ weld.addProperty(new Property("Name", DataType.String), "ToolWeld_GripRoAvatar");
51899
+ weld.addProperty(new Property("Archivable", DataType.Bool), true);
51900
+ weld.addProperty(new Property("C0", DataType.CFrame), rightGripAttCF);
51901
+ weld.addProperty(new Property("C1", DataType.CFrame), grip);
51902
+ weld.addProperty(new Property("Part0", DataType.Referent), child.parent);
51903
+ weld.addProperty(new Property("Part1", DataType.Referent), handle);
51904
+ weld.addProperty(new Property("Active", DataType.Bool), true);
51905
+ weld.addProperty(new Property("Enabled", DataType.Bool), false);
51906
+ weld.setParent(handle);
51907
+ weld.setProperty("Enabled", true);
51908
+ }
51909
+ }
51910
+ }
51911
+ }
51912
+ }
51913
+ }
51914
+ const __vite_glob_0_24 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
51915
+ __proto__: null,
51916
+ ToolWrapper
51917
+ }, Symbol.toStringTag, { value: "Module" }));
51918
+ class WedgePartWrapper extends BasePartWrapper {
51919
+ static className = "WedgePart";
51920
+ }
51921
+ const __vite_glob_0_25 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
51922
+ __proto__: null,
51923
+ WedgePartWrapper
51924
+ }, Symbol.toStringTag, { value: "Module" }));
51925
+ class WeldWrapper extends JointInstanceWrapper {
51926
+ static className = "Weld";
51927
+ }
51928
+ const __vite_glob_0_26 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
51929
+ __proto__: null,
51930
+ WeldWrapper
51931
+ }, Symbol.toStringTag, { value: "Module" }));
51932
+ const modules$1 = /* @__PURE__ */ Object.assign({ "./instance/Accessory.ts": __vite_glob_0_0$1, "./instance/AccessoryDescription.ts": __vite_glob_0_1$1, "./instance/AnimationConstraint.ts": __vite_glob_0_2$1, "./instance/Animator.ts": __vite_glob_0_3, "./instance/Attachment.ts": __vite_glob_0_4, "./instance/BasePart.ts": __vite_glob_0_5, "./instance/BodyColors.ts": __vite_glob_0_6, "./instance/BodyPartDescription.ts": __vite_glob_0_7, "./instance/Bone.ts": __vite_glob_0_8, "./instance/Constraint.ts": __vite_glob_0_9, "./instance/Decal.ts": __vite_glob_0_10, "./instance/FaceControls.ts": __vite_glob_0_11, "./instance/HumanoidDescription.ts": __vite_glob_0_12, "./instance/InstanceWrapper.ts": __vite_glob_0_13, "./instance/JointInstance.ts": __vite_glob_0_14, "./instance/MakeupDescription.ts": __vite_glob_0_15, "./instance/ManualWeld.ts": __vite_glob_0_16, "./instance/MeshPart.ts": __vite_glob_0_17, "./instance/Model.ts": __vite_glob_0_18, "./instance/Motor6D.ts": __vite_glob_0_19, "./instance/Part.ts": __vite_glob_0_20, "./instance/ParticleEmitter.ts": __vite_glob_0_21, "./instance/Script.ts": __vite_glob_0_22, "./instance/Sound.ts": __vite_glob_0_23, "./instance/Tool.ts": __vite_glob_0_24, "./instance/WedgePart.ts": __vite_glob_0_25, "./instance/Weld.ts": __vite_glob_0_26 });
51933
+ function RegisterWrappers() {
51934
+ for (const module of Object.values(modules$1)) {
51935
+ for (const exprt of Object.values(module)) {
51936
+ let prototype = Object.getPrototypeOf(exprt);
51937
+ while (prototype) {
51938
+ if (prototype === InstanceWrapper) {
51939
+ exprt.register();
51940
+ break;
51941
+ }
51942
+ prototype = Object.getPrototypeOf(prototype);
51943
+ }
51944
+ }
51945
+ }
51946
+ }
51947
+ const attachmentGeometry = new SphereGeometry(0.125, 16, 8);
51948
+ class AttachmentDesc extends RenderDesc {
51949
+ static classTypes = ["Attachment"];
51950
+ visible = false;
51951
+ cframe = new CFrame();
51952
+ isSame(other) {
51953
+ return this.visible === other.visible && this.cframe.isSame(other.cframe);
51954
+ }
51955
+ needsRegeneration(other) {
51956
+ return this.visible !== other.visible;
51957
+ }
51958
+ virtualFromRenderDesc(other) {
51959
+ this.cframe = other.cframe.clone();
51960
+ }
51961
+ fromInstance(child) {
51962
+ const attachmentW = new AttachmentWrapper(child);
51963
+ this.cframe = attachmentW.getWorldCFrame();
51964
+ this.visible = child.PropOrDefault("Visible", this.visible) || FLAGS.ALWAYS_SHOW_ATTACHMENTS;
51965
+ }
51966
+ async compileResults() {
51967
+ this.results = [];
51968
+ if (this.visible) {
51969
+ const mesh = new Mesh(attachmentGeometry, new MeshLambertMaterial({ color: 65280 }));
51970
+ mesh.name = this.instance ? this.instance.PropOrDefault("Name", "Unknown") + "_Att" : "Unknown_Att";
51971
+ this.results.push(mesh);
51972
+ }
51973
+ this.updateResults();
51974
+ return this.results;
51975
+ }
51976
+ updateResults() {
51977
+ if (!this.results) return;
51978
+ for (const attachment of this.results) {
51979
+ const resultCF = this.cframe;
51980
+ setTHREEObjectCF(attachment, resultCF);
51981
+ }
51982
+ }
51983
+ dispose(_renderer, scene) {
51984
+ if (!this.results) return;
51985
+ for (const result of this.results) {
51986
+ scene.remove(result);
51987
+ }
51988
+ }
51989
+ }
51990
+ const __vite_glob_0_0 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
51991
+ __proto__: null,
51992
+ AttachmentDesc
51993
+ }, Symbol.toStringTag, { value: "Module" }));
51493
51994
  function disposeLight(scene, light) {
51494
51995
  if (light.shadow && light.shadow.map) {
51495
51996
  light.shadow.map.dispose();
@@ -52337,6 +52838,14 @@ class RBXRenderer {
52337
52838
  RBXRenderer.removeInstance(child, renderScene);
52338
52839
  }
52339
52840
  }
52841
+ static getRenderDescs(instance) {
52842
+ const renderDescs = [];
52843
+ for (const renderScene of RBXRenderer.scenes) {
52844
+ const renderDesc = renderScene.renderDescs.get(instance);
52845
+ if (renderDesc) renderDescs.push(renderDesc);
52846
+ }
52847
+ return renderDescs;
52848
+ }
52340
52849
  static _addRenderDesc(instance, auth, DescClass, renderScene) {
52341
52850
  if (!RBXRenderer.renderer) return;
52342
52851
  const oldDesc = renderScene.renderDescs.get(instance);
@@ -52662,7 +53171,7 @@ function zoomExtents(cameraCFrame, modelCFrame, modelSize, targetFOV, distanceSc
52662
53171
  if (sizeType === "calculate") {
52663
53172
  largestSize = modelSize.magnitude() / 2 / Math.sin(rad(targetFOV / 2));
52664
53173
  }
52665
- const fovMultiplier = 70 / targetFOV;
53174
+ const fovMultiplier = sizeType === "largestAxis" ? 70 / targetFOV : 1;
52666
53175
  const lookDir = multiply(normalize(minus(cameraCFrame.Position, modelCFrame.Position)), [distanceScale, distanceScale, distanceScale]);
52667
53176
  cameraCFrame.Position = add(modelCFrame.Position, multiply(multiply(lookDir, [largestSize, largestSize, largestSize]), [fovMultiplier, fovMultiplier, fovMultiplier]));
52668
53177
  }
@@ -52761,7 +53270,7 @@ function getCameraCFrameForAvatarNonCustomized(rig) {
52761
53270
  zoomExtents(cameraCF, rootPartCF, extentsSize, 70, 1);
52762
53271
  return cameraCF;
52763
53272
  }
52764
- function getThumbnailCameraCFrame(model) {
53273
+ function getThumbnailCameraCFrame(model, fov2, forceAngle) {
52765
53274
  const thumbnailCamera = model.FindFirstChildOfClass("Camera");
52766
53275
  if (thumbnailCamera) return thumbnailCamera.PropOrDefault("CFrame", new CFrame());
52767
53276
  let rootPart = model.PropOrDefault("PrimaryPart", void 0);
@@ -52781,14 +53290,18 @@ function getThumbnailCameraCFrame(model) {
52781
53290
  lookVector = normalize(lookVector);
52782
53291
  }
52783
53292
  let lookCF = CFrame.lookAt([0, 0, 0], lookVector);
52784
- lookCF = lookCF.multiply(CFrame.fromEulerAngles(0, 0, rad(45)));
52785
- lookCF = lookCF.multiply(CFrame.fromEulerAngles(rad(35), 0, 0));
52786
- lookCF = lookCF.multiply(CFrame.fromEulerAngles(0, 0, 0));
53293
+ if (!forceAngle) {
53294
+ lookCF = lookCF.multiply(CFrame.fromEulerAngles(0, 0, rad(45)));
53295
+ lookCF = lookCF.multiply(CFrame.fromEulerAngles(rad(35), 0, 0));
53296
+ lookCF = lookCF.multiply(CFrame.fromEulerAngles(0, 0, 0));
53297
+ } else {
53298
+ lookCF = lookCF.multiply(CFrame.fromEulerAngles(rad(forceAngle[0]), rad(forceAngle[1]), rad(forceAngle[2])));
53299
+ }
52787
53300
  lookVector = lookCF.lookVector();
52788
53301
  lookCF.Position = add(rootPartCF.Position, multiply([10, 10, 10], lookVector));
52789
53302
  lookCF = CFrame.lookAt(lookCF.Position, rootPartCF.Position);
52790
53303
  const cameraCF = lookCF.clone();
52791
- zoomExtents(cameraCF, rootPartCF, extentsSize, 70, 1);
53304
+ zoomExtents(cameraCF, rootPartCF, extentsSize, fov2, 1);
52792
53305
  return cameraCF;
52793
53306
  }
52794
53307
  class OutfitRenderer {
@@ -53051,7 +53564,7 @@ async function renderTargetToCanvas(renderTarget) {
53051
53564
  }
53052
53565
  async function generateModelThumbnail(auth, renderScene, model, size = [150, 150], type = "png", quality = 1, gltfAutoDownload = false, includeAnimations = false) {
53053
53566
  return new Promise((resolve) => {
53054
- const cameraCFrame = getThumbnailCameraCFrame(model);
53567
+ const cameraCFrame = getThumbnailCameraCFrame(model, renderScene.camera.fov);
53055
53568
  if (cameraCFrame) {
53056
53569
  RBXRenderer.setCameraCFrame(cameraCFrame, renderScene);
53057
53570
  }
@@ -53089,11 +53602,54 @@ async function generateModelThumbnail(auth, renderScene, model, size = [150, 150
53089
53602
  }
53090
53603
  });
53091
53604
  }
53092
- async function generateOutfitThumbnail(auth, outfit, size = [150, 150], type = "png", quality = 1, gltfAutoDownload = false, includeAnimations = false) {
53605
+ async function generateOutfitModelThumbnail(auth, outfitModel, options) {
53606
+ const defaultOptions = {
53607
+ size: [150, 150],
53608
+ type: "png",
53609
+ quality: 1,
53610
+ gltfAutoDownload: false,
53611
+ includeAnimations: false
53612
+ };
53613
+ Object.assign(defaultOptions, options);
53614
+ const renderScene = RBXRenderer.addScene();
53615
+ setupThumbnailScene(renderScene);
53616
+ if (outfitModel.background?.id) {
53617
+ const avatarCycloramaRBX = await API.Asset.GetRBX("roavatar://AvatarCyclorama.rbxm");
53618
+ if (avatarCycloramaRBX instanceof Response) return void 0;
53619
+ const avatarCycloramaRoot = avatarCycloramaRBX.generateTree();
53620
+ const avatarCyclorama = avatarCycloramaRoot.GetChildren()[0];
53621
+ if (avatarCyclorama) {
53622
+ const backgroundDataRBX = await API.Asset.GetRBX("rbxassetid://" + outfitModel.background.id);
53623
+ if (backgroundDataRBX instanceof Response) return void 0;
53624
+ const backgroundDataRoot = backgroundDataRBX.generateTree();
53625
+ const backgroundData = backgroundDataRoot.GetChildren()[0];
53626
+ if (backgroundData) {
53627
+ if (backgroundData) {
53628
+ const colorValue = backgroundData.Child("Color");
53629
+ const imageIdValue = backgroundData.Child("ImageId");
53630
+ if (colorValue && imageIdValue) {
53631
+ const color = colorValue.Prop("Value");
53632
+ const imageId = imageIdValue.Prop("Value");
53633
+ avatarCyclorama.Child("color_mesh").setProperty("Color", color.toColor3uint8());
53634
+ avatarCyclorama.Child("texture_mesh").setProperty("TextureID", `rbxassetid://${imageId}`);
53635
+ avatarCyclorama.preRender();
53636
+ RBXRenderer.addInstance(avatarCyclorama, auth, renderScene);
53637
+ renderScene.camera.fov = 30;
53638
+ renderScene.camera.updateProjectionMatrix();
53639
+ }
53640
+ }
53641
+ }
53642
+ }
53643
+ }
53644
+ return generateOutfitThumbnail(auth, outfitModel.outfit, defaultOptions.size, defaultOptions.type, defaultOptions.quality, defaultOptions.gltfAutoDownload, defaultOptions.includeAnimations, renderScene);
53645
+ }
53646
+ async function generateOutfitThumbnail(auth, outfit, size = [150, 150], type = "png", quality = 1, gltfAutoDownload = false, includeAnimations = false, renderSceneParam) {
53093
53647
  return new Promise((resolve) => {
53094
53648
  const startTime = performance.now();
53095
- const renderScene = RBXRenderer.addScene();
53096
- setupThumbnailScene(renderScene);
53649
+ const renderScene = renderSceneParam || RBXRenderer.addScene();
53650
+ if (renderScene !== renderSceneParam) {
53651
+ setupThumbnailScene(renderScene);
53652
+ }
53097
53653
  const outfitRenderer = new OutfitRenderer(auth, outfit, renderScene);
53098
53654
  outfitRenderer.doAddInstance = false;
53099
53655
  if (outfit.playerAvatarType === AvatarType.R6) outfitRenderer.deltaTimeMultiplier = 0;
@@ -53176,6 +53732,7 @@ export {
53176
53732
  AllAccessorySorts,
53177
53733
  AllAnimationSorts,
53178
53734
  AllAnimations,
53735
+ AllAvatarModelOutfitUpdateTypes,
53179
53736
  AllBodyParts,
53180
53737
  AllBodyPartsSorts,
53181
53738
  AllCharacterSorts,
@@ -53272,6 +53829,7 @@ export {
53272
53829
  NumberSequence,
53273
53830
  NumberSequenceKeypoint,
53274
53831
  Outfit,
53832
+ OutfitModel,
53275
53833
  OutfitOrigin,
53276
53834
  OutfitRenderer,
53277
53835
  PartType,
@@ -53306,6 +53864,7 @@ export {
53306
53864
  SpecialInfo,
53307
53865
  SpecialLayeredAssetTypes,
53308
53866
  StringBufferProperties,
53867
+ ThumbnailCustomization,
53309
53868
  ToRemoveBeforeBundleType,
53310
53869
  ToolWrapper,
53311
53870
  UDim,
@@ -53363,6 +53922,7 @@ export {
53363
53922
  floor,
53364
53923
  gaussian_rbf,
53365
53924
  generateModelThumbnail,
53925
+ generateOutfitModelThumbnail,
53366
53926
  generateOutfitThumbnail,
53367
53927
  generateUUIDv4,
53368
53928
  getCameraCFrameForAvatarNonCustomized,