roavatar-renderer 1.4.1 → 1.4.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
@@ -213,10 +213,38 @@ export declare class AnimatorWrapper extends InstanceWrapper {
213
213
  private _switchToolAnimation;
214
214
  isValidTrackForSet(track: AnimationTrack, name: string): boolean;
215
215
  private _fixUnloaded;
216
+ /**
217
+ * Resets all joints in the rig to be in their rest pose
218
+ * @param includeMotors If motors (body movement joints) should be set to rest pose
219
+ * @param includeFACS If FACS (face movement bones) should be set to rest pose
220
+ */
216
221
  restPose(includeMotors?: boolean, includeFACS?: boolean): void;
222
+ /**
223
+ * Renders animation pose
224
+ * @param addTime Time to add to the current time
225
+ * @param forceTime Time to force animation to be at, -1 is in the middle of the animation
226
+ * @param forceKeyframe Keyframe to force animation to be at
227
+ */
217
228
  renderAnimation(addTime?: number, forceTime?: number, forceKeyframe?: number): void;
229
+ /**
230
+ *
231
+ * @returns Currently playing animation track
232
+ */
218
233
  getCurrentAnimationTrack(): AnimationTrack | undefined;
234
+ /**
235
+ * Loads a new animation
236
+ * @param id
237
+ * @param isEmote
238
+ * @param forceLoop Forces animation track to loop
239
+ * @returns undefined on success
240
+ */
219
241
  loadAvatarAnimation(id: bigint, isEmote?: boolean, forceLoop?: boolean): Promise<Response | undefined>;
242
+ /**
243
+ * Switches to new animation
244
+ * @param name Animation name, such as "idle", "walk" or "emote.1234"
245
+ * @param type
246
+ * @returns If animation sucessfully played
247
+ */
220
248
  playAnimation(name: string, type?: "main" | "mood" | "tool"): boolean;
221
249
  }
222
250
 
@@ -590,7 +618,7 @@ export declare class BodyColor3s {
590
618
  fromJson(bodyColorsJson: BodyColor3sJson): void;
591
619
  }
592
620
 
