roavatar-renderer 1.2.14 → 1.2.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,21 +1,25 @@
1
1
  # Renderer for RoAvatar
2
- This is the Roblox avatar renderer made for https://github.com/steinann/RoAvatar
2
+ The Roblox Avatar renderer used by https://github.com/steinann/RoAvatar
3
3
 
4
- It was originally a part of that repository but has now gained independence
4
+ Links: [npm](https://www.npmjs.com/package/roavatar-renderer) | [GitHub](https://github.com/steinann/RoAvatar-Renderer)
5
5
 
6
- Also available on npm: https://www.npmjs.com/package/roavatar-renderer
6
+ > **IMPORTANT** <br>
7
+ > Assets are *NOT* included in the npm module or this repository, you have to get them from the main RoAvatar repository OR set
8
+ > ```FLAGS.ONLINE_ASSETS = true```
7
9
 
8
- IMPORTANT: Assets are NOT included in the npm module or this repository, you have to get them from the main RoAvatar repository OR set FLAGS.ONLINE_ASSETS = true
10
+ Basic example on how to load an avatar using OutfitRenderer (to make it simpler):
9
11
 
10
- Basic example on how to load an avatar, that is also untested:
12
+ **HTML:**
11
13
  ```html
12
- <!--I know this is kind of terrible but... it has to be included-->
14
+ <!--This script has to be loaded in before loading any meshes-->
13
15
  <script src="/draco_decoder.js"></script>
14
16
  ```
17
+ **TYPESCRIPT:**
15
18
  ```ts
16
19
  //setup flags that are compatible with you environment
17
- FLAGS.ONLINE_ASSETS = false //set this to true if you want assets to be loaded from roblox instead of locally
20
+ FLAGS.ONLINE_ASSETS = true //set false to true if you want assets to be loaded locally
18
21
 
22
+ //if we arent using online assets we have to provide the renderer with the paths
19
23
  if (!FLAGS.ONLINE_ASSETS) {
20
24
  //path to asset files from RoAvatar
21
25
  FLAGS.ASSETS_PATH = chrome.runtime.getURL("assets/rbxasset/")
@@ -47,9 +51,11 @@ if (!(outfit instanceof Outfit)) throw new Error("Failed to get outfit")
47
51
  //used by api
48
52
  const auth = new Authentication()
49
53
  //manages outfit rendering for you
50
- const outfitRenderer = new OutfitRenderer(auth, outfit, "roavatar://")
54
+ const outfitRenderer = new OutfitRenderer(auth, outfit)
51
55
  outfitRenderer.startAnimating()
52
56
  outfitRenderer.setMainAnimation("idle")
53
57
  ```
54
58
 
55
- See the RoAvatar source code to know more, especially avatarPreview.tsx is useful
59
+ More info available in ```/docs```
60
+
61
+ Also the OutfitRenderer code or RoAvatar source code is useful, especially ```avatarPreview.ts```
package/dist/index.d.ts CHANGED
@@ -880,6 +880,10 @@ declare class Event_2 {
880
880
  }
881
881
  export { Event_2 as Event }
882
882
 
883
+ export declare function exposeAPI(): void;
884
+
885
+ export declare function exposeMesh(): void;
886
+
883
887
  export declare const FaceControlNames: string[];
884
888
 
885
889
  export declare class FaceControlsWrapper extends InstanceWrapper {
@@ -1279,7 +1283,7 @@ export declare class Instance {
1279
1283
  PropOrDefault(name: string, def: unknown): unknown;
1280
1284
  PropertyType(name: string): number | undefined;
1281
1285
  getPropertyNames(): string[];
1282
- setParent(instance: Instance | undefined | null): void;
1286
+ setParent(instance: Instance | undefined | null, fireEvents?: boolean): void;
1283
1287
  Destroy(): void;
1284
1288
  GetFullName(): string;
1285
1289
  GetChildren(): Instance[];
@@ -1882,13 +1886,15 @@ export declare class OutfitRenderer {
1882
1886
  hasNewUpdate: boolean;
1883
1887
  lastFrameTime: number;
1884
1888
  animationInterval?: NodeJS.Timeout;
1889
+ animationFPS: number;
1890
+ deltaTimeMultiplier: number;
1885
1891
  /**
1886
1892
  * Creates a new OutfitRenderer which makes it easy to render outfits
1887
1893
  * @param auth The authentication object, you should have one you use for everything
1888
1894
  * @param outfit The outfit you want to render, it can be updated later by calling setOutfit()
1889
- * @param rigPath The path that contains RigR6.rbxm and RigR15.rbxm, for example "../assets/"
1895
+ * @param rigPath The path that contains RigR6.rbxm and RigR15.rbxm, should always be "roavatar://" as rig path is now controlled by FLAGS
1890
1896
  */
1891
- constructor(auth: Authentication, outfit: Outfit, rigPath: string);
1897
+ constructor(auth: Authentication, outfit: Outfit, rigPath?: string);
1892
1898
  /**
1893
1899
  * Updates the current rig, called internally by _updateOutfit()
1894
1900
  */
package/dist/index.js CHANGED
@@ -29537,16 +29537,16 @@ const FLAGS = {
29537
29537
  };
29538
29538
  function log(critical, ...args) {
29539
29539
  if (critical || FLAGS.VERBOSE_LOGGING) {
29540
- console.log(args);
29540
+ console.log(...args);
29541
29541
  }
29542
29542
  }
29543
29543
  function warn(critical, ...args) {
29544
29544
  if (critical || FLAGS.VERBOSE_LOGGING) {
29545
- console.warn(args);
29545
+ console.warn(...args);
29546
29546
  }
29547
29547
  }
29548
29548
  function error(...args) {
29549
- console.error(args);
29549
+ console.error(...args);
29550
29550
  }
29551
29551
  function time(label) {
29552
29552
  if (FLAGS.VERBOSE_LOGGING) {
@@ -30266,7 +30266,7 @@ class Instance {
30266
30266
  getPropertyNames() {
30267
30267
  return Array.from(this._properties.keys());
30268
30268
  }
30269
- setParent(instance) {
30269
+ setParent(instance, fireEvents = true) {
30270
30270
  if (!instance) {
30271
30271
  instance = void 0;
30272
30272
  }
@@ -30286,10 +30286,14 @@ class Instance {
30286
30286
  }
30287
30287
  if (instance) {
30288
30288
  instance.children.push(this);
30289
- instance.ChildAdded.Fire(this);
30290
- instance.AncestryChanged.Fire(this, instance);
30291
30289
  }
30292
- this.AncestryChanged.Fire(this, instance);
30290
+ if (fireEvents) {
30291
+ if (instance) {
30292
+ instance.ChildAdded.Fire(this);
30293
+ instance.AncestryChanged.Fire(this, instance);
30294
+ }
30295
+ this.AncestryChanged.Fire(this, instance);
30296
+ }
30293
30297
  }
30294
30298
  Destroy() {
30295
30299
  for (const connection of this._connectionReferences) {
@@ -30344,8 +30348,8 @@ class Instance {
30344
30348
  return childrenList;
30345
30349
  }
30346
30350
  GetDescendants() {
30347
- let descendants = this.children;
30348
- for (const child of this.children) {
30351
+ let descendants = this.GetChildren();
30352
+ for (const child of this.GetChildren()) {
30349
30353
  descendants = descendants.concat(child.GetDescendants());
30350
30354
  }
30351
30355
  return descendants;
@@ -30840,6 +30844,7 @@ class RBX {
30840
30844
  const content = new Content();
30841
30845
  content.sourceType = sourceTypes[i];
30842
30846
  switch (content.sourceType) {
30847
+ //2 - Uri, 0 - Object/None,
30843
30848
  case 0:
30844
30849
  break;
30845
30850
  case 1:
@@ -41185,7 +41190,7 @@ function TraverseRigFromAttachmentsInternal(self2, part, characterParts, buildJo
41185
41190
  if (attachment.className === "Attachment") {
41186
41191
  const attachmentName = attachment.Prop("Name");
41187
41192
  const findPos = attachmentName.indexOf(rigAttachmentName);
41188
- if (findPos) {
41193
+ if (findPos !== -1) {
41189
41194
  const jointName = attachmentName.substring(0, findPos);
41190
41195
  const joint = part.FindFirstChild(jointName);
41191
41196
  if (!joint || joint.className !== "Motor6D") {
@@ -41193,6 +41198,7 @@ function TraverseRigFromAttachmentsInternal(self2, part, characterParts, buildJo
41193
41198
  if (part !== characterPart) {
41194
41199
  const matchingAttachment = characterPart.FindFirstChild(attachmentName);
41195
41200
  if (matchingAttachment && matchingAttachment.className === "Attachment") {
41201
+ log(false, "matchingAtt", part, characterPart, attachmentName);
41196
41202
  AdjustRootRigAttachmentPosition(self2, part, characterPart, attachment, matchingAttachment);
41197
41203
  {
41198
41204
  createJoint(jointName, attachment, matchingAttachment);
@@ -42630,6 +42636,26 @@ class MeshDesc {
42630
42636
  const meshIdStr = child.Property("MeshId");
42631
42637
  this.mesh = meshIdStr;
42632
42638
  this.scaleIsRelative = true;
42639
+ if (!FLAGS.AVATAR_JOINT_UPGRADE) {
42640
+ if (child.FindFirstChildOfClass("Bone")) {
42641
+ this.canHaveSkinning = false;
42642
+ } else {
42643
+ if (child.Prop("Name").includes("Arm")) {
42644
+ const rig = child.parent;
42645
+ if (rig) {
42646
+ const humanoid = rig.FindFirstChildOfClass("Humanoid");
42647
+ if (humanoid) {
42648
+ const side = child.Prop("Name").startsWith("Right") ? "Right" : "Left";
42649
+ const handName = side + "Hand";
42650
+ const hand = rig.FindFirstChild(handName);
42651
+ if (hand && hand.FindFirstChildOfClass("Bone")) {
42652
+ this.canHaveSkinning = false;
42653
+ }
42654
+ }
42655
+ }
42656
+ }
42657
+ }
42658
+ }
42633
42659
  const surfaceAppearance = child.FindLastChildOfClass("SurfaceAppearance");
42634
42660
  if (surfaceAppearance) {
42635
42661
  const color = surfaceAppearance.HasProperty("Color") ? surfaceAppearance.Prop("Color") : new Color3(1, 1, 1);
@@ -43980,6 +44006,7 @@ function setBoneToCFrame$1(bone, cf) {
43980
44006
  bone.rotation.y = rad(cf.Orientation[1]);
43981
44007
  bone.rotation.z = rad(cf.Orientation[2]);
43982
44008
  }
44009
+ const BaseR15Bones = ["Root", "HumanoidRootNode", "LowerTorso", "UpperTorso", "RightUpperArm", "RightLowerArm", "RightHand", "LeftUpperArm", "LeftLowerArm", "LeftHand", "Head", "DynamicHead"];
43983
44010
  function getJointForInstances$1(parent, child, includeTransform) {
43984
44011
  const childMotor = child.FindFirstChildOfClass("Motor6D");
43985
44012
  const parentMotor = parent.FindFirstChildOfClass("Motor6D");
@@ -44007,6 +44034,21 @@ function boneIsChildOf(bone, parentName) {
44007
44034
  }
44008
44035
  return false;
44009
44036
  }
44037
+ function getBoneBaseR15Parent(bone) {
44038
+ let currentParent = bone.parent;
44039
+ if (!currentParent) return;
44040
+ while (currentParent && !BaseR15Bones.includes(currentParent.name)) {
44041
+ currentParent = currentParent.parent;
44042
+ }
44043
+ if (!currentParent) {
44044
+ return bone.parent;
44045
+ } else {
44046
+ return currentParent;
44047
+ }
44048
+ }
44049
+ function boneIsBaseR15(bone) {
44050
+ return BaseR15Bones.includes(bone.name);
44051
+ }
44010
44052
  function getMotorsInRig(rigChildren) {
44011
44053
  const motors = [];
44012
44054
  for (const child of rigChildren) {
@@ -44025,15 +44067,17 @@ function getBoneDependencies(rig) {
44025
44067
  let currentSearchOrigin = hrp ? ["Root"] : [];
44026
44068
  const children = rig.GetChildren();
44027
44069
  const motors = getMotorsInRig(children);
44070
+ const searchedParts = [];
44028
44071
  while (currentSearch.length > 0 && currentSearch[0]) {
44029
44072
  const newCurrentSearch = [];
44030
44073
  const newCurrentSearchOrigin = [];
44031
44074
  for (let i = 0; i < currentSearch.length; i++) {
44032
44075
  const toSearch = currentSearch[i];
44076
+ searchedParts.push(toSearch);
44033
44077
  const selfName = toSearch === hrp ? "HumanoidRootNode" : toSearch.Prop("Name");
44034
44078
  names.set(selfName, currentSearchOrigin[i]);
44035
44079
  for (const motor of motors) {
44036
- if (motor.Prop("Part0") === toSearch) {
44080
+ if (motor.Prop("Part0") === toSearch && !searchedParts.includes(motor.parent)) {
44037
44081
  newCurrentSearch.push(motor.parent);
44038
44082
  newCurrentSearchOrigin.push(selfName);
44039
44083
  }
@@ -44237,7 +44281,8 @@ let SkeletonDesc$1 = class SkeletonDesc {
44237
44281
  for (let i = 0; i < this.bones.length; i++) {
44238
44282
  const bone = this.bones[i];
44239
44283
  const partEquivalent = this.getPartEquivalent(selfInstance, bone.name);
44240
- const parentPartEquivalent = bone.parent ? bone.parent.name !== "HumanoidRootNode" ? this.getPartEquivalent(selfInstance, bone.parent.name) : humanoidRootPartEquivalent : void 0;
44284
+ const boneParent = boneIsBaseR15(bone) ? getBoneBaseR15Parent(bone) : bone.parent;
44285
+ const parentPartEquivalent = boneParent ? boneParent.name !== "HumanoidRootNode" ? this.getPartEquivalent(selfInstance, boneParent.name) : humanoidRootPartEquivalent : void 0;
44241
44286
  let rootBoneCF = new CFrame();
44242
44287
  if (bone.name === "Root") {
44243
44288
  rootBoneCF = rootBoneCFog;
@@ -47206,6 +47251,32 @@ function isSameAccessoryDesc(desc0, desc1) {
47206
47251
  function isSameMakeupDesc(desc0, desc1) {
47207
47252
  return hasSameVal(desc0, desc1, "AssetId") && hasSameVal(desc0, desc1, "MakeupType") && hasSameVal(desc0, desc1, "Order");
47208
47253
  }
47254
+ function moveAttachmentsToBase(rigPart) {
47255
+ let nextCollapse = rigPart.GetChildren();
47256
+ let cframeHierarchy = new Array(nextCollapse.length).fill(new CFrame());
47257
+ while (nextCollapse.length > 0) {
47258
+ const newNextCollapse = [];
47259
+ const newCFrameHierarchy = [];
47260
+ for (let i = 0; i < nextCollapse.length; i++) {
47261
+ const child = nextCollapse[i];
47262
+ if (child.className !== "Bone" && child.className !== "Attachment" || !child.HasProperty("CFrame")) {
47263
+ continue;
47264
+ }
47265
+ const selfCFrameHierarchy = cframeHierarchy[i];
47266
+ const originalCFrame = child.Prop("CFrame");
47267
+ const newCFrame = selfCFrameHierarchy.multiply(originalCFrame);
47268
+ child.setProperty("CFrame", newCFrame);
47269
+ const childChildren = child.GetChildren();
47270
+ for (const childChild of childChildren) {
47271
+ newNextCollapse.push(childChild);
47272
+ newCFrameHierarchy.push(newCFrame);
47273
+ }
47274
+ child.setParent(rigPart);
47275
+ }
47276
+ nextCollapse = newNextCollapse;
47277
+ cframeHierarchy = newCFrameHierarchy;
47278
+ }
47279
+ }
47209
47280
  class HumanoidDescriptionWrapper extends InstanceWrapper {
47210
47281
  static className = "HumanoidDescription";
47211
47282
  static requiredProperties = [
@@ -47860,6 +47931,9 @@ class HumanoidDescriptionWrapper extends InstanceWrapper {
47860
47931
  if (R15Folder) {
47861
47932
  const children = R15Folder.GetChildren();
47862
47933
  for (const child of children) {
47934
+ if (!FLAGS.AVATAR_JOINT_UPGRADE) {
47935
+ moveAttachmentsToBase(child);
47936
+ }
47863
47937
  replaceBodyPart(rig, child);
47864
47938
  }
47865
47939
  }
@@ -49473,6 +49547,14 @@ class HSR {
49473
49547
  }
49474
49548
  }
49475
49549
  }
49550
+ function exposeAPI() {
49551
+ globalThis.API = API;
49552
+ globalThis.APICACHE = CACHE;
49553
+ globalThis.Authentication = Authentication;
49554
+ }
49555
+ function exposeMesh() {
49556
+ globalThis.fileMeshToTHREEGeometry = fileMeshToTHREEGeometry;
49557
+ }
49476
49558
  function getCorners(cframe, size) {
49477
49559
  const halfX = size.X / 2;
49478
49560
  const halfY = size.Y / 2;
@@ -49586,13 +49668,15 @@ class OutfitRenderer {
49586
49668
  hasNewUpdate = false;
49587
49669
  lastFrameTime = Date.now() / 100;
49588
49670
  animationInterval;
49671
+ animationFPS = 60;
49672
+ deltaTimeMultiplier = 1;
49589
49673
  /**
49590
49674
  * Creates a new OutfitRenderer which makes it easy to render outfits
49591
49675
  * @param auth The authentication object, you should have one you use for everything
49592
49676
  * @param outfit The outfit you want to render, it can be updated later by calling setOutfit()
49593
- * @param rigPath The path that contains RigR6.rbxm and RigR15.rbxm, for example "../assets/"
49677
+ * @param rigPath The path that contains RigR6.rbxm and RigR15.rbxm, should always be "roavatar://" as rig path is now controlled by FLAGS
49594
49678
  */
49595
- constructor(auth, outfit, rigPath) {
49679
+ constructor(auth, outfit, rigPath = "roavatar://") {
49596
49680
  this.auth = auth;
49597
49681
  this.outfit = outfit;
49598
49682
  this.currentRigType = outfit.playerAvatarType;
@@ -49703,7 +49787,7 @@ class OutfitRenderer {
49703
49787
  */
49704
49788
  startAnimating() {
49705
49789
  if (this.animationInterval !== void 0) return;
49706
- this.lastFrameTime = Date.now() / 100;
49790
+ this.lastFrameTime = Date.now() / 1e3;
49707
49791
  this.animationInterval = setInterval(() => {
49708
49792
  if (this.currentRig && this.doCameraUpdate) {
49709
49793
  this.centerCamera();
@@ -49713,7 +49797,7 @@ class OutfitRenderer {
49713
49797
  if (humanoid) {
49714
49798
  const animator = humanoid.FindFirstChildOfClass("Animator");
49715
49799
  if (animator) {
49716
- const deltaTime = Date.now() / 1e3 - this.lastFrameTime;
49800
+ const deltaTime = (Date.now() / 1e3 - this.lastFrameTime) * this.deltaTimeMultiplier;
49717
49801
  this.lastFrameTime = Date.now() / 1e3;
49718
49802
  const animatorW = new AnimatorWrapper(animator);
49719
49803
  animatorW.renderAnimation(deltaTime);
@@ -49722,7 +49806,7 @@ class OutfitRenderer {
49722
49806
  }
49723
49807
  }
49724
49808
  }
49725
- }, 1e3 / 60);
49809
+ }, 1e3 / this.animationFPS);
49726
49810
  }
49727
49811
  /**
49728
49812
  * Stops updating the animation of the outfit per frame
@@ -49730,6 +49814,7 @@ class OutfitRenderer {
49730
49814
  stopAnimating() {
49731
49815
  if (this.animationInterval) {
49732
49816
  clearInterval(this.animationInterval);
49817
+ this.animationInterval = void 0;
49733
49818
  }
49734
49819
  }
49735
49820
  /**
@@ -49913,6 +49998,8 @@ export {
49913
49998
  divide,
49914
49999
  dot,
49915
50000
  download,
50001
+ exposeAPI,
50002
+ exposeMesh,
49916
50003
  floor,
49917
50004
  gaussian_rbf,
49918
50005
  generateUUIDv4,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "roavatar-renderer",
3
- "version": "1.2.14",
3
+ "version": "1.2.15",
4
4
  "description": "A renderer for Roblox avatars, used by the RoAvatar extension.",
5
5
  "author": "steinan",
6
6
  "type": "module",