roavatar-renderer 1.9.9 → 1.9.10
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 +123 -7
- package/dist/index.js +575 -230
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -33687,7 +33687,13 @@ class Instance {
|
|
|
33687
33687
|
}
|
|
33688
33688
|
return lastChild;
|
|
33689
33689
|
}
|
|
33690
|
+
/**
|
|
33691
|
+
* IMPORTANT: Only works properly for instances with an InstanceWrapper
|
|
33692
|
+
* @param className
|
|
33693
|
+
* @returns
|
|
33694
|
+
*/
|
|
33690
33695
|
IsA(className) {
|
|
33696
|
+
if (this.className === className) return true;
|
|
33691
33697
|
const wrapper = this.w;
|
|
33692
33698
|
if (wrapper) {
|
|
33693
33699
|
return wrapper.IsA(className);
|
|
@@ -36722,7 +36728,7 @@ class LocalOutfit {
|
|
|
36722
36728
|
this.name = outfit.name;
|
|
36723
36729
|
this.id = outfit.id;
|
|
36724
36730
|
this.creator = outfit.creatorId;
|
|
36725
|
-
this.date = Date.now();
|
|
36731
|
+
this.date = outfit.creationDate || Date.now();
|
|
36726
36732
|
this.buffer = arrayBufferToBase64(outfit.toBuffer());
|
|
36727
36733
|
}
|
|
36728
36734
|
toJson() {
|
|
@@ -36740,6 +36746,7 @@ class LocalOutfit {
|
|
|
36740
36746
|
this.name = data.name;
|
|
36741
36747
|
this.id = data.id;
|
|
36742
36748
|
this.creator = data.creator;
|
|
36749
|
+
this.date = data.date;
|
|
36743
36750
|
this.image = data.image;
|
|
36744
36751
|
this.buffer = data.buffer;
|
|
36745
36752
|
this.bg = data.bg || 0;
|
|
@@ -36759,6 +36766,7 @@ class LocalOutfit {
|
|
|
36759
36766
|
outfit.name = this.name;
|
|
36760
36767
|
outfit.id = this.id;
|
|
36761
36768
|
outfit.creatorId = this.creator;
|
|
36769
|
+
outfit.creationDate = this.date;
|
|
36762
36770
|
await outfit.fromBuffer(base64ToArrayBuffer(this.buffer), auth);
|
|
36763
36771
|
return outfit;
|
|
36764
36772
|
}
|
|
@@ -36768,6 +36776,7 @@ class LocalOutfit {
|
|
|
36768
36776
|
outfit.name = this.name;
|
|
36769
36777
|
outfit.id = this.id;
|
|
36770
36778
|
outfit.creatorId = this.creator;
|
|
36779
|
+
outfit.creationDate = this.date;
|
|
36771
36780
|
await outfit.fromBuffer(base64ToArrayBuffer(this.buffer), auth);
|
|
36772
36781
|
if (this.bg) {
|
|
36773
36782
|
await outfit.addAssetId(this.bg, auth);
|
|
@@ -36817,9 +36826,7 @@ const AllAccessorySorts = [
|
|
|
36817
36826
|
new ItemSort(46),
|
|
36818
36827
|
new ItemSort(47)
|
|
36819
36828
|
];
|
|
36820
|
-
|
|
36821
|
-
AllAccessorySorts.push(new ItemSort(41));
|
|
36822
|
-
}
|
|
36829
|
+
AllAccessorySorts.push(new ItemSort(41));
|
|
36823
36830
|
const AllClothingSorts = [
|
|
36824
36831
|
new ItemSort(12),
|
|
36825
36832
|
new ItemSort(11),
|
|
@@ -36843,9 +36850,7 @@ const AllBodyPartsSorts = [
|
|
|
36843
36850
|
new ItemSort(31),
|
|
36844
36851
|
new ItemSort(27)
|
|
36845
36852
|
];
|
|
36846
|
-
|
|
36847
|
-
AllBodyPartsSorts.push(new ItemSort(41));
|
|
36848
|
-
}
|
|
36853
|
+
AllBodyPartsSorts.push(new ItemSort(41));
|
|
36849
36854
|
const AllAnimationSorts = [
|
|
36850
36855
|
new ItemSort(48),
|
|
36851
36856
|
new ItemSort(50),
|
|
@@ -36906,6 +36911,7 @@ const CategoryDictionary = {
|
|
|
36906
36911
|
"Dynamic Heads": new SortInfo([new ItemSort(2, "Outfit")]),
|
|
36907
36912
|
"Adjustment": new SpecialInfo("HeadAdjustment"),
|
|
36908
36913
|
"|": new SortDivision(),
|
|
36914
|
+
"Hair": new SortInfo([new ItemSort(41)]),
|
|
36909
36915
|
"Heads": new SortInfo([new ItemSort(17)], "inventory"),
|
|
36910
36916
|
"Faces": new SortInfo([new ItemSort(18)], "inventory")
|
|
36911
36917
|
},
|
|
@@ -39386,6 +39392,7 @@ class Cache {
|
|
|
39386
39392
|
map = /* @__PURE__ */ new Map();
|
|
39387
39393
|
lastAccess = /* @__PURE__ */ new Map();
|
|
39388
39394
|
maxEntries;
|
|
39395
|
+
minDeleteLifetime = 5;
|
|
39389
39396
|
onDelete;
|
|
39390
39397
|
constructor(maxEntries = 250) {
|
|
39391
39398
|
this.maxEntries = maxEntries;
|
|
@@ -39399,12 +39406,7 @@ class Cache {
|
|
|
39399
39406
|
set(key, value) {
|
|
39400
39407
|
this.map.set(key, value);
|
|
39401
39408
|
this.lastAccess.set(key, Date.now());
|
|
39402
|
-
|
|
39403
|
-
const toDelete = [...this.lastAccess.entries()].reduce((min, current) => {
|
|
39404
|
-
return current[1] < min[1] ? current : min;
|
|
39405
|
-
});
|
|
39406
|
-
this.delete(toDelete[0]);
|
|
39407
|
-
}
|
|
39409
|
+
this.deleteUntil();
|
|
39408
39410
|
return this;
|
|
39409
39411
|
}
|
|
39410
39412
|
has(key) {
|
|
@@ -39416,11 +39418,28 @@ class Cache {
|
|
|
39416
39418
|
this.lastAccess.delete(key);
|
|
39417
39419
|
return toReturn;
|
|
39418
39420
|
}
|
|
39421
|
+
deleteUntil() {
|
|
39422
|
+
while (this.map.size > this.maxEntries) {
|
|
39423
|
+
if (!this.deleteOne()) break;
|
|
39424
|
+
}
|
|
39425
|
+
}
|
|
39426
|
+
deleteOne() {
|
|
39427
|
+
if (this.map.size > this.maxEntries) {
|
|
39428
|
+
const toDelete = [...this.lastAccess.entries()].reduce((min, current) => {
|
|
39429
|
+
return current[1] < min[1] ? current : min;
|
|
39430
|
+
});
|
|
39431
|
+
if (Date.now() - toDelete[1] >= this.minDeleteLifetime * 1e3) {
|
|
39432
|
+
this.delete(toDelete[0]);
|
|
39433
|
+
return true;
|
|
39434
|
+
}
|
|
39435
|
+
}
|
|
39436
|
+
return false;
|
|
39437
|
+
}
|
|
39419
39438
|
}
|
|
39420
39439
|
const CACHE = {
|
|
39421
|
-
"AssetBuffer": new Cache(
|
|
39440
|
+
"AssetBuffer": new Cache(100),
|
|
39422
39441
|
"RBX": new Cache(100),
|
|
39423
|
-
"Mesh": new Cache(
|
|
39442
|
+
"Mesh": new Cache(100),
|
|
39424
39443
|
"Image": new Cache(100),
|
|
39425
39444
|
"Thumbnails": new Cache(1e3),
|
|
39426
39445
|
"ItemOwned": new Cache(1e3),
|
|
@@ -39429,6 +39448,54 @@ const CACHE = {
|
|
|
39429
39448
|
"ItemDetails": new Cache(1e4),
|
|
39430
39449
|
"UserInfo": void 0
|
|
39431
39450
|
};
|
|
39451
|
+
function setCacheFootprintPreset(preset) {
|
|
39452
|
+
switch (preset) {
|
|
39453
|
+
case "none":
|
|
39454
|
+
CACHE.AssetBuffer.maxEntries = 0;
|
|
39455
|
+
CACHE.RBX.maxEntries = 0;
|
|
39456
|
+
CACHE.Mesh.maxEntries = 0;
|
|
39457
|
+
CACHE.Image.maxEntries = 0;
|
|
39458
|
+
CACHE.Thumbnails.maxEntries = 0;
|
|
39459
|
+
CACHE.ItemOwned.maxEntries = 0;
|
|
39460
|
+
CACHE.IsLayered.maxEntries = 0;
|
|
39461
|
+
CACHE.AvatarInventoryItem.maxEntries = 0;
|
|
39462
|
+
CACHE.ItemDetails.maxEntries = 0;
|
|
39463
|
+
break;
|
|
39464
|
+
case "low":
|
|
39465
|
+
CACHE.AssetBuffer.maxEntries = 10;
|
|
39466
|
+
CACHE.RBX.maxEntries = 10;
|
|
39467
|
+
CACHE.Mesh.maxEntries = 10;
|
|
39468
|
+
CACHE.Image.maxEntries = 10;
|
|
39469
|
+
CACHE.Thumbnails.maxEntries = 500;
|
|
39470
|
+
CACHE.ItemOwned.maxEntries = 500;
|
|
39471
|
+
CACHE.IsLayered.maxEntries = 100;
|
|
39472
|
+
CACHE.AvatarInventoryItem.maxEntries = 500;
|
|
39473
|
+
CACHE.ItemDetails.maxEntries = 5e3;
|
|
39474
|
+
break;
|
|
39475
|
+
case "normal":
|
|
39476
|
+
CACHE.AssetBuffer.maxEntries = 100;
|
|
39477
|
+
CACHE.RBX.maxEntries = 100;
|
|
39478
|
+
CACHE.Mesh.maxEntries = 100;
|
|
39479
|
+
CACHE.Image.maxEntries = 100;
|
|
39480
|
+
CACHE.Thumbnails.maxEntries = 1e3;
|
|
39481
|
+
CACHE.ItemOwned.maxEntries = 1e3;
|
|
39482
|
+
CACHE.IsLayered.maxEntries = 1e3;
|
|
39483
|
+
CACHE.AvatarInventoryItem.maxEntries = 1e3;
|
|
39484
|
+
CACHE.ItemDetails.maxEntries = 1e4;
|
|
39485
|
+
break;
|
|
39486
|
+
case "high":
|
|
39487
|
+
CACHE.AssetBuffer.maxEntries = 250;
|
|
39488
|
+
CACHE.RBX.maxEntries = 250;
|
|
39489
|
+
CACHE.Mesh.maxEntries = 250;
|
|
39490
|
+
CACHE.Image.maxEntries = 250;
|
|
39491
|
+
CACHE.Thumbnails.maxEntries = 1e3;
|
|
39492
|
+
CACHE.ItemOwned.maxEntries = 1e3;
|
|
39493
|
+
CACHE.IsLayered.maxEntries = 1e3;
|
|
39494
|
+
CACHE.AvatarInventoryItem.maxEntries = 1e3;
|
|
39495
|
+
CACHE.ItemDetails.maxEntries = 1e4;
|
|
39496
|
+
break;
|
|
39497
|
+
}
|
|
39498
|
+
}
|
|
39432
39499
|
const ContentMap = /* @__PURE__ */ new Map();
|
|
39433
39500
|
function createContentMap() {
|
|
39434
39501
|
ContentMap.set("rbxasset://fonts/BaseballCap.mesh", "12220916");
|
|
@@ -43854,6 +43921,89 @@ GLTFExporter.Utils = {
|
|
|
43854
43921
|
return dstAttribute;
|
|
43855
43922
|
}
|
|
43856
43923
|
};
|
|
43924
|
+
const managedTextures = /* @__PURE__ */ new Map();
|
|
43925
|
+
async function createTexturePromise(url, params) {
|
|
43926
|
+
const image = await API.Generic.LoadImage(url.replace(".dds", ".png"));
|
|
43927
|
+
if (!image) return void 0;
|
|
43928
|
+
const texture = new Texture(
|
|
43929
|
+
image,
|
|
43930
|
+
void 0,
|
|
43931
|
+
params?.wrapS || ClampToEdgeWrapping,
|
|
43932
|
+
params?.wrapT || ClampToEdgeWrapping,
|
|
43933
|
+
params?.magFilter,
|
|
43934
|
+
params?.minFilter,
|
|
43935
|
+
void 0,
|
|
43936
|
+
void 0,
|
|
43937
|
+
void 0,
|
|
43938
|
+
params?.colorSpace || SRGBColorSpace
|
|
43939
|
+
);
|
|
43940
|
+
if (params?.generateMipmaps !== void 0) texture.generateMipmaps = params?.generateMipmaps;
|
|
43941
|
+
texture.needsUpdate = true;
|
|
43942
|
+
return texture;
|
|
43943
|
+
}
|
|
43944
|
+
function createManagedTexture(url, params) {
|
|
43945
|
+
const textureInfo = {
|
|
43946
|
+
texture: void 0,
|
|
43947
|
+
uses: 1
|
|
43948
|
+
//used by texture promise (internal), so we dont try to dispose when it doesnt even exist yet
|
|
43949
|
+
};
|
|
43950
|
+
textureInfo.texture = new Promise((resolve) => {
|
|
43951
|
+
createTexturePromise(url, params).then((result) => {
|
|
43952
|
+
textureInfo.texture = result;
|
|
43953
|
+
finishManagedTexture(url, params);
|
|
43954
|
+
resolve(result);
|
|
43955
|
+
});
|
|
43956
|
+
});
|
|
43957
|
+
return textureInfo;
|
|
43958
|
+
}
|
|
43959
|
+
function getTextureInfoKey(url, params) {
|
|
43960
|
+
url = url.replace(".dds", ".png");
|
|
43961
|
+
if (params?.colorSpace === "srgb") delete params.colorSpace;
|
|
43962
|
+
if (params?.wrapS === ClampToEdgeWrapping) delete params.wrapS;
|
|
43963
|
+
if (params?.wrapT === ClampToEdgeWrapping) delete params.wrapT;
|
|
43964
|
+
if (params?.magFilter === LinearFilter) delete params.magFilter;
|
|
43965
|
+
if (params?.minFilter === LinearMipmapLinearFilter) delete params.minFilter;
|
|
43966
|
+
if (params && Object.keys(params).length > 0) {
|
|
43967
|
+
return url + JSON.stringify(params);
|
|
43968
|
+
} else {
|
|
43969
|
+
return url;
|
|
43970
|
+
}
|
|
43971
|
+
}
|
|
43972
|
+
async function getManagedTexture(url, params) {
|
|
43973
|
+
const key = getTextureInfoKey(url, params);
|
|
43974
|
+
let managedTextureInfo = managedTextures.get(key);
|
|
43975
|
+
if (!managedTextureInfo) {
|
|
43976
|
+
managedTextureInfo = createManagedTexture(url, params);
|
|
43977
|
+
managedTextures.set(key, managedTextureInfo);
|
|
43978
|
+
}
|
|
43979
|
+
managedTextureInfo.uses += 1;
|
|
43980
|
+
const disposeTimeout = managedTextureInfo.disposeTimeout;
|
|
43981
|
+
if (disposeTimeout) {
|
|
43982
|
+
clearTimeout(disposeTimeout);
|
|
43983
|
+
managedTextureInfo.disposeTimeout = void 0;
|
|
43984
|
+
}
|
|
43985
|
+
return managedTextureInfo.texture;
|
|
43986
|
+
}
|
|
43987
|
+
async function finishManagedTexture(url, params) {
|
|
43988
|
+
const key = getTextureInfoKey(url, params);
|
|
43989
|
+
const managedTextureInfo = managedTextures.get(key);
|
|
43990
|
+
if (managedTextureInfo) {
|
|
43991
|
+
managedTextureInfo.uses -= 1;
|
|
43992
|
+
if (managedTextureInfo.uses <= 0) {
|
|
43993
|
+
if (!managedTextureInfo.disposeTimeout) {
|
|
43994
|
+
const disposeTimeout = setTimeout(() => {
|
|
43995
|
+
if (managedTextureInfo.disposeTimeout !== disposeTimeout || managedTextureInfo.uses > 0) return;
|
|
43996
|
+
const texture = managedTextureInfo.texture;
|
|
43997
|
+
if (texture && texture instanceof Texture || texture === void 0) {
|
|
43998
|
+
managedTextures.delete(key);
|
|
43999
|
+
if (texture) texture.dispose();
|
|
44000
|
+
}
|
|
44001
|
+
}, 5e3);
|
|
44002
|
+
managedTextureInfo.disposeTimeout = disposeTimeout;
|
|
44003
|
+
}
|
|
44004
|
+
}
|
|
44005
|
+
}
|
|
44006
|
+
}
|
|
43857
44007
|
const RenderDescClassTypes = /* @__PURE__ */ new Map();
|
|
43858
44008
|
function getRenderDescForClass(className) {
|
|
43859
44009
|
return RenderDescClassTypes.get(className);
|
|
@@ -43870,22 +44020,9 @@ function setTHREEObjectCF(threeObject, cframe) {
|
|
|
43870
44020
|
threeObject.rotation.y = rad(cframe.Orientation[1]);
|
|
43871
44021
|
threeObject.rotation.z = rad(cframe.Orientation[2]);
|
|
43872
44022
|
}
|
|
43873
|
-
async function getTexture(texture, colorSpace = SRGBColorSpace) {
|
|
43874
|
-
if (texture) {
|
|
43875
|
-
const source = texture.replace(".dds", ".png");
|
|
43876
|
-
const image = await API.Generic.LoadImage(source);
|
|
43877
|
-
if (image) {
|
|
43878
|
-
const texture2 = new Texture(image);
|
|
43879
|
-
texture2.wrapS = ClampToEdgeWrapping;
|
|
43880
|
-
texture2.wrapT = ClampToEdgeWrapping;
|
|
43881
|
-
texture2.colorSpace = colorSpace;
|
|
43882
|
-
texture2.needsUpdate = true;
|
|
43883
|
-
return texture2;
|
|
43884
|
-
}
|
|
43885
|
-
}
|
|
43886
|
-
return void 0;
|
|
43887
|
-
}
|
|
43888
44023
|
class DisposableDesc {
|
|
44024
|
+
toDispose = [];
|
|
44025
|
+
managedTextures = [];
|
|
43889
44026
|
disposeMesh(scene, mesh) {
|
|
43890
44027
|
disposeMesh(scene, mesh);
|
|
43891
44028
|
}
|
|
@@ -43901,6 +44038,22 @@ class DisposableDesc {
|
|
|
43901
44038
|
dispose(_renderer, _scene) {
|
|
43902
44039
|
throw new Error("Virtual method dispose called");
|
|
43903
44040
|
}
|
|
44041
|
+
clearToDispose() {
|
|
44042
|
+
for (const disposeable of this.toDispose) {
|
|
44043
|
+
disposeable.dispose();
|
|
44044
|
+
}
|
|
44045
|
+
this.toDispose = [];
|
|
44046
|
+
for (const managedTexture of this.managedTextures) {
|
|
44047
|
+
finishManagedTexture(managedTexture.url, managedTexture.params);
|
|
44048
|
+
}
|
|
44049
|
+
this.managedTextures = [];
|
|
44050
|
+
}
|
|
44051
|
+
removeFromToDispose(disposable) {
|
|
44052
|
+
const index = this.toDispose.indexOf(disposable);
|
|
44053
|
+
if (index > -1) {
|
|
44054
|
+
this.toDispose.splice(index, 1);
|
|
44055
|
+
}
|
|
44056
|
+
}
|
|
43904
44057
|
}
|
|
43905
44058
|
class RenderDesc extends DisposableDesc {
|
|
43906
44059
|
static classTypes = [];
|
|
@@ -46158,7 +46311,7 @@ async function promiseForMesh(url, readOnly = false) {
|
|
|
46158
46311
|
});
|
|
46159
46312
|
});
|
|
46160
46313
|
}
|
|
46161
|
-
class MeshDesc {
|
|
46314
|
+
class MeshDesc extends DisposableDesc {
|
|
46162
46315
|
//size: Vector3 = new Vector3(1,1,1)
|
|
46163
46316
|
scaleIsRelative = false;
|
|
46164
46317
|
mesh;
|
|
@@ -46186,9 +46339,6 @@ class MeshDesc {
|
|
|
46186
46339
|
fileMesh;
|
|
46187
46340
|
wasAutoSkinned = false;
|
|
46188
46341
|
wasDeformed = false;
|
|
46189
|
-
dispose() {
|
|
46190
|
-
this.instance = void 0;
|
|
46191
|
-
}
|
|
46192
46342
|
isSame(other) {
|
|
46193
46343
|
const singularTrue = (
|
|
46194
46344
|
//this.size.isSame(other.size) &&
|
|
@@ -46535,6 +46685,7 @@ class MeshDesc {
|
|
|
46535
46685
|
if (wrapTextureTransferResult instanceof Response) return wrapTextureTransferResult;
|
|
46536
46686
|
this.fileMesh = mesh;
|
|
46537
46687
|
const geometry = fileMeshToTHREEGeometry(the_ref_mesh || mesh, this.canHaveSkinning, this.forceVertexColor);
|
|
46688
|
+
this.toDispose.push(geometry);
|
|
46538
46689
|
let threeMesh = void 0;
|
|
46539
46690
|
if (geometry.attributes.skinWeight) {
|
|
46540
46691
|
threeMesh = new SkinnedMesh(geometry);
|
|
@@ -46699,6 +46850,11 @@ class MeshDesc {
|
|
|
46699
46850
|
this.wrapTextureTargetOrigin = wrapTarget.Prop("CageOrigin").removeNaN();
|
|
46700
46851
|
}
|
|
46701
46852
|
}
|
|
46853
|
+
dispose(renderer) {
|
|
46854
|
+
this.instance = void 0;
|
|
46855
|
+
this.clearToDispose();
|
|
46856
|
+
this.disposeRenderLists(renderer);
|
|
46857
|
+
}
|
|
46702
46858
|
}
|
|
46703
46859
|
const compositMeshPaths = [
|
|
46704
46860
|
"rbxasset://avatar/compositing/CompositFullAtlasBaseTexture.mesh",
|
|
@@ -47050,67 +47206,6 @@ const Shader_TextureComposer_Gamma = new ShaderMaterial({
|
|
|
47050
47206
|
depthWrite: false,
|
|
47051
47207
|
transparent: true
|
|
47052
47208
|
});
|
|
47053
|
-
const managedTextures = /* @__PURE__ */ new Map();
|
|
47054
|
-
async function createTexturePromise(url, params) {
|
|
47055
|
-
const image = await API.Generic.LoadImage(url);
|
|
47056
|
-
if (!image) return void 0;
|
|
47057
|
-
const texture = new Texture(image, void 0, void 0, void 0, void 0, void 0, void 0, void 0, void 0, params?.colorSpace || "srgb");
|
|
47058
|
-
texture.needsUpdate = true;
|
|
47059
|
-
return texture;
|
|
47060
|
-
}
|
|
47061
|
-
function createManagedTexture(url, params) {
|
|
47062
|
-
const textureInfo = {
|
|
47063
|
-
texture: void 0,
|
|
47064
|
-
uses: 1
|
|
47065
|
-
//used by texture promise (internal), so we dont try to dispose when it doesnt even exist yet
|
|
47066
|
-
};
|
|
47067
|
-
textureInfo.texture = new Promise((resolve) => {
|
|
47068
|
-
createTexturePromise(url, params).then((result) => {
|
|
47069
|
-
textureInfo.texture = result;
|
|
47070
|
-
finishManagedTexture(url, params);
|
|
47071
|
-
resolve(result);
|
|
47072
|
-
});
|
|
47073
|
-
});
|
|
47074
|
-
return textureInfo;
|
|
47075
|
-
}
|
|
47076
|
-
function getTextureInfoKey(url, params) {
|
|
47077
|
-
return url + JSON.stringify(params);
|
|
47078
|
-
}
|
|
47079
|
-
async function getManagedTexture(url, params) {
|
|
47080
|
-
const key = getTextureInfoKey(url, params);
|
|
47081
|
-
let managedTextureInfo = managedTextures.get(key);
|
|
47082
|
-
if (!managedTextureInfo) {
|
|
47083
|
-
managedTextureInfo = createManagedTexture(url, params);
|
|
47084
|
-
managedTextures.set(key, managedTextureInfo);
|
|
47085
|
-
}
|
|
47086
|
-
managedTextureInfo.uses += 1;
|
|
47087
|
-
const disposeTimeout = managedTextureInfo.disposeTimeout;
|
|
47088
|
-
if (disposeTimeout) {
|
|
47089
|
-
clearTimeout(disposeTimeout);
|
|
47090
|
-
managedTextureInfo.disposeTimeout = void 0;
|
|
47091
|
-
}
|
|
47092
|
-
return managedTextureInfo.texture;
|
|
47093
|
-
}
|
|
47094
|
-
async function finishManagedTexture(url, params) {
|
|
47095
|
-
const key = getTextureInfoKey(url, params);
|
|
47096
|
-
const managedTextureInfo = managedTextures.get(key);
|
|
47097
|
-
if (managedTextureInfo) {
|
|
47098
|
-
managedTextureInfo.uses -= 1;
|
|
47099
|
-
if (managedTextureInfo.uses <= 0) {
|
|
47100
|
-
if (!managedTextureInfo.disposeTimeout) {
|
|
47101
|
-
const disposeTimeout = setTimeout(() => {
|
|
47102
|
-
if (managedTextureInfo.disposeTimeout !== disposeTimeout || managedTextureInfo.uses > 0) return;
|
|
47103
|
-
managedTextures.delete(key);
|
|
47104
|
-
const texture = managedTextureInfo.texture;
|
|
47105
|
-
if (texture && texture instanceof Texture) {
|
|
47106
|
-
texture.dispose();
|
|
47107
|
-
}
|
|
47108
|
-
}, 5e3);
|
|
47109
|
-
managedTextureInfo.disposeTimeout = disposeTimeout;
|
|
47110
|
-
}
|
|
47111
|
-
}
|
|
47112
|
-
}
|
|
47113
|
-
}
|
|
47114
47209
|
async function renderBodyPartClothingR15(limbId, texture) {
|
|
47115
47210
|
let instruction;
|
|
47116
47211
|
if (limbId !== BodyPart.Torso) {
|
|
@@ -47249,7 +47344,7 @@ class TextureLayer {
|
|
|
47249
47344
|
return this.uvType === other.uvType && this.face === other.face && this.color === other.color && this.normal === other.normal && this.roughness === other.roughness && this.metalness === other.metalness && this.emissive === other.emissive;
|
|
47250
47345
|
}
|
|
47251
47346
|
}
|
|
47252
|
-
class MaterialDesc {
|
|
47347
|
+
class MaterialDesc extends DisposableDesc {
|
|
47253
47348
|
layers = [];
|
|
47254
47349
|
isDecal = false;
|
|
47255
47350
|
canHaveMipmaps = true;
|
|
@@ -47268,6 +47363,7 @@ class MaterialDesc {
|
|
|
47268
47363
|
createdTextures = [];
|
|
47269
47364
|
noTextureTransparency = false;
|
|
47270
47365
|
result;
|
|
47366
|
+
resultRenderTarget;
|
|
47271
47367
|
isSame(other) {
|
|
47272
47368
|
if (this.dirty || other.dirty) return false;
|
|
47273
47369
|
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;
|
|
@@ -47578,6 +47674,7 @@ class MaterialDesc {
|
|
|
47578
47674
|
}
|
|
47579
47675
|
}
|
|
47580
47676
|
if (composeInsts.length === 0) {
|
|
47677
|
+
this.finishManagedTextures(textureType);
|
|
47581
47678
|
return void 0;
|
|
47582
47679
|
}
|
|
47583
47680
|
TextureComposer.new(width, height, textureType === "color" ? LinearSRGBColorSpace : NoColorSpace, RepeatWrapping, noMipmaps);
|
|
@@ -47586,12 +47683,15 @@ class MaterialDesc {
|
|
|
47586
47683
|
TextureComposer.add(inst);
|
|
47587
47684
|
}
|
|
47588
47685
|
const renderTarget = TextureComposer.render();
|
|
47686
|
+
this.toDispose.push(renderTarget);
|
|
47589
47687
|
this.finishManagedTextures(textureType);
|
|
47688
|
+
const linearRenderTarget = renderTarget;
|
|
47590
47689
|
const lineartexture = renderTarget.texture;
|
|
47591
47690
|
lineartexture.wrapS = RepeatWrapping;
|
|
47592
47691
|
lineartexture.wrapT = RepeatWrapping;
|
|
47593
47692
|
lineartexture.needsUpdate = true;
|
|
47594
47693
|
let texture = lineartexture;
|
|
47694
|
+
let renderTargetFinal = linearRenderTarget;
|
|
47595
47695
|
if (textureType === "color") {
|
|
47596
47696
|
const gammaInst = await TextureComposer.simpleMesh(
|
|
47597
47697
|
"CompositQuad",
|
|
@@ -47605,11 +47705,15 @@ class MaterialDesc {
|
|
|
47605
47705
|
TextureComposer.new(width, height, SRGBColorSpace, RepeatWrapping, noMipmaps);
|
|
47606
47706
|
TextureComposer.cameraSize(camWidth, camHeight);
|
|
47607
47707
|
TextureComposer.add(gammaInst);
|
|
47608
|
-
|
|
47708
|
+
renderTargetFinal = TextureComposer.render();
|
|
47709
|
+
this.toDispose.push(renderTargetFinal);
|
|
47710
|
+
texture = renderTargetFinal.texture;
|
|
47609
47711
|
}
|
|
47610
|
-
if (
|
|
47611
|
-
|
|
47712
|
+
if (linearRenderTarget !== renderTargetFinal) {
|
|
47713
|
+
linearRenderTarget.dispose();
|
|
47714
|
+
this.removeFromToDispose(linearRenderTarget);
|
|
47612
47715
|
}
|
|
47716
|
+
this.resultRenderTarget = renderTargetFinal;
|
|
47613
47717
|
texture.magFilter = this.resampleMode === ResamplerMode.Default ? LinearFilter : NearestFilter;
|
|
47614
47718
|
let hasTransparency = false;
|
|
47615
47719
|
const rbxRenderer = RBXRenderer.getRenderer();
|
|
@@ -47625,6 +47729,7 @@ class MaterialDesc {
|
|
|
47625
47729
|
if (FLAGS.RENDERTARGET_TO_CANVASTEXTURE) {
|
|
47626
47730
|
const ogTexture = texture;
|
|
47627
47731
|
texture = imageDataToCanvasTexture(data, width, height);
|
|
47732
|
+
this.toDispose.push(texture);
|
|
47628
47733
|
texture.colorSpace = textureType === "color" ? SRGBColorSpace : NoColorSpace;
|
|
47629
47734
|
texture.wrapS = ogTexture.wrapS;
|
|
47630
47735
|
texture.wrapT = ogTexture.wrapT;
|
|
@@ -47632,6 +47737,7 @@ class MaterialDesc {
|
|
|
47632
47737
|
texture.magFilter = ogTexture.magFilter;
|
|
47633
47738
|
texture.generateMipmaps = ogTexture.generateMipmaps;
|
|
47634
47739
|
ogTexture.dispose();
|
|
47740
|
+
this.removeFromToDispose(ogTexture);
|
|
47635
47741
|
}
|
|
47636
47742
|
}
|
|
47637
47743
|
if (!this.transparent) {
|
|
@@ -47660,6 +47766,7 @@ class MaterialDesc {
|
|
|
47660
47766
|
throw new Error("Failed to get CanvasContext");
|
|
47661
47767
|
}
|
|
47662
47768
|
const texture = new CanvasTexture(canvas);
|
|
47769
|
+
this.toDispose.push(texture);
|
|
47663
47770
|
texture.colorSpace = textureType === "color" ? SRGBColorSpace : NoColorSpace;
|
|
47664
47771
|
texture.wrapS = RepeatWrapping;
|
|
47665
47772
|
texture.wrapT = RepeatWrapping;
|
|
@@ -47711,21 +47818,21 @@ class MaterialDesc {
|
|
|
47711
47818
|
}
|
|
47712
47819
|
}
|
|
47713
47820
|
if (textureUrl) {
|
|
47714
|
-
|
|
47715
|
-
if (
|
|
47716
|
-
|
|
47717
|
-
|
|
47718
|
-
|
|
47719
|
-
|
|
47720
|
-
|
|
47721
|
-
|
|
47722
|
-
|
|
47723
|
-
|
|
47724
|
-
|
|
47725
|
-
|
|
47726
|
-
|
|
47727
|
-
|
|
47728
|
-
|
|
47821
|
+
let hasTransparency = true;
|
|
47822
|
+
if (!this.transparent) {
|
|
47823
|
+
hasTransparency = false;
|
|
47824
|
+
}
|
|
47825
|
+
const textureParams = {
|
|
47826
|
+
colorSpace: textureType === "color" ? SRGBColorSpace : NoColorSpace,
|
|
47827
|
+
wrapS: RepeatWrapping,
|
|
47828
|
+
wrapT: RepeatWrapping,
|
|
47829
|
+
generateMipmaps: this.canHaveMipmaps,
|
|
47830
|
+
//resampling mode
|
|
47831
|
+
magFilter: this.resampleMode === ResamplerMode.Default ? LinearFilter : NearestFilter
|
|
47832
|
+
};
|
|
47833
|
+
const texture = await getManagedTexture(textureUrl, textureParams);
|
|
47834
|
+
this.managedTextures.push({ url: textureUrl, params: textureParams });
|
|
47835
|
+
return texture ? [texture, hasTransparency] : void 0;
|
|
47729
47836
|
}
|
|
47730
47837
|
}
|
|
47731
47838
|
getComposeType(textureType) {
|
|
@@ -47742,8 +47849,8 @@ class MaterialDesc {
|
|
|
47742
47849
|
}
|
|
47743
47850
|
}
|
|
47744
47851
|
if (layer instanceof ColorLayer) {
|
|
47745
|
-
hasColorLayer = true;
|
|
47746
47852
|
if (layer.textureType === textureType) {
|
|
47853
|
+
hasColorLayer = true;
|
|
47747
47854
|
hasLayerOfType = true;
|
|
47748
47855
|
}
|
|
47749
47856
|
}
|
|
@@ -48178,6 +48285,10 @@ class MaterialDesc {
|
|
|
48178
48285
|
this.addDecals(child.parent, "Normal", true);
|
|
48179
48286
|
}
|
|
48180
48287
|
}
|
|
48288
|
+
dispose() {
|
|
48289
|
+
this.resultRenderTarget = void 0;
|
|
48290
|
+
this.clearToDispose();
|
|
48291
|
+
}
|
|
48181
48292
|
}
|
|
48182
48293
|
class BasePartWrapperData {
|
|
48183
48294
|
assemblyNode;
|
|
@@ -48289,7 +48400,7 @@ function boneIsChildOf(bone, parentName) {
|
|
|
48289
48400
|
}
|
|
48290
48401
|
return false;
|
|
48291
48402
|
}
|
|
48292
|
-
class SkeletonDesc {
|
|
48403
|
+
class SkeletonDesc extends DisposableDesc {
|
|
48293
48404
|
renderableDesc;
|
|
48294
48405
|
meshDesc;
|
|
48295
48406
|
skeleton;
|
|
@@ -48300,6 +48411,7 @@ class SkeletonDesc {
|
|
|
48300
48411
|
skeletonHelper;
|
|
48301
48412
|
frameCount = 0;
|
|
48302
48413
|
constructor(renderableDesc, meshDesc, scene) {
|
|
48414
|
+
super();
|
|
48303
48415
|
this.renderableDesc = renderableDesc;
|
|
48304
48416
|
this.meshDesc = meshDesc;
|
|
48305
48417
|
const mesh = this.meshDesc.fileMesh;
|
|
@@ -48576,14 +48688,14 @@ class SkeletonDesc {
|
|
|
48576
48688
|
this.updateMatrixWorld();
|
|
48577
48689
|
this.frameCount += 1;
|
|
48578
48690
|
}
|
|
48579
|
-
dispose(
|
|
48691
|
+
dispose() {
|
|
48580
48692
|
if (this.skeletonHelper) {
|
|
48581
|
-
|
|
48693
|
+
this.skeletonHelper.removeFromParent();
|
|
48582
48694
|
this.skeletonHelper.dispose();
|
|
48583
48695
|
this.skeletonHelper = void 0;
|
|
48584
48696
|
}
|
|
48585
48697
|
if (this.rootBone.parent) {
|
|
48586
|
-
this.rootBone.
|
|
48698
|
+
this.rootBone.removeFromParent();
|
|
48587
48699
|
}
|
|
48588
48700
|
for (let i = 0; i < this.skeleton.bones.length; i++) {
|
|
48589
48701
|
const bone = this.skeleton.bones[i];
|
|
@@ -48591,6 +48703,7 @@ class SkeletonDesc {
|
|
|
48591
48703
|
bone.removeFromParent();
|
|
48592
48704
|
}
|
|
48593
48705
|
}
|
|
48706
|
+
this.skeleton.dispose();
|
|
48594
48707
|
}
|
|
48595
48708
|
static descNeedsSkeleton(meshDesc) {
|
|
48596
48709
|
return meshDesc.canHaveSkinning && meshDesc.fileMesh && meshDesc.fileMesh.skinning && meshDesc.fileMesh.skinning.numskinnings > 0;
|
|
@@ -48694,32 +48807,10 @@ class ObjectDesc extends RenderDesc {
|
|
|
48694
48807
|
this.meshDesc.fromInstance(child);
|
|
48695
48808
|
this.materialDesc.fromInstance(child);
|
|
48696
48809
|
}
|
|
48697
|
-
|
|
48698
|
-
skeletonDesc.dispose(scene);
|
|
48699
|
-
}
|
|
48700
|
-
//Used to dispose OLD stuff
|
|
48701
|
-
dispose(renderer, scene) {
|
|
48702
|
-
if (this.meshDesc) {
|
|
48703
|
-
this.meshDesc.dispose();
|
|
48704
|
-
}
|
|
48705
|
-
if (this.results) {
|
|
48706
|
-
for (const mesh of this.results) {
|
|
48707
|
-
this.disposeMesh(scene, mesh);
|
|
48708
|
-
}
|
|
48709
|
-
}
|
|
48710
|
-
if (this.skeletonDesc) {
|
|
48711
|
-
this.disposeSkeleton(scene, this.skeletonDesc);
|
|
48712
|
-
}
|
|
48713
|
-
if (this.results) {
|
|
48714
|
-
this.disposeRenderLists(renderer);
|
|
48715
|
-
}
|
|
48716
|
-
}
|
|
48717
|
-
async compileResults(renderer, scene) {
|
|
48810
|
+
async compileResults(_renderer, scene) {
|
|
48718
48811
|
const loadingLabel = this.instance ? this.instance.GetFullName() : "unknown";
|
|
48719
48812
|
API.Misc.startCurrentlyLoadingAssets(loadingLabel);
|
|
48720
48813
|
try {
|
|
48721
|
-
const originalResult = this.results;
|
|
48722
|
-
const originalSkeletonDesc = this.skeletonDesc;
|
|
48723
48814
|
this.results = void 0;
|
|
48724
48815
|
this.skeletonDesc = void 0;
|
|
48725
48816
|
const promises = [
|
|
@@ -48756,15 +48847,6 @@ class ObjectDesc extends RenderDesc {
|
|
|
48756
48847
|
} else {
|
|
48757
48848
|
this.meshDesc.fileMesh = void 0;
|
|
48758
48849
|
}
|
|
48759
|
-
if (originalResult) {
|
|
48760
|
-
this.disposeMeshes(scene, originalResult);
|
|
48761
|
-
}
|
|
48762
|
-
if (originalSkeletonDesc) {
|
|
48763
|
-
this.disposeSkeleton(scene, originalSkeletonDesc);
|
|
48764
|
-
}
|
|
48765
|
-
if (originalResult) {
|
|
48766
|
-
this.disposeRenderLists(renderer);
|
|
48767
|
-
}
|
|
48768
48850
|
} finally {
|
|
48769
48851
|
API.Misc.stopCurrentlyLoadingAssets(loadingLabel);
|
|
48770
48852
|
}
|
|
@@ -48840,6 +48922,17 @@ class ObjectDesc extends RenderDesc {
|
|
|
48840
48922
|
}
|
|
48841
48923
|
return !isBakedDecal && (!isDecal || isFirstDecal);
|
|
48842
48924
|
}
|
|
48925
|
+
//Used to dispose OLD stuff
|
|
48926
|
+
dispose(renderer) {
|
|
48927
|
+
if (this.results) {
|
|
48928
|
+
for (const result of this.results) {
|
|
48929
|
+
result.removeFromParent();
|
|
48930
|
+
}
|
|
48931
|
+
}
|
|
48932
|
+
if (this.meshDesc) this.meshDesc.dispose(renderer);
|
|
48933
|
+
if (this.materialDesc) this.materialDesc.dispose();
|
|
48934
|
+
if (this.skeletonDesc) this.skeletonDesc.dispose();
|
|
48935
|
+
}
|
|
48843
48936
|
}
|
|
48844
48937
|
const __vite_glob_0_4$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
48845
48938
|
__proto__: null,
|
|
@@ -59819,7 +59912,7 @@ const $05f6997e4b65da14$export$ed4ee5d1e55474a5 = {
|
|
|
59819
59912
|
class RBXRendererScene {
|
|
59820
59913
|
//important scene components
|
|
59821
59914
|
scene = new Scene();
|
|
59822
|
-
camera = new PerspectiveCamera(70, 1 / 1, 0.1,
|
|
59915
|
+
camera = new PerspectiveCamera(70, 1 / 1, 0.1, 1e3);
|
|
59823
59916
|
controls;
|
|
59824
59917
|
shouldAnimate = true;
|
|
59825
59918
|
destroyed = false;
|
|
@@ -59967,6 +60060,41 @@ class RBXRendererScene {
|
|
|
59967
60060
|
isFullyCompiled() {
|
|
59968
60061
|
return this.areInstancesCompiled(this.addedInstances);
|
|
59969
60062
|
}
|
|
60063
|
+
/**
|
|
60064
|
+
* @param instances Array of instances you want to wait to be finished compiling
|
|
60065
|
+
* @param timeoutSeconds Default is 30 seconds
|
|
60066
|
+
* @returns true if successful, false if a RenderDesc failed to compile or timed out
|
|
60067
|
+
*/
|
|
60068
|
+
async waitUntilFullyCompiled(instances, timeoutSeconds = 30) {
|
|
60069
|
+
if (this.areInstancesCompiled(instances)) return true;
|
|
60070
|
+
const connections = [];
|
|
60071
|
+
const compiledSuccessfully = await Promise.race([
|
|
60072
|
+
//on fail compilation
|
|
60073
|
+
new Promise((resolve) => {
|
|
60074
|
+
connections.push(this.failedRenderDesc.Connect(() => {
|
|
60075
|
+
resolve(false);
|
|
60076
|
+
}));
|
|
60077
|
+
}),
|
|
60078
|
+
//on success compilation, check if everything is successfull
|
|
60079
|
+
new Promise((resolve) => {
|
|
60080
|
+
connections.push(this.compiledRenderDesc.Connect(() => {
|
|
60081
|
+
if (this.areInstancesCompiled(instances)) {
|
|
60082
|
+
resolve(true);
|
|
60083
|
+
}
|
|
60084
|
+
}));
|
|
60085
|
+
}),
|
|
60086
|
+
//on fail due to timeout
|
|
60087
|
+
new Promise((resolve) => {
|
|
60088
|
+
setTimeout(() => {
|
|
60089
|
+
resolve(false);
|
|
60090
|
+
}, timeoutSeconds * 1e3);
|
|
60091
|
+
})
|
|
60092
|
+
]);
|
|
60093
|
+
for (const connection of connections) {
|
|
60094
|
+
connection.Disconnect();
|
|
60095
|
+
}
|
|
60096
|
+
return compiledSuccessfully;
|
|
60097
|
+
}
|
|
59970
60098
|
/**
|
|
59971
60099
|
* Exports scene as a GLTF or GLB
|
|
59972
60100
|
* @param name Name of the resulting file if autoDownload is true
|
|
@@ -60842,13 +60970,6 @@ class EmitterDesc extends DisposableDesc {
|
|
|
60842
60970
|
this.flipbookSizeY = other.flipbookSizeY;
|
|
60843
60971
|
this.flipbookStartRandom = other.flipbookStartRandom;
|
|
60844
60972
|
}
|
|
60845
|
-
dispose(renderer, scene) {
|
|
60846
|
-
const mesh = this.result;
|
|
60847
|
-
if (mesh) {
|
|
60848
|
-
this.disposeMesh(scene, mesh);
|
|
60849
|
-
this.disposeRenderLists(renderer);
|
|
60850
|
-
}
|
|
60851
|
-
}
|
|
60852
60973
|
getFlipbookSize() {
|
|
60853
60974
|
let flipbookSizeX = this.flipbookSizeX;
|
|
60854
60975
|
let flipbookSizeY = this.flipbookSizeY;
|
|
@@ -60874,27 +60995,33 @@ class EmitterDesc extends DisposableDesc {
|
|
|
60874
60995
|
}
|
|
60875
60996
|
return [flipbookSizeX, flipbookSizeY];
|
|
60876
60997
|
}
|
|
60877
|
-
async compileResult(
|
|
60878
|
-
const originalResult = this.result;
|
|
60998
|
+
async compileResult() {
|
|
60879
60999
|
const texturePromises = [
|
|
60880
|
-
|
|
60881
|
-
|
|
60882
|
-
|
|
61000
|
+
this.texture ? getManagedTexture(this.texture, { colorSpace: SRGBColorSpace }) : void 0,
|
|
61001
|
+
this.alphaTexture ? getManagedTexture(this.alphaTexture, { colorSpace: NoColorSpace }) : void 0,
|
|
61002
|
+
this.colorTexture ? getManagedTexture(this.colorTexture, { colorSpace: SRGBColorSpace }) : void 0
|
|
60883
61003
|
];
|
|
61004
|
+
if (this.texture) this.managedTextures.push({ url: this.texture, params: { colorSpace: SRGBColorSpace } });
|
|
61005
|
+
if (this.alphaTexture) this.managedTextures.push({ url: this.alphaTexture, params: { colorSpace: NoColorSpace } });
|
|
61006
|
+
if (this.colorTexture) this.managedTextures.push({ url: this.colorTexture, params: { colorSpace: SRGBColorSpace } });
|
|
60884
61007
|
let [mapToUse, alphaMapToUse, colorMapToUse] = await Promise.all(texturePromises);
|
|
60885
61008
|
if (!mapToUse) {
|
|
60886
61009
|
mapToUse = new DataTexture(new Uint8Array([0, 0, 0, 0]), 1, 1, RGBAFormat);
|
|
60887
61010
|
mapToUse.needsUpdate = true;
|
|
61011
|
+
this.toDispose.push(mapToUse);
|
|
60888
61012
|
}
|
|
60889
61013
|
if (!alphaMapToUse) {
|
|
60890
61014
|
alphaMapToUse = new DataTexture(new Uint8Array([255, 255, 255, 255]), 1, 1, RGBAFormat);
|
|
60891
61015
|
alphaMapToUse.needsUpdate = true;
|
|
61016
|
+
this.toDispose.push(alphaMapToUse);
|
|
60892
61017
|
}
|
|
60893
61018
|
if (!colorMapToUse) {
|
|
60894
61019
|
colorMapToUse = new DataTexture(new Uint8Array([255, 255, 255, 255]), 1, 1, RGBAFormat);
|
|
60895
61020
|
colorMapToUse.needsUpdate = true;
|
|
61021
|
+
this.toDispose.push(colorMapToUse);
|
|
60896
61022
|
}
|
|
60897
61023
|
const geometry = new PlaneGeometry(2, 2);
|
|
61024
|
+
this.toDispose.push(geometry);
|
|
60898
61025
|
this.instanceColorBuffer = new InstancedBufferAttribute(new Float32Array(this.maxCount * 3), 3);
|
|
60899
61026
|
geometry.setAttribute("instanceColor", this.instanceColorBuffer);
|
|
60900
61027
|
this.instanceOpacityBuffer = new InstancedBufferAttribute(new Float32Array(this.maxCount), 1);
|
|
@@ -60960,14 +61087,12 @@ class EmitterDesc extends DisposableDesc {
|
|
|
60960
61087
|
}
|
|
60961
61088
|
])
|
|
60962
61089
|
});
|
|
61090
|
+
this.toDispose.push(material);
|
|
60963
61091
|
this.resultMaterial = material;
|
|
60964
61092
|
this.result = new InstancedMesh(geometry, material, this.maxCount);
|
|
61093
|
+
this.toDispose.push(this.result);
|
|
60965
61094
|
this.result.name = "Particles";
|
|
60966
61095
|
this.result.frustumCulled = false;
|
|
60967
|
-
if (originalResult) {
|
|
60968
|
-
this.disposeMesh(scene, originalResult);
|
|
60969
|
-
this.disposeRenderLists(renderer);
|
|
60970
|
-
}
|
|
60971
61096
|
return this.result;
|
|
60972
61097
|
}
|
|
60973
61098
|
emit(groupDesc, force = false) {
|
|
@@ -61089,6 +61214,14 @@ class EmitterDesc extends DisposableDesc {
|
|
|
61089
61214
|
this.instanceSeedTimeBuffer.needsUpdate = true;
|
|
61090
61215
|
this.instanceFlipbookBuffer.needsUpdate = true;
|
|
61091
61216
|
}
|
|
61217
|
+
dispose(renderer) {
|
|
61218
|
+
const mesh = this.result;
|
|
61219
|
+
if (mesh) {
|
|
61220
|
+
mesh.removeFromParent();
|
|
61221
|
+
}
|
|
61222
|
+
this.clearToDispose();
|
|
61223
|
+
this.disposeRenderLists(renderer);
|
|
61224
|
+
}
|
|
61092
61225
|
}
|
|
61093
61226
|
class EmitterGroupDesc extends RenderDesc {
|
|
61094
61227
|
static classTypes = ["ParticleEmitter", "Sparkles", "Fire", "Smoke"];
|
|
@@ -61228,7 +61361,7 @@ class EmitterGroupDesc extends RenderDesc {
|
|
|
61228
61361
|
}
|
|
61229
61362
|
}
|
|
61230
61363
|
fromParticleEmitter(child) {
|
|
61231
|
-
this.emitterDir = child.
|
|
61364
|
+
this.emitterDir = child.PropOrDefault("EmissionDirection", this.emitterDir);
|
|
61232
61365
|
const emitterDesc = new EmitterDesc(this.renderScene);
|
|
61233
61366
|
if (child.HasProperty("Lifetime")) emitterDesc.lifetime = child.Prop("Lifetime");
|
|
61234
61367
|
if (child.HasProperty("Rate")) emitterDesc.rate = child.Prop("Rate");
|
|
@@ -61245,7 +61378,7 @@ class EmitterGroupDesc extends RenderDesc {
|
|
|
61245
61378
|
if (child.HasProperty("Color")) emitterDesc.color = child.Prop("Color");
|
|
61246
61379
|
if (child.HasProperty("Texture")) emitterDesc.texture = child.Prop("Texture");
|
|
61247
61380
|
if (child.HasProperty("Transparency")) emitterDesc.transparency = child.Prop("Transparency");
|
|
61248
|
-
|
|
61381
|
+
emitterDesc.lightEmission = specialClamp(child.PropOrDefault("LightEmission", emitterDesc.lightEmission), 0, 1);
|
|
61249
61382
|
emitterDesc.blending = emitterDesc.lightEmission === 0 ? EmitterBlendType.Normal : EmitterBlendType.PremultipliedAdditive;
|
|
61250
61383
|
if (child.HasProperty("LightInfluence")) emitterDesc.lightInfluence = child.Prop("LightInfluence");
|
|
61251
61384
|
if (child.HasProperty("ZOffset")) emitterDesc.zOffset = child.Prop("ZOffset");
|
|
@@ -61381,18 +61514,10 @@ class EmitterGroupDesc extends RenderDesc {
|
|
|
61381
61514
|
shader: EmitterShaderType.Smoke
|
|
61382
61515
|
}));
|
|
61383
61516
|
}
|
|
61384
|
-
dispose(renderer, scene) {
|
|
61385
|
-
const meshes = this.results;
|
|
61386
|
-
if (meshes) {
|
|
61387
|
-
this.disposeMeshes(scene, meshes);
|
|
61388
|
-
this.disposeRenderLists(renderer);
|
|
61389
|
-
}
|
|
61390
|
-
}
|
|
61391
61517
|
async compileResults(renderer, scene) {
|
|
61392
|
-
const originalResults = this.results;
|
|
61393
61518
|
const resultPromises = [];
|
|
61394
61519
|
for (const emitterDesc of this.emitterDescs) {
|
|
61395
|
-
resultPromises.push(emitterDesc.compileResult(
|
|
61520
|
+
resultPromises.push(emitterDesc.compileResult());
|
|
61396
61521
|
}
|
|
61397
61522
|
this.results = [];
|
|
61398
61523
|
const compiledResults = await Promise.all(resultPromises);
|
|
@@ -61405,10 +61530,6 @@ class EmitterGroupDesc extends RenderDesc {
|
|
|
61405
61530
|
return compiledResult;
|
|
61406
61531
|
}
|
|
61407
61532
|
}
|
|
61408
|
-
if (originalResults) {
|
|
61409
|
-
this.disposeMeshes(scene, originalResults);
|
|
61410
|
-
this.disposeRenderLists(renderer);
|
|
61411
|
-
}
|
|
61412
61533
|
const startFull = this.renderScene.particlesStartFull || FLAGS.PARTICLES_START_FULL;
|
|
61413
61534
|
const startFullFramerate = this.renderScene.particlesStartFullFramerate;
|
|
61414
61535
|
if (startFull) {
|
|
@@ -61438,6 +61559,11 @@ class EmitterGroupDesc extends RenderDesc {
|
|
|
61438
61559
|
}
|
|
61439
61560
|
}
|
|
61440
61561
|
}
|
|
61562
|
+
dispose(renderer) {
|
|
61563
|
+
for (const emitterDesc of this.emitterDescs) {
|
|
61564
|
+
emitterDesc.dispose(renderer);
|
|
61565
|
+
}
|
|
61566
|
+
}
|
|
61441
61567
|
}
|
|
61442
61568
|
const __vite_glob_0_2 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
61443
61569
|
__proto__: null,
|
|
@@ -62172,21 +62298,20 @@ class BeamDesc extends RenderDesc {
|
|
|
62172
62298
|
this.segments = child.PropOrDefault("Segments", this.segments);
|
|
62173
62299
|
if (!FLAGS.BEAMS_ENABLED) this.enabled = false;
|
|
62174
62300
|
}
|
|
62175
|
-
async compileResults(
|
|
62176
|
-
const originalResults = this.results;
|
|
62301
|
+
async compileResults() {
|
|
62177
62302
|
this.results = [];
|
|
62178
62303
|
if (this.enabled) {
|
|
62179
62304
|
let textureResult = void 0;
|
|
62180
62305
|
if (this.texture) {
|
|
62181
|
-
|
|
62182
|
-
|
|
62183
|
-
|
|
62184
|
-
}
|
|
62306
|
+
const params = { colorSpace: "srgb", wrapT: RepeatWrapping };
|
|
62307
|
+
textureResult = await getManagedTexture(this.texture, params);
|
|
62308
|
+
this.managedTextures.push({ url: this.texture, params });
|
|
62185
62309
|
}
|
|
62186
62310
|
if (!textureResult) {
|
|
62187
62311
|
textureResult = new DataTexture(new Uint8Array([255, 255, 255, 255]), 1, 1, RGBAFormat);
|
|
62188
62312
|
textureResult.colorSpace = SRGBColorSpace;
|
|
62189
62313
|
textureResult.needsUpdate = true;
|
|
62314
|
+
this.toDispose.push(textureResult);
|
|
62190
62315
|
}
|
|
62191
62316
|
const material = new ShaderMaterial({
|
|
62192
62317
|
side: DoubleSide,
|
|
@@ -62215,17 +62340,15 @@ class BeamDesc extends RenderDesc {
|
|
|
62215
62340
|
}
|
|
62216
62341
|
])
|
|
62217
62342
|
});
|
|
62343
|
+
this.toDispose.push(material);
|
|
62218
62344
|
const geometry = new PlaneGeometry(1, 1, this.segments, 1);
|
|
62345
|
+
this.toDispose.push(geometry);
|
|
62219
62346
|
const colorValues = new Float32Array((this.segments + 1) * 2 * 4).fill(0);
|
|
62220
62347
|
geometry.setAttribute("color", new BufferAttribute(colorValues, 4));
|
|
62221
62348
|
const mesh = new Mesh(geometry, material);
|
|
62222
62349
|
mesh.name = this.instance ? this.instance.PropOrDefault("Name", "Unknown") + "_Beam" : "Unknown_Beam";
|
|
62223
62350
|
this.results.push(mesh);
|
|
62224
62351
|
}
|
|
62225
|
-
if (originalResults) {
|
|
62226
|
-
this.disposeMeshes(scene, originalResults);
|
|
62227
|
-
this.disposeRenderLists(renderer);
|
|
62228
|
-
}
|
|
62229
62352
|
this.updateResults();
|
|
62230
62353
|
return this.results;
|
|
62231
62354
|
}
|
|
@@ -62349,11 +62472,13 @@ class BeamDesc extends RenderDesc {
|
|
|
62349
62472
|
}
|
|
62350
62473
|
this.lastTime = this.time;
|
|
62351
62474
|
}
|
|
62352
|
-
dispose(
|
|
62475
|
+
dispose(renderer) {
|
|
62353
62476
|
if (!this.results) return;
|
|
62354
62477
|
for (const result of this.results) {
|
|
62355
|
-
|
|
62478
|
+
result.removeFromParent();
|
|
62356
62479
|
}
|
|
62480
|
+
this.clearToDispose();
|
|
62481
|
+
this.disposeRenderLists(renderer);
|
|
62357
62482
|
}
|
|
62358
62483
|
}
|
|
62359
62484
|
const __vite_glob_0_1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
@@ -62601,21 +62726,20 @@ class TrailDesc extends RenderDesc {
|
|
|
62601
62726
|
this.faceCamera = child.PropOrDefault("FaceCamera", this.faceCamera);
|
|
62602
62727
|
if (!FLAGS.BEAMS_ENABLED) this.enabled = false;
|
|
62603
62728
|
}
|
|
62604
|
-
async compileResults(
|
|
62605
|
-
const originalResults = this.results;
|
|
62729
|
+
async compileResults() {
|
|
62606
62730
|
this.results = [];
|
|
62607
62731
|
if (this.enabled) {
|
|
62608
62732
|
let textureResult = void 0;
|
|
62609
62733
|
if (this.texture) {
|
|
62610
|
-
|
|
62611
|
-
|
|
62612
|
-
|
|
62613
|
-
}
|
|
62734
|
+
const params = { colorSpace: "srgb", wrapT: RepeatWrapping };
|
|
62735
|
+
textureResult = await getManagedTexture(this.texture, params);
|
|
62736
|
+
this.managedTextures.push({ url: this.texture, params });
|
|
62614
62737
|
}
|
|
62615
62738
|
if (!textureResult) {
|
|
62616
62739
|
textureResult = new DataTexture(new Uint8Array([255, 255, 255, 255]), 1, 1, RGBAFormat);
|
|
62617
62740
|
textureResult.colorSpace = SRGBColorSpace;
|
|
62618
62741
|
textureResult.needsUpdate = true;
|
|
62742
|
+
this.toDispose.push(textureResult);
|
|
62619
62743
|
}
|
|
62620
62744
|
const material = new ShaderMaterial({
|
|
62621
62745
|
side: DoubleSide,
|
|
@@ -62644,7 +62768,9 @@ class TrailDesc extends RenderDesc {
|
|
|
62644
62768
|
}
|
|
62645
62769
|
])
|
|
62646
62770
|
});
|
|
62771
|
+
this.toDispose.push(material);
|
|
62647
62772
|
const geometry = new PlaneGeometry(1, 1, this.maxSegments, 1);
|
|
62773
|
+
this.toDispose.push(geometry);
|
|
62648
62774
|
const colorValues = new Float32Array((this.maxSegments + 1) * 2 * 4).fill(1);
|
|
62649
62775
|
geometry.setAttribute("color", new BufferAttribute(colorValues, 4));
|
|
62650
62776
|
const mesh = new Mesh(geometry, material);
|
|
@@ -62652,10 +62778,6 @@ class TrailDesc extends RenderDesc {
|
|
|
62652
62778
|
mesh.name = this.instance ? this.instance.PropOrDefault("Name", "Unknown") + "_Trail" : "Unknown_Trail";
|
|
62653
62779
|
this.results.push(mesh);
|
|
62654
62780
|
}
|
|
62655
|
-
if (originalResults) {
|
|
62656
|
-
this.disposeMeshes(scene, originalResults);
|
|
62657
|
-
this.disposeRenderLists(renderer);
|
|
62658
|
-
}
|
|
62659
62781
|
this.updateResults();
|
|
62660
62782
|
return this.results;
|
|
62661
62783
|
}
|
|
@@ -62792,11 +62914,13 @@ class TrailDesc extends RenderDesc {
|
|
|
62792
62914
|
segment.cframe.Position = add(segment.cframe.Position, vec);
|
|
62793
62915
|
}
|
|
62794
62916
|
}
|
|
62795
|
-
dispose(
|
|
62917
|
+
dispose(renderer, scene) {
|
|
62796
62918
|
if (!this.results) return;
|
|
62797
62919
|
for (const result of this.results) {
|
|
62798
62920
|
scene.remove(result);
|
|
62799
62921
|
}
|
|
62922
|
+
this.clearToDispose();
|
|
62923
|
+
this.disposeRenderLists(renderer);
|
|
62800
62924
|
}
|
|
62801
62925
|
}
|
|
62802
62926
|
const __vite_glob_0_5 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
@@ -63418,31 +63542,35 @@ class RBXRenderer {
|
|
|
63418
63542
|
renderScene.scene.add(result);
|
|
63419
63543
|
}
|
|
63420
63544
|
}
|
|
63545
|
+
static _updateCompiledRenderDesc(oldDesc, newDesc, renderScene, instance) {
|
|
63546
|
+
if (!oldDesc.compiled && !oldDesc.failed) {
|
|
63547
|
+
oldDesc.compiled = true;
|
|
63548
|
+
renderScene.compiledRenderDesc.Fire(instance);
|
|
63549
|
+
}
|
|
63550
|
+
if (!oldDesc.isSame(newDesc)) {
|
|
63551
|
+
oldDesc.fromRenderDesc(newDesc);
|
|
63552
|
+
oldDesc.updateResults();
|
|
63553
|
+
}
|
|
63554
|
+
}
|
|
63421
63555
|
static _addRenderDesc(instance, auth, DescClass, renderScene) {
|
|
63422
63556
|
if (!RBXRenderer.renderer) return;
|
|
63423
63557
|
const oldDesc = renderScene.renderDescs.get(instance);
|
|
63424
63558
|
const newDesc = new DescClass(renderScene);
|
|
63425
63559
|
newDesc.fromInstance(instance);
|
|
63426
63560
|
if (oldDesc && !oldDesc.needsRegeneration(newDesc) && !renderScene.isRenderingMesh.get(instance)) {
|
|
63427
|
-
|
|
63428
|
-
oldDesc.compiled = true;
|
|
63429
|
-
renderScene.compiledRenderDesc.Fire(instance);
|
|
63430
|
-
}
|
|
63431
|
-
if (!oldDesc.isSame(newDesc)) {
|
|
63432
|
-
oldDesc.fromRenderDesc(newDesc);
|
|
63433
|
-
oldDesc.updateResults();
|
|
63434
|
-
}
|
|
63561
|
+
RBXRenderer._updateCompiledRenderDesc(oldDesc, newDesc, renderScene, instance);
|
|
63435
63562
|
} else {
|
|
63436
63563
|
if (!renderScene.isRenderingMesh.get(instance)) {
|
|
63437
|
-
if (oldDesc
|
|
63438
|
-
|
|
63564
|
+
if (oldDesc && Object.getPrototypeOf(oldDesc).constructor === Object.getPrototypeOf(newDesc).constructor) {
|
|
63565
|
+
newDesc.transferFrom(oldDesc);
|
|
63566
|
+
}
|
|
63439
63567
|
renderScene.renderDescs.set(instance, newDesc);
|
|
63440
63568
|
renderScene.isRenderingMesh.set(instance, true);
|
|
63441
63569
|
newDesc.compileResults(RBXRenderer.renderer, renderScene.scene).then((results) => {
|
|
63570
|
+
if (RBXRenderer.renderer) oldDesc?.dispose(RBXRenderer.renderer, renderScene.scene);
|
|
63442
63571
|
if (results && !(results instanceof Response)) {
|
|
63443
63572
|
newDesc.updateResults();
|
|
63444
|
-
if (renderScene.renderDescs.get(instance) && RBXRenderer.renderer) {
|
|
63445
|
-
oldDesc?.dispose(RBXRenderer.renderer, renderScene.scene);
|
|
63573
|
+
if (renderScene.renderDescs.get(instance) === newDesc && RBXRenderer.renderer) {
|
|
63446
63574
|
for (const result of results) {
|
|
63447
63575
|
RBXRenderer._addSkeletonToResult(result, newDesc, renderScene);
|
|
63448
63576
|
}
|
|
@@ -63452,9 +63580,12 @@ class RBXRenderer {
|
|
|
63452
63580
|
newDesc.dispose(RBXRenderer.renderer, renderScene.scene);
|
|
63453
63581
|
}
|
|
63454
63582
|
} else {
|
|
63583
|
+
if (RBXRenderer.renderer) newDesc.dispose(RBXRenderer.renderer, renderScene.scene);
|
|
63455
63584
|
newDesc.failed = true;
|
|
63456
|
-
renderScene.
|
|
63457
|
-
|
|
63585
|
+
if (renderScene.renderDescs.get(instance) === newDesc) {
|
|
63586
|
+
renderScene.isRenderingMesh.set(instance, false);
|
|
63587
|
+
renderScene.failedRenderDesc.Fire(instance);
|
|
63588
|
+
}
|
|
63458
63589
|
warn(false, "Failed to compile mesh", this, results);
|
|
63459
63590
|
}
|
|
63460
63591
|
});
|
|
@@ -63469,16 +63600,26 @@ class RBXRenderer {
|
|
|
63469
63600
|
}));
|
|
63470
63601
|
}
|
|
63471
63602
|
}
|
|
63472
|
-
/**
|
|
63473
|
-
|
|
63603
|
+
/** */
|
|
63604
|
+
/**
|
|
63605
|
+
* Adds an instance to the renderer or updates it, add it again to update it after changes have been made
|
|
63606
|
+
* @param instance The instance that will be updated (the descendants will also update)
|
|
63607
|
+
* @param auth This is here just in case something requires it in the future
|
|
63608
|
+
* @param renderScene The scene the instances will be rendered in. Default RBXRenderer.firstScene
|
|
63609
|
+
* @param includeDescendants If descendants should also have addInstance called on them. Default true
|
|
63610
|
+
* @returns
|
|
63611
|
+
*/
|
|
63612
|
+
static addInstance(instance, auth, renderScene = RBXRenderer.firstScene, includeDescendants = true) {
|
|
63474
63613
|
if (renderScene.destroyed) return;
|
|
63475
63614
|
const RenderDescType = getRenderDescForInstance(instance);
|
|
63476
63615
|
if (RenderDescType) {
|
|
63477
63616
|
if (renderScene.addedInstances.indexOf(instance) < 0) renderScene.addedInstances.push(instance);
|
|
63478
63617
|
RBXRenderer._addRenderDesc(instance, auth, RenderDescType, renderScene);
|
|
63479
63618
|
}
|
|
63480
|
-
|
|
63481
|
-
|
|
63619
|
+
if (includeDescendants) {
|
|
63620
|
+
for (const child of instance.GetDescendants()) {
|
|
63621
|
+
RBXRenderer.addInstance(child, auth, renderScene, false);
|
|
63622
|
+
}
|
|
63482
63623
|
}
|
|
63483
63624
|
}
|
|
63484
63625
|
static setRendererSize(width, height) {
|
|
@@ -64188,8 +64329,8 @@ function getExtentsForParts(parts, includeTransform) {
|
|
|
64188
64329
|
}
|
|
64189
64330
|
function getExtents(cframe, parts) {
|
|
64190
64331
|
const inverseCF = cframe.inverse();
|
|
64191
|
-
let lowerExtents = new Vector3(
|
|
64192
|
-
let higherExtents = new Vector3(
|
|
64332
|
+
let lowerExtents = new Vector3(1e6, 1e6, 1e6);
|
|
64333
|
+
let higherExtents = new Vector3(-1e6, -1e6, -1e5);
|
|
64193
64334
|
for (const child of parts) {
|
|
64194
64335
|
if (child.createWrapper()?.IsA("BasePart")) {
|
|
64195
64336
|
const partCF = child.Prop("CFrame");
|
|
@@ -65070,10 +65211,11 @@ async function renderTargetToCanvas$1(renderTarget) {
|
|
|
65070
65211
|
}
|
|
65071
65212
|
async function imageThumbnailClick(renderScene, width, height, format, options) {
|
|
65072
65213
|
const resultOptions = {
|
|
65073
|
-
quality: 1
|
|
65214
|
+
quality: 1,
|
|
65215
|
+
size: [width, height]
|
|
65074
65216
|
};
|
|
65075
65217
|
if (options) Object.assign(resultOptions, options);
|
|
65076
|
-
const renderTarget = renderToRenderTarget$1(
|
|
65218
|
+
const renderTarget = renderToRenderTarget$1(resultOptions.size[0], resultOptions.size[1], renderScene);
|
|
65077
65219
|
const canvas = await renderTargetToCanvas$1(renderTarget);
|
|
65078
65220
|
renderTarget.dispose();
|
|
65079
65221
|
if (canvas) {
|
|
@@ -65093,8 +65235,24 @@ async function modelThumbnailClick(renderScene, format, options) {
|
|
|
65093
65235
|
});
|
|
65094
65236
|
}
|
|
65095
65237
|
function getThumbnailCameraCFrame(model, fov2, forceAngle) {
|
|
65096
|
-
const thumbnailCamera = model.
|
|
65097
|
-
if (thumbnailCamera) return thumbnailCamera.PropOrDefault("CFrame", new CFrame());
|
|
65238
|
+
const thumbnailCamera = model.FindFirstChild("ThumbnailCamera");
|
|
65239
|
+
if (thumbnailCamera && thumbnailCamera.IsA("Camera")) return thumbnailCamera.PropOrDefault("CFrame", new CFrame());
|
|
65240
|
+
const thumbnailConfiguration = model.FindFirstChild("ThumbnailConfiguration");
|
|
65241
|
+
if (thumbnailConfiguration) {
|
|
65242
|
+
const thumbnailCameraTarget = thumbnailConfiguration.FindFirstChild("ThumbnailCameraTarget");
|
|
65243
|
+
if (thumbnailCameraTarget && thumbnailCameraTarget.IsA("ObjectValue")) {
|
|
65244
|
+
const targetInstance = thumbnailCameraTarget.Prop("Value");
|
|
65245
|
+
if (targetInstance && targetInstance.IsA("BasePart")) {
|
|
65246
|
+
const targetCF = targetInstance.PropOrDefault("CFrame", new CFrame());
|
|
65247
|
+
const thumbnailCameraValue = thumbnailConfiguration.FindFirstChild("ThumbnailCameraValue");
|
|
65248
|
+
if (thumbnailCameraValue && thumbnailCameraValue.IsA("CFrameValue")) {
|
|
65249
|
+
const cf = thumbnailCameraValue.PropOrDefault("Value", new CFrame());
|
|
65250
|
+
const resultCF = targetCF.multiply(cf);
|
|
65251
|
+
return resultCF;
|
|
65252
|
+
}
|
|
65253
|
+
}
|
|
65254
|
+
}
|
|
65255
|
+
}
|
|
65098
65256
|
let rootPart = model.PropOrDefault("PrimaryPart", void 0);
|
|
65099
65257
|
if (!rootPart) rootPart = model.FindFirstChildOfClass("Part");
|
|
65100
65258
|
if (!rootPart) rootPart = model.FindFirstChildOfClass("MeshPart");
|
|
@@ -65126,6 +65284,56 @@ function getThumbnailCameraCFrame(model, fov2, forceAngle) {
|
|
|
65126
65284
|
zoomExtents(cameraCF, rootPartCF, extentsSize, fov2, 1);
|
|
65127
65285
|
return cameraCF;
|
|
65128
65286
|
}
|
|
65287
|
+
function getThumbnailCamera(model) {
|
|
65288
|
+
const thumbnailCamera = model.FindFirstChild("ThumbnailCamera");
|
|
65289
|
+
if (thumbnailCamera && thumbnailCamera.IsA("Camera")) return thumbnailCamera;
|
|
65290
|
+
const camera = new Instance("Camera");
|
|
65291
|
+
const thumbnailConfiguration = model.FindFirstChild("ThumbnailConfiguration");
|
|
65292
|
+
if (thumbnailConfiguration) {
|
|
65293
|
+
const thumbnailCameraTarget = thumbnailConfiguration.FindFirstChild("ThumbnailCameraTarget");
|
|
65294
|
+
if (thumbnailCameraTarget && thumbnailCameraTarget.IsA("ObjectValue")) {
|
|
65295
|
+
const targetInstance = thumbnailCameraTarget.Prop("Value");
|
|
65296
|
+
if (targetInstance && targetInstance.IsA("BasePart")) {
|
|
65297
|
+
const targetCF = targetInstance.PropOrDefault("CFrame", new CFrame());
|
|
65298
|
+
const thumbnailCameraValue = thumbnailConfiguration.FindFirstChild("ThumbnailCameraValue");
|
|
65299
|
+
if (thumbnailCameraValue && thumbnailCameraValue.IsA("CFrameValue")) {
|
|
65300
|
+
const cf = thumbnailCameraValue.PropOrDefault("Value", new CFrame());
|
|
65301
|
+
const resultCF = targetCF.multiply(cf);
|
|
65302
|
+
camera.setProperty("FieldOfView", 70);
|
|
65303
|
+
camera.setProperty("CFrame", resultCF);
|
|
65304
|
+
return camera;
|
|
65305
|
+
}
|
|
65306
|
+
}
|
|
65307
|
+
}
|
|
65308
|
+
}
|
|
65309
|
+
let rootPart = model.PropOrDefault("PrimaryPart", void 0);
|
|
65310
|
+
if (!rootPart) rootPart = model.FindFirstChildOfClass("Part");
|
|
65311
|
+
if (!rootPart) rootPart = model.FindFirstChildOfClass("MeshPart");
|
|
65312
|
+
if (!rootPart) return camera;
|
|
65313
|
+
const rootPartCF = rootPart.PropOrDefault("CFrame", new CFrame()).clone();
|
|
65314
|
+
const worldExtents = getExtentsWorld(model);
|
|
65315
|
+
if (!worldExtents) return camera;
|
|
65316
|
+
const extentsSize = worldExtents[1].minus(worldExtents[0]);
|
|
65317
|
+
rootPartCF.Position = getExtentsCenter(worldExtents).toVec3();
|
|
65318
|
+
let lookVector = rootPartCF.lookVector();
|
|
65319
|
+
if (Math.abs(lookVector[1]) > 0.95) {
|
|
65320
|
+
lookVector = [0, 0, -1];
|
|
65321
|
+
} else {
|
|
65322
|
+
lookVector[1] = 0;
|
|
65323
|
+
lookVector = normalize(lookVector);
|
|
65324
|
+
}
|
|
65325
|
+
let lookCF = CFrame.lookAt([0, 0, 0], lookVector);
|
|
65326
|
+
lookCF = lookCF.multiply(CFrame.fromEulerAngles(0, 0, rad(45)));
|
|
65327
|
+
lookCF = lookCF.multiply(CFrame.fromEulerAngles(rad(35), 0, 0));
|
|
65328
|
+
lookCF = lookCF.multiply(CFrame.fromEulerAngles(0, 0, 0));
|
|
65329
|
+
lookVector = lookCF.lookVector();
|
|
65330
|
+
lookCF.Position = add(rootPartCF.Position, multiply([10, 10, 10], lookVector));
|
|
65331
|
+
lookCF = CFrame.lookAt(lookCF.Position, rootPartCF.Position);
|
|
65332
|
+
const cameraCF = lookCF.clone();
|
|
65333
|
+
zoomExtents(cameraCF, rootPartCF, extentsSize, 70, 1);
|
|
65334
|
+
camera.setProperty("CFrame", cameraCF);
|
|
65335
|
+
return camera;
|
|
65336
|
+
}
|
|
65129
65337
|
function setupThumbnailScene(renderScene) {
|
|
65130
65338
|
renderScene.particlesStartFull = 4;
|
|
65131
65339
|
renderScene.particlesStartFullFramerate = 20;
|
|
@@ -65214,6 +65422,135 @@ async function generateOutfitModelThumbnail(auth, outfitModel, options) {
|
|
|
65214
65422
|
Object.assign(defaultOptions, options);
|
|
65215
65423
|
return generateOutfitThumbnail(auth, outfitModel, defaultOptions.size, defaultOptions.type, defaultOptions.quality, defaultOptions.gltfAutoDownload, defaultOptions.includeAnimations);
|
|
65216
65424
|
}
|
|
65425
|
+
function getViewExtents(camera, positions, width, height) {
|
|
65426
|
+
const minExtents = new Vector2(1e6, 1e6);
|
|
65427
|
+
const maxExtents = new Vector2(-1e6, -1e6);
|
|
65428
|
+
for (const pos of positions) {
|
|
65429
|
+
const projPos = new Vector3$1(...pos.toVec3()).project(camera);
|
|
65430
|
+
const x = (projPos.x / 2 + 0.5) * width;
|
|
65431
|
+
const y = (-projPos.y / 2 + 0.5) * height;
|
|
65432
|
+
if (x < minExtents.X) minExtents.X = x;
|
|
65433
|
+
if (x > maxExtents.X) maxExtents.X = x;
|
|
65434
|
+
if (y < minExtents.Y) minExtents.Y = y;
|
|
65435
|
+
if (y > maxExtents.Y) maxExtents.Y = y;
|
|
65436
|
+
}
|
|
65437
|
+
minExtents.X = Math.max(0, minExtents.X);
|
|
65438
|
+
minExtents.Y = Math.max(0, minExtents.Y);
|
|
65439
|
+
maxExtents.X = Math.min(width, maxExtents.X);
|
|
65440
|
+
maxExtents.Y = Math.min(height, maxExtents.Y);
|
|
65441
|
+
return [minExtents, maxExtents];
|
|
65442
|
+
}
|
|
65443
|
+
function getModelViewExtents(model, camera, width, height) {
|
|
65444
|
+
const worldExtents = getExtentsWorld(model);
|
|
65445
|
+
const corners = [
|
|
65446
|
+
new Vector3(worldExtents[0].X, worldExtents[0].Y, worldExtents[0].Z),
|
|
65447
|
+
new Vector3(worldExtents[0].X, worldExtents[0].Y, worldExtents[1].Z),
|
|
65448
|
+
new Vector3(worldExtents[0].X, worldExtents[1].Y, worldExtents[0].Z),
|
|
65449
|
+
new Vector3(worldExtents[0].X, worldExtents[1].Y, worldExtents[1].Z),
|
|
65450
|
+
new Vector3(worldExtents[1].X, worldExtents[0].Y, worldExtents[0].Z),
|
|
65451
|
+
new Vector3(worldExtents[1].X, worldExtents[0].Y, worldExtents[1].Z),
|
|
65452
|
+
new Vector3(worldExtents[1].X, worldExtents[1].Y, worldExtents[0].Z),
|
|
65453
|
+
new Vector3(worldExtents[1].X, worldExtents[1].Y, worldExtents[1].Z)
|
|
65454
|
+
];
|
|
65455
|
+
return getViewExtents(camera, corners, width, height);
|
|
65456
|
+
}
|
|
65457
|
+
function cropCameraToViewExtents(camera, viewExtents, width, height, keepAspectRatio = true) {
|
|
65458
|
+
const blx = viewExtents[0].X;
|
|
65459
|
+
const bly = viewExtents[0].Y;
|
|
65460
|
+
const bhx = viewExtents[1].X;
|
|
65461
|
+
const bhy = viewExtents[1].Y;
|
|
65462
|
+
const xDiff = bhx - blx;
|
|
65463
|
+
const yDiff = bhy - bly;
|
|
65464
|
+
const cx = blx + xDiff / 2;
|
|
65465
|
+
const cy = bly + yDiff / 2;
|
|
65466
|
+
const scaleW = xDiff / width;
|
|
65467
|
+
const scaleH = yDiff / height;
|
|
65468
|
+
const maxScale = Math.max(scaleW, scaleH);
|
|
65469
|
+
const cropWidth = keepAspectRatio ? width * maxScale : xDiff;
|
|
65470
|
+
const cropHeight = keepAspectRatio ? height * maxScale : yDiff;
|
|
65471
|
+
const flx = cx - cropWidth / 2;
|
|
65472
|
+
const fly = cy - cropHeight / 2;
|
|
65473
|
+
const x = flx;
|
|
65474
|
+
const y = fly;
|
|
65475
|
+
camera.setViewOffset(
|
|
65476
|
+
width,
|
|
65477
|
+
height,
|
|
65478
|
+
x,
|
|
65479
|
+
y,
|
|
65480
|
+
cropWidth,
|
|
65481
|
+
cropHeight
|
|
65482
|
+
);
|
|
65483
|
+
return cropWidth / cropHeight;
|
|
65484
|
+
}
|
|
65485
|
+
function cropForModel(model, renderScene, width, height, resizeToRemoveUnusedSpace = false) {
|
|
65486
|
+
const viewExtents = getModelViewExtents(model, renderScene.camera, width, height);
|
|
65487
|
+
const targetAspectRatio = cropCameraToViewExtents(renderScene.camera, viewExtents, width, height, !resizeToRemoveUnusedSpace);
|
|
65488
|
+
renderScene.camera.updateProjectionMatrix();
|
|
65489
|
+
let newHeight = height;
|
|
65490
|
+
let newWidth = width;
|
|
65491
|
+
if (resizeToRemoveUnusedSpace) {
|
|
65492
|
+
newWidth = width * targetAspectRatio;
|
|
65493
|
+
if (newWidth > width) {
|
|
65494
|
+
newWidth = width;
|
|
65495
|
+
newHeight = height / targetAspectRatio;
|
|
65496
|
+
}
|
|
65497
|
+
}
|
|
65498
|
+
return [Math.ceil(newWidth), Math.ceil(newHeight)];
|
|
65499
|
+
}
|
|
65500
|
+
function createThumbnailScene() {
|
|
65501
|
+
const renderScene = RBXRenderer.addScene(false);
|
|
65502
|
+
renderScene.isForRenderTarget = true;
|
|
65503
|
+
setupThumbnailScene(renderScene);
|
|
65504
|
+
return renderScene;
|
|
65505
|
+
}
|
|
65506
|
+
async function generateAccessoryThumbnail(auth, id, type, imageOptions, isAccessoryCamera = false) {
|
|
65507
|
+
let renderSceneToDestroy = void 0;
|
|
65508
|
+
const instancesToDestroy = [];
|
|
65509
|
+
const cleanup = () => {
|
|
65510
|
+
if (renderSceneToDestroy) renderSceneToDestroy.destroy();
|
|
65511
|
+
for (const instance of instancesToDestroy) {
|
|
65512
|
+
instance.Destroy();
|
|
65513
|
+
}
|
|
65514
|
+
return void 0;
|
|
65515
|
+
};
|
|
65516
|
+
const resultOptions = {
|
|
65517
|
+
quality: 1,
|
|
65518
|
+
size: [420, 420]
|
|
65519
|
+
};
|
|
65520
|
+
if (imageOptions) Object.assign(resultOptions, imageOptions);
|
|
65521
|
+
const renderScene = createThumbnailScene();
|
|
65522
|
+
renderSceneToDestroy = renderScene;
|
|
65523
|
+
const rbx = await API.Asset.GetRBX(`rbxassetid://${id}`, { "Roblox-AssetFormat": "avatar_meshpart_accessory" });
|
|
65524
|
+
if (rbx instanceof Response) return cleanup();
|
|
65525
|
+
const root = rbx.generateTree();
|
|
65526
|
+
instancesToDestroy.push(root);
|
|
65527
|
+
const accessory = root.FindFirstChildOfClass("Accessory");
|
|
65528
|
+
if (!accessory) return cleanup();
|
|
65529
|
+
let camera = void 0;
|
|
65530
|
+
if (isAccessoryCamera) {
|
|
65531
|
+
camera = new Instance("Camera");
|
|
65532
|
+
setupAccessoryCamera(root, camera);
|
|
65533
|
+
} else {
|
|
65534
|
+
camera = getThumbnailCamera(accessory);
|
|
65535
|
+
}
|
|
65536
|
+
instancesToDestroy.push(camera);
|
|
65537
|
+
RBXRenderer.setCameraCFrame(camera.PropOrDefault("CFrame", new CFrame()), renderScene);
|
|
65538
|
+
RBXRenderer.setCameraFov(camera.PropOrDefault("FieldOfView", 70), renderScene);
|
|
65539
|
+
renderScene.camera.aspect = resultOptions.size[0] / resultOptions.size[1];
|
|
65540
|
+
renderScene.camera.updateProjectionMatrix();
|
|
65541
|
+
let [newWidth, newHeight] = [resultOptions.size[0], resultOptions.size[1]];
|
|
65542
|
+
if (!isAccessoryCamera) {
|
|
65543
|
+
[newWidth, newHeight] = cropForModel(accessory, renderScene, resultOptions.size[0], resultOptions.size[1]);
|
|
65544
|
+
}
|
|
65545
|
+
RBXRenderer.addInstance(accessory, auth, renderScene);
|
|
65546
|
+
const compiledSuccessfully = await renderScene.waitUntilFullyCompiled([accessory, ...accessory.GetChildrenDangerous()]);
|
|
65547
|
+
if (!compiledSuccessfully) return cleanup();
|
|
65548
|
+
const result = type === "gltf" || type === "glb" ? await modelThumbnailClick(renderScene, type) : await imageThumbnailClick(renderScene, newWidth, newHeight, type, {
|
|
65549
|
+
quality: resultOptions.quality
|
|
65550
|
+
});
|
|
65551
|
+
cleanup();
|
|
65552
|
+
return result;
|
|
65553
|
+
}
|
|
65217
65554
|
async function runTests() {
|
|
65218
65555
|
const auth = new Authentication();
|
|
65219
65556
|
const testModel = await API.Asset.GetRBX(FLAGS.AUTOTEST_MODEL);
|
|
@@ -65394,6 +65731,7 @@ function exposeThumbnailGenerator() {
|
|
|
65394
65731
|
globalThis.generateModelThumbnail = generateModelThumbnail;
|
|
65395
65732
|
globalThis.setupThumbnailScene = setupThumbnailScene;
|
|
65396
65733
|
globalThis.getThumbnailCameraCFrame = getThumbnailCameraCFrame;
|
|
65734
|
+
globalThis.generateAccessoryThumbnail = generateAccessoryThumbnail;
|
|
65397
65735
|
}
|
|
65398
65736
|
function exposeTests() {
|
|
65399
65737
|
globalThis.runTests = runTests;
|
|
@@ -65593,7 +65931,10 @@ export {
|
|
|
65593
65931
|
closestPointTriangle,
|
|
65594
65932
|
createContentMap,
|
|
65595
65933
|
createThumbnailCamera,
|
|
65934
|
+
createThumbnailScene,
|
|
65596
65935
|
createWeightsForMeshChunked,
|
|
65936
|
+
cropCameraToViewExtents,
|
|
65937
|
+
cropForModel,
|
|
65597
65938
|
cross,
|
|
65598
65939
|
defaultPantAssetIds,
|
|
65599
65940
|
defaultPantTemplateAssetIds,
|
|
@@ -65635,6 +65976,7 @@ export {
|
|
|
65635
65976
|
getFullBodyCameraCFrame,
|
|
65636
65977
|
getHeadExtents,
|
|
65637
65978
|
getHeadshotCameraCFrame,
|
|
65979
|
+
getModelViewExtents,
|
|
65638
65980
|
getOffsetArray,
|
|
65639
65981
|
getOriginalAttachmentOrientation,
|
|
65640
65982
|
getOriginalAttachmentPosition,
|
|
@@ -65643,9 +65985,11 @@ export {
|
|
|
65643
65985
|
getPartsInAssembly_Generate,
|
|
65644
65986
|
getRandomBetweenInclusive,
|
|
65645
65987
|
getRootAssemblyPart_Generate,
|
|
65988
|
+
getThumbnailCamera,
|
|
65646
65989
|
getThumbnailCameraCFrame,
|
|
65647
65990
|
getUVtoIndexMap,
|
|
65648
65991
|
getUVtoIndicesMap,
|
|
65992
|
+
getViewExtents,
|
|
65649
65993
|
getWorkerOnMessage,
|
|
65650
65994
|
hasSameVal,
|
|
65651
65995
|
hasSameValFloat,
|
|
@@ -65689,6 +66033,7 @@ export {
|
|
|
65689
66033
|
rotationMatrixToEulerAngles,
|
|
65690
66034
|
saveByteArray,
|
|
65691
66035
|
scaleMesh,
|
|
66036
|
+
setCacheFootprintPreset,
|
|
65692
66037
|
setupAccessoryCamera,
|
|
65693
66038
|
setupBodyPartCamera,
|
|
65694
66039
|
setupCamera,
|