roavatar-renderer 1.6.0 → 1.6.1

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 +126 -8
  2. package/dist/index.js +855 -282
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -30279,6 +30279,16 @@ class RBXSimpleView {
30279
30279
  }
30280
30280
  const magic = "<roblox!";
30281
30281
  const xmlMagic = "<roblox ";
30282
+ const CameraType = {
30283
+ "Fixed": 0,
30284
+ "Attach": 1,
30285
+ "Watch": 2,
30286
+ "Track": 3,
30287
+ "Follow": 4,
30288
+ "Custom": 5,
30289
+ "Scriptable": 6,
30290
+ "Orbital": 7
30291
+ };
30282
30292
  const ParticleFlipbookLayout = {
30283
30293
  "None": 0,
30284
30294
  "Grid2x2": 1,
@@ -30436,6 +30446,24 @@ const BodyPartNameToEnum = {
30436
30446
  "UpperTorso": BodyPart.Torso,
30437
30447
  "LowerTorso": BodyPart.Torso
30438
30448
  };
30449
+ const R6BodyPartNames = ["Head", "Torso", "Left Arm", "Right Arm", "Left Leg", "Right Leg"];
30450
+ const R15BodyPartNames = [
30451
+ "Head",
30452
+ "UpperTorso",
30453
+ "LowerTorso",
30454
+ "LeftUpperArm",
30455
+ "LeftLowerArm",
30456
+ "LeftHand",
30457
+ "RightUpperArm",
30458
+ "RightLowerArm",
30459
+ "RightHand",
30460
+ "LeftUpperLeg",
30461
+ "LeftLowerLeg",
30462
+ "LeftFoot",
30463
+ "RightUpperLeg",
30464
+ "RightLowerLeg",
30465
+ "RightFoot"
30466
+ ];
30439
30467
  const BodyPartEnumToNames = {
30440
30468
  [BodyPart.Head]: ["Head"],
30441
30469
  [BodyPart.Torso]: ["Torso", "UpperTorso", "LowerTorso"],
@@ -32744,6 +32772,9 @@ class InstanceWrapper {
32744
32772
  }
32745
32773
  }
32746
32774
  }
32775
+ addProp(name, type, value) {
32776
+ if (!this.instance.HasProperty(name)) this.instance.addProperty(new Property(name, type), value);
32777
+ }
32747
32778
  setup() {
32748
32779
  throw new Error("Virtual method setup() called");
32749
32780
  }
@@ -32783,7 +32814,7 @@ class InstanceWrapper {
32783
32814
  preRender() {
32784
32815
  }
32785
32816
  }
32786
- const __vite_glob_0_13 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
32817
+ const __vite_glob_0_14 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
32787
32818
  __proto__: null,
32788
32819
  GetWrapperForInstance,
32789
32820
  InstanceWrapper
