roavatar-renderer 1.6.2 → 1.6.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
@@ -695,9 +695,11 @@ export declare class BackgroundRenderer {
695
695
  hasNewUpdate: boolean;
696
696
  affectSceneAppearance: boolean;
697
697
  cameraAffectsTransparency: boolean;
698
+ cameraAffectsRotation: boolean;
698
699
  lastFrameTime: number;
699
700
  animationInterval?: NodeJS.Timeout;
700
701
  animationFPS: number;
702
+ originalPartCFrames: Map<Instance, CFrame>;
701
703
  renderScene: RBXRendererScene;
702
704
  private _renderSceneCompiledConnection?;
703
705
  private _renderSceneFailedConnection?;
@@ -733,6 +735,7 @@ export declare class BackgroundRenderer {
733
735
  _loadBackgroundData(): Promise<void>;
734
736
  _loadAvatarCyclorama(): Promise<void>;
735
737
  _applyBackgroundData(): void;
738
+ _applyBackgroundRotation(): void;
736
739
  /**
737
740
  * Starts updating the animation of the background per frame
738
741
  */
@@ -3671,6 +3674,12 @@ declare class RenderDesc extends DisposableDesc {
3671
3674
 
3672
3675
  export declare function replaceBodyPart(rig: Instance, child: Instance): void;
3673
3676
 
3677
+ /**@category DataModelEnum */
3678
+ export declare const ResamplerMode: {
3679
+ Default: number;
3680
+ Pixelated: number;
3681
+ };
3682
+
3674
3683
  export declare function rgbToHex(r: number, g: number, b: number): string;
3675
3684
 
3676
3685
  export declare type RigData = {
package/dist/index.js CHANGED
@@ -30279,6 +30279,10 @@ class RBXSimpleView {
30279
30279
  }
30280
30280
  const magic = "<roblox!";
30281
30281
  const xmlMagic = "<roblox ";
30282
+ const ResamplerMode = {
30283
+ "Default": 0,
30284
+ "Pixelated": 1
30285
+ };
30282
30286
  const CameraType = {
30283
30287
  "Fixed": 0,
30284
30288
  "Attach": 1,
@@ -33167,9 +33171,7 @@ class CFrame {
33167
33171
  this.Position = [x, y, z];
33168
33172
  }
33169
33173
  static Angles(x, y, z) {
33170
- const cf = new CFrame();
33171
- cf.Orientation = [x, y, z];
33172
- return cf;
33174
+ return CFrame.fromEulerAngles(x, y, z, "XYZ");
33173
33175
  }
33174
33176
  clone() {
33175
33177
  const cloneCF = new CFrame(this.Position[0], this.Position[1], this.Position[2]);
@@ -38944,6 +38946,7 @@ function createContentMap() {
38944
38946
  ContentMap.set("roavatar://AvatarCyclorama.rbxm", "79116945688799");
38945
38947
  }
38946
38948
  let CachedRoAvatarData = void 0;
38949
+ const thumbnailTypesWithBackground = ["Outfit", "Avatar", "AvatarHeadshot"];
38947
38950
  let ThumbnailsToBatch = [];
38948
38951
  const API = {
38949
38952
  "Misc": {
@@ -39492,7 +39495,7 @@ const API = {
39492
39495
  try {
39493
39496
  await mesh.fromBuffer(buffer2);
39494
39497
  if (FLAGS.ENABLE_API_CACHE && FLAGS.ENABLE_API_MESH_CACHE) {
39495
- CACHE.Mesh.set(cacheStr, mesh.clone());
39498
+ CACHE.Mesh.set(cacheStr, readOnly ? mesh : mesh.clone());
39496
39499
  }
39497
39500
  return mesh;
39498
39501
  } catch {
@@ -39717,7 +39720,7 @@ const API = {
39717
39720
  id,
39718
39721
  size,
39719
39722
  headShape,
39720
- includeBackground: type === "Outfit"
39723
+ includeBackground: thumbnailTypesWithBackground.includes(type)
39721
39724
  };
39722
39725
  const cachedThumbnail = CACHE.Thumbnails.get(requestIdFromThumbnailInfo(thisThumbnailInfo));
39723
39726
  if (CACHE.Thumbnails.has(requestIdFromThumbnailInfo(thisThumbnailInfo))) {
@@ -39742,7 +39745,7 @@ const API = {
39742
39745
  attempt: 0,
39743
39746
  lastTryTimestamp: 0,
39744
39747
  headShape,
39745
- includeBackground: type === "Outfit"
39748
+ includeBackground: thumbnailTypesWithBackground.includes(type)
39746
39749
  });
39747
39750
  });
39748
39751
  },
@@ -39752,7 +39755,7 @@ const API = {
39752
39755
  id,
39753
39756
  size,
39754
39757
  headShape,
39755
- includeBackground: type === "Outfit"
39758
+ includeBackground: thumbnailTypesWithBackground.includes(type)
39756
39759
  };
39757
39760
  CACHE.Thumbnails.delete(requestIdFromThumbnailInfo(thisThumbnailInfo));
39758
39761
  },
@@ -46469,6 +46472,7 @@ class MaterialDesc {
46469
46472
  transparency = 0;
46470
46473
  doubleSided = false;
46471
46474
  visible = true;
46475
+ resampleMode = ResamplerMode.Default;
46472
46476
  emissiveStrength = 1;
46473
46477
  emissiveTint = new Color3(1, 1, 1);
46474
46478
  bodyPart;
@@ -46481,7 +46485,7 @@ class MaterialDesc {
46481
46485
  result;
46482
46486
  isSame(other) {
46483
46487
  if (this.dirty || other.dirty) return false;
46484
- const propertiesSame = this.isDecal === other.isDecal && this.transparent === other.transparent && Math.round(this.transparency * 100) === Math.round(other.transparency * 100) && this.doubleSided === other.doubleSided && this.visible === other.visible && this.canHaveMipmaps === other.canHaveMipmaps;
46488
+ const propertiesSame = this.isDecal === other.isDecal && this.transparent === other.transparent && Math.round(this.transparency * 100) === Math.round(other.transparency * 100) && this.doubleSided === other.doubleSided && this.visible === other.visible && this.canHaveMipmaps === other.canHaveMipmaps && this.resampleMode === other.resampleMode;
46485
46489
  let layersSame = true;
46486
46490
  if (this.layers.length !== other.layers.length) {
46487
46491
  layersSame = false;
@@ -46496,7 +46500,7 @@ class MaterialDesc {
46496
46500
  }
46497
46501
  needsRegeneration(other) {
46498
46502
  if (this.dirty || other.dirty) return true;
46499
- const propertiesSame = this.isDecal === other.isDecal && this.doubleSided === other.doubleSided && this.visible === other.visible && this.canHaveMipmaps === other.canHaveMipmaps;
46503
+ const propertiesSame = this.isDecal === other.isDecal && this.doubleSided === other.doubleSided && this.visible === other.visible && this.canHaveMipmaps === other.canHaveMipmaps && this.resampleMode === other.resampleMode;
46500
46504
  let layersSame = true;
46501
46505
  if (this.layers.length !== other.layers.length) {
46502
46506
  layersSame = false;
@@ -46795,6 +46799,7 @@ class MaterialDesc {
46795
46799
  if (texture !== lineartexture) {
46796
46800
  lineartexture.dispose();
46797
46801
  }
46802
+ texture.magFilter = this.resampleMode === ResamplerMode.Default ? LinearFilter : NearestFilter;
46798
46803
  let hasTransparency = false;
46799
46804
  const rbxRenderer = RBXRenderer.getRenderer();
46800
46805
  if (!hasColorLayer && rbxRenderer || FLAGS.RENDERTARGET_TO_CANVASTEXTURE && rbxRenderer) {
@@ -46815,6 +46820,7 @@ class MaterialDesc {
46815
46820
  texture.minFilter = ogTexture.minFilter;
46816
46821
  texture.magFilter = ogTexture.magFilter;
46817
46822
  texture.generateMipmaps = ogTexture.generateMipmaps;
46823
+ ogTexture.dispose();
46818
46824
  }
46819
46825
  }
46820
46826
  if (!this.transparent) {
@@ -46880,6 +46886,7 @@ class MaterialDesc {
46880
46886
  } else {
46881
46887
  hasTransparency = false;
46882
46888
  }
46889
+ texture.magFilter = this.resampleMode === ResamplerMode.Default ? LinearFilter : NearestFilter;
46883
46890
  texture.needsUpdate = true;
46884
46891
  return [texture, hasTransparency];
46885
46892
  }
@@ -46904,6 +46911,7 @@ class MaterialDesc {
46904
46911
  texture.wrapT = RepeatWrapping;
46905
46912
  texture.colorSpace = textureType === "color" ? SRGBColorSpace : NoColorSpace;
46906
46913
  texture.generateMipmaps = this.canHaveMipmaps;
46914
+ texture.magFilter = this.resampleMode === ResamplerMode.Default ? LinearFilter : NearestFilter;
46907
46915
  texture.needsUpdate = true;
46908
46916
  return [texture, hasTransparency];
46909
46917
  }
@@ -47294,6 +47302,7 @@ class MaterialDesc {
47294
47302
  if (surfaceAppearance.Prop("AlphaMode") === AlphaMode.Transparency) {
47295
47303
  this.transparent = true;
47296
47304
  }
47305
+ this.resampleMode = surfaceAppearance.PropOrDefault("ResampleMode", this.resampleMode);
47297
47306
  affectedByHumanoid = false;
47298
47307
  }
47299
47308
  if (affectedByHumanoid && child.parent && !surfaceAppearance) {
@@ -57786,7 +57795,11 @@ class RBXRenderer {
57786
57795
  directionalLight.shadow.camera.bottom = -shadowPhysicalSize + bottomOffset;
57787
57796
  directionalLight.shadow.camera.near = 0.5;
57788
57797
  directionalLight.shadow.camera.far = 25;
57789
- directionalLight.shadow.intensity = 0.5;
57798
+ if (lightingType === "WellLit") directionalLight.shadow.intensity = 0.5;
57799
+ if (lightingType === "Thumbnail") {
57800
+ directionalLight.shadow.radius = 4;
57801
+ directionalLight.shadow.bias = 5e-4;
57802
+ }
57790
57803
  directionalLight.target.position.set(0, 0, 0);
57791
57804
  renderScene.scene.add(directionalLight);
57792
57805
  renderScene.directionalLight = directionalLight;
@@ -58803,9 +58816,11 @@ class BackgroundRenderer {
58803
58816
  hasNewUpdate = false;
58804
58817
  affectSceneAppearance = true;
58805
58818
  cameraAffectsTransparency = true;
58819
+ cameraAffectsRotation = false;
58806
58820
  lastFrameTime = Date.now() / 1e3;
58807
58821
  animationInterval;
58808
58822
  animationFPS = 60;
58823
+ originalPartCFrames = /* @__PURE__ */ new Map();
58809
58824
  renderScene = RBXRenderer.firstScene;
58810
58825
  _renderSceneCompiledConnection;
58811
58826
  _renderSceneFailedConnection;
@@ -58894,6 +58909,12 @@ class BackgroundRenderer {
58894
58909
  const root = rbx.generateTree();
58895
58910
  this.avatarCyclorama = root.GetChildren()[0];
58896
58911
  this.avatarCyclorama.setParent(null);
58912
+ for (const child of this.avatarCyclorama.GetChildren()) {
58913
+ if (child.IsA("BasePart")) {
58914
+ const childCF = child.Prop("CFrame");
58915
+ this.originalPartCFrames.set(child, childCF);
58916
+ }
58917
+ }
58897
58918
  root.Destroy();
58898
58919
  } else {
58899
58920
  this.onError.Fire("avatarCyclorama");
@@ -58935,6 +58956,25 @@ class BackgroundRenderer {
58935
58956
  }
58936
58957
  this.fireFullyRenderedIfNeeded();
58937
58958
  }
58959
+ _applyBackgroundRotation() {
58960
+ if (this.avatarCyclorama && this.cameraAffectsRotation) {
58961
+ const cameraCF = RBXRenderer.getCameraCFrame(this.renderScene);
58962
+ const cameraLook = cameraCF.lookVector();
58963
+ cameraLook[0] = -cameraLook[0];
58964
+ cameraLook[1] = 0;
58965
+ cameraLook[2] = -cameraLook[2];
58966
+ const cameraAngle = CFrame.lookAt([0, 0, 0], cameraLook);
58967
+ for (const child of this.avatarCyclorama.GetChildren()) {
58968
+ if (child.IsA("BasePart")) {
58969
+ const ogChildCF = this.originalPartCFrames.get(child);
58970
+ if (ogChildCF) {
58971
+ const newChildCF = cameraAngle.multiply(ogChildCF);
58972
+ child.setProperty("CFrame", newChildCF);
58973
+ }
58974
+ }
58975
+ }
58976
+ }
58977
+ }
58938
58978
  /**
58939
58979
  * Starts updating the animation of the background per frame
58940
58980
  */
@@ -58949,6 +58989,7 @@ class BackgroundRenderer {
58949
58989
  * Updates the animation once
58950
58990
  */
58951
58991
  animateOnce() {
58992
+ this._applyBackgroundRotation();
58952
58993
  this._applyBackgroundData();
58953
58994
  }
58954
58995
  /**
@@ -59334,6 +59375,7 @@ class OutfitRenderer {
59334
59375
  this.doAddInstance = false;
59335
59376
  this.backgroundRenderer.affectSceneAppearance = false;
59336
59377
  this.backgroundRenderer.cameraAffectsTransparency = false;
59378
+ this.backgroundRenderer.cameraAffectsRotation = true;
59337
59379
  if (this.outfit.playerAvatarType === AvatarType.R6) this.deltaTimeMultiplier = 0;
59338
59380
  await new Promise((resolve) => {
59339
59381
  this.onSuccess.Connect(() => {
@@ -59509,6 +59551,18 @@ async function generateOutfitThumbnail(auth, outfit, size = [150, 150], type = "
59509
59551
  renderScene.destroy();
59510
59552
  return void 0;
59511
59553
  }
59554
+ if (thumbnailCameraType === "default" && outfitRenderer.backgroundRenderer.backgroundId) {
59555
+ thumbnailCameraType = "avatarFullbody";
59556
+ }
59557
+ if (outfitRenderer.backgroundRenderer.backgroundId) {
59558
+ renderScene.directionalLight.castShadow = true;
59559
+ renderScene.directionalLight.position.set(...renderScene.directionalLight.position.toArray().map((v, i) => {
59560
+ return i === 2 ? -v : v;
59561
+ }));
59562
+ renderScene.directionalLight2.position.set(...renderScene.directionalLight2.position.toArray().map((v, i) => {
59563
+ return i === 2 ? -v : v;
59564
+ }));
59565
+ }
59512
59566
  if (outfitRenderer.currentRig) {
59513
59567
  let cameraCFrame = new CFrame();
59514
59568
  switch (thumbnailCameraType) {
@@ -59516,10 +59570,10 @@ async function generateOutfitThumbnail(auth, outfit, size = [150, 150], type = "
59516
59570
  cameraCFrame = getThumbnailCameraCFrame(outfitRenderer.currentRig, renderScene.camera.fov) || cameraCFrame;
59517
59571
  break;
59518
59572
  case "avatarHeadshot":
59519
- cameraCFrame = getCameraCFrameForHeadshotCustomized(outfitRenderer.currentRig, 28, 0, 1) || cameraCFrame;
59573
+ cameraCFrame = getCameraCFrameForHeadshotCustomized(outfitRenderer.currentRig, 30, 0, 1) || cameraCFrame;
59520
59574
  break;
59521
59575
  case "avatarFullbody":
59522
- cameraCFrame = getCameraCFrameForAvatarCustomized(outfitRenderer.currentRig, 28, 0) || cameraCFrame;
59576
+ cameraCFrame = getCameraCFrameForAvatarCustomized(outfitRenderer.currentRig, 30, 0) || cameraCFrame;
59523
59577
  break;
59524
59578
  case "fullbody":
59525
59579
  cameraCFrame = getFullBodyCameraCFrame(outfitRenderer.currentRig) || cameraCFrame;
@@ -59527,10 +59581,11 @@ async function generateOutfitThumbnail(auth, outfit, size = [150, 150], type = "
59527
59581
  }
59528
59582
  if (cameraCFrame) {
59529
59583
  RBXRenderer.setCameraCFrame(cameraCFrame, renderScene);
59530
- RBXRenderer.setCameraFov(thumbnailCameraType === "default" ? 70 : thumbnailCameraType === "fullbody" ? 56 : 28, renderScene);
59584
+ RBXRenderer.setCameraFov(thumbnailCameraType === "default" ? 70 : thumbnailCameraType === "fullbody" ? 56 : 30, renderScene);
59531
59585
  renderScene.camera.updateProjectionMatrix();
59532
59586
  }
59533
59587
  outfitRenderer.updateParticleMatrix();
59588
+ outfitRenderer.backgroundRenderer.animateOnce();
59534
59589
  const result = type === "gltf" || type === "glb" ? await modelThumbnailClick(renderScene, type, {
59535
59590
  includeAnimations
59536
59591
  }) : await imageThumbnailClick(renderScene, size[0], size[1], type, {
@@ -59779,6 +59834,7 @@ export {
59779
59834
  Ray3 as Ray,
59780
59835
  RegisterWrappers,
59781
59836
  RegularBodyColors,
59837
+ ResamplerMode,
59782
59838
  RoAvatarData,
59783
59839
  RoAvatarDataError,
59784
59840
  RoAvatarVersions,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "roavatar-renderer",
3
- "version": "1.6.2",
3
+ "version": "1.6.3",
4
4
  "description": "A renderer for Roblox avatars, used by the RoAvatar extension.",
5
5
  "author": "steinan",
6
6
  "type": "module",