593
- declare type BodyColor3sJson = {
621
+ export declare type BodyColor3sJson = {
594
622
  headColor3?: string;
595
623
  torsoColor3?: string;
596
624
  rightArmColor3?: string;
@@ -626,7 +654,7 @@ export declare class BodyColors {
626
654
  toColor3(): BodyColor3s;
627
655
  }
628
656
 
629
- declare type BodyColorsJson = {
657
+ export declare type BodyColorsJson = {
630
658
  headColorId?: number;
631
659
  torsoColorId?: number;
632
660
  rightArmColorId?: number;
@@ -1187,7 +1215,9 @@ export declare class FileMeshSubset {
1187
1215
  clone(): FileMeshSubset;
1188
1216
  }
1189
1217
 
1190
- /** @category Mesh */
1218
+ /**
1219
+ * Converts a FileMesh to geometry that can be used by ThreeJS
1220
+ * @category Mesh */
1191
1221
  export declare function fileMeshToTHREEGeometry(mesh: FileMesh, canIncludeSkinning?: boolean, forceVertexColor?: Vector3): THREE.BufferGeometry<THREE.NormalBufferAttributes, THREE.BufferGeometryEventMap>;
1192
1222
 
1193
1223
  export declare function FindFirstMatchingAttachment(attachmentName: string, rig: Instance): Instance | null;
@@ -1196,53 +1226,105 @@ export declare function FindFirstMatchingAttachment(attachmentName: string, rig:
1196
1226
  * @category FLAGS
1197
1227
  */
1198
1228
  export declare const FLAGS: {
1229
+ /** Only used by RoAvatar UI */
1199
1230
  HAIR_IS_BODYPART: boolean;
1231
+ /**wip, do not enable */
1200
1232
  AVATAR_JOINT_UPGRADE: boolean;
1233
+ /**wip, only for memory leak debugging */
1201
1234
  INSTANCE_GARBAGE_COLLECT: boolean;
1235
+ /**outfits returned by api use Color3 instead of BrickColor */
1202
1236
  BODYCOLOR3: boolean;
1237
+ /**allows API to cache data */
1203
1238
  ENABLE_API_CACHE: boolean;
1239
+ /**allows API to cache mesh data */
1204
1240
  ENABLE_API_MESH_CACHE: boolean;
1241
+ /**allows API to cache RBX data */
1205
1242
  ENABLE_API_RBX_CACHE: boolean;
1243
+ /**url of model to load that lists issues with specific versions (only used by RoAvatar) */
1206
1244
  ROAVATAR_DATA_URL: string;
1245
+ /**the place try-on button sends you to (only used by RoAvatar) */
1207
1246
  ROAVATAR_TRYON_PLACE: number;
1208
- ASSETS_PATH: string;
1247
+ /**API uses assetdelivery v2 instead of v1 */
1209
1248
  ASSETDELIVERY_V2: boolean;
1249
+ /**request priority given to fetch for assetdelivery */
1210
1250
  ASSET_REQUEST_PRIORITY: RequestPriority | undefined;
1251
+ /**the domain all api requests go through */
1252
+ API_DOMAIN: string;
1253
+ /**credentials request type when fetching from API_DOMAIN and credentials are usually include */
1254
+ INCLUDE_REQUEST_CREDENTIALS_OVERRIDE: RequestCredentials;
1255
+ /**loads assets from assetdelivery instead of local files */
1211
1256
  ONLINE_ASSETS: boolean;
1257
+ /**path to rbxasset:// local files*/
1258
+ ASSETS_PATH: string;
1259
+ /**path to RigR6.rbxm and RigR15.rbxm*/
1212
1260
  RIG_PATH: string;
1261
+ /**if WebWorkers (multithreading) can be used */
1213
1262
  USE_WORKERS: boolean;
1263
+ /**makes linear algorithms cache weights */
1214
1264
  ENABLE_LC_WEIGHT_CACHE: boolean;
1265
+ /**only used by linear algorithms */
1215
1266
  INFLATE_LAYERED_CLOTHING: number;
1267
+ /**algorithm, rbf (default) is fastest, others are deprecated */
1216
1268
  LAYERED_CLOTHING_ALGORITHM: "linear" | "linearnormal" | "linearnormal2" | "rbf";
1269
+ /**renders cage mesh instead of actual mesh */
1217
1270
  SHOW_CAGE: boolean;
1271
+ /**cooldown between mesh recompile */
1218
1272
  LAYERED_CLOTHING_COOLDOWN: number;
1273
+ /**function WorkerPool uses to create workers, replace with your own if workers cant be created using the default method */
1219
1274
  GET_WORKER_FUNC: () => Worker;
1275
+ /**amount of "patches" that are used for layered clothing, multiple verts share the same patch */
1220
1276
  RBF_PATCH_COUNT: number;
1277
+ /**amount of nearby vertices each patch samples from */
1221
1278
  RBF_PATCH_DETAIL_SAMPLES: number;
1279
+ /**amount of far-away vertices (importants) each patch samples from, this is done so that the overall mesh shape is preserved */
1222
1280
  RBF_PATCH_SHAPE_SAMPLES: number;
1281
+ /**forces vertex color to be white when false */
1223
1282
  USE_VERTEX_COLOR: boolean;
1283
+ /**this is needed to enable bloom, but ugly since it disables anti aliasing... */
1224
1284
  USE_POST_PROCESSING: boolean;
1285
+ /**doubles render resolution when using post processing */
1225
1286
  POST_PROCESSING_IS_DOUBLE_SIZE: boolean;
1287
+ /**makes HumanoidDescription load gears */
1226
1288
  GEAR_ENABLED: boolean;
1289
+ /**makes Audio instances play sound when played */
1227
1290
  AUDIO_ENABLED: boolean;
1291
+ /**makes welds immediately update (bad for performance) */
1228
1292
  LEGACY_WELD_BEHAVIOR: boolean;
1293
+ /**enables full texture compilation using ThreeJS RenderTarget */
1229
1294
  USE_RENDERTARGET: boolean;
1295
+ /**the renderer will attempt to restore the webgl context when it is lost */
1230
1296
  AUTO_RESTORE_CONTEXT: boolean;
1297
+ /**RenderTarget textures are converted to CanvasTextures which can be exported */
1231
1298
  RENDERTARGET_TO_CANVASTEXTURE: boolean;
1299
+ /**Amount of time thumbnail generator will wait after no assets are being loaded to resolve */
1232
1300
  THUMBNAIL_TIMEOUT: number;
1301
+ /**shows ThreeJS SkeletonHelper */
1233
1302
  SHOW_SKELETON_HELPER: boolean;
1303
+ /**skeleton is updated every frame */
1234
1304
  UPDATE_SKELETON: boolean;
1305
+ /**skeleton is animated every frame */
1235
1306
  ANIMATE_SKELETON: boolean;
1307
+ /**autoskin is applied even when its disabled */
1236
1308
  AUTO_SKIN_EVERYTHING: boolean;
1309
+ /**skeleton is local instead of global (broken) */
1237
1310
  USE_LOCAL_SKELETONDESC: boolean;
1311
+ /**enables HSR (hidden surface removal) */
1238
1312
  ENABLE_HSR: boolean;
1313
+ /**shows rays created by HSR */
1239
1314
  HSR_SHOW_RAY: boolean;
1315
+ /**hides layered clothing */
1240
1316
  HIDE_LAYERED_CLOTHING: boolean;
1317
+ /**rays per triangle */
1241
1318
  HSR_RAY_COUNT: number;
1319
+ /**length of each ray */
1242
1320
  HSR_RAY_LENGTH: number;
1321
+ /**caches amount of hits for each triangle */
1243
1322
  CACHE_HSR_HITS: boolean;
1323
+ /**enables logging for non-critical information */
1244
1324
  VERBOSE_LOGGING: boolean;
1325
+ /**makes renderer print out strings in RBX that contain SEARCH_FOR_STRING */
1245
1326
  SEARCH_FOR_STRING: string | undefined;
1327
+ /**only used by RoAvatar, set this to a string to load a place file, for example "../assets/UniversalApp.rbxm" */
1246
1328
  LOAD_TEST_PLACE: string | undefined;
1247
1329
  };
1248
1330
 
@@ -2098,6 +2180,14 @@ export declare function mount(container: HTMLDivElement): void;
2098
2180
  * Mounting function for use with React
2099
2181
  * @param container Container to mount inside
2100
2182
  * @category Renderer
2183
+ * @example
2184
+ * ```ts
2185
+ * export default function Component(): React.JSX.Element {
2186
+ * const containerRef = useCallback(mountElement, [])
2187
+ *
2188
+ * return <div ref={containerRef}></div>
2189
+ * }
2190
+ * ```
2101
2191
  */
2102
2192
  export declare function mountElement(container: HTMLDivElement): void;
2103
2193
 
@@ -2312,6 +2402,10 @@ export declare class Outfit {
2312
2402
  */
2313
2403
  isValid(): boolean;
2314
2404
  getValidationIssues(): ValidationIssue[];
2405
+ /**
2406
+ * @deprecated Outdated
2407
+ * @returns
2408
+ */
2315
2409
  toHumanoidDescription(): Promise<Document | null>;
2316
2410
  /** @deprecated */
2317
2411
  fromHumanoidDescription(rootDocument: Document): Promise<void>;
@@ -2324,6 +2418,9 @@ export declare class Outfit {
2324
2418
  removeAsset(assetId: number): void;
2325
2419
  removeAssetType(type: string | number): void;
2326
2420
  addAsset(id: number, type: string | number, name: string, supportsHeadShapes?: boolean): void;
2421
+ /**
2422
+ * Fixes multiple layered assets having the same order value
2423
+ */
2327
2424
  fixOrders(): void;
2328
2425
  getAssetsAtOrder(order: number): Asset[];
2329
2426
  isOrderUsed(order: number, self?: Asset): boolean;
@@ -2337,7 +2434,7 @@ export declare class Outfit {
2337
2434
  toBuffer(): ArrayBuffer;
2338
2435
  }
2339
2436
 
2340
- declare type OutfitJson = {
2437
+ export declare type OutfitJson = {
2341
2438
  scale?: ScaleJson;
2342
2439
  playerAvatarType?: AvatarType;
2343
2440
  assets?: AssetJson[];
@@ -2374,6 +2471,7 @@ export declare class OutfitRenderer {
2374
2471
  currentlyChangingRig: boolean;
2375
2472
  currentlyUpdating: boolean;
2376
2473
  hasNewUpdate: boolean;
2474
+ private _queuedMainAnimation;
2377
2475
  lastFrameTime: number;
2378
2476
  animationInterval?: NodeJS.Timeout;
2379
2477
  animationFPS: number;
@@ -2538,6 +2636,7 @@ declare class Ray_2 {
2538
2636
  }
2539
2637
 
2540
2638
  /**
2639
+ * The deformer used for layered clothing
2541
2640
  * @category Mesh
2542
2641
  */
2543
2642
  export declare class RBFDeformerPatch {
@@ -2557,9 +2656,33 @@ export declare class RBFDeformerPatch {
2557
2656
  epsilon: number;
2558
2657
  affectBones: boolean;
2559
2658
  id: number;
2659
+ /**
2660
+ * Creates the deformer and prepares for deformation
2661
+ * @param refMesh The reference cage
2662
+ * @param distMesh The destination cage
2663
+ * @param mesh The mesh to deform
2664
+ * @param ignoredIndices Indices in the reference cage to ignore
2665
+ * @param patchCount Amount of patches spread around the mesh, each one solves a linear equation
2666
+ * @param detailsCount Amount of close vertices in each patch
2667
+ * @param importantsCount Amount of far away vertices in each patch
2668
+ */
2560
2669
  constructor(refMesh: FileMesh, distMesh: FileMesh, mesh: FileMesh, ignoredIndices?: number[], patchCount?: number, detailsCount?: number, importantsCount?: number);
2670
+ /**
2671
+ * Solves the linear equations asynchronously, required before deformation
2672
+ * @returns void
2673
+ */
2561
2674
  solveAsync(): Promise<void>;
2675
+ /**
2676
+ * solveAsync() needs to be called before this
2677
+ * Deforms the position of something inside the mesh
2678
+ * @param i The index of the vert to deform, if it is outside the range of vertices it will be a bone instead. For example vertices range from 1 - 100, and bones range from 101 - 110. Then index 101 will represent the first bone
2679
+ * @returns New position after deformation
2680
+ */
2562
2681
  deform(i: number): Vec3;
2682
+ /**
2683
+ * solveAsync() needs to be called before this
2684
+ * Deforms vertices and bones in mesh (if this.affectBones = true)
2685
+ */
2563
2686
  deformMesh(): void;
2564
2687
  }
2565
2688
 
@@ -2684,7 +2807,7 @@ export declare class RBXRenderer {
2684
2807
  static _createEffectComposer(renderScene?: RBXRendererScene): void;
2685
2808
  /**Removes an instance from the renderer */
2686
2809
  static removeInstance(instance: Instance, renderScene?: RBXRendererScene): void;
2687
- static _addRenderDesc(instance: Instance, auth: Authentication, DescClass: typeof RenderDesc, renderScene: RBXRendererScene): void;
2810
+ private static _addRenderDesc;
2688
2811
  /**Adds an instance to the renderer or updates it */
2689
2812
  static addInstance(instance: Instance, auth: Authentication, renderScene?: RBXRendererScene): void;
2690
2813
  static setRendererSize(width: number, height: number): void;
@@ -2704,10 +2827,14 @@ export declare class RBXRenderer {
2704
2827
  static setCameraFov(fov: number, renderScene?: RBXRendererScene): void;
2705
2828
  /**@deprecated This can only get the first renderScene's controls */
2706
2829
  static getRendererControls(): OrbitControls | undefined;
2830
+ /**
2831
+ * @returns ThreeJS renderer
2832
+ */
2707
2833
  static getRenderer(): THREE.WebGLRenderer | undefined;
2708
2834
  /**@deprecated This can only get the first renderScene's scene */
2709
2835
  static getScene(): THREE.Scene;
2710
- /**@deprecated
2836
+ /**
2837
+ * @deprecated Superseded by RBXRendererScene.exportGLTF()
2711
2838
  * This function is unstable and can throw errors, but might work
2712
2839
  */
2713
2840
  static exportScene(renderScene?: RBXRendererScene): void;
@@ -2745,7 +2872,14 @@ export declare class RBXRendererScene {
2745
2872
  setRect(bounds: DOMRect): void;
2746
2873
  /** Makes viewport size 0x0, invisible */
2747
2874
  noRect(): void;
2875
+ /** Destroys all renderDescs but does not call Destroy on instances */
2748
2876
  destroy(): void;
2877
+ /**
2878
+ * Exports scene as a GLTF or GLB
2879
+ * @param name Name of the resulting file if autoDownload is true
2880
+ * @param autoDownload If resulting file should be auto downloaded
2881
+ * @returns The GLB (buffer) or GLTF (object)
2882
+ */
2749
2883
  exportGLTF(name?: string, autoDownload?: boolean): Promise<ArrayBuffer | {
2750
2884
  [key: string]: unknown;
2751
2885
  }>;
@@ -2905,7 +3039,7 @@ export declare function ScaleAccessoryForRig(accessory: Instance, rig: Instance,
2905
3039
 
2906
3040
  export declare function ScaleCharacter(rig: Instance, outfit: Outfit, humanoidDescription: Instance): RigData | undefined;
2907
3041
 
2908
- declare type ScaleJson = {
3042
+ export declare type ScaleJson = {
2909
3043
  height?: number;
2910
3044
  width?: number;
2911
3045
  head?: number;
@@ -3229,13 +3363,13 @@ export declare interface UserOmniSearch_Result {
3229
3363
  "nextPageToken": string;
3230
3364
  }
3231
3365
 
3232
- declare type ValidationIssue = {
3366
+ export declare type ValidationIssue = {
3233
3367
  type: ValidationIssueType;
3234
3368
  text: string;
3235
3369
  assetIndex?: number;
3236
3370
  };
3237
3371
 
3238
- declare type ValidationIssueType = "AccessoryLimit" | "LayeredLimit" | "OneOfTypeLimit" | "DuplicateId" | "NotWearable" | "MissingLayeredMeta" | "InvalidAsset" | "MakeupLimit";
3372
+ export declare type ValidationIssueType = "AccessoryLimit" | "LayeredLimit" | "OneOfTypeLimit" | "DuplicateId" | "NotWearable" | "MissingLayeredMeta" | "InvalidAsset" | "MakeupLimit";
3239
3373
 
3240
3374
  /** @category Mesh */
3241
3375
  export declare type Vec2 = [number, number];
package/dist/index.js CHANGED
@@ -29514,6 +29514,8 @@ const FLAGS = {
29514
29514
  ROAVATAR_TRYON_PLACE: 135979364355750,
29515
29515
  ASSETDELIVERY_V2: true,
29516
29516
  ASSET_REQUEST_PRIORITY: "high",
29517
+ API_DOMAIN: "roblox.com",
29518
+ INCLUDE_REQUEST_CREDENTIALS_OVERRIDE: "include",
29517
29519
  //assets
29518
29520
  ONLINE_ASSETS: false,
29519
29521
  ASSETS_PATH: "../assets/rbxasset/",
@@ -32778,6 +32780,10 @@ class Outfit {
32778
32780
  }
32779
32781
  return issues;
32780
32782
  }
32783
+ /**
32784
+ * @deprecated Outdated
32785
+ * @returns
32786
+ */
32781
32787
  async toHumanoidDescription() {
32782
32788
  const response = await fetch("/assets/HumanoidDescriptionTemplate.xml");
32783
32789
  if (response.status !== 200)
@@ -33080,6 +33086,9 @@ class Outfit {
33080
33086
  asset.assetType.name = typeName;
33081
33087
  this.assets.push(asset);
33082
33088
  }
33089
+ /**
33090
+ * Fixes multiple layered assets having the same order value
33091
+ */
33083
33092
  fixOrders() {
33084
33093
  for (const asset of this.assets.slice().reverse()) {
33085
33094
  if (!AccessoryAssetTypes.includes(asset.assetType.name) && LayeredAssetTypes.includes(asset.assetType.name)) {
@@ -35191,6 +35200,9 @@ class Authentication {
35191
35200
  }
35192
35201
  }
35193
35202
  async function RBLXPost(url, auth, body, attempt = 0, method = "POST") {
35203
+ if (url.match(/https?:\/\/[a-z]+.roblox.com/)) {
35204
+ url = url.replace("roblox.com", FLAGS.API_DOMAIN);
35205
+ }
35194
35206
  if (typeof body !== "string") {
35195
35207
  body = JSON.stringify(body);
35196
35208
  }
@@ -35209,7 +35221,7 @@ async function RBLXPost(url, auth, body, attempt = 0, method = "POST") {
35209
35221
  try {
35210
35222
  fetch(url, {
35211
35223
  method,
35212
- credentials: "include",
35224
+ credentials: FLAGS.INCLUDE_REQUEST_CREDENTIALS_OVERRIDE,
35213
35225
  headers: fetchHeaders,
35214
35226
  body
35215
35227
  }).then((response) => {
@@ -35237,6 +35249,9 @@ async function RBLXPost(url, auth, body, attempt = 0, method = "POST") {
35237
35249
  });
35238
35250
  }
35239
35251
  async function RBLXGet(url, headers, includeCredentials = true) {
35252
+ if (url.match(/https?:\/\/[a-z]+.roblox.com/)) {
35253
+ url = url.replace("roblox.com", FLAGS.API_DOMAIN);
35254
+ }
35240
35255
  return new Promise((resolve) => {
35241
35256
  let newHeaders = {
35242
35257
  "Content-Type": "application/json"
@@ -35250,7 +35265,7 @@ async function RBLXGet(url, headers, includeCredentials = true) {
35250
35265
  const fetchHeaders = new Headers(newHeaders);
35251
35266
  try {
35252
35267
  fetch(url, {
35253
- credentials: includeCredentials ? "include" : void 0,
35268
+ credentials: includeCredentials ? FLAGS.INCLUDE_REQUEST_CREDENTIALS_OVERRIDE : void 0,
35254
35269
  headers: fetchHeaders,
35255
35270
  priority: FLAGS.ASSET_REQUEST_PRIORITY
35256
35271
  }).then((response) => {
@@ -36432,6 +36447,16 @@ class RBFDeformerPatch {
36432
36447
  // avoid matrix from being singular
36433
36448
  affectBones = true;
36434
36449
  id = rbfDeformerIdCount++;
36450
+ /**
36451
+ * Creates the deformer and prepares for deformation
36452
+ * @param refMesh The reference cage
36453
+ * @param distMesh The destination cage
36454
+ * @param mesh The mesh to deform
36455
+ * @param ignoredIndices Indices in the reference cage to ignore
36456
+ * @param patchCount Amount of patches spread around the mesh, each one solves a linear equation
36457
+ * @param detailsCount Amount of close vertices in each patch
36458
+ * @param importantsCount Amount of far away vertices in each patch
36459
+ */
36435
36460
  constructor(refMesh, distMesh, mesh, ignoredIndices = [], patchCount = FLAGS.RBF_PATCH_COUNT, detailsCount = FLAGS.RBF_PATCH_DETAIL_SAMPLES, importantsCount = FLAGS.RBF_PATCH_SHAPE_SAMPLES) {
36436
36461
  time(`RBFDeformerPatch.constructor.${this.id}`);
36437
36462
  this.mesh = mesh;
@@ -36481,6 +36506,10 @@ class RBFDeformerPatch {
36481
36506
  this.patchCount = patchCount;
36482
36507
  timeEnd(`RBFDeformerPatch.constructor.${this.id}`);
36483
36508
  }
36509
+ /**
36510
+ * Solves the linear equations asynchronously, required before deformation
36511
+ * @returns void
36512
+ */
36484
36513
  async solveAsync() {
36485
36514
  if (this.refVerts.length === 0) {
36486
36515
  return;
@@ -36506,6 +36535,12 @@ class RBFDeformerPatch {
36506
36535
  this.nearestPatch = new Uint16Array(nearestPatchBuf);
36507
36536
  timeEnd(`RBFDeformerPatch.solveAsync.unpack.${this.id}`);
36508
36537
  }
36538
+ /**
36539
+ * solveAsync() needs to be called before this
36540
+ * Deforms the position of something inside the mesh
36541
+ * @param i The index of the vert to deform, if it is outside the range of vertices it will be a bone instead. For example vertices range from 1 - 100, and bones range from 101 - 110. Then index 101 will represent the first bone
36542
+ * @returns New position after deformation
36543
+ */
36509
36544
  deform(i) {
36510
36545
  if (!this.nearestPatch || !this.neighborIndices || !this.weights) {
36511
36546
  throw new Error("RBF has not been solved");
@@ -36529,6 +36564,10 @@ class RBFDeformerPatch {
36529
36564
  }
36530
36565
  return add(vec, [dx, dy, dz]);
36531
36566
  }
36567
+ /**
36568
+ * solveAsync() needs to be called before this
36569
+ * Deforms vertices and bones in mesh (if this.affectBones = true)
36570
+ */
36532
36571
  deformMesh() {
36533
36572
  if (this.refVerts.length === 0) {
36534
36573
  return;
@@ -47001,6 +47040,11 @@ class AnimatorWrapper extends InstanceWrapper {
47001
47040
  this._switchToolAnimation(this.data.currentToolAnimation);
47002
47041
  }
47003
47042
  }
47043
+ /**
47044
+ * Resets all joints in the rig to be in their rest pose
47045
+ * @param includeMotors If motors (body movement joints) should be set to rest pose
47046
+ * @param includeFACS If FACS (face movement bones) should be set to rest pose
47047
+ */
47004
47048
  restPose(includeMotors = true, includeFACS = true) {
47005
47049
  const rig = this.instance.parent?.parent;
47006
47050
  if (!rig) {
@@ -47020,6 +47064,12 @@ class AnimatorWrapper extends InstanceWrapper {
47020
47064
  }
47021
47065
  }
47022
47066
  }
47067
+ /**
47068
+ * Renders animation pose
47069
+ * @param addTime Time to add to the current time
47070
+ * @param forceTime Time to force animation to be at, -1 is in the middle of the animation
47071
+ * @param forceKeyframe Keyframe to force animation to be at
47072
+ */
47023
47073
  renderAnimation(addTime = 1 / 60, forceTime, forceKeyframe) {
47024
47074
  const humanoid = this.instance.parent;
47025
47075
  if (!humanoid) {
@@ -47092,11 +47142,22 @@ class AnimatorWrapper extends InstanceWrapper {
47092
47142
  }
47093
47143
  }
47094
47144
  }
47145
+ /**
47146
+ *
47147
+ * @returns Currently playing animation track
47148
+ */
47095
47149
  getCurrentAnimationTrack() {
47096
47150
  if (this.data.currentAnimationTrack) {
47097
47151
  return this.data.currentAnimationTrack;
47098
47152
  }
47099
47153
  }
47154
+ /**
47155
+ * Loads a new animation
47156
+ * @param id
47157
+ * @param isEmote
47158
+ * @param forceLoop Forces animation track to loop
47159
+ * @returns undefined on success
47160
+ */
47100
47161
  async loadAvatarAnimation(id, isEmote = false, forceLoop = false) {
47101
47162
  const humanoid = this.instance.parent;
47102
47163
  if (!humanoid) {
@@ -47207,6 +47268,12 @@ class AnimatorWrapper extends InstanceWrapper {
47207
47268
  }
47208
47269
  }
47209
47270
  }
47271
+ /**
47272
+ * Switches to new animation
47273
+ * @param name Animation name, such as "idle", "walk" or "emote.1234"
47274
+ * @param type
47275
+ * @returns If animation sucessfully played
47276
+ */
47210
47277
  playAnimation(name, type = "main") {
47211
47278
  const humanoid = this.instance.parent;
47212
47279
  if (!humanoid) {
@@ -49280,6 +49347,7 @@ class RBXRendererScene {
49280
49347
  this.viewport = [0, 0, 0, 0];
49281
49348
  this.scissor = [0, 0, 0, 0];
49282
49349
  }
49350
+ /** Destroys all renderDescs but does not call Destroy on instances */
49283
49351
  destroy() {
49284
49352
  if (this.destroyed) return;
49285
49353
  this.destroyed = true;
@@ -49296,6 +49364,12 @@ class RBXRendererScene {
49296
49364
  this.shadowPlane = void 0;
49297
49365
  }
49298
49366
  }
49367
+ /**
49368
+ * Exports scene as a GLTF or GLB
49369
+ * @param name Name of the resulting file if autoDownload is true
49370
+ * @param autoDownload If resulting file should be auto downloaded
49371
+ * @returns The GLB (buffer) or GLTF (object)
49372
+ */
49299
49373
  async exportGLTF(name = "scene", autoDownload = true) {
49300
49374
  return new Promise((resolve, reject) => {
49301
49375
  const exporter = new GLTFExporter();
@@ -49905,6 +49979,9 @@ class RBXRenderer {
49905
49979
  static getRendererControls() {
49906
49980
  return RBXRenderer.controls;
49907
49981
  }
49982
+ /**
49983
+ * @returns ThreeJS renderer
49984
+ */
49908
49985
  static getRenderer() {
49909
49986
  return RBXRenderer.renderer;
49910
49987
  }
@@ -49912,7 +49989,8 @@ class RBXRenderer {
49912
49989
  static getScene() {
49913
49990
  return RBXRenderer.scene;
49914
49991
  }
49915
- /**@deprecated
49992
+ /**
49993
+ * @deprecated Superseded by RBXRendererScene.exportGLTF()
49916
49994
  * This function is unstable and can throw errors, but might work
49917
49995
  */
49918
49996
  static exportScene(renderScene = RBXRenderer.firstScene) {
@@ -50208,6 +50286,7 @@ class OutfitRenderer {
50208
50286
  currentlyChangingRig = false;
50209
50287
  currentlyUpdating = false;
50210
50288
  hasNewUpdate = false;
50289
+ _queuedMainAnimation;
50211
50290
  lastFrameTime = Date.now() / 100;
50212
50291
  animationInterval;
50213
50292
  animationFPS = 60;
@@ -50274,6 +50353,10 @@ class OutfitRenderer {
50274
50353
  const humanoid = this.currentRig.FindFirstChildOfClass("Humanoid");
50275
50354
  if (humanoid) {
50276
50355
  hrpWrapper.applyDescription(humanoid).then((result) => {
50356
+ if (this._queuedMainAnimation) {
50357
+ this.setMainAnimation(this._queuedMainAnimation);
50358
+ this._queuedMainAnimation = void 0;
50359
+ }
50277
50360
  this.currentlyUpdating = false;
50278
50361
  if (this.currentRig) {
50279
50362
  RBXRenderer.addInstance(this.currentRig, this.auth, this.renderScene);
@@ -50380,6 +50463,8 @@ class OutfitRenderer {
50380
50463
  }
50381
50464
  }
50382
50465
  }
50466
+ } else {
50467
+ this._queuedMainAnimation = name;
50383
50468
  }
50384
50469
  }
50385
50470
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "roavatar-renderer",
3
- "version": "1.4.1",
3
+ "version": "1.4.3",
4
4
  "description": "A renderer for Roblox avatars, used by the RoAvatar extension.",
5
5
  "author": "steinan",
6
6
  "type": "module",