@@ -32899,6 +32930,13 @@ class Vector3 {
32899
32930
  isSame(other) {
32900
32931
  return isSameFloat(this.X, other.X) && isSameFloat(this.Y, other.Y) && isSameFloat(this.Z, other.Z);
32901
32932
  }
32933
+ lerp(other, t) {
32934
+ return new Vector3(
32935
+ lerp(this.X, other.X, t),
32936
+ lerp(this.Y, other.Y, t),
32937
+ lerp(this.Z, other.Z, t)
32938
+ );
32939
+ }
32902
32940
  static new(X, Y, Z) {
32903
32941
  return new Vector3(X, Y, Z);
32904
32942
  }
@@ -33128,6 +33166,11 @@ class CFrame {
33128
33166
  constructor(x = 0, y = 0, z = 0) {
33129
33167
  this.Position = [x, y, z];
33130
33168
  }
33169
+ static Angles(x, y, z) {
33170
+ const cf = new CFrame();
33171
+ cf.Orientation = [x, y, z];
33172
+ return cf;
33173
+ }
33131
33174
  clone() {
33132
33175
  const cloneCF = new CFrame(this.Position[0], this.Position[1], this.Position[2]);
33133
33176
  cloneCF.Orientation = [this.Orientation[0], this.Orientation[1], this.Orientation[2]];
@@ -33198,6 +33241,17 @@ class CFrame {
33198
33241
  const matrix = new Matrix4().makeRotationFromEuler(new Euler(rx, ry, rz, order));
33199
33242
  return new CFrame().fromMatrix(matrix.elements);
33200
33243
  }
33244
+ rotationOnly() {
33245
+ const copy = this.clone();
33246
+ copy.Position = [0, 0, 0];
33247
+ return copy;
33248
+ }
33249
+ toEulerAngles(order = "XYZ") {
33250
+ const [rx, ry, rz] = this.Orientation;
33251
+ let euler = new Euler(rad(rx), rad(ry), rad(rz), "YXZ");
33252
+ euler = euler.reorder(order);
33253
+ return euler.toArray();
33254
+ }
33201
33255
  inverse() {
33202
33256
  const thisM = new Matrix4().fromArray(this.getMatrix());
33203
33257
  const inverse = thisM.clone();
@@ -33211,6 +33265,26 @@ class CFrame {
33211
33265
  const newCf = new CFrame().fromMatrix(newM.elements);
33212
33266
  return newCf;
33213
33267
  }
33268
+ multiplyVector(vector) {
33269
+ const vectorCF = new CFrame(...vector.toVec3());
33270
+ const resultCF = this.multiply(vectorCF);
33271
+ const resultVector = new Vector3(...resultCF.Position);
33272
+ return resultVector;
33273
+ }
33274
+ removeNaN(newValue = 0) {
33275
+ const newCF = new CFrame();
33276
+ newCF.Position = [
33277
+ isNaN(this.Position[0]) ? newValue : this.Position[0],
33278
+ isNaN(this.Position[1]) ? newValue : this.Position[1],
33279
+ isNaN(this.Position[2]) ? newValue : this.Position[2]
33280
+ ];
33281
+ newCF.Orientation = [
33282
+ isNaN(this.Orientation[0]) ? newValue : this.Orientation[0],
33283
+ isNaN(this.Orientation[1]) ? newValue : this.Orientation[1],
33284
+ isNaN(this.Orientation[2]) ? newValue : this.Orientation[2]
33285
+ ];
33286
+ return newCF;
33287
+ }
33214
33288
  isSame(other) {
33215
33289
  return isSameFloat(this.Position[0], other.Position[0]) && isSameFloat(this.Position[1], other.Position[1]) && isSameFloat(this.Position[2], other.Position[2]) && isSameFloat(this.Orientation[0], other.Orientation[0]) && isSameFloat(this.Orientation[1], other.Orientation[1]) && isSameFloat(this.Orientation[2], other.Orientation[2]);
33216
33290
  }
@@ -36917,8 +36991,10 @@ class LocalOutfit {
36917
36991
  this.bg = data.bg || 0;
36918
36992
  return this;
36919
36993
  }
36920
- update(outfit) {
36994
+ update(outfitModel) {
36995
+ const outfit = outfitModel instanceof OutfitModel ? outfitModel.outfit : outfitModel;
36921
36996
  this.buffer = arrayBufferToBase64(outfit.toBuffer());
36997
+ if (outfitModel instanceof OutfitModel) this.bg = outfitModel.background?.id || 0;
36922
36998
  this.image = void 0;
36923
36999
  }
36924
37000
  /**
@@ -39122,8 +39198,15 @@ const API = {
39122
39198
  return response;
39123
39199
  }
39124
39200
  },
39201
+ GetUserAvatarModel: async function(userId) {
39202
+ const response = await RBLXGet(`https://avatar.roblox.com/v4/avatar/users/${userId}?selectionTypes=0&selectionTypes=1&selectionTypes=2&selectionTypes=3&selectionTypes=4&selectionTypes=5&selectionTypes=6`);
39203
+ if (response.status !== 200) return response;
39204
+ const body = await response.json();
39205
+ const outfitModel = new OutfitModel().fromJson(body);
39206
+ return outfitModel;
39207
+ },
39125
39208
  GetAvatarModel: async function() {
39126
- const response = await RBLXGet("https://avatar.roblox.com/v4/avatar?selectionTypes=0&selectionTypes=1&selectionTypes=2&selectionTypes=3&selectionTypes=4&selectionTypes=5");
39209
+ const response = await RBLXGet("https://avatar.roblox.com/v4/avatar?selectionTypes=0&selectionTypes=1&selectionTypes=2&selectionTypes=3&selectionTypes=4&selectionTypes=5&selectionTypes=6");
39127
39210
  if (response.status !== 200) return response;
39128
39211
  const body = await response.json();
39129
39212
  const outfitModel = new OutfitModel().fromJson(body);
@@ -43484,7 +43567,7 @@ class ConstraintWrapper extends InstanceWrapper {
43484
43567
  if (!this.instance.HasProperty("Attachment1")) this.instance.addProperty(new Property("Attachment1", DataType.Referent), void 0);
43485
43568
  }
43486
43569
  }
43487
- const __vite_glob_0_9 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
43570
+ const __vite_glob_0_10 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
43488
43571
  __proto__: null,
43489
43572
  ConstraintWrapper
43490
43573
  }, Symbol.toStringTag, { value: "Module" }));
@@ -45902,7 +45985,7 @@ class MeshDesc {
45902
45985
  const wrapTarget = child.parent?.parent?.FindFirstChildOfClass("WrapTarget");
45903
45986
  if (wrapTarget) {
45904
45987
  this.wrapTextureTarget = wrapTarget.Prop("CageMeshId");
45905
- this.wrapTextureTargetOrigin = wrapTarget.Prop("CageOrigin");
45988
+ this.wrapTextureTargetOrigin = wrapTarget.Prop("CageOrigin").removeNaN();
45906
45989
  }
45907
45990
  }
45908
45991
  }
@@ -47330,7 +47413,7 @@ class FaceControlsWrapper extends InstanceWrapper {
47330
47413
  }
47331
47414
  }
47332
47415
  }
47333
- const __vite_glob_0_11 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
47416
+ const __vite_glob_0_12 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
47334
47417
  __proto__: null,
47335
47418
  FaceControlsWrapper
47336
47419
  }, Symbol.toStringTag, { value: "Module" }));
@@ -47778,51 +47861,54 @@ class ObjectDesc extends RenderDesc {
47778
47861
  async compileResults(renderer, scene) {
47779
47862
  const loadingLabel = this.instance ? this.instance.GetFullName() : "unknown";
47780
47863
  API.Misc.startCurrentlyLoadingAssets(loadingLabel);
47781
- const originalResult = this.results;
47782
- const originalSkeletonDesc = this.skeletonDesc;
47783
- this.results = void 0;
47784
- this.skeletonDesc = void 0;
47785
- const promises = [
47786
- this.meshDesc.compileMesh(),
47787
- this.materialDesc.compileMaterial(this.meshDesc)
47788
- ];
47789
- const [threeMesh, threeMaterial] = await Promise.all(promises);
47790
- if (!(threeMesh instanceof Mesh)) {
47791
- warn(true, "Failed to get mesh for objectDesc", this.instance ? this.instance.GetFullName() : "unknown");
47864
+ try {
47865
+ const originalResult = this.results;
47866
+ const originalSkeletonDesc = this.skeletonDesc;
47867
+ this.results = void 0;
47868
+ this.skeletonDesc = void 0;
47869
+ const promises = [
47870
+ this.meshDesc.compileMesh(),
47871
+ this.materialDesc.compileMaterial(this.meshDesc)
47872
+ ];
47873
+ const [threeMesh, threeMaterial] = await Promise.all(promises);
47874
+ if (!(threeMesh instanceof Mesh)) {
47875
+ warn(true, "Failed to get mesh for objectDesc", this.instance ? this.instance.GetFullName() : "unknown");
47876
+ API.Misc.stopCurrentlyLoadingAssets(loadingLabel);
47877
+ return threeMesh;
47878
+ }
47879
+ if (threeMesh instanceof SkinnedMesh) {
47880
+ threeMaterial.skinning = true;
47881
+ this.isSkinned = true;
47882
+ }
47883
+ threeMesh.material = threeMaterial;
47884
+ threeMesh.receiveShadow = true;
47885
+ threeMaterial.needsUpdate = true;
47886
+ threeMesh.visible = threeMaterial.visible;
47887
+ this.results = [threeMesh];
47888
+ this.originalScale = threeMesh.scale.clone();
47889
+ if (!this.meshDesc.scaleIsRelative) {
47890
+ threeMesh.scale.set(this.size.X, this.size.Y, this.size.Z);
47891
+ } else {
47892
+ const oldSize = this.originalScale;
47893
+ threeMesh.scale.set(this.size.X / oldSize.x, this.size.Y / oldSize.y, this.size.Z / oldSize.z);
47894
+ }
47895
+ if (SkeletonDesc.descNeedsSkeleton(this.meshDesc)) {
47896
+ this.skeletonDesc = new SkeletonDesc(this, this.meshDesc, scene);
47897
+ } else {
47898
+ this.meshDesc.fileMesh = void 0;
47899
+ }
47900
+ if (originalResult) {
47901
+ this.disposeMeshes(scene, originalResult);
47902
+ }
47903
+ if (originalSkeletonDesc) {
47904
+ this.disposeSkeleton(scene, originalSkeletonDesc);
47905
+ }
47906
+ if (originalResult) {
47907
+ this.disposeRenderLists(renderer);
47908
+ }
47909
+ } finally {
47792
47910
  API.Misc.stopCurrentlyLoadingAssets(loadingLabel);
47793
- return threeMesh;
47794
- }
47795
- if (threeMesh instanceof SkinnedMesh) {
47796
- threeMaterial.skinning = true;
47797
- this.isSkinned = true;
47798
- }
47799
- threeMesh.material = threeMaterial;
47800
- threeMesh.receiveShadow = true;
47801
- threeMaterial.needsUpdate = true;
47802
- threeMesh.visible = threeMaterial.visible;
47803
- this.results = [threeMesh];
47804
- this.originalScale = threeMesh.scale.clone();
47805
- if (!this.meshDesc.scaleIsRelative) {
47806
- threeMesh.scale.set(this.size.X, this.size.Y, this.size.Z);
47807
- } else {
47808
- const oldSize = this.originalScale;
47809
- threeMesh.scale.set(this.size.X / oldSize.x, this.size.Y / oldSize.y, this.size.Z / oldSize.z);
47810
- }
47811
- if (SkeletonDesc.descNeedsSkeleton(this.meshDesc)) {
47812
- this.skeletonDesc = new SkeletonDesc(this, this.meshDesc, scene);
47813
- } else {
47814
- this.meshDesc.fileMesh = void 0;
47815
- }
47816
- if (originalResult) {
47817
- this.disposeMeshes(scene, originalResult);
47818
- }
47819
- if (originalSkeletonDesc) {
47820
- this.disposeSkeleton(scene, originalSkeletonDesc);
47821
- }
47822
- if (originalResult) {
47823
- this.disposeRenderLists(renderer);
47824
47911
  }
47825
- API.Misc.stopCurrentlyLoadingAssets(loadingLabel);
47826
47912
  return this.results;
47827
47913
  }
47828
47914
  getScale() {
@@ -48746,7 +48832,7 @@ class AnimationTrack {
48746
48832
  tick(deltaTime = 1 / 60) {
48747
48833
  const addTime = deltaTime * this.pSpeed;
48748
48834
  this.pFadedTime += addTime;
48749
- const newWeight = lerp(this.pOriginalWeight, this.pTargetWeight, specialClamp(this.pFadedTime / this.pFadeTime, 0, 1));
48835
+ const newWeight = this.pFadeTime === 0 ? this.pTargetWeight : lerp(this.pOriginalWeight, this.pTargetWeight, specialClamp(this.pFadedTime / this.pFadeTime, 0, 1));
48750
48836
  this.weight = newWeight;
48751
48837
  const ogTime = this.timePosition;
48752
48838
  if (this.weight >= 0.01) {
@@ -48769,6 +48855,7 @@ class AnimatorWrapperData {
48769
48855
  toolTracks = [];
48770
48856
  toolAddedConnection;
48771
48857
  toolRemovedConnection;
48858
+ forceTransitionTime;
48772
48859
  }
48773
48860
  class AnimatorWrapper extends InstanceWrapper {
48774
48861
  static className = "Animator";
@@ -48838,7 +48925,7 @@ class AnimatorWrapper extends InstanceWrapper {
48838
48925
  const realId = BigInt(API.Misc.idFromStr(id));
48839
48926
  return this.data.animationTracks.get(realId);
48840
48927
  }
48841
- _switchAnimation(name) {
48928
+ _switchAnimation(name, subAnimSpecifier) {
48842
48929
  let transitionTime = 0.2;
48843
48930
  if (name === this.data.currentAnimation) {
48844
48931
  transitionTime = 0.15;
@@ -48851,7 +48938,8 @@ class AnimatorWrapper extends InstanceWrapper {
48851
48938
  if (!name.startsWith("emote.") && !name.startsWith("id.")) {
48852
48939
  const entries = this.data.animationSet[name];
48853
48940
  if (entries && entries.length > 0) {
48854
- const entry = this._pickRandom(entries);
48941
+ const isSpecificSub = subAnimSpecifier !== void 0 && subAnimSpecifier >= 0;
48942
+ const entry = isSpecificSub ? entries[subAnimSpecifier] : this._pickRandom(entries);
48855
48943
  if (entry) {
48856
48944
  toPlayTrack = this._getTrack(entry.id);
48857
48945
  }
@@ -48877,7 +48965,7 @@ class AnimatorWrapper extends InstanceWrapper {
48877
48965
  this.data.currentAnimationTrack = void 0;
48878
48966
  this.data.currentAnimationTrack = toPlayTrack;
48879
48967
  if (toPlayTrack) {
48880
- toPlayTrack.Play(transitionTime);
48968
+ toPlayTrack.Play(this.data.forceTransitionTime === void 0 ? transitionTime : this.data.forceTransitionTime);
48881
48969
  }
48882
48970
  }
48883
48971
  }
@@ -48915,7 +49003,7 @@ class AnimatorWrapper extends InstanceWrapper {
48915
49003
  this.data.moodTracks.push(toPlayTrack);
48916
49004
  }
48917
49005
  this.data.currentMoodAnimationTrack = toPlayTrack;
48918
- toPlayTrack.Play(transitionTime);
49006
+ toPlayTrack.Play(this.data.forceTransitionTime === void 0 ? transitionTime : this.data.forceTransitionTime);
48919
49007
  }
48920
49008
  }
48921
49009
  return !!toPlayTrack;
@@ -48952,7 +49040,7 @@ class AnimatorWrapper extends InstanceWrapper {
48952
49040
  this.data.toolTracks.push(toPlayTrack);
48953
49041
  }
48954
49042
  this.data.currentToolAnimationTrack = toPlayTrack;
48955
- toPlayTrack.Play(transitionTime);
49043
+ toPlayTrack.Play(this.data.forceTransitionTime === void 0 ? transitionTime : this.data.forceTransitionTime);
48956
49044
  }
48957
49045
  }
48958
49046
  return !!toPlayTrack;
@@ -49217,7 +49305,7 @@ class AnimatorWrapper extends InstanceWrapper {
49217
49305
  }
49218
49306
  /**
49219
49307
  * Switches to new animation
49220
- * @param name Animation name, such as "idle", "walk", "emote.1234" or "id.1234"
49308
+ * @param name Animation name, such as "idle", "walk", "emote.1234" or "id.1234", can also specify sub animation like "idle:0"
49221
49309
  * @param type
49222
49310
  * @returns If animation sucessfully played
49223
49311
  */
@@ -49234,6 +49322,12 @@ class AnimatorWrapper extends InstanceWrapper {
49234
49322
  this.restPose(false, true);
49235
49323
  }
49236
49324
  }
49325
+ let subAnimSpecifier = -1;
49326
+ if (name.includes(":")) {
49327
+ const splitName = name.split(":");
49328
+ name = splitName[0];
49329
+ subAnimSpecifier = Number(splitName[1]);
49330
+ }
49237
49331
  switch (type) {
49238
49332
  case "main":
49239
49333
  if (this.data.currentAnimation !== name) {
@@ -49243,7 +49337,8 @@ class AnimatorWrapper extends InstanceWrapper {
49243
49337
  this.stopMoodAnimation();
49244
49338
  }
49245
49339
  log(false, "playing", name);
49246
- return this._switchAnimation(name);
49340
+ log(false, this.data.forceTransitionTime);
49341
+ return this._switchAnimation(name, subAnimSpecifier);
49247
49342
  } else {
49248
49343
  return true;
49249
49344
  }
@@ -49392,6 +49487,25 @@ const __vite_glob_0_8 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.def
49392
49487
  __proto__: null,
49393
49488
  BoneWrapper
49394
49489
  }, Symbol.toStringTag, { value: "Module" }));
49490
+ class CameraWrapper extends InstanceWrapper {
49491
+ static className = "Camera";
49492
+ static requiredProperties = [
49493
+ "Name",
49494
+ "CFrame",
49495
+ "CameraType",
49496
+ "FieldOfView"
49497
+ ];
49498
+ setup() {
49499
+ this.addProp("Name", DataType.String, this.instance.className);
49500
+ this.addProp("CFrame", DataType.CFrame, new CFrame());
49501
+ this.addProp("CameraType", DataType.Enum, CameraType.Fixed);
49502
+ this.addProp("FieldOfView", DataType.Float32, 70);
49503
+ }
49504
+ }
49505
+ const __vite_glob_0_9 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
49506
+ __proto__: null,
49507
+ CameraWrapper
49508
+ }, Symbol.toStringTag, { value: "Module" }));
49395
49509
  class DecalWrapper extends InstanceWrapper {
49396
49510
  static className = "Decal";
49397
49511
  static requiredProperties = [
@@ -49413,7 +49527,7 @@ class DecalWrapper extends InstanceWrapper {
49413
49527
  if (!this.instance.HasProperty("UVScale")) this.instance.addProperty(new Property("UVScale", DataType.Vector2), new Vector2());
49414
49528
  }
49415
49529
  }
49416
- const __vite_glob_0_10 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
49530
+ const __vite_glob_0_11 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
49417
49531
  __proto__: null,
49418
49532
  DecalWrapper
49419
49533
  }, Symbol.toStringTag, { value: "Module" }));
@@ -49557,7 +49671,7 @@ class MakeupDescriptionWrapper extends InstanceWrapper {
49557
49671
  if (!this.instance.HasProperty("Instance")) this.instance.addProperty(new Property("Instance", DataType.Referent), void 0);
49558
49672
  }
49559
49673
  }
49560
- const __vite_glob_0_15 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
49674
+ const __vite_glob_0_16 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
49561
49675
  __proto__: null,
49562
49676
  MakeupDescriptionWrapper
49563
49677
  }, Symbol.toStringTag, { value: "Module" }));
