roavatar-renderer 1.2.2 → 1.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -107,6 +107,7 @@ export declare class AnimationTrack {
107
107
  length: number;
108
108
  looped: boolean;
109
109
  priority: number;
110
+ shouldUpdateMotors: boolean;
110
111
  pOriginalWeight: number;
111
112
  pTargetWeight: number;
112
113
  pSpeed: number;
@@ -128,7 +129,8 @@ export declare class AnimationTrack {
128
129
  * @deprecated, reset inside Animator instead
129
130
  */
130
131
  resetMotorTransforms(): void;
131
- renderPose(): void;
132
+ renderPose(updateMotors?: boolean): void;
133
+ updateMotors(): void;
132
134
  setTime(time: number): void;
133
135
  /**
134
136
  * Remember to call tick() on each frame
@@ -918,6 +920,8 @@ export declare const FLAGS: {
918
920
  HAIR_IS_BODYPART: boolean;
919
921
  BODYCOLOR3: boolean;
920
922
  ENABLE_API_CACHE: boolean;
923
+ ENABLE_API_MESH_CACHE: boolean;
924
+ ENABLE_API_RBX_CACHE: boolean;
921
925
  ROAVATAR_DATA_URL: string;
922
926
  ROAVATAR_TRYON_PLACE: number;
923
927
  ASSETS_PATH: string;
@@ -937,6 +941,7 @@ export declare const FLAGS: {
937
941
  UPDATE_SKELETON: boolean;
938
942
  ANIMATE_SKELETON: boolean;
939
943
  AUTO_SKIN_EVERYTHING: boolean;
944
+ USE_LOCAL_SKELETONDESC: boolean;
940
945
  SEARCH_FOR_STRING: string | undefined;
941
946
  LOAD_TEST_PLACE: string | undefined;
942
947
  };
@@ -1143,7 +1148,7 @@ export declare class Instance {
1143
1148
  removeReferencedBy(instance: Instance): void;
1144
1149
  addProperty(property: Property, value?: unknown): void;
1145
1150
  fixPropertyName(name: string): string;
1146
- setProperty(name: string, value: unknown): void;
1151
+ setProperty(name: string, value: unknown, supressEvents?: boolean): void;
1147
1152
  HasProperty(name: string): boolean;
1148
1153
  Property(name: string): unknown;
1149
1154
  Prop(name: string): unknown;
@@ -1950,6 +1955,9 @@ export declare class RBXRenderer {
1950
1955
  static loadingIconStyle?: HTMLStyleElement;
1951
1956
  static plane?: THREE.Mesh;
1952
1957
  static shadowPlane?: THREE.Mesh;
1958
+ static ambientLight?: THREE.AmbientLight;
1959
+ static directionalLight?: THREE.DirectionalLight;
1960
+ static directionalLight2?: THREE.DirectionalLight;
1953
1961
  static boilerplateSetup(): Promise<void>;
1954
1962
  /**Fully sets up renderer with scene, camera and frame rendering*/
1955
1963
  static fullSetup(includeScene?: boolean, includeControls?: boolean): Promise<void>;
package/dist/index.js CHANGED
@@ -28208,10 +28208,12 @@ class InstanceWrapper {
28208
28208
  if (this.instance.className !== this.static().className) {
28209
28209
  throw new Error(`Provided Instance is not a ${this.static().className}`);
28210
28210
  }
28211
- const hasAllProperties = this.static().requiredProperties.every((value) => this.instance.getPropertyNames().includes(value));
28211
+ const propertyNames = this.instance.getPropertyNames();
28212
+ const hasAllProperties = this.static().requiredProperties.every((value) => propertyNames.includes(value));
28212
28213
  if (!hasAllProperties) {
28213
28214
  this.setup();
28214
- const hasAllProperties2 = this.static().requiredProperties.every((value) => this.instance.getPropertyNames().includes(value));
28215
+ const newPropertyNames = this.instance.getPropertyNames();
28216
+ const hasAllProperties2 = this.static().requiredProperties.every((value) => newPropertyNames.includes(value));
28215
28217
  if (!hasAllProperties2) {
28216
28218
  throw new Error("setup() does not add all properties listed in requiredProperties");
28217
28219
  }
@@ -28239,6 +28241,8 @@ const FLAGS = {
28239
28241
  //api
28240
28242
  BODYCOLOR3: true,
28241
28243
  ENABLE_API_CACHE: true,
28244
+ ENABLE_API_MESH_CACHE: true,
28245
+ ENABLE_API_RBX_CACHE: true,
28242
28246
  ROAVATAR_DATA_URL: "rbxassetid://102463700065175",
28243
28247
  //url of model to load that lists issues with specific versions
28244
28248
  ROAVATAR_TRYON_PLACE: 135979364355750,
@@ -28268,6 +28272,7 @@ const FLAGS = {
28268
28272
  UPDATE_SKELETON: true,
28269
28273
  ANIMATE_SKELETON: true,
28270
28274
  AUTO_SKIN_EVERYTHING: false,
28275
+ USE_LOCAL_SKELETONDESC: false,
28271
28276
  //debug
28272
28277
  SEARCH_FOR_STRING: void 0,
28273
28278
  //"requestparams" //"looks/" //this is useful if you want to find api endpoints
@@ -28587,9 +28592,7 @@ class CFrame {
28587
28592
  return cloneCF;
28588
28593
  }
28589
28594
  getTHREEMatrix() {
28590
- const quat = new Quaternion().setFromEuler(new Euler(rad(this.Orientation[0]), rad(this.Orientation[1]), rad(this.Orientation[2]), "YXZ"));
28591
- const transformMatrix = new Matrix4().makeTranslation(this.Position[0], this.Position[1], this.Position[2]);
28592
- return transformMatrix.multiply(new Matrix4().makeRotationFromQuaternion(quat));
28595
+ return new Matrix4().compose(new Vector3$1(...this.Position), new Quaternion().setFromEuler(new Euler(rad(this.Orientation[0]), rad(this.Orientation[1]), rad(this.Orientation[2]), "YXZ")), new Vector3$1(1, 1, 1));
28593
28596
  }
28594
28597
  getMatrix() {
28595
28598
  return this.getTHREEMatrix().toArray();
@@ -28721,132 +28724,6 @@ class Instance {
28721
28724
  throw new Error("Instance was not provided a className");
28722
28725
  }
28723
28726
  this.className = className;
28724
- switch (this.className) {
28725
- case "Motor6D":
28726
- case "Weld":
28727
- {
28728
- let update = function(self2, affectedPart = 1) {
28729
- if (!self2.HasProperty("Part0") || !self2.HasProperty("Part1")) return;
28730
- let part0 = void 0;
28731
- if (self2.HasProperty("Part0")) {
28732
- part0 = self2.Property("Part0");
28733
- if (part0) {
28734
- if (part0ChangedConnection) {
28735
- part0ChangedConnection.Disconnect();
28736
- self2.removeConnectionReference(part0ChangedConnection);
28737
- }
28738
- }
28739
- }
28740
- let part1 = void 0;
28741
- if (self2.HasProperty("Part1")) {
28742
- part1 = self2.Property("Part1");
28743
- }
28744
- if (!self2.HasProperty("C0") || !self2.HasProperty("C1")) {
28745
- return;
28746
- }
28747
- const C0 = self2.Property("C0");
28748
- const C1 = self2.Property("C1");
28749
- if (!C0 || !C1) {
28750
- return;
28751
- }
28752
- let transform = new CFrame();
28753
- if (self2.HasProperty("Transform")) {
28754
- transform = self2.Property("Transform");
28755
- }
28756
- if (self2.HasProperty("Enabled") && self2.Prop("Enabled")) {
28757
- if (self2.parent) {
28758
- if (affectedPart === 1) {
28759
- if (part0 && part1 && part0.HasProperty("CFrame")) {
28760
- const part0Cf = part0.Property("CFrame");
28761
- const offset1 = C1.multiply(transform).inverse();
28762
- const finalCF = part0Cf.multiply(C0).multiply(offset1);
28763
- part1.setProperty("CFrame", finalCF);
28764
- }
28765
- } else {
28766
- if (part1 && part0 && part1.HasProperty("CFrame")) {
28767
- const part1Cf = part1.Property("CFrame");
28768
- const offset0 = C0.multiply(transform).inverse();
28769
- const finalCF = part1Cf.multiply(C1).multiply(offset0);
28770
- part0.setProperty("CFrame", finalCF);
28771
- }
28772
- }
28773
- } else {
28774
- console.warn("Motor6D/Weld is missing parent");
28775
- }
28776
- }
28777
- if (part0) {
28778
- part0ChangedConnection = part0.Changed.Connect((propertyName) => {
28779
- if (propertyName === "CFrame") {
28780
- update(self2, 1);
28781
- }
28782
- });
28783
- self2.addConnectionReference(part0ChangedConnection);
28784
- }
28785
- }, setup = function() {
28786
- if (this.className === "Motor6D") {
28787
- const transformProperty = new Property();
28788
- transformProperty.name = "Transform";
28789
- transformProperty.typeID = DataType.CFrame;
28790
- this.addProperty(transformProperty);
28791
- this.setProperty(transformProperty.name, new CFrame());
28792
- }
28793
- const changedConnection = this.Changed.Connect(() => {
28794
- update(this);
28795
- });
28796
- const ancestryChangedConnection = this.AncestryChanged.Connect(() => {
28797
- update(this);
28798
- });
28799
- this.addConnectionReference(changedConnection);
28800
- this.addConnectionReference(ancestryChangedConnection);
28801
- };
28802
- let part0ChangedConnection = void 0;
28803
- setup.bind(this)();
28804
- }
28805
- break;
28806
- case "BodyColors":
28807
- {
28808
- let update = function(self2) {
28809
- const rig = self2.parent;
28810
- if (!rig) {
28811
- return;
28812
- }
28813
- const humanoid = rig.FindFirstChildOfClass("Humanoid");
28814
- if (!humanoid) {
28815
- return;
28816
- }
28817
- const bodyPartDictionary = {
28818
- "Head": ["Head"],
28819
- "Torso": ["Torso", "UpperTorso", "LowerTorso"],
28820
- "LeftArm": ["Left Arm", "LeftHand", "LeftLowerArm", "LeftUpperArm"],
28821
- "RightArm": ["Right Arm", "RightHand", "RightLowerArm", "RightUpperArm"],
28822
- "LeftLeg": ["Left Leg", "LeftFoot", "LeftLowerLeg", "LeftUpperLeg"],
28823
- "RightLeg": ["Right Leg", "RightFoot", "RightLowerLeg", "RightUpperLeg"]
28824
- };
28825
- const bodyParts = [];
28826
- for (const child of rig.GetChildren()) {
28827
- if (child.className === "Part" || child.className === "MeshPart") {
28828
- bodyParts.push(child);
28829
- }
28830
- }
28831
- for (const bodyPart in bodyPartDictionary) {
28832
- const bodyPartNames = bodyPartDictionary[bodyPart];
28833
- const color = self2.Prop(bodyPart + "Color3").toColor3uint8();
28834
- for (const child of bodyParts) {
28835
- if (bodyPartNames.includes(child.Prop("Name"))) {
28836
- child.setProperty("Color", color);
28837
- }
28838
- }
28839
- }
28840
- }, setup = function() {
28841
- const changedConnection = this.Changed.Connect(() => {
28842
- update(this);
28843
- });
28844
- this.addConnectionReference(changedConnection);
28845
- };
28846
- setup.bind(this)();
28847
- }
28848
- break;
28849
- }
28850
28727
  if (!notComplete) {
28851
28728
  this.createWrapper();
28852
28729
  }
@@ -28934,7 +28811,7 @@ class Instance {
28934
28811
  }
28935
28812
  return name2;
28936
28813
  }
28937
- setProperty(name2, value) {
28814
+ setProperty(name2, value, supressEvents = false) {
28938
28815
  let property = this._properties.get(name2);
28939
28816
  if (!property) {
28940
28817
  name2 = this.fixPropertyName(name2);
@@ -28972,7 +28849,7 @@ class Instance {
28972
28849
  const valueInstance = property.value;
28973
28850
  valueInstance.addReferencedBy(this);
28974
28851
  }
28975
- this.Changed.Fire(name2);
28852
+ if (!supressEvents) this.Changed.Fire(name2);
28976
28853
  } else {
28977
28854
  console.warn(`Property with name ${name2} was not found in ${this.GetFullName()}`);
28978
28855
  }
@@ -33845,6 +33722,9 @@ class FileMesh {
33845
33722
  console.warn(`Issue with parsed mesh: ${issue}`);
33846
33723
  }
33847
33724
  console.log(`Bytes left: ${view.view.byteLength - view.viewOffset}`);
33725
+ if (this.skinning && this.skinning.skinnings.length > 0) {
33726
+ console.log(this);
33727
+ }
33848
33728
  }
33849
33729
  stripLODS() {
33850
33730
  let facesEnd = this.coreMesh.faces.length;
@@ -34732,7 +34612,7 @@ const API = {
34732
34612
  const buffer = response;
34733
34613
  const rbx = new RBX();
34734
34614
  rbx.fromBuffer(buffer);
34735
- if (FLAGS.ENABLE_API_CACHE) {
34615
+ if (FLAGS.ENABLE_API_CACHE && FLAGS.ENABLE_API_RBX_CACHE) {
34736
34616
  CACHE.RBX.set(cacheStr, rbx.clone());
34737
34617
  }
34738
34618
  return rbx;
@@ -34760,7 +34640,7 @@ const API = {
34760
34640
  const buffer = response;
34761
34641
  const mesh = new FileMesh();
34762
34642
  await mesh.fromBuffer(buffer);
34763
- if (FLAGS.ENABLE_API_CACHE) {
34643
+ if (FLAGS.ENABLE_API_CACHE && FLAGS.ENABLE_API_MESH_CACHE) {
34764
34644
  CACHE.Mesh.set(cacheStr, mesh.clone());
34765
34645
  }
34766
34646
  return mesh;
@@ -50396,6 +50276,7 @@ class AnimationTrack {
50396
50276
  length = 0;
50397
50277
  looped = false;
50398
50278
  priority = AnimationPriority.Core;
50279
+ shouldUpdateMotors = false;
50399
50280
  //playing info
50400
50281
  pOriginalWeight = 0;
50401
50282
  pTargetWeight = 0;
@@ -50681,13 +50562,13 @@ class AnimationTrack {
50681
50562
  const propertyNames = child.getPropertyNames();
50682
50563
  for (const propertyName of propertyNames) {
50683
50564
  if (FaceControlNames.includes(propertyName)) {
50684
- child.setProperty(propertyName, 0);
50565
+ child.setProperty(propertyName, 0, true);
50685
50566
  }
50686
50567
  }
50687
50568
  }
50688
50569
  }
50689
50570
  }
50690
- renderPose() {
50571
+ renderPose(updateMotors = true) {
50691
50572
  const time = this.timePosition;
50692
50573
  if (this.trackType === "Sequence") {
50693
50574
  for (const group of this.keyframeGroups) {
@@ -50703,11 +50584,11 @@ class AnimationTrack {
50703
50584
  const easedTime = getEasingFunction(lowerKeyframe.easingDirection, lowerKeyframe.easingStyle)(keyframeTime);
50704
50585
  const oldTransformCF = motor.Prop("Transform").clone();
50705
50586
  const transformCF = lerpCFrame(oldTransformCF, lerpCFrame(lowerKeyframe.cframe, higherKeyframe.cframe, easedTime).inverse(), this.weight);
50706
- motor.setProperty("Transform", transformCF);
50587
+ motor.setProperty("Transform", transformCF, true);
50707
50588
  } else if (lowerKeyframe) {
50708
50589
  const oldTransformCF = motor.Prop("Transform").clone();
50709
50590
  const transformCF = lerpCFrame(oldTransformCF, lowerKeyframe.cframe.inverse(), this.weight);
50710
- motor.setProperty("Transform", transformCF);
50591
+ motor.setProperty("Transform", transformCF, true);
50711
50592
  }
50712
50593
  }
50713
50594
  } else if (group instanceof FaceKeyframeGroup && this.rig) {
@@ -50774,7 +50655,7 @@ class AnimationTrack {
50774
50655
  }
50775
50656
  const oldTransformCF = motor.Prop("Transform").clone();
50776
50657
  const transformCF = lerpCFrame(oldTransformCF, cf.inverse(), this.weight);
50777
- motor.setProperty("Transform", transformCF);
50658
+ motor.setProperty("Transform", transformCF, true);
50778
50659
  }
50779
50660
  } else if (curve instanceof FaceCruve && this.rig && curve.value) {
50780
50661
  const part = this.rig.FindFirstChild(curve.parentName);
@@ -50795,6 +50676,15 @@ class AnimationTrack {
50795
50676
  }
50796
50677
  }
50797
50678
  }
50679
+ if (updateMotors) this.updateMotors();
50680
+ }
50681
+ updateMotors() {
50682
+ if (!this.rig) return;
50683
+ for (const child of this.rig.GetDescendants()) {
50684
+ if (child.className === "Motor6D" || child.className === "Weld") {
50685
+ child.Changed.Fire("C0");
50686
+ }
50687
+ }
50798
50688
  }
50799
50689
  setTime(time) {
50800
50690
  if (this.looped) {
@@ -50805,7 +50695,7 @@ class AnimationTrack {
50805
50695
  }
50806
50696
  this.timePosition = time;
50807
50697
  this.finished = time >= this.length;
50808
- this.renderPose();
50698
+ this.renderPose(this.shouldUpdateMotors);
50809
50699
  }
50810
50700
  /**
50811
50701
  * Remember to call tick() on each frame
@@ -51065,7 +50955,7 @@ class AnimatorWrapper extends InstanceWrapper {
51065
50955
  const descendants = rig.GetDescendants();
51066
50956
  for (const child of descendants) {
51067
50957
  if (child.className === "Motor6D" && includeMotors) {
51068
- child.setProperty("Transform", new CFrame(0, 0, 0));
50958
+ child.setProperty("Transform", new CFrame(0, 0, 0), true);
51069
50959
  } else if (child.className === "FaceControls" && includeFACS) {
51070
50960
  const propertyNames = child.getPropertyNames();
51071
50961
  for (const propertyName of propertyNames) {
@@ -51108,11 +50998,12 @@ class AnimatorWrapper extends InstanceWrapper {
51108
50998
  }
51109
50999
  const rig = this.instance.parent?.parent;
51110
51000
  if (rig) {
51111
- for (const child of rig.GetDescendants()) {
51112
- if (child.className === "Motor6D") {
51113
- child.setProperty("Transform", child.Prop("Transform"));
51114
- } else if (child.className === "Weld") {
51115
- child.setProperty("C0", child.Prop("C0"));
51001
+ const descedants = rig.GetDescendants();
51002
+ for (let i = 0; i < 2; i++) {
51003
+ for (const child of descedants) {
51004
+ if (child.className === "Motor6D" || child.className === "Weld") {
51005
+ child.Changed.Fire("C0");
51006
+ }
51116
51007
  }
51117
51008
  }
51118
51009
  }
@@ -51259,6 +51150,65 @@ class AnimatorWrapper extends InstanceWrapper {
51259
51150
  return false;
51260
51151
  }
51261
51152
  }
51153
+ class BodyColorsWrapper extends InstanceWrapper {
51154
+ static className = "BodyColors";
51155
+ static requiredProperties = [
51156
+ "Name",
51157
+ "HeadColor3",
51158
+ "TorsoColor3",
51159
+ "LeftArmColor3",
51160
+ "RightArmColor3",
51161
+ "LeftLegColor3",
51162
+ "RightLegColor3"
51163
+ ];
51164
+ setup() {
51165
+ if (!this.instance.HasProperty("Name")) this.instance.addProperty(new Property("Name", DataType.String), this.instance.className);
51166
+ if (!this.instance.HasProperty("HeadColor3")) this.instance.addProperty(new Property("HeadColor3", DataType.Color3), new Color3());
51167
+ if (!this.instance.HasProperty("TorsoColor3")) this.instance.addProperty(new Property("TorsoColor3", DataType.Color3), new Color3());
51168
+ if (!this.instance.HasProperty("LeftArmColor3")) this.instance.addProperty(new Property("LeftArmColor3", DataType.Color3), new Color3());
51169
+ if (!this.instance.HasProperty("RightArmColor3")) this.instance.addProperty(new Property("RightArmColor3", DataType.Color3), new Color3());
51170
+ if (!this.instance.HasProperty("LeftLegColor3")) this.instance.addProperty(new Property("LeftLegColor3", DataType.Color3), new Color3());
51171
+ if (!this.instance.HasProperty("RightLegColor3")) this.instance.addProperty(new Property("RightLegColor3", DataType.Color3), new Color3());
51172
+ }
51173
+ created() {
51174
+ this.instance.Changed.Connect(() => {
51175
+ this.update();
51176
+ });
51177
+ }
51178
+ update() {
51179
+ const rig = this.instance.parent;
51180
+ if (!rig) {
51181
+ return;
51182
+ }
51183
+ const humanoid = rig.FindFirstChildOfClass("Humanoid");
51184
+ if (!humanoid) {
51185
+ return;
51186
+ }
51187
+ const bodyPartDictionary = {
51188
+ "Head": ["Head"],
51189
+ "Torso": ["Torso", "UpperTorso", "LowerTorso"],
51190
+ "LeftArm": ["Left Arm", "LeftHand", "LeftLowerArm", "LeftUpperArm"],
51191
+ "RightArm": ["Right Arm", "RightHand", "RightLowerArm", "RightUpperArm"],
51192
+ "LeftLeg": ["Left Leg", "LeftFoot", "LeftLowerLeg", "LeftUpperLeg"],
51193
+ "RightLeg": ["Right Leg", "RightFoot", "RightLowerLeg", "RightUpperLeg"]
51194
+ };
51195
+ const bodyParts = [];
51196
+ for (const child of rig.GetChildren()) {
51197
+ if (child.className === "Part" || child.className === "MeshPart") {
51198
+ bodyParts.push(child);
51199
+ }
51200
+ }
51201
+ for (const bodyPart in bodyPartDictionary) {
51202
+ const bodyPartNames = bodyPartDictionary[bodyPart];
51203
+ const color = this.instance.Prop(bodyPart + "Color3").toColor3uint8();
51204
+ for (const child of bodyParts) {
51205
+ if (bodyPartNames.includes(child.Prop("Name"))) {
51206
+ child.setProperty("Color", color);
51207
+ }
51208
+ }
51209
+ }
51210
+ }
51211
+ }
51262
51212
  class BodyPartDescriptionWrapper extends InstanceWrapper {
51263
51213
  static className = "BodyPartDescription";
51264
51214
  static requiredProperties = ["Name", "AssetId", "BodyPart", "Color", "Instance"];
@@ -52143,13 +52093,15 @@ class HumanoidDescriptionWrapper extends InstanceWrapper {
52143
52093
  if (rbx instanceof RBX) {
52144
52094
  const dataModel = rbx.generateTree();
52145
52095
  const asset = dataModel.GetChildren()[0];
52146
- if (asset) {
52096
+ if (asset && ["Shirt", "Pants", "ShirtGraphic"].includes(asset.className)) {
52147
52097
  const assetClassName = asset.className;
52148
52098
  const originalAsset = rig.FindFirstChildOfClass(assetClassName);
52149
52099
  if (originalAsset) {
52150
52100
  originalAsset.Destroy();
52151
52101
  }
52152
52102
  asset.setParent(rig);
52103
+ } else {
52104
+ console.warn(`Clothing asset does not exist or is invalid`);
52153
52105
  }
52154
52106
  resolve(void 0);
52155
52107
  } else {
@@ -52192,7 +52144,7 @@ class HumanoidDescriptionWrapper extends InstanceWrapper {
52192
52144
  if (rbx instanceof RBX) {
52193
52145
  const dataModel = rbx.generateTree();
52194
52146
  const face = dataModel.GetChildren()[0];
52195
- if (face) {
52147
+ if (face && face.className === "Decal") {
52196
52148
  const head = rig.FindFirstChild("Head");
52197
52149
  if (head) {
52198
52150
  const children = head.GetChildren();
@@ -52203,6 +52155,8 @@ class HumanoidDescriptionWrapper extends InstanceWrapper {
52203
52155
  }
52204
52156
  face.setParent(head);
52205
52157
  }
52158
+ } else {
52159
+ console.warn(`Face asset does not exist or is invalid`);
52206
52160
  }
52207
52161
  } else {
52208
52162
  return rbx;
@@ -52236,17 +52190,32 @@ class HumanoidDescriptionWrapper extends InstanceWrapper {
52236
52190
  if (rbx instanceof RBX) {
52237
52191
  const dataModel = rbx.generateTree();
52238
52192
  const tool = dataModel.GetChildren()[0];
52239
- if (tool) {
52193
+ if (tool && tool.className === "Tool") {
52240
52194
  const oldTool = rig.FindFirstChildOfClass("Tool");
52241
52195
  if (oldTool) {
52242
52196
  oldTool.Destroy();
52243
52197
  }
52198
+ const handle = tool.FindFirstChild("Handle");
52244
52199
  for (const child of tool.GetDescendants()) {
52245
52200
  if (child.className === "Motor6D" || child.className === "Weld") {
52246
- child.Destroy();
52201
+ if (child.HasProperty("Part0") && child.HasProperty("Part1") && child.HasProperty("C0") && child.HasProperty("C1") && child.Prop("Part1") === handle) {
52202
+ const part0 = child.Prop("Part0");
52203
+ const part1 = child.Prop("Part1");
52204
+ const c0 = child.Prop("C0");
52205
+ const c1 = child.Prop("C1");
52206
+ child.setProperty("Part0", part1, true);
52207
+ child.setProperty("Part1", part0, true);
52208
+ child.setProperty("C0", c1, true);
52209
+ child.setProperty("C1", c0);
52210
+ } else if (child.HasProperty("Part0") && child.Prop("Part0") === handle) ;
52211
+ else {
52212
+ child.Destroy();
52213
+ }
52247
52214
  }
52248
52215
  }
52249
52216
  tool.setParent(rig);
52217
+ } else {
52218
+ console.warn(`Gear asset does not exist or is invalid`);
52250
52219
  }
52251
52220
  } else {
52252
52221
  return rbx;
@@ -52323,7 +52292,7 @@ class HumanoidDescriptionWrapper extends InstanceWrapper {
52323
52292
  if (rbx instanceof RBX) {
52324
52293
  const dataModel = rbx.generateTree();
52325
52294
  const accessory = dataModel.GetChildren()[0];
52326
- if (accessory) {
52295
+ if (accessory && accessory.className === "Accessory") {
52327
52296
  let isLayered = false;
52328
52297
  const handle = accessory.FindFirstChild("Handle");
52329
52298
  if (handle) {
@@ -52336,6 +52305,8 @@ class HumanoidDescriptionWrapper extends InstanceWrapper {
52336
52305
  if (accessoryDesc) {
52337
52306
  accessoryDesc.setProperty("Instance", accessory);
52338
52307
  }
52308
+ } else {
52309
+ console.warn(`Accessory asset does not exist or is invalid`);
52339
52310
  }
52340
52311
  resolve(void 0);
52341
52312
  } else {
@@ -52409,7 +52380,7 @@ class HumanoidDescriptionWrapper extends InstanceWrapper {
52409
52380
  if (rbx instanceof RBX) {
52410
52381
  const dataModel = rbx.generateTree();
52411
52382
  const makeup = dataModel.GetChildren()[0];
52412
- if (makeup) {
52383
+ if (makeup && makeup.className === "Decal") {
52413
52384
  const head2 = rig.FindFirstChild("Head");
52414
52385
  if (head2) {
52415
52386
  makeup.setParent(head2);
@@ -52418,6 +52389,8 @@ class HumanoidDescriptionWrapper extends InstanceWrapper {
52418
52389
  if (makeupDesc) {
52419
52390
  makeupDesc.setProperty("Instance", makeup);
52420
52391
  }
52392
+ } else {
52393
+ console.warn(`Makeup asset does not exist or is invalid`);
52421
52394
  }
52422
52395
  resolve(void 0);
52423
52396
  } else {
@@ -52690,6 +52663,106 @@ class ModelWrapper extends InstanceWrapper {
52690
52663
  return higherExtents.minus(lowerExtents);
52691
52664
  }
52692
52665
  }
52666
+ class WeldWrapperData {
52667
+ part0ChangedConnection;
52668
+ lastUpdateTime = 0;
52669
+ timeUpdates = 0;
52670
+ }
52671
+ class WeldWrapper extends InstanceWrapper {
52672
+ static className = "Weld";
52673
+ static requiredProperties = [
52674
+ "Name",
52675
+ "Enabled",
52676
+ "Part0",
52677
+ "Part1",
52678
+ "C0",
52679
+ "C1",
52680
+ "_data"
52681
+ ];
52682
+ setup() {
52683
+ if (!this.instance.HasProperty("Name")) this.instance.addProperty(new Property("Name", DataType.String), this.instance.className);
52684
+ if (!this.instance.HasProperty("Enabled")) this.instance.addProperty(new Property("Enabled", DataType.Bool), true);
52685
+ if (!this.instance.HasProperty("Part0")) this.instance.addProperty(new Property("Part0", DataType.Referent), void 0);
52686
+ if (!this.instance.HasProperty("Part1")) this.instance.addProperty(new Property("Part1", DataType.Referent), void 0);
52687
+ if (!this.instance.HasProperty("C0")) this.instance.addProperty(new Property("C0", DataType.CFrame), new CFrame());
52688
+ if (!this.instance.HasProperty("C1")) this.instance.addProperty(new Property("C1", DataType.CFrame), new CFrame());
52689
+ if (!this.instance.HasProperty("_data")) this.instance.addProperty(new Property("_data", DataType.NonSerializable), new WeldWrapperData());
52690
+ }
52691
+ get data() {
52692
+ return this.instance.Prop("_data");
52693
+ }
52694
+ created() {
52695
+ const changedConnection = this.instance.Changed.Connect(() => {
52696
+ this.update();
52697
+ });
52698
+ const ancestryChangedConnection = this.instance.AncestryChanged.Connect(() => {
52699
+ this.update();
52700
+ });
52701
+ this.instance.addConnectionReference(changedConnection);
52702
+ this.instance.addConnectionReference(ancestryChangedConnection);
52703
+ }
52704
+ update(affectedPart = 1) {
52705
+ if (!this.instance.parent) return;
52706
+ if (this.data.lastUpdateTime === Date.now()) {
52707
+ this.data.timeUpdates += 1;
52708
+ if (this.data.timeUpdates > 100) {
52709
+ console.error(this.instance);
52710
+ console.error(`${this.instance.className} is exhausted`);
52711
+ return;
52712
+ }
52713
+ } else {
52714
+ this.data.timeUpdates = 0;
52715
+ }
52716
+ this.data.lastUpdateTime = Date.now();
52717
+ const part0 = this.instance.Prop("Part0");
52718
+ if (part0) {
52719
+ if (this.data.part0ChangedConnection) {
52720
+ this.data.part0ChangedConnection.Disconnect();
52721
+ this.instance.removeConnectionReference(this.data.part0ChangedConnection);
52722
+ }
52723
+ }
52724
+ const part1 = this.instance.Prop("Part1");
52725
+ const C0 = this.instance.Prop("C0");
52726
+ const C1 = this.instance.Prop("C1");
52727
+ const transform = this.instance.PropOrDefault("Transform", new CFrame());
52728
+ if (part0 === part1 || !part0 || !part1) {
52729
+ return;
52730
+ }
52731
+ if (this.instance.HasProperty("Enabled") && this.instance.Prop("Enabled")) {
52732
+ if (this.instance.parent) {
52733
+ if (affectedPart === 1) {
52734
+ if (part0.HasProperty("CFrame") && part1.HasProperty("CFrame")) {
52735
+ const part0Cf = part0.Property("CFrame");
52736
+ const offset1 = C1.multiply(transform).inverse();
52737
+ const finalCF = part0Cf.multiply(C0).multiply(offset1);
52738
+ part1.setProperty("CFrame", finalCF);
52739
+ }
52740
+ }
52741
+ } else {
52742
+ console.warn("Motor6D/Weld is missing parent");
52743
+ }
52744
+ }
52745
+ if (part0) {
52746
+ this.data.part0ChangedConnection = part0.Changed.Connect((propertyName) => {
52747
+ if (propertyName === "CFrame") {
52748
+ this.update(1);
52749
+ }
52750
+ });
52751
+ this.instance.addConnectionReference(this.data.part0ChangedConnection);
52752
+ }
52753
+ }
52754
+ }
52755
+ class Motor6DWrapper extends WeldWrapper {
52756
+ static className = "Motor6D";
52757
+ static requiredProperties = [
52758
+ ...super.requiredProperties,
52759
+ "Transform"
52760
+ ];
52761
+ setup() {
52762
+ super.setup();
52763
+ if (!this.instance.HasProperty("Transform")) this.instance.addProperty(new Property("Transform", DataType.CFrame), new CFrame());
52764
+ }
52765
+ }
52693
52766
  class SoundWrapperData {
52694
52767
  audio;
52695
52768
  }
@@ -52866,12 +52939,15 @@ function RegisterWrappers() {
52866
52939
  ScriptWrapper.register();
52867
52940
  SoundWrapper.register();
52868
52941
  ToolWrapper.register();
52942
+ WeldWrapper.register();
52943
+ Motor6DWrapper.register();
52869
52944
  AnimatorWrapper.register();
52870
52945
  FaceControlsWrapper.register();
52871
52946
  HumanoidDescriptionWrapper.register();
52872
52947
  BodyPartDescriptionWrapper.register();
52873
52948
  AccessoryDescriptionWrapper.register();
52874
52949
  MakeupDescriptionWrapper.register();
52950
+ BodyColorsWrapper.register();
52875
52951
  }
52876
52952
  const _changeEvent = { type: "change" };
52877
52953
  const _startEvent = { type: "start" };
@@ -57581,7 +57657,7 @@ class MeshDesc {
57581
57657
  inheritSkeleton(mesh, transferTo);
57582
57658
  }
57583
57659
  const rbfDeformer = new RBFDeformerPatch(ref_mesh, dist_mesh, mesh);
57584
- rbfDeformer.affectBones = false;
57660
+ rbfDeformer.affectBones = FLAGS.USE_LOCAL_SKELETONDESC;
57585
57661
  await rbfDeformer.solveAsync();
57586
57662
  rbfDeformer.deformMesh();
57587
57663
  break;
@@ -59046,14 +59122,14 @@ class MaterialDesc {
59046
59122
  }
59047
59123
  }
59048
59124
  }
59049
- function setBoneToCFrame(bone, cf) {
59125
+ function setBoneToCFrame$1(bone, cf) {
59050
59126
  bone.position.set(...cf.Position);
59051
59127
  bone.rotation.order = "YXZ";
59052
59128
  bone.rotation.x = rad(cf.Orientation[0]);
59053
59129
  bone.rotation.y = rad(cf.Orientation[1]);
59054
59130
  bone.rotation.z = rad(cf.Orientation[2]);
59055
59131
  }
59056
- function getJointForInstances(parent, child, includeTransform) {
59132
+ function getJointForInstances$1(parent, child, includeTransform) {
59057
59133
  const childMotor = child.FindFirstChildOfClass("Motor6D");
59058
59134
  const parentMotor = parent.FindFirstChildOfClass("Motor6D");
59059
59135
  let transform = new CFrame();
@@ -59070,13 +59146,65 @@ function getJointForInstances(parent, child, includeTransform) {
59070
59146
  }
59071
59147
  return new CFrame();
59072
59148
  }
59073
- class SkeletonDesc {
59149
+ function boneIsChildOf(bone, parentName) {
59150
+ let nextParent = bone.parent;
59151
+ while (nextParent) {
59152
+ if (nextParent.name === parentName) {
59153
+ return true;
59154
+ }
59155
+ nextParent = nextParent.parent;
59156
+ }
59157
+ return false;
59158
+ }
59159
+ function getMotorsInRig(rigChildren) {
59160
+ const motors = [];
59161
+ for (const child of rigChildren) {
59162
+ for (const motor of child.GetChildren()) {
59163
+ if (motor.className === "Motor6D") {
59164
+ motors.push(motor);
59165
+ }
59166
+ }
59167
+ }
59168
+ return motors;
59169
+ }
59170
+ function getBoneDependencies(rig) {
59171
+ const names = /* @__PURE__ */ new Map();
59172
+ const hrp = rig.FindFirstChild("HumanoidRootPart");
59173
+ let currentSearch = hrp ? [hrp] : [];
59174
+ let currentSearchOrigin = hrp ? ["Root"] : [];
59175
+ const children = rig.GetChildren();
59176
+ const motors = getMotorsInRig(children);
59177
+ while (currentSearch.length > 0 && currentSearch[0]) {
59178
+ const newCurrentSearch = [];
59179
+ const newCurrentSearchOrigin = [];
59180
+ for (let i = 0; i < currentSearch.length; i++) {
59181
+ const toSearch = currentSearch[i];
59182
+ const selfName = toSearch === hrp ? "HumanoidRootNode" : toSearch.Prop("Name");
59183
+ names.set(selfName, currentSearchOrigin[i]);
59184
+ for (const motor of motors) {
59185
+ if (motor.Prop("Part0") === toSearch) {
59186
+ newCurrentSearch.push(motor.parent);
59187
+ newCurrentSearchOrigin.push(selfName);
59188
+ }
59189
+ }
59190
+ }
59191
+ currentSearch = newCurrentSearch;
59192
+ currentSearchOrigin = newCurrentSearchOrigin;
59193
+ }
59194
+ if (names.get("Head")) {
59195
+ names.set("DynamicHead", "Head");
59196
+ }
59197
+ return names;
59198
+ }
59199
+ let SkeletonDesc$1 = class SkeletonDesc {
59074
59200
  renderableDesc;
59075
59201
  meshDesc;
59076
59202
  skeleton;
59077
59203
  rootBone;
59078
59204
  bones;
59079
59205
  originalBoneCFrames = [];
59206
+ originalHeadCFrame = new CFrame();
59207
+ originalDynamicHeadCFrame = new CFrame();
59080
59208
  skeletonHelper;
59081
59209
  constructor(renderableDesc, meshDesc, scene) {
59082
59210
  this.renderableDesc = renderableDesc;
@@ -59090,6 +59218,9 @@ class SkeletonDesc {
59090
59218
  for (let i = 0; i < skinning.bones.length; i++) {
59091
59219
  const threeBone = new Bone();
59092
59220
  threeBone.name = skinning.nameTable[i];
59221
+ if (threeBone.name === "HumanoidRootPart") {
59222
+ threeBone.name = "HumanoidRootNode";
59223
+ }
59093
59224
  boneArr.push(threeBone);
59094
59225
  }
59095
59226
  this.bones = boneArr;
@@ -59106,13 +59237,19 @@ class SkeletonDesc {
59106
59237
  worldBoneCF.fromRotationMatrix(...bone.rotationMatrix);
59107
59238
  const boneCF = worldParentBoneCF.inverse().multiply(worldBoneCF);
59108
59239
  this.originalBoneCFrames.push(boneCF);
59109
- setBoneToCFrame(threeBone, boneCF);
59240
+ if (threeBone.name === "Head") {
59241
+ this.originalHeadCFrame = boneCF;
59242
+ } else if (threeBone.name === "DynamicHead") {
59243
+ this.originalDynamicHeadCFrame = boneCF;
59244
+ }
59245
+ setBoneToCFrame$1(threeBone, boneCF);
59110
59246
  parentThreeBone.add(threeBone);
59111
59247
  } else {
59112
59248
  rootBone = threeBone;
59113
- threeBone.position.set(0, 0, 0);
59114
- threeBone.rotation.set(0, 0, 0, "YXZ");
59115
- this.originalBoneCFrames.push(new CFrame());
59249
+ const boneCF = new CFrame(...bone.position);
59250
+ boneCF.fromRotationMatrix(...bone.rotationMatrix);
59251
+ this.originalBoneCFrames.push(boneCF);
59252
+ setBoneToCFrame$1(threeBone, boneCF);
59116
59253
  }
59117
59254
  }
59118
59255
  if (!rootBone) {
@@ -59130,6 +59267,20 @@ class SkeletonDesc {
59130
59267
  }
59131
59268
  this.rootBone = rootBone;
59132
59269
  }
59270
+ const rig = this.getRig();
59271
+ if (rig) {
59272
+ const boneDependencies = getBoneDependencies(rig);
59273
+ for (const bone of [...this.bones]) {
59274
+ let lastBone = bone.name;
59275
+ while (lastBone) {
59276
+ const newLastBone = boneDependencies.get(lastBone);
59277
+ if (newLastBone && !this.getBoneWithName(newLastBone)) {
59278
+ this.insertBefore(newLastBone, lastBone);
59279
+ }
59280
+ lastBone = newLastBone;
59281
+ }
59282
+ }
59283
+ }
59133
59284
  this.skeleton = new Skeleton(boneArr);
59134
59285
  this.setAsRest();
59135
59286
  if (FLAGS.SHOW_SKELETON_HELPER) {
@@ -59137,6 +59288,7 @@ class SkeletonDesc {
59137
59288
  scene.add(skeletonHelper);
59138
59289
  this.skeletonHelper = skeletonHelper;
59139
59290
  }
59291
+ console.log(this.skeleton);
59140
59292
  }
59141
59293
  setAsRest() {
59142
59294
  for (const bone of this.skeleton.bones) {
@@ -59144,6 +59296,57 @@ class SkeletonDesc {
59144
59296
  this.skeleton.boneInverses[boneIndex].copy(bone.matrixWorld).invert();
59145
59297
  }
59146
59298
  }
59299
+ traverseOriginal(name2) {
59300
+ const cframes = [];
59301
+ let lastBone = this.getBoneWithName(name2);
59302
+ while (lastBone) {
59303
+ const index = this.bones.indexOf(lastBone);
59304
+ const ogCFrame = this.originalBoneCFrames[index];
59305
+ cframes.push(ogCFrame);
59306
+ lastBone = lastBone.parent ? this.getBoneWithName(lastBone.parent.name) : void 0;
59307
+ }
59308
+ cframes.reverse();
59309
+ let finalCF = new CFrame();
59310
+ for (const cf of cframes) {
59311
+ finalCF = finalCF.multiply(cf);
59312
+ }
59313
+ return finalCF;
59314
+ }
59315
+ insertBefore(toInsert, before) {
59316
+ const bone = new Bone();
59317
+ bone.name = toInsert;
59318
+ bone.position.set(0, 0, 0);
59319
+ bone.rotation.set(0, 0, 0, "YXZ");
59320
+ for (let i = 0; i < this.bones.length; i++) {
59321
+ if (this.bones[i].name === before) {
59322
+ const beforeBone = this.bones[i];
59323
+ const beforeParent = beforeBone.parent;
59324
+ this.originalBoneCFrames.push(new CFrame());
59325
+ this.bones.push(bone);
59326
+ bone.add(beforeBone);
59327
+ beforeParent?.add(bone);
59328
+ break;
59329
+ }
59330
+ }
59331
+ }
59332
+ getBoneWithName(name2) {
59333
+ for (const bone of this.bones) {
59334
+ if (bone.name === name2) {
59335
+ return bone;
59336
+ }
59337
+ }
59338
+ }
59339
+ getRig() {
59340
+ const selfInstance = this.meshDesc.instance;
59341
+ if (!selfInstance) return;
59342
+ let rig = selfInstance.parent;
59343
+ if (rig && rig.className !== "Model") {
59344
+ rig = rig.parent;
59345
+ }
59346
+ if (rig?.className === "Model") {
59347
+ return rig;
59348
+ }
59349
+ }
59147
59350
  getPartEquivalent(selfInstance, name2) {
59148
59351
  if (!selfInstance.parent) return;
59149
59352
  let partEquivalent = selfInstance.parent.FindFirstChild(name2);
@@ -59171,51 +59374,87 @@ class SkeletonDesc {
59171
59374
  }
59172
59375
  updateBoneMatrix(selfInstance, includeTransform = false) {
59173
59376
  if (!selfInstance.parent) return;
59377
+ if (!this.meshDesc.fileMesh) return;
59378
+ const isHead = this.meshDesc.headMesh === this.meshDesc.mesh;
59379
+ const rootBoneCFog = this.getRootCFrame(selfInstance, includeTransform);
59380
+ const humanoidRootPartEquivalent = this.getPartEquivalent(selfInstance, "HumanoidRootPart");
59174
59381
  for (let i = 0; i < this.bones.length; i++) {
59175
59382
  const bone = this.bones[i];
59176
59383
  const partEquivalent = this.getPartEquivalent(selfInstance, bone.name);
59177
- const parentPartEquivalent = bone.parent ? this.getPartEquivalent(selfInstance, bone.parent.name !== "HumanoidRootNode" ? bone.parent.name : "HumanoidRootPart") : void 0;
59384
+ const parentPartEquivalent = bone.parent ? bone.parent.name !== "HumanoidRootNode" ? this.getPartEquivalent(selfInstance, bone.parent.name) : humanoidRootPartEquivalent : void 0;
59178
59385
  let rootBoneCF = new CFrame();
59179
59386
  if (bone.name === "Root") {
59180
- rootBoneCF = this.getRootCFrame(selfInstance, includeTransform);
59387
+ rootBoneCF = rootBoneCFog;
59181
59388
  } else if (bone.parent?.name === "Root") {
59182
- rootBoneCF = this.getRootCFrame(selfInstance, includeTransform).inverse();
59389
+ rootBoneCF = rootBoneCFog.inverse();
59183
59390
  }
59184
59391
  if (partEquivalent && parentPartEquivalent) {
59185
- setBoneToCFrame(bone, rootBoneCF.multiply(getJointForInstances(parentPartEquivalent, partEquivalent, includeTransform)));
59392
+ setBoneToCFrame$1(bone, rootBoneCF.multiply(getJointForInstances$1(parentPartEquivalent, partEquivalent, includeTransform)));
59186
59393
  } else if (partEquivalent) {
59187
59394
  if (includeTransform) {
59188
- setBoneToCFrame(bone, rootBoneCF.multiply(partEquivalent.Prop("CFrame")));
59395
+ setBoneToCFrame$1(bone, rootBoneCF.multiply(partEquivalent.Prop("CFrame")));
59189
59396
  } else {
59190
59397
  let hrpCF = new CFrame();
59191
- const hrp = this.getPartEquivalent(selfInstance, "HumanoidRootPart");
59398
+ const hrp = humanoidRootPartEquivalent;
59192
59399
  if (hrp) {
59193
59400
  hrpCF = hrp.Prop("CFrame");
59194
59401
  }
59195
- setBoneToCFrame(bone, rootBoneCF.multiply(hrpCF.multiply(traverseRigCFrame(partEquivalent))));
59402
+ setBoneToCFrame$1(bone, rootBoneCF.multiply(hrpCF.multiply(traverseRigCFrame(partEquivalent))));
59196
59403
  }
59197
59404
  } else if (bone.name === "Root") {
59198
- setBoneToCFrame(bone, rootBoneCF.multiply(new CFrame()));
59405
+ setBoneToCFrame$1(bone, rootBoneCF.multiply(new CFrame()));
59199
59406
  } else if (bone.name === "HumanoidRootNode") {
59200
59407
  let rootCF = new CFrame();
59201
- const rootPart = this.getPartEquivalent(selfInstance, "HumanoidRootPart");
59408
+ const rootPart = humanoidRootPartEquivalent;
59202
59409
  if (rootPart) {
59203
59410
  rootCF = rootPart.Prop("CFrame");
59204
59411
  }
59205
- setBoneToCFrame(bone, rootBoneCF.multiply(rootCF));
59206
- } else if (bone.name === "DynamicHead" || bone.parent?.name === "DynamicHead" || bone.parent?.parent?.name === "DynamicHead" || bone.parent?.parent?.parent?.name === "DynamicHead") {
59412
+ setBoneToCFrame$1(bone, rootBoneCF.multiply(rootCF));
59413
+ } else if (bone.name === "DynamicHead" && isHead) {
59414
+ const head = this.getPartEquivalent(selfInstance, "Head");
59415
+ if (head) {
59416
+ let targetCF = this.traverseOriginal("DynamicHead");
59417
+ if (this.meshDesc.wasAutoSkinned) {
59418
+ targetCF = this.originalBoneCFrames[i];
59419
+ }
59420
+ const headSize = head.Prop("Size");
59421
+ const ogHeadSize = isHead ? new Vector32(...this.meshDesc.fileMesh.size) : getOriginalSize(head);
59422
+ let scale = divide$1(headSize.toVec3(), ogHeadSize.toVec3());
59423
+ if (this.meshDesc.wasAutoSkinned) {
59424
+ scale = [1, 1, 1];
59425
+ }
59426
+ const scaledCF = targetCF.clone();
59427
+ scaledCF.Position = multiply$1(scaledCF.Position, scale);
59428
+ const neck = head.FindFirstChildOfClass("Motor6D");
59429
+ let neckCF = new CFrame();
59430
+ if (neck) {
59431
+ neckCF = neck.PropOrDefault("C1", new CFrame());
59432
+ }
59433
+ if (this.meshDesc.wasAutoSkinned) {
59434
+ neckCF = new CFrame();
59435
+ }
59436
+ const totalCF = neckCF.inverse().multiply(scaledCF);
59437
+ setBoneToCFrame$1(bone, totalCF);
59438
+ }
59439
+ } else if (!isHead || boneIsChildOf(bone, "DynamicHead")) {
59207
59440
  const ogCF = this.originalBoneCFrames[i];
59208
59441
  const head = this.getPartEquivalent(selfInstance, "Head");
59209
59442
  if (head) {
59210
59443
  const headSize = head.Prop("Size");
59211
- const ogHeadSize = getOriginalSize(head);
59444
+ const ogHeadSize = isHead ? new Vector32(...this.meshDesc.fileMesh.size) : getOriginalSize(head);
59212
59445
  let scale = divide$1(headSize.toVec3(), ogHeadSize.toVec3());
59213
59446
  if (this.meshDesc.wasAutoSkinned) {
59214
59447
  scale = [1, 1, 1];
59215
59448
  }
59216
59449
  const scaledCF = ogCF.clone();
59217
59450
  scaledCF.Position = multiply$1(scaledCF.Position, scale);
59218
- setBoneToCFrame(bone, scaledCF);
59451
+ const headOffset = this.originalHeadCFrame.clone();
59452
+ headOffset.Position = [0, 0, 0];
59453
+ if (bone.name !== "DynamicHead") {
59454
+ headOffset.Orientation = [0, 0, 0];
59455
+ }
59456
+ const finalCF = headOffset.multiply(scaledCF);
59457
+ setBoneToCFrame$1(bone, finalCF);
59219
59458
  }
59220
59459
  }
59221
59460
  }
@@ -59231,7 +59470,8 @@ class SkeletonDesc {
59231
59470
  }
59232
59471
  }
59233
59472
  update(instance) {
59234
- if (!FLAGS.UPDATE_SKELETON || !instance.parent) return;
59473
+ if (!FLAGS.UPDATE_SKELETON || !instance.parent || !this.meshDesc.fileMesh) return;
59474
+ const isHead = this.meshDesc.headMesh === this.meshDesc.mesh;
59235
59475
  this.updateBoneMatrix(instance);
59236
59476
  if (FLAGS.ANIMATE_SKELETON) {
59237
59477
  this.updateBoneMatrix(instance, true);
@@ -59243,7 +59483,7 @@ class SkeletonDesc {
59243
59483
  const head = this.getPartEquivalent(instance, "Head");
59244
59484
  if (head && facsMesh && facs && facs.quantizedTransforms) {
59245
59485
  const headSize = head.Prop("Size");
59246
- const ogHeadSize = getOriginalSize(head);
59486
+ const ogHeadSize = isHead ? new Vector32(...this.meshDesc.fileMesh.size) : getOriginalSize(head);
59247
59487
  let headScale = divide$1(headSize.toVec3(), ogHeadSize.toVec3());
59248
59488
  if (this.meshDesc.wasAutoSkinned) {
59249
59489
  headScale = [1, 1, 1];
@@ -59263,7 +59503,7 @@ class SkeletonDesc {
59263
59503
  const head2 = this.getPartEquivalent(instance, "Head");
59264
59504
  if (head2) {
59265
59505
  const headSize2 = head2.Prop("Size");
59266
- const ogHeadSize2 = getOriginalSize(head2);
59506
+ const ogHeadSize2 = isHead ? new Vector32(...this.meshDesc.fileMesh.size) : getOriginalSize(head2);
59267
59507
  let scale = divide$1(headSize2.toVec3(), ogHeadSize2.toVec3());
59268
59508
  if (this.meshDesc.wasAutoSkinned) {
59269
59509
  scale = [1, 1, 1];
@@ -59304,9 +59544,265 @@ class SkeletonDesc {
59304
59544
  totalRotation = totalRotation.add(rot.multiply(new Vector32(weight, weight, weight)));
59305
59545
  }
59306
59546
  const resultCF = new CFrame();
59307
- const euler = new Euler(rad(totalRotation.X), rad(totalRotation.Y), rad(totalRotation.Z), "YXZ");
59547
+ const euler = new Euler(rad(totalRotation.X), rad(totalRotation.Y), rad(totalRotation.Z), "XYZ");
59548
+ euler.reorder("YXZ");
59308
59549
  resultCF.Orientation = [deg(euler.x), deg(euler.y), deg(euler.z)];
59309
59550
  resultCF.Position = multiply$1(totalPosition.toVec3(), headScale);
59551
+ setBoneToCFrame$1(bone, jointCF.multiply(resultCF));
59552
+ break;
59553
+ }
59554
+ }
59555
+ }
59556
+ }
59557
+ }
59558
+ }
59559
+ this.updateMatrixWorld();
59560
+ }
59561
+ dispose(scene) {
59562
+ if (this.skeletonHelper) {
59563
+ scene.remove(this.skeletonHelper);
59564
+ this.skeletonHelper.dispose();
59565
+ this.skeletonHelper = void 0;
59566
+ }
59567
+ if (this.rootBone.parent) {
59568
+ this.rootBone.parent.remove(this.rootBone);
59569
+ }
59570
+ for (let i = 0; i < this.skeleton.bones.length; i++) {
59571
+ const bone = this.skeleton.bones[i];
59572
+ if (bone.parent) {
59573
+ bone.removeFromParent();
59574
+ }
59575
+ }
59576
+ }
59577
+ static descNeedsSkeleton(meshDesc) {
59578
+ return meshDesc.canHaveSkinning && meshDesc.fileMesh && meshDesc.fileMesh.skinning && meshDesc.fileMesh.skinning.subsets.length > 0 && meshDesc.fileMesh.skinning.skinnings.length > 0;
59579
+ }
59580
+ };
59581
+ function setBoneToCFrame(bone, cf) {
59582
+ bone.position.set(...cf.Position);
59583
+ bone.rotation.order = "YXZ";
59584
+ bone.rotation.x = rad(cf.Orientation[0]);
59585
+ bone.rotation.y = rad(cf.Orientation[1]);
59586
+ bone.rotation.z = rad(cf.Orientation[2]);
59587
+ }
59588
+ function getJointForInstances(child, includeTransform) {
59589
+ const childMotor = child.FindFirstChildOfClass("Motor6D");
59590
+ let transform = new CFrame();
59591
+ if (childMotor) {
59592
+ if (includeTransform) {
59593
+ transform = childMotor.Prop("Transform");
59594
+ return transform.inverse();
59595
+ }
59596
+ }
59597
+ return new CFrame();
59598
+ }
59599
+ class SkeletonDesc2 {
59600
+ renderableDesc;
59601
+ meshDesc;
59602
+ skeleton;
59603
+ rootBone;
59604
+ bones;
59605
+ originalBoneCFrames = [];
59606
+ originalHeadCFrame = new CFrame();
59607
+ originalDynamicHeadCFrame = new CFrame();
59608
+ skeletonHelper;
59609
+ constructor(renderableDesc, meshDesc, scene) {
59610
+ this.renderableDesc = renderableDesc;
59611
+ this.meshDesc = meshDesc;
59612
+ const mesh = this.meshDesc.fileMesh;
59613
+ if (!mesh) {
59614
+ throw new Error("MeshDesc is not compiled");
59615
+ }
59616
+ const skinning = mesh.skinning;
59617
+ const boneArr = [];
59618
+ for (let i = 0; i < skinning.bones.length; i++) {
59619
+ const threeBone = new Bone();
59620
+ threeBone.name = skinning.nameTable[i];
59621
+ boneArr.push(threeBone);
59622
+ }
59623
+ this.bones = boneArr;
59624
+ let rootBone = void 0;
59625
+ for (let i = 0; i < skinning.bones.length; i++) {
59626
+ const bone = skinning.bones[i];
59627
+ const threeBone = boneArr[i];
59628
+ if (bone.parentIndex < skinning.bones.length) {
59629
+ const parentBone = skinning.bones[bone.parentIndex];
59630
+ const parentThreeBone = boneArr[bone.parentIndex];
59631
+ const worldParentBoneCF = new CFrame(...parentBone.position);
59632
+ worldParentBoneCF.fromRotationMatrix(...parentBone.rotationMatrix);
59633
+ const worldBoneCF = new CFrame(...bone.position);
59634
+ worldBoneCF.fromRotationMatrix(...bone.rotationMatrix);
59635
+ const boneCF = worldParentBoneCF.inverse().multiply(worldBoneCF);
59636
+ this.originalBoneCFrames.push(boneCF);
59637
+ if (threeBone.name === "Head") {
59638
+ this.originalHeadCFrame = boneCF;
59639
+ } else if (threeBone.name === "DynamicHead") {
59640
+ this.originalDynamicHeadCFrame = boneCF;
59641
+ }
59642
+ setBoneToCFrame(threeBone, boneCF);
59643
+ parentThreeBone.add(threeBone);
59644
+ } else {
59645
+ rootBone = threeBone;
59646
+ const worldBoneCF = new CFrame(...bone.position);
59647
+ worldBoneCF.fromRotationMatrix(...bone.rotationMatrix);
59648
+ setBoneToCFrame(threeBone, worldBoneCF);
59649
+ this.originalBoneCFrames.push(worldBoneCF);
59650
+ }
59651
+ }
59652
+ if (!rootBone) {
59653
+ throw new Error("FileMesh has no root bone");
59654
+ } else {
59655
+ if (rootBone && rootBone.name !== "Root") {
59656
+ const trueRootBone = new Bone();
59657
+ trueRootBone.name = "Root";
59658
+ trueRootBone.position.set(0, 0, 0);
59659
+ trueRootBone.rotation.set(0, 0, 0, "YXZ");
59660
+ this.originalBoneCFrames.unshift(new CFrame());
59661
+ this.bones.unshift(trueRootBone);
59662
+ trueRootBone.add(rootBone);
59663
+ rootBone = trueRootBone;
59664
+ }
59665
+ this.rootBone = rootBone;
59666
+ }
59667
+ this.skeleton = new Skeleton(boneArr);
59668
+ this.setAsRest();
59669
+ if (FLAGS.SHOW_SKELETON_HELPER) {
59670
+ const skeletonHelper = new SkeletonHelper(this.rootBone);
59671
+ scene.add(skeletonHelper);
59672
+ this.skeletonHelper = skeletonHelper;
59673
+ }
59674
+ console.log(this.skeleton);
59675
+ }
59676
+ setAsRest() {
59677
+ for (const bone of this.skeleton.bones) {
59678
+ const boneIndex = this.skeleton.bones.indexOf(bone);
59679
+ this.skeleton.boneInverses[boneIndex].copy(bone.matrixWorld).invert();
59680
+ }
59681
+ }
59682
+ getPartEquivalent(selfInstance, name2) {
59683
+ if (!selfInstance.parent) return;
59684
+ let partEquivalent = selfInstance.parent.FindFirstChild(name2);
59685
+ if (partEquivalent === void 0 && selfInstance.parent.parent) {
59686
+ partEquivalent = selfInstance.parent.parent.FindFirstChild(name2);
59687
+ }
59688
+ return partEquivalent;
59689
+ }
59690
+ getRootCFrame(instance, includeTransform) {
59691
+ if (includeTransform) {
59692
+ return instance.Prop("CFrame");
59693
+ } else {
59694
+ let bodyPart = void 0;
59695
+ if (instance.parent && instance.parent.FindFirstChildOfClass("Humanoid")) {
59696
+ bodyPart = instance;
59697
+ } else if (instance.parent && instance.parent.parent && instance.parent.className === "Accessory") {
59698
+ bodyPart = GetAttachedPart(instance.parent, instance.parent.parent);
59699
+ }
59700
+ const hrp = this.getPartEquivalent(instance, "HumanoidRootPart");
59701
+ if (hrp && bodyPart) {
59702
+ return hrp.Prop("CFrame").multiply(traverseRigCFrame(bodyPart));
59703
+ }
59704
+ }
59705
+ return new CFrame();
59706
+ }
59707
+ updateBoneMatrix(selfInstance, includeTransform = false) {
59708
+ if (!selfInstance.parent) return;
59709
+ if (!this.meshDesc.fileMesh) return;
59710
+ const ogMeshSize = new Vector32(...this.meshDesc.fileMesh.size);
59711
+ const scale = divide$1((this.meshDesc.instance?.Prop("Size")).toVec3(), ogMeshSize.toVec3());
59712
+ for (let i = 0; i < this.bones.length; i++) {
59713
+ const bone = this.bones[i];
59714
+ const partEquivalent = this.getPartEquivalent(selfInstance, bone.name);
59715
+ const ogBoneCF = this.originalBoneCFrames[i].clone();
59716
+ ogBoneCF.Position = multiply$1(ogBoneCF.Position, scale);
59717
+ if (partEquivalent && includeTransform) {
59718
+ setBoneToCFrame(bone, ogBoneCF.multiply(getJointForInstances(partEquivalent, includeTransform)));
59719
+ } else {
59720
+ setBoneToCFrame(bone, ogBoneCF);
59721
+ }
59722
+ }
59723
+ this.updateMatrixWorld();
59724
+ if (!includeTransform) {
59725
+ this.setAsRest();
59726
+ this.updateMatrixWorld();
59727
+ }
59728
+ }
59729
+ updateMatrixWorld() {
59730
+ for (const bone of this.skeleton.bones) {
59731
+ bone.updateMatrixWorld(true);
59732
+ }
59733
+ }
59734
+ update(instance) {
59735
+ if (!FLAGS.UPDATE_SKELETON || !instance.parent || !this.meshDesc.fileMesh) return;
59736
+ const isHead = this.meshDesc.headMesh === this.meshDesc.mesh;
59737
+ this.updateBoneMatrix(instance);
59738
+ if (FLAGS.ANIMATE_SKELETON) {
59739
+ this.updateBoneMatrix(instance, true);
59740
+ for (const bone of this.skeleton.bones) {
59741
+ const isFACS = this.meshDesc.fileMesh?.facs?.faceBoneNames.includes(bone.name);
59742
+ if (isFACS) {
59743
+ const facsMesh = this.meshDesc.fileMesh;
59744
+ const facs = this.meshDesc.fileMesh?.facs;
59745
+ const head = this.getPartEquivalent(instance, "Head");
59746
+ if (head && facsMesh && facs && facs.quantizedTransforms) {
59747
+ let faceControls = head.FindFirstChildOfClass("FaceControls");
59748
+ if (!faceControls) {
59749
+ faceControls = new Instance("FaceControls");
59750
+ faceControls.setParent(head);
59751
+ }
59752
+ new FaceControlsWrapper(faceControls);
59753
+ for (let j = 0; j < facs.faceBoneNames.length; j++) {
59754
+ const boneName = facs.faceBoneNames[j];
59755
+ if (boneName === bone.name) {
59756
+ let jointCF = new CFrame();
59757
+ const ogCF = this.originalBoneCFrames[this.bones.indexOf(bone)];
59758
+ jointCF = ogCF.clone();
59759
+ const head2 = this.getPartEquivalent(instance, "Head");
59760
+ if (head2) {
59761
+ const headSize = head2.Prop("Size");
59762
+ const ogHeadSize = isHead ? new Vector32(...this.meshDesc.fileMesh.size) : getOriginalSize(head2);
59763
+ let scale = divide$1(headSize.toVec3(), ogHeadSize.toVec3());
59764
+ if (this.meshDesc.wasAutoSkinned) {
59765
+ scale = [1, 1, 1];
59766
+ }
59767
+ jointCF.Position = multiply$1(jointCF.Position, scale);
59768
+ }
59769
+ let totalPosition = new Vector32();
59770
+ let totalRotation = new Vector32();
59771
+ for (let i = 0; i < facs.faceControlNames.length; i++) {
59772
+ const faceControlName = facs.faceControlNames[i];
59773
+ const col = i;
59774
+ const row = j;
59775
+ const cols = facs.faceControlNames.length;
59776
+ const index = row * cols + col;
59777
+ const posX = facs.quantizedTransforms.px.matrix[index];
59778
+ const posY = facs.quantizedTransforms.py.matrix[index];
59779
+ const posZ = facs.quantizedTransforms.pz.matrix[index];
59780
+ const rotX = facs.quantizedTransforms.rx.matrix[index];
59781
+ const rotY = facs.quantizedTransforms.ry.matrix[index];
59782
+ const rotZ = facs.quantizedTransforms.rz.matrix[index];
59783
+ const pos = new Vector32(posX, posY, posZ);
59784
+ const rot = new Vector32(rotX, rotY, rotZ);
59785
+ let weight = 0;
59786
+ if (faceControlName.includes(" ")) {
59787
+ weight = 1;
59788
+ for (const faceControlSubname of faceControlName.split(" ")) {
59789
+ const propertyName = AbbreviationToFaceControlProperty[faceControlSubname];
59790
+ weight *= faceControls.Prop(propertyName);
59791
+ }
59792
+ } else {
59793
+ const propertyName = AbbreviationToFaceControlProperty[faceControlName];
59794
+ if (propertyName === void 0) {
59795
+ console.log(faceControlName);
59796
+ }
59797
+ weight = faceControls.Prop(propertyName);
59798
+ }
59799
+ totalPosition = totalPosition.add(pos.multiply(new Vector32(weight, weight, weight)));
59800
+ totalRotation = totalRotation.add(rot.multiply(new Vector32(weight, weight, weight)));
59801
+ }
59802
+ const resultCF = new CFrame();
59803
+ const euler = new Euler(rad(totalRotation.X), rad(totalRotation.Y), rad(totalRotation.Z), "YXZ");
59804
+ resultCF.Orientation = [deg(euler.x), deg(euler.y), deg(euler.z)];
59805
+ resultCF.Position = totalPosition.toVec3();
59310
59806
  setBoneToCFrame(bone, jointCF.multiply(resultCF));
59311
59807
  break;
59312
59808
  }
@@ -59558,8 +60054,14 @@ class ObjectDesc extends RenderDesc {
59558
60054
  const oldSize = this.originalScale;
59559
60055
  threeMesh.scale.set(this.size.X / oldSize.x, this.size.Y / oldSize.y, this.size.Z / oldSize.z);
59560
60056
  }
59561
- if (SkeletonDesc.descNeedsSkeleton(this.meshDesc)) {
59562
- this.skeletonDesc = new SkeletonDesc(this, this.meshDesc, scene);
60057
+ if (SkeletonDesc$1.descNeedsSkeleton(this.meshDesc)) {
60058
+ if (FLAGS.USE_LOCAL_SKELETONDESC) {
60059
+ this.skeletonDesc = new SkeletonDesc2(this, this.meshDesc, scene);
60060
+ } else {
60061
+ this.skeletonDesc = new SkeletonDesc$1(this, this.meshDesc, scene);
60062
+ }
60063
+ } else {
60064
+ this.meshDesc.fileMesh = void 0;
59563
60065
  }
59564
60066
  if (originalResult) {
59565
60067
  this.disposeMeshes(scene, originalResult);
@@ -59902,7 +60404,7 @@ class EmitterDesc extends DisposableDesc {
59902
60404
  return this.result;
59903
60405
  }
59904
60406
  emit(groupDesc) {
59905
- if (this.particles.length >= this.maxCount) {
60407
+ if (this.particles.length >= this.maxCount || groupDesc.enabled === false) {
59906
60408
  return;
59907
60409
  }
59908
60410
  const speed = randomBetween(this.speed.Min, this.speed.Max);
@@ -59995,6 +60497,7 @@ class EmitterDesc extends DisposableDesc {
59995
60497
  class EmitterGroupDesc extends RenderDesc {
59996
60498
  lastTime = Date.now() / 1e3;
59997
60499
  time = Date.now() / 1e3;
60500
+ enabled = true;
59998
60501
  lowerBound = new Vector32(0, 0, 0);
59999
60502
  higherBound = new Vector32(0, 0, 0);
60000
60503
  lastCframe = new CFrame();
@@ -60094,6 +60597,7 @@ class EmitterGroupDesc extends RenderDesc {
60094
60597
  this.lowerBound = size2.multiply(new Vector32(-0.5, -0.5, -0.5));
60095
60598
  }
60096
60599
  }
60600
+ this.enabled = child.PropOrDefault("Enabled", true);
60097
60601
  const className = child.className;
60098
60602
  switch (className) {
60099
60603
  case "ParticleEmitter":
@@ -60305,6 +60809,9 @@ class RBXRenderer {
60305
60809
  static loadingIconStyle;
60306
60810
  static plane;
60307
60811
  static shadowPlane;
60812
+ static ambientLight;
60813
+ static directionalLight;
60814
+ static directionalLight2;
60308
60815
  static async boilerplateSetup() {
60309
60816
  RegisterWrappers();
60310
60817
  setupWorkerPool();
@@ -60402,6 +60909,7 @@ class RBXRenderer {
60402
60909
  }
60403
60910
  const ambientLight = new AmbientLight(ambientLightColor, Math.PI / 2);
60404
60911
  RBXRenderer.scene.add(ambientLight);
60912
+ RBXRenderer.ambientLight = ambientLight;
60405
60913
  let directionalLightColor = void 0;
60406
60914
  const directionalLightVal = 0.7 * 0.9 * 2 * 0.4;
60407
60915
  if (lightingType === "Thumbnail") {
@@ -60435,16 +60943,19 @@ class RBXRenderer {
60435
60943
  directionalLight.shadow.intensity = 0.5;
60436
60944
  directionalLight.target.position.set(0, 0, 0);
60437
60945
  RBXRenderer.scene.add(directionalLight);
60946
+ RBXRenderer.directionalLight = directionalLight;
60438
60947
  if (lightingType === "WellLit") {
60439
60948
  const directionalLight2 = new DirectionalLight(16777215, 0.3);
60440
60949
  directionalLight2.position.set(5, -7, 5);
60441
60950
  directionalLight2.target.position.set(0, 0, 0);
60442
60951
  RBXRenderer.scene.add(directionalLight2);
60952
+ RBXRenderer.directionalLight2 = directionalLight2;
60443
60953
  } else if (lightingType === "Thumbnail") {
60444
60954
  const directionalLight2 = new DirectionalLight(directionalLightColor, directionalLightIntensity * 0.5);
60445
60955
  directionalLight2.position.set(-0.47489210963249207 * -10, 0.8225368857383728 * -10, 0.3129066228866577 * -10);
60446
60956
  directionalLight2.target.position.set(0, 0, 0);
60447
60957
  RBXRenderer.scene.add(directionalLight2);
60958
+ RBXRenderer.directionalLight2 = directionalLight2;
60448
60959
  }
60449
60960
  const planeGeometry = new PlaneGeometry(100, 100, 1, 1);
60450
60961
  const planeShadowMaterial = new ShadowMaterial({ opacity: 1 });
@@ -60570,7 +61081,11 @@ class RBXRenderer {
60570
61081
  if (skeleton) {
60571
61082
  result.bindMode = "detached";
60572
61083
  if (newDesc.skeletonDesc) {
60573
- RBXRenderer.scene.add(newDesc.skeletonDesc.rootBone);
61084
+ if (FLAGS.USE_LOCAL_SKELETONDESC) {
61085
+ result.add(newDesc.skeletonDesc.rootBone);
61086
+ } else {
61087
+ RBXRenderer.scene.add(newDesc.skeletonDesc.rootBone);
61088
+ }
60574
61089
  }
60575
61090
  result.bind(skeleton);
60576
61091
  RBXRenderer.scene.add(result);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "roavatar-renderer",
3
- "version": "1.2.2",
3
+ "version": "1.2.3",
4
4
  "description": "A renderer for Roblox avatars, used by the RoAvatar extension.",
5
5
  "author": "steinan",
6
6
  "type": "module",