roavatar-renderer 1.4.1 → 1.4.2

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