@@ -50795,12 +50909,16 @@ class HumanoidDescriptionWrapper extends InstanceWrapper {
50795
50909
  if (this.instance.PropOrDefault(animationProp, 0n) > 0n && avatarType === AvatarType.R15) {
50796
50910
  const id = this.instance.Prop(animationProp);
50797
50911
  promises.push(new Promise((resolve) => {
50912
+ if (animationProp === "IdleAnimation") {
50913
+ delete animatorW.data.animationSet["pose"];
50914
+ }
50798
50915
  animatorW.loadAvatarAnimation(id, false, true).then((result) => {
50799
50916
  resolve(result);
50800
50917
  });
50801
50918
  }));
50802
50919
  } else {
50803
50920
  this._loadDefaultAnimation(animationProp, avatarType, animatorW, promises);
50921
+ if (animationProp === "IdleAnimation" && !toChange.includes("pose")) this._loadDefaultAnimation("pose", avatarType, animatorW, promises);
50804
50922
  }
50805
50923
  }
50806
50924
  const values = await Promise.all(promises);
@@ -50935,7 +51053,7 @@ class HumanoidDescriptionWrapper extends InstanceWrapper {
50935
51053
  return this.instance;
50936
51054
  }
50937
51055
  }
50938
- const __vite_glob_0_12 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
51056
+ const __vite_glob_0_13 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
50939
51057
  __proto__: null,
50940
51058
  HumanoidDescriptionWrapper
50941
51059
  }, Symbol.toStringTag, { value: "Module" }));
@@ -51070,14 +51188,14 @@ class JointInstanceWrapper extends InstanceWrapper {
51070
51188
  }
51071
51189
  }
51072
51190
  }
51073
- const __vite_glob_0_14 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
51191
+ const __vite_glob_0_15 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
51074
51192
  __proto__: null,
51075
51193
  JointInstanceWrapper
51076
51194
  }, Symbol.toStringTag, { value: "Module" }));
51077
51195
  class ManualWeldWrapper extends JointInstanceWrapper {
51078
51196
  static className = "ManualWeld";
51079
51197
  }
51080
- const __vite_glob_0_16 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
51198
+ const __vite_glob_0_17 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
51081
51199
  __proto__: null,
51082
51200
  ManualWeldWrapper
51083
51201
  }, Symbol.toStringTag, { value: "Module" }));
@@ -51092,7 +51210,7 @@ class MeshPartWrapper extends BasePartWrapper {
51092
51210
  if (!this.instance.HasProperty("DoubleSided")) this.instance.addProperty(new Property("DoubleSided", DataType.Bool), false);
51093
51211
  }
51094
51212
  }
51095
- const __vite_glob_0_17 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
51213
+ const __vite_glob_0_18 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
51096
51214
  __proto__: null,
51097
51215
  MeshPartWrapper
51098
51216
  }, Symbol.toStringTag, { value: "Module" }));
@@ -51111,7 +51229,7 @@ class ModelWrapper extends InstanceWrapper {
51111
51229
  throw new Error("Model has no PrimaryPart");
51112
51230
  }
51113
51231
  }
51114
- const __vite_glob_0_18 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
51232
+ const __vite_glob_0_19 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
51115
51233
  __proto__: null,
51116
51234
  ModelWrapper
51117
51235
  }, Symbol.toStringTag, { value: "Module" }));
@@ -51126,7 +51244,7 @@ class Motor6DWrapper extends JointInstanceWrapper {
51126
51244
  if (!this.instance.HasProperty("Transform")) this.instance.addProperty(new Property("Transform", DataType.CFrame), new CFrame());
51127
51245
  }
51128
51246
  }
51129
- const __vite_glob_0_19 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
51247
+ const __vite_glob_0_20 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
51130
51248
  __proto__: null,
51131
51249
  Motor6DWrapper
51132
51250
  }, Symbol.toStringTag, { value: "Module" }));
@@ -51141,7 +51259,7 @@ class PartWrapper extends BasePartWrapper {
51141
51259
  if (!this.instance.HasProperty("shape")) this.instance.addProperty(new Property("shape", DataType.Enum), PartType.Block);
51142
51260
  }
51143
51261
  }
51144
- const __vite_glob_0_20 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
51262
+ const __vite_glob_0_21 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
51145
51263
  __proto__: null,
51146
51264
  PartWrapper
51147
51265
  }, Symbol.toStringTag, { value: "Module" }));
@@ -52066,7 +52184,7 @@ class ParticleEmitterWrapper extends InstanceWrapper {
52066
52184
  }
52067
52185
  }
52068
52186
  }
52069
- const __vite_glob_0_21 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
52187
+ const __vite_glob_0_22 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
52070
52188
  __proto__: null,
52071
52189
  ParticleEmitterWrapper
52072
52190
  }, Symbol.toStringTag, { value: "Module" }));
@@ -52172,7 +52290,7 @@ class SoundWrapper extends InstanceWrapper {
52172
52290
  }
52173
52291
  }
52174
52292
  }
52175
- const __vite_glob_0_23 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
52293
+ const __vite_glob_0_24 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
52176
52294
  __proto__: null,
52177
52295
  SoundWrapper
52178
52296
  }, Symbol.toStringTag, { value: "Module" }));
@@ -52426,7 +52544,7 @@ class ScriptWrapper extends InstanceWrapper {
52426
52544
  }
52427
52545
  }
52428
52546
  }
52429
- const __vite_glob_0_22 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
52547
+ const __vite_glob_0_23 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
52430
52548
  __proto__: null,
52431
52549
  ScriptWrapper
52432
52550
  }, Symbol.toStringTag, { value: "Module" }));
@@ -52483,25 +52601,25 @@ class ToolWrapper extends InstanceWrapper {
52483
52601
  }
52484
52602
  }
52485
52603
  }
52486
- const __vite_glob_0_24 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
52604
+ const __vite_glob_0_25 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
52487
52605
  __proto__: null,
52488
52606
  ToolWrapper
52489
52607
  }, Symbol.toStringTag, { value: "Module" }));
52490
52608
  class WedgePartWrapper extends BasePartWrapper {
52491
52609
  static className = "WedgePart";
52492
52610
  }
52493
- const __vite_glob_0_25 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
52611
+ const __vite_glob_0_26 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
52494
52612
  __proto__: null,
52495
52613
  WedgePartWrapper
52496
52614
  }, Symbol.toStringTag, { value: "Module" }));
52497
52615
  class WeldWrapper extends JointInstanceWrapper {
52498
52616
  static className = "Weld";
52499
52617
  }
52500
- const __vite_glob_0_26 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
52618
+ const __vite_glob_0_27 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
52501
52619
  __proto__: null,
52502
52620
  WeldWrapper
52503
52621
  }, Symbol.toStringTag, { value: "Module" }));
52504
- 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 });
52622
+ 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/Camera.ts": __vite_glob_0_9, "./instance/Constraint.ts": __vite_glob_0_10, "./instance/Decal.ts": __vite_glob_0_11, "./instance/FaceControls.ts": __vite_glob_0_12, "./instance/HumanoidDescription.ts": __vite_glob_0_13, "./instance/InstanceWrapper.ts": __vite_glob_0_14, "./instance/JointInstance.ts": __vite_glob_0_15, "./instance/MakeupDescription.ts": __vite_glob_0_16, "./instance/ManualWeld.ts": __vite_glob_0_17, "./instance/MeshPart.ts": __vite_glob_0_18, "./instance/Model.ts": __vite_glob_0_19, "./instance/Motor6D.ts": __vite_glob_0_20, "./instance/Part.ts": __vite_glob_0_21, "./instance/ParticleEmitter.ts": __vite_glob_0_22, "./instance/Script.ts": __vite_glob_0_23, "./instance/Sound.ts": __vite_glob_0_24, "./instance/Tool.ts": __vite_glob_0_25, "./instance/WedgePart.ts": __vite_glob_0_26, "./instance/Weld.ts": __vite_glob_0_27 });
52505
52623
  function RegisterWrappers() {
52506
52624
  for (const module of Object.values(modules$1)) {
52507
52625
  for (const exprt of Object.values(module)) {
@@ -58114,6 +58232,579 @@ class HSR {
58114
58232
  }
58115
58233
  }
58116
58234
  }
58235
+ function getHeadAttachments(rig) {
58236
+ const headAttachments = /* @__PURE__ */ new Map();
58237
+ const head = rig.Child("Head");
58238
+ if (head) {
58239
+ for (const child of head.GetDescendants()) {
58240
+ if (child.IsA("Attachment")) {
58241
+ headAttachments.set(child.Prop("Name"), true);
58242
+ }
58243
+ }
58244
+ }
58245
+ return headAttachments;
58246
+ }
58247
+ function makeRotatedCorner(x, y, z, halfSize, cFrame) {
58248
+ const corner = Vector3.new(x * halfSize.X, y * halfSize.Y, z * halfSize.Z);
58249
+ const newCF = cFrame.multiply(new CFrame(...corner.toVec3()));
58250
+ return Vector3.new(...newCF.Position);
58251
+ }
58252
+ function growExtentsToIncludePoint(minExtent, maxExtent, point) {
58253
+ minExtent = Vector3.new(Math.min(point.X, minExtent.X), Math.min(point.Y, minExtent.Y), Math.min(point.Z, minExtent.Z));
58254
+ maxExtent = Vector3.new(Math.max(point.X, maxExtent.X), Math.max(point.Y, maxExtent.Y), Math.max(point.Z, maxExtent.Z));
58255
+ return [minExtent, maxExtent];
58256
+ }
58257
+ function growExtentsToInclude(minExtent, maxExtent, part, cInverse, optYMinCFrame, optYMin) {
58258
+ const size = part.Prop("Size").divide(new Vector3(2, 2, 2));
58259
+ for (let x = -1; x <= 1; x += 2) {
58260
+ for (let y = -1; y <= 1; y += 2) {
58261
+ for (let z = -1; z <= 1; z += 2) {
58262
+ let corner = makeRotatedCorner(x, y, z, size, part.Prop("CFrame"));
58263
+ if (optYMinCFrame && optYMin !== void 0) {
58264
+ const transformedCorner = new Vector3(...optYMinCFrame.inverse().multiply(new CFrame(...corner.toVec3())).Position);
58265
+ const clampedTransformedCorner = Vector3.new(transformedCorner.X, Math.max(optYMin, transformedCorner.Y), transformedCorner.Z);
58266
+ corner = new Vector3(...optYMinCFrame.multiply(new CFrame(...clampedTransformedCorner.toVec3())).Position);
58267
+ }
58268
+ corner = new Vector3(...cInverse.multiply(new CFrame(...corner.toVec3())).Position);
58269
+ [minExtent, maxExtent] = growExtentsToIncludePoint(minExtent, maxExtent, corner);
58270
+ }
58271
+ }
58272
+ }
58273
+ return [minExtent, maxExtent];
58274
+ }
58275
+ function initExtents() {
58276
+ const minExtent = Vector3.new(Infinity, Infinity, Infinity);
58277
+ const maxExtent = Vector3.new(-Infinity, -Infinity, -Infinity);
58278
+ return [minExtent, maxExtent];
58279
+ }
58280
+ function recursiveCalculateExtents(minExtent, maxExtent, instance, cInverse, indent) {
58281
+ for (const child of instance.GetChildren()) {
58282
+ if (child.IsA("BasePart")) {
58283
+ [minExtent, maxExtent] = growExtentsToInclude(minExtent, maxExtent, child, cInverse);
58284
+ }
58285
+ [minExtent, maxExtent] = recursiveCalculateExtents(minExtent, maxExtent, child, cInverse);
58286
+ }
58287
+ return [minExtent, maxExtent];
58288
+ }
58289
+ function calculateModelExtents(model, targetCFrame) {
58290
+ let [minExtent, maxExtent] = initExtents();
58291
+ const cInverse = targetCFrame.inverse();
58292
+ [minExtent, maxExtent] = recursiveCalculateExtents(minExtent, maxExtent, model, cInverse);
58293
+ return [minExtent, maxExtent];
58294
+ }
58295
+ function calculateHeadExtents(character, targetCFrame) {
58296
+ let [minExtent, maxExtent] = initExtents();
58297
+ const head = character.FindFirstChild("Head");
58298
+ if (!head) {
58299
+ return [minExtent, maxExtent];
58300
+ }
58301
+ const cInverse = targetCFrame.inverse();
58302
+ const untransformedHeadYMin = -head.Prop("Size").Y / 2;
58303
+ [minExtent, maxExtent] = growExtentsToInclude(minExtent, maxExtent, head, cInverse);
58304
+ const headAttachments = getHeadAttachments(character);
58305
+ for (const child of character.GetChildren()) {
58306
+ if (child.IsA("Accessory")) {
58307
+ const handle = child.FindFirstChild("Handle");
58308
+ if (handle) {
58309
+ const attachment = handle.FindFirstChildOfClass("Attachment");
58310
+ if (!attachment || headAttachments.has(attachment.Prop("Name"))) {
58311
+ [minExtent, maxExtent] = growExtentsToInclude(minExtent, maxExtent, handle, cInverse, head.Prop("CFrame"), untransformedHeadYMin);
58312
+ }
58313
+ }
58314
+ }
58315
+ }
58316
+ return [minExtent, maxExtent];
58317
+ }
58318
+ function calculateBodyPartsExtents(targetCFrame, bodyParts) {
58319
+ let [minExtent, maxExtent] = initExtents();
58320
+ const cInverse = targetCFrame.inverse();
58321
+ for (const part of bodyParts) {
58322
+ [minExtent, maxExtent] = growExtentsToInclude(minExtent, maxExtent, part, cInverse, targetCFrame);
58323
+ }
58324
+ return [minExtent, maxExtent];
58325
+ }
58326
+ function calculateTargetCFrame(baseCFrame) {
58327
+ let targetLookVector = new Vector3();
58328
+ if (Math.abs(baseCFrame.lookVector()[1]) > 0.9) {
58329
+ targetLookVector = new Vector3().fromVec3(baseCFrame.upVector());
58330
+ } else {
58331
+ targetLookVector = new Vector3().fromVec3(baseCFrame.lookVector());
58332
+ }
58333
+ targetLookVector = Vector3.new(targetLookVector.X, 0, targetLookVector.Z).normalize();
58334
+ return CFrame.lookAt(baseCFrame.Position, new Vector3().fromVec3(baseCFrame.Position).add(targetLookVector).toVec3());
58335
+ }
58336
+ function adjustTargetCFrameWithExtents(targetCFrame, minExtent, maxExtent) {
58337
+ let adjustment = minExtent.add(maxExtent).divide(new Vector3(2, 2, 2));
58338
+ const tmpCFrame = targetCFrame.rotationOnly();
58339
+ adjustment = tmpCFrame.multiplyVector(adjustment);
58340
+ targetCFrame.Position = add(targetCFrame.Position, adjustment.toVec3());
58341
+ return targetCFrame;
58342
+ }
58343
+ function vector3FromXYRotPlusDistance(xAngleDeg, yAngleDeg, radius) {
58344
+ const cFrame = CFrame.fromEulerAngles(rad(xAngleDeg), rad(yAngleDeg), 0, "XYZ");
58345
+ return new Vector3(...cFrame.lookVector()).multiply(new Vector3(radius, radius, radius));
58346
+ }
58347
+ const CONSTANTS_CameraUtility = {
58348
+ //When generating a head thumbnail, how much 'margin' around extent of head + accoutrements?
58349
+ DefaultHeadMarginScale: 1.1,
58350
+ //When generating a full body thumbnail, how much 'margin' around whole body?
58351
+ DefaultBodyMarginScale: 1.1,
58352
+ //Amount of margin around a body part in a generated thumbnail
58353
+ DefaultBodyPartMarginScale: 1.2,
58354
+ XRotForFullBody: 15,
58355
+ XRotForCloseup: 0,
58356
+ DistanceScaleForFullBody: 1
58357
+ };
58358
+ const HEAD_MARGIN_SCALE = 1.1;
58359
+ const HEAD_X_ROTATION_RAD = rad(15);
58360
+ const HEAD_Y_ROTATION_RAD = rad(30);
58361
+ const FACE_LEFT_CFRAME = CFrame.fromEulerAngles(rad(-20), rad(20), 0, "YXZ");
58362
+ const FACE_RIGHT_CFRAME = CFrame.fromEulerAngles(rad(-20), rad(-20), 0, "YXZ");
58363
+ const HEAD_BODYPART_FIELD_OF_VIEW_DEG = 30;
58364
+ const ACCESSORY_DEFAULT_CFRAME = CFrame.Angles(rad(25), rad(25), rad(0));
58365
+ const ACCESSORY_FIELD_OF_VIEW_DEG = 20;
58366
+ const ACCESSORY_EXTENT_SCALE = 1.1;
58367
+ const LEFT_SHOE_CFRAME = CFrame.Angles(rad(0), rad(90), rad(0));
58368
+ const RIGHT_SHOE_CFRAME = CFrame.Angles(rad(0), rad(-90), rad(0));
58369
+ function getCameraCFrame(targetCFrame, relativePos) {
58370
+ const cameraPos = targetCFrame.multiplyVector(relativePos);
58371
+ return CFrame.lookAt(cameraPos.toVec3(), targetCFrame.Position);
58372
+ }
58373
+ function createThumbnailCamera() {
58374
+ const camera = new Instance("Camera");
58375
+ camera.setProperty("Name", "ThumbnailCamera");
58376
+ camera.setProperty("CameraType", CameraType.Scriptable);
58377
+ return camera;
58378
+ }
58379
+ function calculateBaseDistanceToCamera(fieldOfViewRad, minExtent, maxExtent, marginScale) {
58380
+ const offsetFromCenter = Math.max((maxExtent.X - minExtent.X) / 2, (maxExtent.Y - minExtent.Y) / 2);
58381
+ const t = Math.tan(fieldOfViewRad / 2);
58382
+ return offsetFromCenter * marginScale / t;
58383
+ }
58384
+ function setupCamera(camera, cameraOptions) {
58385
+ if (cameraOptions.optFieldOfView) {
58386
+ camera.setProperty("FieldOfView", cameraOptions.optFieldOfView);
58387
+ }
58388
+ const fieldOfViewForDistanceScale = cameraOptions.optFieldOfViewForDistanceScale || camera.Prop("FieldOfView");
58389
+ let distanceToCamera = calculateBaseDistanceToCamera(
58390
+ rad(fieldOfViewForDistanceScale),
58391
+ cameraOptions.minExtent,
58392
+ cameraOptions.maxExtent,
58393
+ cameraOptions.extentScale
58394
+ );
58395
+ if (cameraOptions.optCameraDistanceScale) {
58396
+ distanceToCamera = distanceToCamera * cameraOptions.optCameraDistanceScale;
58397
+ }
58398
+ const finalTargetCFrame = adjustTargetCFrameWithExtents(
58399
+ cameraOptions.targetCFrame,
58400
+ cameraOptions.minExtent,
58401
+ cameraOptions.maxExtent
58402
+ );
58403
+ const cameraXRotDeg = cameraOptions.optCameraXRot || 0;
58404
+ const cameraYRotDeg = cameraOptions.optCameraYRot || 0;
58405
+ const cPos = vector3FromXYRotPlusDistance(cameraXRotDeg, cameraYRotDeg, distanceToCamera);
58406
+ camera.setProperty("CFrame", getCameraCFrame(finalTargetCFrame, cPos));
58407
+ }
58408
+ function setupBodyPartCamera(mannequin, faceRight, focusPartNames, camera) {
58409
+ const mannequinFocusParts = [];
58410
+ for (const focusPartName of focusPartNames) {
58411
+ const focusPart = mannequin.FindFirstDescendant(focusPartName);
58412
+ if (focusPart) {
58413
+ mannequinFocusParts.push(focusPart);
58414
+ }
58415
+ }
58416
+ const humanoidRootPart = mannequin.FindFirstChild("HumanoidRootPart");
58417
+ if (humanoidRootPart) {
58418
+ let mannequinTargetCFrame = humanoidRootPart.Prop("CFrame");
58419
+ const adjustment = faceRight ? FACE_RIGHT_CFRAME : FACE_LEFT_CFRAME;
58420
+ mannequinTargetCFrame = adjustment.multiply(mannequinTargetCFrame);
58421
+ const [minPartsExtent, maxPartsExtent] = calculateBodyPartsExtents(mannequinTargetCFrame, mannequinFocusParts);
58422
+ const cameraOptions = {
58423
+ optFieldOfView: HEAD_BODYPART_FIELD_OF_VIEW_DEG,
58424
+ targetCFrame: mannequinTargetCFrame,
58425
+ minExtent: minPartsExtent,
58426
+ maxExtent: maxPartsExtent,
58427
+ extentScale: CONSTANTS_CameraUtility.DefaultBodyPartMarginScale
58428
+ };
58429
+ setupCamera(camera, cameraOptions);
58430
+ }
58431
+ }
58432
+ function setupHeadCamera(headModel, camera) {
58433
+ const head = headModel.FindFirstChild("Head");
58434
+ if (head) {
58435
+ let headTargetCFrame = calculateTargetCFrame(head.Prop("CFrame"));
58436
+ const adjustment = CFrame.fromEulerAngles(HEAD_X_ROTATION_RAD, HEAD_Y_ROTATION_RAD, 0, "YXZ");
58437
+ headTargetCFrame = adjustment.multiply(headTargetCFrame);
58438
+ const [minHeadExtent, maxHeadExtent] = calculateHeadExtents(headModel, headTargetCFrame);
58439
+ const cameraOptions = {
58440
+ optFieldOfView: HEAD_BODYPART_FIELD_OF_VIEW_DEG,
58441
+ targetCFrame: headTargetCFrame,
58442
+ minExtent: minHeadExtent,
58443
+ maxExtent: maxHeadExtent,
58444
+ extentScale: HEAD_MARGIN_SCALE
58445
+ };
58446
+ setupCamera(camera, cameraOptions);
58447
+ }
58448
+ }
58449
+ function isLeftShoe(acc) {
58450
+ const handle = acc.FindFirstChildOfClass("MeshPart");
58451
+ if (!handle) {
58452
+ return false;
58453
+ }
58454
+ return void 0 !== handle.FindFirstChild("LeftFootAttachment");
58455
+ }
58456
+ function isRightShoe(acc) {
58457
+ const handle = acc.FindFirstChildOfClass("MeshPart");
58458
+ if (!handle) {
58459
+ return false;
58460
+ }
58461
+ return void 0 !== handle.FindFirstChild("RightFootAttachment");
58462
+ }
58463
+ function getAccessoryAngle(acc) {
58464
+ if (isLeftShoe(acc)) {
58465
+ return LEFT_SHOE_CFRAME;
58466
+ } else if (isRightShoe(acc)) {
58467
+ return RIGHT_SHOE_CFRAME;
58468
+ }
58469
+ return ACCESSORY_DEFAULT_CFRAME;
58470
+ }
58471
+ function setupAccessoryCamera(accessoryModel, camera) {
58472
+ const modelChildren = accessoryModel.GetChildren();
58473
+ const accoutrement = modelChildren[0];
58474
+ const handle = accoutrement.FindFirstChild("Handle");
58475
+ if (handle) {
58476
+ handle.setProperty("CFrame", new CFrame());
58477
+ const targetCFrame = handle.Prop("CFrame").multiply(getAccessoryAngle(accoutrement));
58478
+ const [minPartsExtent, maxPartsExtent] = calculateModelExtents(accessoryModel, targetCFrame);
58479
+ const cameraOptions = {
58480
+ optFieldOfView: ACCESSORY_FIELD_OF_VIEW_DEG,
58481
+ targetCFrame,
58482
+ minExtent: minPartsExtent,
58483
+ maxExtent: maxPartsExtent,
58484
+ extentScale: ACCESSORY_EXTENT_SCALE
58485
+ };
58486
+ setupCamera(camera, cameraOptions);
58487
+ }
58488
+ }
58489
+ const FIntCameraPresetHeadshotExtentScaleHundredths = 110;
58490
+ const CONSTANTS_CameraPresetsUtility = {
58491
+ GOLDEN_RATIO: 600 / 1e3,
58492
+ //game:DefineFastInt("AvatarGoldenRatio", 618) / 1000 -- = 0.618
58493
+ UPVECTOR_ORENTATION_TRESHOLD: -60 / 100,
58494
+ //game:DefineFastInt("UpVectorOrentationThreshold1", -60) / 100 // = -0.6
58495
+ AVATAR_ROTATION_DEGREE: 15
58496
+ //game:DefineFastInt("LookAvatarRotationDegree1", 23)
58497
+ };
58498
+ function getTorsoOrUpperTorso(character) {
58499
+ return character.FindFirstChild("Torso") || character.FindFirstChild("UpperTorso");
58500
+ }
58501
+ function getMannequinBodyParts(character, humanoid) {
58502
+ const bodyParts = [];
58503
+ if (humanoid.Prop("RigType") === HumanoidRigType.R6) {
58504
+ for (const partName of R6BodyPartNames) {
58505
+ const bodyPart = character.FindFirstChild(partName);
58506
+ if (bodyPart) bodyParts.push(bodyPart);
58507
+ }
58508
+ } else if (humanoid.Prop("RigType") === HumanoidRigType.R15) {
58509
+ for (const partName of R15BodyPartNames) {
58510
+ const bodyPart = character.FindFirstChild(partName);
58511
+ if (bodyPart) bodyParts.push(bodyPart);
58512
+ }
58513
+ }
58514
+ return bodyParts;
58515
+ }
58516
+ function getCharacterTorsoCFrame(character) {
58517
+ const torso = getTorsoOrUpperTorso(character);
58518
+ return torso ? torso.Prop("CFrame") : new CFrame();
58519
+ }
58520
+ function getFullBodyCameraCFrame(character, applyEmote, isFallbackEmoteApplied = true, fieldOfViewDeg, characterInitialCFrame, autoZoom = true) {
58521
+ const fovAngle = fieldOfViewDeg || 56;
58522
+ const characterInitialPivotTo = characterInitialCFrame || getCharacterTorsoCFrame(character);
58523
+ const characterInitialLookVector = characterInitialPivotTo.lookVector();
58524
+ if (applyEmote) {
58525
+ applyEmote();
58526
+ }
58527
+ const humanoid = character.FindFirstChildOfClass("Humanoid");
58528
+ if (!humanoid) {
58529
+ return;
58530
+ }
58531
+ const bodyParts = getMannequinBodyParts(character, humanoid);
58532
+ const characterPivotToAuxiliaryCFrame = getCharacterTorsoCFrame(character);
58533
+ const characterAuxiliaryUpVector = characterPivotToAuxiliaryCFrame.upVector();
58534
+ const head = character.FindFirstChild("Head");
58535
+ if (!head) return;
58536
+ const [characterHeadRotationX, characterHeadRotationY, characterHeadRotationZ] = head.Prop("CFrame").toEulerAngles("XYZ");
58537
+ if (isFallbackEmoteApplied) {
58538
+ const rootAssembly = head.w.GetAssembly();
58539
+ const rootPart = rootAssembly.rootNode.part;
58540
+ rootPart.setProperty("CFrame", rootPart.Prop("CFrame").multiply(CFrame.Angles(0, rad(CONSTANTS_CameraPresetsUtility.AVATAR_ROTATION_DEGREE * -1), 0)));
58541
+ rootAssembly.traverseTree();
58542
+ }
58543
+ const [minPartsExtent, maxPartsExtent] = calculateBodyPartsExtents(characterPivotToAuxiliaryCFrame, bodyParts);
58544
+ const tanAlpha = Math.tan(rad(fovAngle / 2));
58545
+ const goldPositionOfExtent = minPartsExtent.lerp(maxPartsExtent, CONSTANTS_CameraPresetsUtility.GOLDEN_RATIO);
58546
+ const centerPositionOfExtent = minPartsExtent.lerp(maxPartsExtent, 0.5);
58547
+ const goldPosition = new Vector3(centerPositionOfExtent.X, goldPositionOfExtent.Y, centerPositionOfExtent.Z);
58548
+ const goldPositionWorldSpace = characterPivotToAuxiliaryCFrame.multiplyVector(goldPosition);
58549
+ let characterGoldenRatioPivotTo = characterPivotToAuxiliaryCFrame.rotationOnly();
58550
+ characterGoldenRatioPivotTo.Position = add(characterGoldenRatioPivotTo.Position, goldPositionWorldSpace.toVec3());
58551
+ if (!isFallbackEmoteApplied) {
58552
+ const headPivotTo = CFrame.fromEulerAngles(characterHeadRotationX, characterHeadRotationY, characterHeadRotationZ, "XYZ");
58553
+ characterGoldenRatioPivotTo = headPivotTo.rotationOnly();
58554
+ characterGoldenRatioPivotTo.Position = add(characterGoldenRatioPivotTo.Position, goldPositionWorldSpace.toVec3());
58555
+ }
58556
+ const distanceToLowerExtents = Math.max(goldPosition.X - minPartsExtent.X, goldPosition.Y - minPartsExtent.Y);
58557
+ const distanceToUpperExtents = Math.max(maxPartsExtent.X - goldPosition.X, maxPartsExtent.Y - goldPosition.Y);
58558
+ const dc1 = distanceToLowerExtents * CONSTANTS_CameraUtility.DefaultBodyMarginScale / tanAlpha;
58559
+ const dc1Option = distanceToUpperExtents * CONSTANTS_CameraUtility.DefaultBodyMarginScale / tanAlpha;
58560
+ let distanceToCameraOption = dc1;
58561
+ const isUpsideDown = characterAuxiliaryUpVector[1] < CONSTANTS_CameraPresetsUtility.UPVECTOR_ORENTATION_TRESHOLD;
58562
+ const isUpsideRight = characterAuxiliaryUpVector[0] < CONSTANTS_CameraPresetsUtility.UPVECTOR_ORENTATION_TRESHOLD;
58563
+ if (isUpsideDown || isUpsideRight) {
58564
+ distanceToCameraOption = Math.max(dc1, dc1Option);
58565
+ }
58566
+ let distanceToCamera = distanceToCameraOption * CONSTANTS_CameraUtility.DistanceScaleForFullBody;
58567
+ if (autoZoom) {
58568
+ const [minExtentWithAccessories, maxExtentWithAccessories] = calculateModelExtents(character, characterPivotToAuxiliaryCFrame);
58569
+ const dc2 = Math.max(maxExtentWithAccessories.X - minExtentWithAccessories.X, maxExtentWithAccessories.Y - minExtentWithAccessories.Y) * CONSTANTS_CameraUtility.DefaultBodyMarginScale / 2 / tanAlpha;
58570
+ distanceToCamera = Math.max(dc1, dc1Option) * Math.max(Math.min(dc2 / Math.max(dc1, dc1Option), 1.5), 1.1);
58571
+ }
58572
+ const relativePositionToCamera = new Vector3().fromVec3(multiply(characterInitialLookVector, [distanceToCamera, distanceToCamera, distanceToCamera]));
58573
+ return getCameraCFrame(characterGoldenRatioPivotTo, relativePositionToCamera);
58574
+ }
58575
+ function getHeadshotCameraCFrame(character, applyEmote, isFallbackEmoteApplied, fieldOfViewDeg, cameraOptionsOverride) {
58576
+ const fovAngle = fieldOfViewDeg || 30;
58577
+ if (applyEmote) {
58578
+ applyEmote();
58579
+ }
58580
+ const characterHead = character.FindFirstChild("Head");
58581
+ if (!characterHead) {
58582
+ return;
58583
+ }
58584
+ let targetCFrame = characterHead.Prop("CFrame");
58585
+ const faceFrontAttachment = characterHead.FindFirstChild("FaceFrontAttachment");
58586
+ if (faceFrontAttachment) {
58587
+ const faceFrontAttachmentW = faceFrontAttachment.w;
58588
+ if (faceFrontAttachmentW) {
58589
+ targetCFrame = faceFrontAttachmentW.getWorldCFrame();
58590
+ }
58591
+ }
58592
+ const headTargetCFrame = calculateTargetCFrame(targetCFrame);
58593
+ const [minHeadExtent, maxHeadExtent] = calculateHeadExtents(character, headTargetCFrame);
58594
+ const camera = createThumbnailCamera();
58595
+ const cameraOptions = {
58596
+ extentScale: FIntCameraPresetHeadshotExtentScaleHundredths / 100,
58597
+ maxExtent: maxHeadExtent,
58598
+ minExtent: minHeadExtent,
58599
+ optCameraXRot: CONSTANTS_CameraUtility.XRotForCloseup,
58600
+ optFieldOfView: fovAngle,
58601
+ targetCFrame: headTargetCFrame
58602
+ };
58603
+ Object.assign(cameraOptions, cameraOptionsOverride);
58604
+ setupCamera(camera, cameraOptions);
58605
+ return camera;
58606
+ }
58607
+ function getAvatarCameraCFrame(character, applyEmote, isFallbackEmoteApplied, fieldOfViewDeg, cameraOptionsOverride) {
58608
+ const fovAngle = fieldOfViewDeg || 30;
58609
+ if (applyEmote) {
58610
+ applyEmote();
58611
+ }
58612
+ const characterHead = character.FindFirstChild("Head");
58613
+ if (!characterHead) {
58614
+ return;
58615
+ }
58616
+ let targetCFrame = characterHead.Prop("CFrame");
58617
+ const faceFrontAttachment = characterHead.FindFirstChild("FaceFrontAttachment");
58618
+ if (faceFrontAttachment) {
58619
+ const faceFrontAttachmentW = faceFrontAttachment.w;
58620
+ if (faceFrontAttachmentW) {
58621
+ targetCFrame = faceFrontAttachmentW.getWorldCFrame();
58622
+ }
58623
+ }
58624
+ const torsoCFrame = getCharacterTorsoCFrame(character);
58625
+ targetCFrame.Position = torsoCFrame.Position;
58626
+ const headTargetCFrame = calculateTargetCFrame(targetCFrame);
58627
+ const [minHeadExtent, maxHeadExtent] = calculateModelExtents(character, headTargetCFrame);
58628
+ const camera = createThumbnailCamera();
58629
+ const cameraOptions = {
58630
+ extentScale: FIntCameraPresetHeadshotExtentScaleHundredths / 100,
58631
+ maxExtent: maxHeadExtent,
58632
+ minExtent: minHeadExtent,
58633
+ optCameraXRot: CONSTANTS_CameraUtility.XRotForFullBody,
58634
+ optFieldOfView: fovAngle,
58635
+ targetCFrame: headTargetCFrame
58636
+ };
58637
+ Object.assign(cameraOptions, cameraOptionsOverride);
58638
+ setupCamera(camera, cameraOptions);
58639
+ return camera;
58640
+ }
58641
+ function getCorners(cframe, size) {
58642
+ const halfX = size.X / 2;
58643
+ const halfY = size.Y / 2;
58644
+ const halfZ = size.Z / 2;
58645
+ return [
58646
+ cframe.multiply(new CFrame(halfX, halfY, halfZ)),
58647
+ cframe.multiply(new CFrame(halfX, halfY, -halfZ)),
58648
+ cframe.multiply(new CFrame(-halfX, halfY, halfZ)),
58649
+ cframe.multiply(new CFrame(-halfX, halfY, -halfZ)),
58650
+ cframe.multiply(new CFrame(halfX, -halfY, halfZ)),
58651
+ cframe.multiply(new CFrame(halfX, -halfY, -halfZ)),
58652
+ cframe.multiply(new CFrame(-halfX, -halfY, halfZ)),
58653
+ cframe.multiply(new CFrame(-halfX, -halfY, -halfZ))
58654
+ ];
58655
+ }
58656
+ function getLower(a, b) {
58657
+ return new Vector3(
58658
+ a.X < b.X ? a.X : b.X,
58659
+ a.Y < b.Y ? a.Y : b.Y,
58660
+ a.Z < b.Z ? a.Z : b.Z
58661
+ );
58662
+ }
58663
+ function getHigher(a, b) {
58664
+ return new Vector3(
58665
+ a.X > b.X ? a.X : b.X,
58666
+ a.Y > b.Y ? a.Y : b.Y,
58667
+ a.Z > b.Z ? a.Z : b.Z
58668
+ );
58669
+ }
58670
+ function getExtentsForParts(parts, includeTransform) {
58671
+ let lowerExtents = new Vector3(0, 0, 0);
58672
+ let higherExtents = new Vector3(0, 0, 0);
58673
+ for (const child of parts) {
58674
+ if (child.createWrapper()?.IsA("BasePart")) {
58675
+ const cframe = traverseRigCFrame(child, includeTransform, true);
58676
+ const size = child.Prop("Size");
58677
+ const corners = getCorners(cframe, size);
58678
+ for (const corner of corners) {
58679
+ lowerExtents = getLower(lowerExtents, new Vector3().fromVec3(corner.Position));
58680
+ higherExtents = getHigher(higherExtents, new Vector3().fromVec3(corner.Position));
58681
+ }
58682
+ }
58683
+ }
58684
+ return [lowerExtents, higherExtents];
58685
+ }
58686
+ function getExtents(cframe, parts) {
58687
+ const inverseCF = cframe.inverse();
58688
+ let lowerExtents = new Vector3(0, 0, 0);
58689
+ let higherExtents = new Vector3(0, 0, 0);
58690
+ for (const child of parts) {
58691
+ if (child.createWrapper()?.IsA("BasePart")) {
58692
+ const partCF = child.Prop("CFrame");
58693
+ const partSize = child.Prop("Size");
58694
+ const corners = getCorners(inverseCF.multiply(partCF), partSize);
58695
+ for (const corner of corners) {
58696
+ lowerExtents = getLower(lowerExtents, new Vector3().fromVec3(corner.Position));
58697
+ higherExtents = getHigher(higherExtents, new Vector3().fromVec3(corner.Position));
58698
+ }
58699
+ }
58700
+ }
58701
+ return [lowerExtents, higherExtents];
58702
+ }
58703
+ function getExtentsWorld(rig) {
58704
+ const rigParts = [];
58705
+ for (const child of rig.GetDescendants()) {
58706
+ if (child.createWrapper()?.IsA("BasePart")) {
58707
+ rigParts.push(child);
58708
+ }
58709
+ }
58710
+ const extents = getExtents(new CFrame(), rigParts);
58711
+ return extents;
58712
+ }
58713
+ function getExtentsCenter(extents) {
58714
+ return extents[1].minus(extents[0]).divide(new Vector3(2, 2, 2)).add(extents[0]);
58715
+ }
58716
+ function zoomExtents(cameraCFrame, modelCFrame, modelSize, targetFOV, distanceScale, sizeType = "calculate") {
58717
+ let largestSize = Math.max(modelSize.X, modelSize.Y, modelSize.Z);
58718
+ if (sizeType === "calculate") {
58719
+ largestSize = modelSize.magnitude() / 2 / Math.sin(rad(targetFOV / 2));
58720
+ }
58721
+ const fovMultiplier = sizeType === "largestAxis" ? 70 / targetFOV : 1;
58722
+ const lookDir = multiply(normalize(minus(cameraCFrame.Position, modelCFrame.Position)), [distanceScale, distanceScale, distanceScale]);
58723
+ cameraCFrame.Position = add(modelCFrame.Position, multiply(multiply(lookDir, [largestSize, largestSize, largestSize]), [fovMultiplier, fovMultiplier, fovMultiplier]));
58724
+ }
58725
+ function getCameraOffset(fov2, extentsSize) {
58726
+ const halfSize = extentsSize.magnitude() / 2;
58727
+ const fovDivisor = Math.tan(rad(fov2 / 2));
58728
+ return halfSize / fovDivisor;
58729
+ }
58730
+ function zoomToExtents(cameraCFrame, modelCFrame, modelSize, fov2 = 70) {
58731
+ const cameraOffset = getCameraOffset(fov2, modelSize);
58732
+ const cameraRotation = new CFrame();
58733
+ cameraRotation.Orientation = cameraCFrame.Orientation;
58734
+ const instancePosition = modelCFrame.Position;
58735
+ cameraCFrame.Position = add(instancePosition, multiply(minus([0, 0, 0], cameraRotation.lookVector()), [cameraOffset, cameraOffset, cameraOffset]));
58736
+ }
58737
+ function getHeadExtents(rig) {
58738
+ const head = rig.FindFirstChild("Head");
58739
+ if (!head) return;
58740
+ const headParts = [];
58741
+ for (const child of rig.GetDescendants()) {
58742
+ if (child === head) {
58743
+ headParts.push(head);
58744
+ } else {
58745
+ const weld = child.FindFirstChildOfClass("Weld");
58746
+ if (weld && child.parent && child.parent.className === "Accessory") {
58747
+ if (weld.Prop("Part0") === head || weld.Prop("Part1") === head) {
58748
+ headParts.push(child);
58749
+ }
58750
+ }
58751
+ }
58752
+ }
58753
+ const extents = getExtents(head.Prop("CFrame"), headParts);
58754
+ return extents;
58755
+ }
58756
+ function getCameraCFrameForHeadshotCustomized(rig, fov2, yRot, distance2) {
58757
+ const camera = getHeadshotCameraCFrame(rig, void 0, void 0, fov2, {
58758
+ optCameraYRot: yRot,
58759
+ optCameraDistanceScale: distance2,
58760
+ extentScale: 1.1
58761
+ });
58762
+ if (camera) {
58763
+ const cameraCF = camera.Prop("CFrame");
58764
+ camera.Destroy();
58765
+ return cameraCF;
58766
+ }
58767
+ }
58768
+ function getCameraCFrameForAvatarCustomized(rig, fov2, yRot) {
58769
+ const camera = getAvatarCameraCFrame(rig, void 0, void 0, fov2, {
58770
+ optCameraYRot: yRot,
58771
+ optCameraDistanceScale: 1,
58772
+ extentScale: 1.1
58773
+ });
58774
+ if (camera) {
58775
+ const cameraCF = camera.Prop("CFrame");
58776
+ camera.Destroy();
58777
+ return cameraCF;
58778
+ }
58779
+ }
58780
+ function getCameraCFrameForAvatarNonCustomized(rig) {
58781
+ const thumbnailCamera = rig.FindFirstChildOfClass("Camera");
58782
+ if (thumbnailCamera) return thumbnailCamera.PropOrDefault("CFrame", new CFrame());
58783
+ let rootPart = rig.PropOrDefault("PrimaryPart", void 0);
58784
+ if (!rootPart) rootPart = rig.FindFirstChildOfClass("Part");
58785
+ if (!rootPart) rootPart = rig.FindFirstChildOfClass("MeshPart");
58786
+ if (!rootPart) return;
58787
+ const rootPartCF = rootPart.PropOrDefault("CFrame", new CFrame()).clone();
58788
+ const worldExtents = getExtentsWorld(rig);
58789
+ if (!worldExtents) return;
58790
+ const extentsSize = worldExtents[1].minus(worldExtents[0]);
58791
+ rootPartCF.Position = getExtentsCenter(worldExtents).toVec3();
58792
+ let lookVector = rootPartCF.lookVector();
58793
+ if (Math.abs(lookVector[1]) > 0.95) {
58794
+ lookVector = [0, 0, -1];
58795
+ } else {
58796
+ lookVector[1] = 0;
58797
+ lookVector = normalize(lookVector);
58798
+ }
58799
+ let lookCF = CFrame.lookAt([0, 0, 0], lookVector);
58800
+ lookCF = lookCF.multiply(CFrame.fromEulerAngles(25 * Math.PI / 180, 27.5 * Math.PI / 180, 0, "ZXY"));
58801
+ lookVector = lookCF.lookVector();
58802
+ lookCF.Position = add(rootPartCF.Position, multiply([10, 10, 10], lookVector));
58803
+ lookCF = CFrame.lookAt(lookCF.Position, rootPartCF.Position);
58804
+ const cameraCF = lookCF.clone();
58805
+ zoomExtents(cameraCF, rootPartCF, extentsSize, 70, 1);
58806
+ return cameraCF;
58807
+ }
58117
58808
  class BackgroundRenderer {
58118
58809
  auth;
58119
58810
  avatarCyclorama;
@@ -58318,7 +59009,7 @@ class OutfitRenderer {
58318
59009
  doCameraUpdate = false;
58319
59010
  /**Does camera update every frame */
58320
59011
  doAddInstance = true;
58321
- /**If outfitRenderer should call RBXRenderer.addInstance() */
59012
+ /**If outfitRenderer should call RBXRenderer.addInstance(), setting this to false will make OutfitRenderer return success early */
58322
59013
  forceAnimationLoop = true;
58323
59014
  /**If future loaded animations should be set to loop */
58324
59015
  backgroundRenderer;
@@ -58360,6 +59051,16 @@ class OutfitRenderer {
58360
59051
  * @returns void
58361
59052
  */
58362
59053
  onRenderError = new Event();
59054
+ get humanoid() {
59055
+ return this.currentRig?.FindFirstChildOfClass("Humanoid");
59056
+ }
59057
+ get animator() {
59058
+ return this.humanoid?.FindFirstChildOfClass("Animator");
59059
+ }
59060
+ get animatorW() {
59061
+ const animator = this.animator;
59062
+ if (animator) return new AnimatorWrapper(animator);
59063
+ }
58363
59064
  /**
58364
59065
  * Creates a new OutfitRenderer which makes it easy to render outfits
58365
59066
  * @param auth The authentication object, you should have one you use for everything
@@ -58551,9 +59252,30 @@ class OutfitRenderer {
58551
59252
  this.animationInterval = void 0;
58552
59253
  }
58553
59254
  }
59255
+ /**
59256
+ * Checks if the provided animation set is loaded
59257
+ * @param name The name of the animation, for example "idle", "run", but NOT "emote.1234" or "id.1234" as they are not in the animation set
59258
+ * @returns If the animation is loaded
59259
+ */
59260
+ hasAnimationSetAnimation(name) {
59261
+ if (this.currentRig) {
59262
+ const humanoid = this.currentRig.FindFirstChildOfClass("Humanoid");
59263
+ if (humanoid) {
59264
+ const animator = humanoid.FindFirstChildOfClass("Animator");
59265
+ if (animator) {
59266
+ const animatorW = new AnimatorWrapper(animator);
59267
+ const entries = animatorW.data.animationSet[name];
59268
+ if (entries) {
59269
+ return entries.length > 0;
59270
+ }
59271
+ }
59272
+ }
59273
+ }
59274
+ return false;
59275
+ }
58554
59276
  /**
58555
59277
  * Sets the current animation being played
58556
- * @param name The name of the animation, for example "idle", "run", "emote.1234" or "anim.1234"
59278
+ * @param name The name of the animation, for example "idle", "run", "emote.1234" or "id.1234"
58557
59279
  * @returns If the animation started playing, it may start playing later if it has been queued despite returning false
58558
59280
  */
58559
59281
  setMainAnimation(name) {
@@ -58622,16 +59344,28 @@ class OutfitRenderer {
58622
59344
  }
58623
59345
  async _prepareForThumbnail() {
58624
59346
  this.doAddInstance = false;
59347
+ this.backgroundRenderer.affectSceneAppearance = false;
59348
+ this.backgroundRenderer.cameraAffectsTransparency = false;
58625
59349
  if (this.outfit.playerAvatarType === AvatarType.R6) this.deltaTimeMultiplier = 0;
58626
59350
  await new Promise((resolve) => {
58627
59351
  this.onSuccess.Connect(() => {
59352
+ const animatorW = this.animatorW;
59353
+ if (animatorW) {
59354
+ animatorW.data.forceTransitionTime = 0;
59355
+ }
58628
59356
  if (!this.outfit.containsAssetType("Gear")) {
58629
59357
  if (this.outfit.playerAvatarType === AvatarType.R15) {
58630
- this.setMainAnimation("pose").then(() => {
58631
- resolve(void 0);
58632
- });
59358
+ if (this.hasAnimationSetAnimation("pose")) {
59359
+ this.setMainAnimation("pose").then(() => {
59360
+ resolve(void 0);
59361
+ });
59362
+ } else {
59363
+ this.setMainAnimation("idle:0").then(() => {
59364
+ resolve(void 0);
59365
+ });
59366
+ }
58633
59367
  } else {
58634
- this.setMainAnimation("idle").then(() => {
59368
+ this.setMainAnimation("idle:0").then(() => {
58635
59369
  resolve(void 0);
58636
59370
  });
58637
59371
  }
@@ -58642,8 +59376,10 @@ class OutfitRenderer {
58642
59376
  }
58643
59377
  });
58644
59378
  });
58645
- this.animateOnce(!this.outfit.containsAssetType("Gear") && this.outfit.playerAvatarType === AvatarType.R6 ? 0 : 1);
59379
+ this.animateOnce(0);
59380
+ if (this.outfit.playerAvatarType !== AvatarType.R6 && this.animatorW?.data.currentAnimation === "idle") this.animateOnce((this.animatorW?.data.currentAnimationTrack?.length || 0) / 2);
58646
59381
  if (this.currentRig) RBXRenderer.addInstance(this.currentRig, this.auth, this.renderScene);
59382
+ this.hasFiredFullyRendered = false;
58647
59383
  await new Promise((resolve) => {
58648
59384
  const connection = this.onRenderSuccess.Connect(() => {
58649
59385
  resolve(void 0);
@@ -58727,102 +59463,6 @@ async function modelThumbnailClick(renderScene, format, options) {
58727
59463
  binary: format === "glb"
58728
59464
  });
58729
59465
  }
58730
- function getCorners(cframe, size) {
58731
- const halfX = size.X / 2;
58732
- const halfY = size.Y / 2;
58733
- const halfZ = size.Z / 2;
58734
- return [
58735
- cframe.multiply(new CFrame(halfX, halfY, halfZ)),
58736
- cframe.multiply(new CFrame(halfX, halfY, -halfZ)),
58737
- cframe.multiply(new CFrame(-halfX, halfY, halfZ)),
58738
- cframe.multiply(new CFrame(-halfX, halfY, -halfZ)),
58739
- cframe.multiply(new CFrame(halfX, -halfY, halfZ)),
58740
- cframe.multiply(new CFrame(halfX, -halfY, -halfZ)),
58741
- cframe.multiply(new CFrame(-halfX, -halfY, halfZ)),
58742
- cframe.multiply(new CFrame(-halfX, -halfY, -halfZ))
58743
- ];
58744
- }
58745
- function getLower(a, b) {
58746
- return new Vector3(
58747
- a.X < b.X ? a.X : b.X,
58748
- a.Y < b.Y ? a.Y : b.Y,
58749
- a.Z < b.Z ? a.Z : b.Z
58750
- );
58751
- }
58752
- function getHigher(a, b) {
58753
- return new Vector3(
58754
- a.X > b.X ? a.X : b.X,
58755
- a.Y > b.Y ? a.Y : b.Y,
58756
- a.Z > b.Z ? a.Z : b.Z
58757
- );
58758
- }
58759
- function getExtentsForParts(parts, includeTransform) {
58760
- let lowerExtents = new Vector3(0, 0, 0);
58761
- let higherExtents = new Vector3(0, 0, 0);
58762
- for (const child of parts) {
58763
- if (child.createWrapper()?.IsA("BasePart")) {
58764
- const cframe = traverseRigCFrame(child, includeTransform, true);
58765
- const size = child.Prop("Size");
58766
- const corners = getCorners(cframe, size);
58767
- for (const corner of corners) {
58768
- lowerExtents = getLower(lowerExtents, new Vector3().fromVec3(corner.Position));
58769
- higherExtents = getHigher(higherExtents, new Vector3().fromVec3(corner.Position));
58770
- }
58771
- }
58772
- }
58773
- return [lowerExtents, higherExtents];
58774
- }
58775
- function getExtents(cframe, parts) {
58776
- const inverseCF = cframe.inverse();
58777
- let lowerExtents = new Vector3(0, 0, 0);
58778
- let higherExtents = new Vector3(0, 0, 0);
58779
- for (const child of parts) {
58780
- if (child.createWrapper()?.IsA("BasePart")) {
58781
- const partCF = child.Prop("CFrame");
58782
- const partSize = child.Prop("Size");
58783
- const corners = getCorners(inverseCF.multiply(partCF), partSize);
58784
- for (const corner of corners) {
58785
- lowerExtents = getLower(lowerExtents, new Vector3().fromVec3(corner.Position));
58786
- higherExtents = getHigher(higherExtents, new Vector3().fromVec3(corner.Position));
58787
- }
58788
- }
58789
- }
58790
- return [lowerExtents, higherExtents];
58791
- }
58792
- function getExtentsWorld(rig) {
58793
- const rigParts = [];
58794
- for (const child of rig.GetDescendants()) {
58795
- if (child.createWrapper()?.IsA("BasePart")) {
58796
- rigParts.push(child);
58797
- }
58798
- }
58799
- const extents = getExtents(new CFrame(), rigParts);
58800
- return extents;
58801
- }
58802
- function getExtentsCenter(extents) {
58803
- return extents[1].minus(extents[0]).divide(new Vector3(2, 2, 2)).add(extents[0]);
58804
- }
58805
- function zoomExtents(cameraCFrame, modelCFrame, modelSize, targetFOV, distanceScale, sizeType = "calculate") {
58806
- let largestSize = Math.max(modelSize.X, modelSize.Y, modelSize.Z);
58807
- if (sizeType === "calculate") {
58808
- largestSize = modelSize.magnitude() / 2 / Math.sin(rad(targetFOV / 2));
58809
- }
58810
- const fovMultiplier = sizeType === "largestAxis" ? 70 / targetFOV : 1;
58811
- const lookDir = multiply(normalize(minus(cameraCFrame.Position, modelCFrame.Position)), [distanceScale, distanceScale, distanceScale]);
58812
- cameraCFrame.Position = add(modelCFrame.Position, multiply(multiply(lookDir, [largestSize, largestSize, largestSize]), [fovMultiplier, fovMultiplier, fovMultiplier]));
58813
- }
58814
- function getCameraOffset(fov2, extentsSize) {
58815
- const halfSize = extentsSize.magnitude() / 2;
58816
- const fovDivisor = Math.tan(rad(fov2 / 2));
58817
- return halfSize / fovDivisor;
58818
- }
58819
- function zoomToExtents(cameraCFrame, modelCFrame, modelSize, fov2 = 70) {
58820
- const cameraOffset = getCameraOffset(fov2, modelSize);
58821
- const cameraRotation = new CFrame();
58822
- cameraRotation.Orientation = cameraCFrame.Orientation;
58823
- const instancePosition = modelCFrame.Position;
58824
- cameraCFrame.Position = add(instancePosition, multiply(minus([0, 0, 0], cameraRotation.lookVector()), [cameraOffset, cameraOffset, cameraOffset]));
58825
- }
58826
59466
  function getThumbnailCameraCFrame(model, fov2, forceAngle) {
58827
59467
  const thumbnailCamera = model.FindFirstChildOfClass("Camera");
58828
59468
  if (thumbnailCamera) return thumbnailCamera.PropOrDefault("CFrame", new CFrame());
@@ -58869,7 +59509,7 @@ function setupThumbnailScene(renderScene) {
58869
59509
  if (renderScene.shadowPlane) renderScene.scene.remove(renderScene.shadowPlane);
58870
59510
  renderScene.scene.background = null;
58871
59511
  }
58872
- async function generateOutfitThumbnail(auth, outfit, size = [150, 150], type = "png", quality = 1, gltfAutoDownload = false, includeAnimations = false, renderSceneParam) {
59512
+ async function generateOutfitThumbnail(auth, outfit, size = [150, 150], type = "png", quality = 1, gltfAutoDownload = false, includeAnimations = false, renderSceneParam, thumbnailCameraType = "default") {
58873
59513
  const renderScene = renderSceneParam || RBXRenderer.addScene();
58874
59514
  if (renderScene !== renderSceneParam) {
58875
59515
  setupThumbnailScene(renderScene);
@@ -58882,9 +59522,25 @@ async function generateOutfitThumbnail(auth, outfit, size = [150, 150], type = "
58882
59522
  return void 0;
58883
59523
  }
58884
59524
  if (outfitRenderer.currentRig) {
58885
- const cameraCFrame = getThumbnailCameraCFrame(outfitRenderer.currentRig, renderScene.camera.fov);
59525
+ let cameraCFrame = new CFrame();
59526
+ switch (thumbnailCameraType) {
59527
+ case "default":
59528
+ cameraCFrame = getThumbnailCameraCFrame(outfitRenderer.currentRig, renderScene.camera.fov) || cameraCFrame;
59529
+ break;
59530
+ case "avatarHeadshot":
59531
+ cameraCFrame = getCameraCFrameForHeadshotCustomized(outfitRenderer.currentRig, 28, 0, 1) || cameraCFrame;
59532
+ break;
59533
+ case "avatarFullbody":
59534
+ cameraCFrame = getCameraCFrameForAvatarCustomized(outfitRenderer.currentRig, 28, 0) || cameraCFrame;
59535
+ break;
59536
+ case "fullbody":
59537
+ cameraCFrame = getFullBodyCameraCFrame(outfitRenderer.currentRig) || cameraCFrame;
59538
+ break;
59539
+ }
58886
59540
  if (cameraCFrame) {
58887
59541
  RBXRenderer.setCameraCFrame(cameraCFrame, renderScene);
59542
+ RBXRenderer.setCameraFov(thumbnailCameraType === "default" ? 70 : thumbnailCameraType === "fullbody" ? 56 : 28, renderScene);
59543
+ renderScene.camera.updateProjectionMatrix();
58888
59544
  }
58889
59545
  outfitRenderer.updateParticleMatrix();
58890
59546
  const result = type === "gltf" || type === "glb" ? await modelThumbnailClick(renderScene, type, {
@@ -58917,37 +59573,7 @@ async function generateOutfitModelThumbnail(auth, outfitModel, options) {
58917
59573
  includeAnimations: false
58918
59574
  };
58919
59575
  Object.assign(defaultOptions, options);
58920
- const renderScene = RBXRenderer.addScene();
58921
- setupThumbnailScene(renderScene);
58922
- if (outfitModel.background?.id) {
58923
- const avatarCycloramaRBX = await API.Asset.GetRBX("roavatar://AvatarCyclorama.rbxm");
58924
- if (avatarCycloramaRBX instanceof Response) return void 0;
58925
- const avatarCycloramaRoot = avatarCycloramaRBX.generateTree();
58926
- const avatarCyclorama = avatarCycloramaRoot.GetChildren()[0];
58927
- if (avatarCyclorama) {
58928
- const backgroundDataRBX = await API.Asset.GetRBX("rbxassetid://" + outfitModel.background.id);
58929
- if (backgroundDataRBX instanceof Response) return void 0;
58930
- const backgroundDataRoot = backgroundDataRBX.generateTree();
58931
- const backgroundData = backgroundDataRoot.GetChildren()[0];
58932
- if (backgroundData) {
58933
- if (backgroundData) {
58934
- const colorValue = backgroundData.Child("Color");
58935
- const imageIdValue = backgroundData.Child("ImageId");
58936
- if (colorValue && imageIdValue) {
58937
- const color2 = colorValue.Prop("Value");
58938
- const imageId = imageIdValue.Prop("Value");
58939
- avatarCyclorama.Child("color_mesh").setProperty("Color", color2.toColor3uint8());
58940
- avatarCyclorama.Child("texture_mesh").setProperty("TextureID", `rbxassetid://${imageId}`);
58941
- avatarCyclorama.preRender();
58942
- RBXRenderer.addInstance(avatarCyclorama, auth, renderScene);
58943
- renderScene.camera.fov = 30;
58944
- renderScene.camera.updateProjectionMatrix();
58945
- }
58946
- }
58947
- }
58948
- }
58949
- }
58950
- return generateOutfitThumbnail(auth, outfitModel.outfit, defaultOptions.size, defaultOptions.type, defaultOptions.quality, defaultOptions.gltfAutoDownload, defaultOptions.includeAnimations, renderScene);
59576
+ return generateOutfitThumbnail(auth, outfitModel, defaultOptions.size, defaultOptions.type, defaultOptions.quality, defaultOptions.gltfAutoDownload, defaultOptions.includeAnimations);
58951
59577
  }
58952
59578
  function renderToRenderTarget(width, height, renderScene) {
58953
59579
  const renderTarget = new WebGLRenderTarget(width, height, {
@@ -59030,79 +59656,6 @@ function exposeThumbnailGenerator() {
59030
59656
  globalThis.setupThumbnailScene = setupThumbnailScene;
59031
59657
  globalThis.getThumbnailCameraCFrame = getThumbnailCameraCFrame;
59032
59658
  }
59033
- function getHeadExtents(rig) {
59034
- const head = rig.FindFirstChild("Head");
59035
- if (!head) return;
59036
- const headParts = [];
59037
- for (const child of rig.GetDescendants()) {
59038
- if (child === head) {
59039
- headParts.push(head);
59040
- } else {
59041
- const weld = child.FindFirstChildOfClass("Weld");
59042
- if (weld && child.parent && child.parent.className === "Accessory") {
59043
- if (weld.Prop("Part0") === head || weld.Prop("Part1") === head) {
59044
- headParts.push(child);
59045
- }
59046
- }
59047
- }
59048
- }
59049
- const extents = getExtents(head.Prop("CFrame"), headParts);
59050
- return extents;
59051
- }
59052
- function getCameraCFrameForHeadshotCustomized(rig, fov2, yRot, distance2) {
59053
- const head = rig.FindFirstChild("Head");
59054
- if (!head) return;
59055
- const headCF = head.PropOrDefault("CFrame", new CFrame());
59056
- const headLocalExtents = getHeadExtents(rig);
59057
- if (!headLocalExtents) return;
59058
- const headCenterPosLocal = headLocalExtents[0].add(headLocalExtents[1].minus(headLocalExtents[0]).divide(new Vector3(2, 2, 2)));
59059
- const headCenterPos = new Vector3().fromVec3(headCF.multiply(new CFrame(...headCenterPosLocal.toVec3())).Position);
59060
- const headCenterCF = new CFrame(...headCenterPos.toVec3());
59061
- let lookVector = headCF.lookVector();
59062
- if (Math.abs(lookVector[1]) > 0.95) {
59063
- lookVector = [0, 0, -1];
59064
- } else {
59065
- lookVector[1] = 0;
59066
- lookVector = normalize(lookVector);
59067
- }
59068
- let lookCF = CFrame.lookAt([0, 0, 0], lookVector);
59069
- lookCF = lookCF.multiply(CFrame.fromEulerAngles(0, rad(yRot), 0, "ZXY"));
59070
- lookVector = lookCF.lookVector();
59071
- const fovMultiplier = 70 / fov2;
59072
- lookCF.Position = add(headCenterCF.Position, multiply(multiply([10, 10, 10], lookVector), [fovMultiplier, fovMultiplier, fovMultiplier]));
59073
- lookCF = CFrame.lookAt(lookCF.Position, headCenterCF.Position);
59074
- const cameraCF = lookCF.clone();
59075
- zoomExtents(cameraCF, headCenterCF, headLocalExtents[1].minus(headLocalExtents[0]), fov2, distance2, "largestAxis");
59076
- return cameraCF;
59077
- }
59078
- function getCameraCFrameForAvatarNonCustomized(rig) {
59079
- const thumbnailCamera = rig.FindFirstChildOfClass("Camera");
59080
- if (thumbnailCamera) return thumbnailCamera.PropOrDefault("CFrame", new CFrame());
59081
- let rootPart = rig.PropOrDefault("PrimaryPart", void 0);
59082
- if (!rootPart) rootPart = rig.FindFirstChildOfClass("Part");
59083
- if (!rootPart) rootPart = rig.FindFirstChildOfClass("MeshPart");
59084
- if (!rootPart) return;
59085
- const rootPartCF = rootPart.PropOrDefault("CFrame", new CFrame()).clone();
59086
- const worldExtents = getExtentsWorld(rig);
59087
- if (!worldExtents) return;
59088
- const extentsSize = worldExtents[1].minus(worldExtents[0]);
59089
- rootPartCF.Position = getExtentsCenter(worldExtents).toVec3();
59090
- let lookVector = rootPartCF.lookVector();
59091
- if (Math.abs(lookVector[1]) > 0.95) {
59092
- lookVector = [0, 0, -1];
59093
- } else {
59094
- lookVector[1] = 0;
59095
- lookVector = normalize(lookVector);
59096
- }
59097
- let lookCF = CFrame.lookAt([0, 0, 0], lookVector);
59098
- lookCF = lookCF.multiply(CFrame.fromEulerAngles(25 * Math.PI / 180, 27.5 * Math.PI / 180, 0, "ZXY"));
59099
- lookVector = lookCF.lookVector();
59100
- lookCF.Position = add(rootPartCF.Position, multiply([10, 10, 10], lookVector));
59101
- lookCF = CFrame.lookAt(lookCF.Position, rootPartCF.Position);
59102
- const cameraCF = lookCF.clone();
59103
- zoomExtents(cameraCF, rootPartCF, extentsSize, 70, 1);
59104
- return cameraCF;
59105
- }
59106
59659
  export {
59107
59660
  API,
59108
59661
  AbbreviationToFaceControlProperty,
@@ -59138,6 +59691,7 @@ export {
59138
59691
  AttachmentWrapper,
59139
59692
  Authentication,
59140
59693
  AvatarType,
59694
+ BackgroundRenderer,
59141
59695
  BasePartWrapper,
59142
59696
  BodyColor3s,
59143
59697
  BodyColors,
@@ -59152,8 +59706,12 @@ export {
59152
59706
  BundleTypes,
59153
59707
  CACHE,
59154
59708
  CFrame,
59709
+ CONSTANTS_CameraPresetsUtility,
59710
+ CONSTANTS_CameraUtility,
59155
59711
  COREMESH,
59156
59712
  Cache,
59713
+ CameraType,
59714
+ CameraWrapper,
59157
59715
  CatalogBundleTypes,
59158
59716
  CategoryDictionary,
59159
59717
  Color3,
@@ -59217,11 +59775,14 @@ export {
59217
59775
  PartType,
59218
59776
  PartWrapper,
59219
59777
  ParticleEmitterShapeInOut,
59778
+ ParticleEmitterWrapper,
59220
59779
  ParticleFlipbookLayout,
59221
59780
  ParticleFlipbookMode,
59222
59781
  ParticleOrientation,
59223
59782
  Property,
59224
59783
  PropertyTypeInfo,
59784
+ R15BodyPartNames,
59785
+ R6BodyPartNames,
59225
59786
  RBFDeformerPatch,
59226
59787
  RBX,
59227
59788
  RBXRenderer,
@@ -59275,6 +59836,7 @@ export {
59275
59836
  browserSendMessage,
59276
59837
  buildFaceKD,
59277
59838
  buildVertKD,
59839
+ calculateBaseDistanceToCamera,
59278
59840
  calculateMagnitude3D,
59279
59841
  calculateMotor6Doffset,
59280
59842
  clamp,
@@ -59283,6 +59845,7 @@ export {
59283
59845
  cloneSearch_Payload,
59284
59846
  closestPointTriangle,
59285
59847
  createContentMap,
59848
+ createThumbnailCamera,
59286
59849
  createWeightsForMeshChunked,
59287
59850
  cross,
59288
59851
  defaultPantAssetIds,
@@ -59307,14 +59870,20 @@ export {
59307
59870
  generateOutfitModelThumbnail,
59308
59871
  generateOutfitThumbnail,
59309
59872
  generateUUIDv4,
59873
+ getAvatarCameraCFrame,
59874
+ getCameraCFrame,
59875
+ getCameraCFrameForAvatarCustomized,
59310
59876
  getCameraCFrameForAvatarNonCustomized,
59311
59877
  getCameraCFrameForHeadshotCustomized,
59878
+ getCharacterTorsoCFrame,
59312
59879
  getDistIndexArray,
59313
59880
  getExtents,
59314
59881
  getExtentsCenter,
59315
59882
  getExtentsForParts,
59316
59883
  getExtentsWorld,
59884
+ getFullBodyCameraCFrame,
59317
59885
  getHeadExtents,
59886
+ getHeadshotCameraCFrame,
59318
59887
  getOffsetArray,
59319
59888
  getOriginalAttachmentOrientation,
59320
59889
  getOriginalAttachmentPosition,
@@ -59369,6 +59938,10 @@ export {
59369
59938
  rotationMatrixToEulerAngles,
59370
59939
  saveByteArray,
59371
59940
  scaleMesh,
59941
+ setupAccessoryCamera,
59942
+ setupBodyPartCamera,
59943
+ setupCamera,
59944
+ setupHeadCamera,
59372
59945
  setupThumbnailScene,
59373
59946
  snapToNumber,
59374
59947
  specialClamp,