roavatar-renderer 1.3.5 → 1.4.0
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 +59 -2
- package/dist/index.js +510 -105
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -97,7 +97,7 @@ export declare class AnimationConstraintWrapper extends InstanceWrapper {
|
|
|
97
97
|
setup(): void;
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
-
export declare type AnimationProp = "ClimbAnimation" | "FallAnimation" | "IdleAnimation" | "JumpAnimation" | "MoodAnimation" | "RunAnimation" | "SwimAnimation" | "WalkAnimation" | "dance1" | "dance2" | "dance3" | "toolnone";
|
|
100
|
+
export declare type AnimationProp = "ClimbAnimation" | "FallAnimation" | "IdleAnimation" | "JumpAnimation" | "MoodAnimation" | "RunAnimation" | "SwimAnimation" | "WalkAnimation" | "dance1" | "dance2" | "dance3" | "toolnone" | "pose";
|
|
101
101
|
|
|
102
102
|
export declare const AnimationPropToName: {
|
|
103
103
|
[K in AnimationProp]: string;
|
|
@@ -309,6 +309,9 @@ export declare const API: {
|
|
|
309
309
|
PremiumFeatures: {
|
|
310
310
|
GetSubscription: (userId: number) => Promise<Response | GetSubscription_Result>;
|
|
311
311
|
};
|
|
312
|
+
Subscriptions: {
|
|
313
|
+
HasPlus: () => Promise<Response | boolean>;
|
|
314
|
+
};
|
|
312
315
|
RBLXGet: typeof RBLXGet;
|
|
313
316
|
RBLXPost: typeof RBLXPost;
|
|
314
317
|
RBLXDelete: typeof RBLXDelete;
|
|
@@ -418,6 +421,13 @@ export declare const AssetTypeToMakeupType: {
|
|
|
418
421
|
EyeMakeup: number;
|
|
419
422
|
};
|
|
420
423
|
|
|
424
|
+
export declare class AttachmentWrapper extends InstanceWrapper {
|
|
425
|
+
static className: string;
|
|
426
|
+
static requiredProperties: string[];
|
|
427
|
+
setup(): void;
|
|
428
|
+
getWorldCFrame(): CFrame;
|
|
429
|
+
}
|
|
430
|
+
|
|
421
431
|
export declare class Authentication {
|
|
422
432
|
TOKEN?: string;
|
|
423
433
|
SessionUUID?: string;
|
|
@@ -810,6 +820,9 @@ declare class COREMESH {
|
|
|
810
820
|
getColors(): Uint8Array;
|
|
811
821
|
getIndices(): Uint16Array;
|
|
812
822
|
getTouchingVerts(index: number): number[];
|
|
823
|
+
getEdgeId(v0: number, v1: number): bigint;
|
|
824
|
+
getFaceEdges(i: number): [bigint, bigint, bigint];
|
|
825
|
+
getEdgeCounts(): Map<bigint, number>;
|
|
813
826
|
}
|
|
814
827
|
|
|
815
828
|
export declare function createContentMap(): void;
|
|
@@ -893,6 +906,8 @@ declare class DisposableDesc {
|
|
|
893
906
|
dispose(_renderer: THREE.WebGLRenderer, _scene: THREE.Scene): void;
|
|
894
907
|
}
|
|
895
908
|
|
|
909
|
+
export declare function disposeMesh(scene: THREE.Scene, mesh: THREE.Mesh): void;
|
|
910
|
+
|
|
896
911
|
export declare function distance(v0: Vec3, v1: Vec3): number;
|
|
897
912
|
|
|
898
913
|
export declare function divide(v0: Vec3, v1: Vec3): Vec3;
|
|
@@ -914,8 +929,12 @@ export { Event_2 as Event }
|
|
|
914
929
|
|
|
915
930
|
export declare function exposeAPI(): void;
|
|
916
931
|
|
|
932
|
+
export declare function exposeFLAGS(): void;
|
|
933
|
+
|
|
917
934
|
export declare function exposeMesh(): void;
|
|
918
935
|
|
|
936
|
+
export declare function exposeThumbnailGenerator(): void;
|
|
937
|
+
|
|
919
938
|
export declare const FaceControlNames: string[];
|
|
920
939
|
|
|
921
940
|
export declare class FaceControlsWrapper extends InstanceWrapper {
|
|
@@ -1012,6 +1031,8 @@ export declare class FileMeshSubset {
|
|
|
1012
1031
|
|
|
1013
1032
|
export declare function fileMeshToTHREEGeometry(mesh: FileMesh, canIncludeSkinning?: boolean, forceVertexColor?: Vector3): THREE.BufferGeometry<THREE.NormalBufferAttributes, THREE.BufferGeometryEventMap>;
|
|
1014
1033
|
|
|
1034
|
+
export declare function FindFirstMatchingAttachment(attachmentName: string, rig: Instance): Instance | null;
|
|
1035
|
+
|
|
1015
1036
|
export declare const FLAGS: {
|
|
1016
1037
|
HAIR_IS_BODYPART: boolean;
|
|
1017
1038
|
AVATAR_JOINT_UPGRADE: boolean;
|
|
@@ -1044,6 +1065,9 @@ export declare const FLAGS: {
|
|
|
1044
1065
|
AUDIO_ENABLED: boolean;
|
|
1045
1066
|
LEGACY_WELD_BEHAVIOR: boolean;
|
|
1046
1067
|
USE_RENDERTARGET: boolean;
|
|
1068
|
+
AUTO_RESTORE_CONTEXT: boolean;
|
|
1069
|
+
RENDERTARGET_TO_CANVASTEXTURE: boolean;
|
|
1070
|
+
THUMBNAIL_TIMEOUT: number;
|
|
1047
1071
|
SHOW_SKELETON_HELPER: boolean;
|
|
1048
1072
|
UPDATE_SKELETON: boolean;
|
|
1049
1073
|
ANIMATE_SKELETON: boolean;
|
|
@@ -1084,16 +1108,26 @@ export declare const FullBodyColors: string[];
|
|
|
1084
1108
|
|
|
1085
1109
|
export declare function gaussian_rbf(v0: Vec3, v1: Vec3, sigma?: number): number;
|
|
1086
1110
|
|
|
1111
|
+
export declare function generateModelThumbnail(auth: Authentication, renderScene: RBXRendererScene, model: Instance, size?: Vec2, type?: ThumbnailType, quality?: number, gltfAutoDownload?: boolean): Promise<ThumbnailResult>;
|
|
1112
|
+
|
|
1113
|
+
export declare function generateOutfitThumbnail(auth: Authentication, outfit: Outfit, size?: Vec2, type?: ThumbnailType, quality?: number, gltfAutoDownload?: boolean): Promise<ThumbnailResult>;
|
|
1114
|
+
|
|
1087
1115
|
export declare function generateUUIDv4(): string;
|
|
1088
1116
|
|
|
1089
1117
|
export declare function GetAttachedPart(accessory: Instance, rig: Instance): Instance | undefined;
|
|
1090
1118
|
|
|
1119
|
+
export declare function getCameraCFrameForAvatarNonCustomized(rig: Instance): CFrame | undefined;
|
|
1120
|
+
|
|
1091
1121
|
export declare function getCameraCFrameForHeadshotCustomized(rig: Instance, fov: number, yRot: number, distance: number): CFrame | undefined;
|
|
1092
1122
|
|
|
1123
|
+
export declare function getCameraOffset(fov: number, extentsSize: Vector3): number;
|
|
1124
|
+
|
|
1093
1125
|
export declare function getDistIndexArray(ref: FileMesh, dist: FileMesh): (number | undefined)[];
|
|
1094
1126
|
|
|
1095
1127
|
export declare function getExtents(cframe: CFrame, parts: Instance[]): [Vector3, Vector3];
|
|
1096
1128
|
|
|
1129
|
+
export declare function getExtentsCenter(extents: [Vector3, Vector3]): Vector3;
|
|
1130
|
+
|
|
1097
1131
|
/**@deprecated this is SO broken */
|
|
1098
1132
|
export declare function getExtentsForParts(parts: Instance[], includeTransform?: boolean): [Vector3, Vector3];
|
|
1099
1133
|
|
|
@@ -1112,10 +1146,16 @@ export declare interface GetInfoForId_Result {
|
|
|
1112
1146
|
|
|
1113
1147
|
export declare function getOffsetArray(inner: FileMesh, outer: FileMesh): ([Vec3, THREE.Quaternion, number] | undefined)[];
|
|
1114
1148
|
|
|
1149
|
+
export declare function getOriginalAttachmentOrientation(attachment: Instance): Vector3;
|
|
1150
|
+
|
|
1151
|
+
export declare function getOriginalAttachmentPosition(attachment: Instance): Vector3;
|
|
1152
|
+
|
|
1115
1153
|
export declare function getOriginalSize(part: Instance): Vector3;
|
|
1116
1154
|
|
|
1117
1155
|
export declare function getRandomBetweenInclusive(min: number, max: number): number;
|
|
1118
1156
|
|
|
1157
|
+
export declare function getRigExtentsWorld(rig: Instance): [Vector3, Vector3];
|
|
1158
|
+
|
|
1119
1159
|
export declare interface GetSubscription_Result {
|
|
1120
1160
|
"subscriptionProductModel": {
|
|
1121
1161
|
"premiumFeatureId": number;
|
|
@@ -2195,7 +2235,8 @@ export declare class RBXRenderer {
|
|
|
2195
2235
|
/**Creates canvasContainer */
|
|
2196
2236
|
static createContainer(): void;
|
|
2197
2237
|
/**Sets up the THREE.js renderer */
|
|
2198
|
-
static create(): void;
|
|
2238
|
+
static create(canvas?: HTMLCanvasElement): void;
|
|
2239
|
+
static setupLostContextHandler(): void;
|
|
2199
2240
|
/**Sets up a basic scene with lighting
|
|
2200
2241
|
* @param lightingType "WellLit" is the default lighting for RoAvatar, "Thumbnail" tries to match the Roblox thumbnail lighting
|
|
2201
2242
|
* @param backgroundColorHex is the hex code for the background color, for example 0x2b2d33
|
|
@@ -2252,6 +2293,8 @@ export declare class RBXRendererScene {
|
|
|
2252
2293
|
scene: THREE.Scene;
|
|
2253
2294
|
camera: THREE.PerspectiveCamera;
|
|
2254
2295
|
controls: OrbitControls | undefined;
|
|
2296
|
+
shouldAnimate: boolean;
|
|
2297
|
+
destroyed: boolean;
|
|
2255
2298
|
effectComposer: EffectComposer | undefined;
|
|
2256
2299
|
scissor?: [number, number, number, number];
|
|
2257
2300
|
viewport?: [number, number, number, number];
|
|
@@ -2272,6 +2315,10 @@ export declare class RBXRendererScene {
|
|
|
2272
2315
|
directionalLight2?: THREE.DirectionalLight;
|
|
2273
2316
|
setRect(bounds: DOMRect): void;
|
|
2274
2317
|
noRect(): void;
|
|
2318
|
+
destroy(): void;
|
|
2319
|
+
exportGLTF(name?: string, autoDownload?: boolean): Promise<ArrayBuffer | {
|
|
2320
|
+
[key: string]: unknown;
|
|
2321
|
+
}>;
|
|
2275
2322
|
}
|
|
2276
2323
|
|
|
2277
2324
|
declare class RBXSimpleView {
|
|
@@ -2501,6 +2548,8 @@ export declare interface Search_Result {
|
|
|
2501
2548
|
}[];
|
|
2502
2549
|
}
|
|
2503
2550
|
|
|
2551
|
+
export declare function setupThumbnailScene(renderScene: RBXRendererScene): void;
|
|
2552
|
+
|
|
2504
2553
|
declare class SimpleView {
|
|
2505
2554
|
view: DataView;
|
|
2506
2555
|
viewOffset: number;
|
|
@@ -2604,6 +2653,10 @@ export declare interface ThumbnailCustomizations_Result {
|
|
|
2604
2653
|
}[];
|
|
2605
2654
|
}
|
|
2606
2655
|
|
|
2656
|
+
export declare type ThumbnailResult = ArrayBuffer | {
|
|
2657
|
+
[key: string]: unknown;
|
|
2658
|
+
} | string | undefined;
|
|
2659
|
+
|
|
2607
2660
|
export declare interface ThumbnailsCustomization_Payload {
|
|
2608
2661
|
thumbnailType: number;
|
|
2609
2662
|
emoteAssetId: number;
|
|
@@ -2614,6 +2667,8 @@ export declare interface ThumbnailsCustomization_Payload {
|
|
|
2614
2667
|
};
|
|
2615
2668
|
}
|
|
2616
2669
|
|
|
2670
|
+
export declare type ThumbnailType = "png" | "webp" | "gltf";
|
|
2671
|
+
|
|
2617
2672
|
export declare class ToolWrapper extends InstanceWrapper {
|
|
2618
2673
|
static className: string;
|
|
2619
2674
|
static requiredProperties: string[];
|
|
@@ -2801,4 +2856,6 @@ export declare const xmlMagic = "<roblox ";
|
|
|
2801
2856
|
|
|
2802
2857
|
export declare function zoomExtents(cameraCFrame: CFrame, modelCFrame: CFrame, modelSize: Vector3, targetFOV: number, distanceScale: number): void;
|
|
2803
2858
|
|
|
2859
|
+
export declare function zoomToExtents(cameraCFrame: CFrame, modelCFrame: CFrame, modelSize: Vector3, fov?: number): void;
|
|
2860
|
+
|
|
2804
2861
|
export { }
|
package/dist/index.js
CHANGED
|
@@ -27277,7 +27277,8 @@ const AnimationPropToName = {
|
|
|
27277
27277
|
"dance1": "dance1",
|
|
27278
27278
|
"dance2": "dance2",
|
|
27279
27279
|
"dance3": "dance3",
|
|
27280
|
-
"toolnone": "toolnone"
|
|
27280
|
+
"toolnone": "toolnone",
|
|
27281
|
+
"pose": "pose"
|
|
27281
27282
|
};
|
|
27282
27283
|
const DefaultAnimations = {
|
|
27283
27284
|
"ClimbAnimation": ["climb", [["ClimbAnim", 507765644n]]],
|
|
@@ -27292,7 +27293,8 @@ const DefaultAnimations = {
|
|
|
27292
27293
|
"dance1": ["dance1", [["2", 507772104n]]],
|
|
27293
27294
|
"dance2": ["dance2", [["2", 507776879n]]],
|
|
27294
27295
|
"dance3": ["dance3", [["2", 507777623n]]],
|
|
27295
|
-
"toolnone": ["toolnone", [["ToolNoneAnim", 507768375n]]]
|
|
27296
|
+
"toolnone": ["toolnone", [["ToolNoneAnim", 507768375n]]],
|
|
27297
|
+
"pose": ["pose", [["pose", 11600209531n]]]
|
|
27296
27298
|
};
|
|
27297
27299
|
const DefaultAnimationsR6 = {
|
|
27298
27300
|
"ClimbAnimation": ["climb", [["ClimbAnim", 180436334n]]],
|
|
@@ -27307,7 +27309,8 @@ const DefaultAnimationsR6 = {
|
|
|
27307
27309
|
"dance1": ["dance1", [["2", 182491065n]]],
|
|
27308
27310
|
"dance2": ["dance2", [["2", 182491277n]]],
|
|
27309
27311
|
"dance3": ["dance3", [["2", 182491423n]]],
|
|
27310
|
-
"toolnone": ["toolnone", [["ToolNoneAnim", 182393478n]]]
|
|
27312
|
+
"toolnone": ["toolnone", [["ToolNoneAnim", 182393478n]]],
|
|
27313
|
+
"pose": ["pose", []]
|
|
27311
27314
|
};
|
|
27312
27315
|
const animNamesR6 = {
|
|
27313
27316
|
idle: [
|
|
@@ -27410,6 +27413,9 @@ const animNamesR15 = {
|
|
|
27410
27413
|
],
|
|
27411
27414
|
mood: [
|
|
27412
27415
|
{ id: "http://www.roblox.com/asset/?id=14366558676", weight: 10 }
|
|
27416
|
+
],
|
|
27417
|
+
pose: [
|
|
27418
|
+
{ id: "http://www.roblox.com/asset/?id=11600209531", weight: 10 }
|
|
27413
27419
|
]
|
|
27414
27420
|
/*wave: [
|
|
27415
27421
|
{ id: "http://www.roblox.com/asset/?id=507770239", weight: 10 }
|
|
@@ -28490,7 +28496,7 @@ function hashVec3Safe(a, b, c) {
|
|
|
28490
28496
|
a = BigInt(a);
|
|
28491
28497
|
b = BigInt(b);
|
|
28492
28498
|
c = BigInt(c);
|
|
28493
|
-
return a *
|
|
28499
|
+
return a * 10000000n + b * 1000n + c * 1n;
|
|
28494
28500
|
}
|
|
28495
28501
|
function calculateMagnitude3D(x, y, z) {
|
|
28496
28502
|
return Math.sqrt(x * x + y * y + z * z);
|
|
@@ -28663,6 +28669,7 @@ function buildVertKD(mesh) {
|
|
|
28663
28669
|
function inheritUV(to, from) {
|
|
28664
28670
|
const meshCollider = new MeshCollider(to);
|
|
28665
28671
|
const faceKD = buildFaceKD(from);
|
|
28672
|
+
const edgeCountMap = from.coreMesh.getEdgeCounts();
|
|
28666
28673
|
for (let i = 0; i < to.coreMesh.numverts; i++) {
|
|
28667
28674
|
const pos = to.coreMesh.getPos(i);
|
|
28668
28675
|
const closest = nearestSearch(faceKD, pos);
|
|
@@ -28671,6 +28678,7 @@ function inheritUV(to, from) {
|
|
|
28671
28678
|
const va = from.coreMesh.getUV(face[0]);
|
|
28672
28679
|
const vb = from.coreMesh.getUV(face[1]);
|
|
28673
28680
|
const vc = from.coreMesh.getUV(face[2]);
|
|
28681
|
+
let newAlpha = 255;
|
|
28674
28682
|
const triangle = from.coreMesh.getTriangle(closestI);
|
|
28675
28683
|
const closestPointPos = closestPointTriangle(pos, triangle);
|
|
28676
28684
|
const barycentricPos = barycentric(closestPointPos, triangle);
|
|
@@ -28678,15 +28686,27 @@ function inheritUV(to, from) {
|
|
|
28678
28686
|
barycentricPos[0] * va[0] + barycentricPos[1] * vb[0] + barycentricPos[2] * vc[0],
|
|
28679
28687
|
barycentricPos[0] * va[1] + barycentricPos[1] * vb[1] + barycentricPos[2] * vc[1]
|
|
28680
28688
|
];
|
|
28689
|
+
if (barycentricPos[0] <= 0.1) {
|
|
28690
|
+
const edgeId = from.coreMesh.getEdgeId(face[1], face[2]);
|
|
28691
|
+
const edgeCount = edgeCountMap.get(edgeId) || 999;
|
|
28692
|
+
if (edgeCount <= 1) newAlpha = 0;
|
|
28693
|
+
} else if (barycentricPos[1] <= 0.1) {
|
|
28694
|
+
const edgeId = from.coreMesh.getEdgeId(face[0], face[2]);
|
|
28695
|
+
const edgeCount = edgeCountMap.get(edgeId) || 999;
|
|
28696
|
+
if (edgeCount <= 1) newAlpha = 0;
|
|
28697
|
+
} else if (barycentricPos[2] <= 0.1) {
|
|
28698
|
+
const edgeId = from.coreMesh.getEdgeId(face[0], face[1]);
|
|
28699
|
+
const edgeCount = edgeCountMap.get(edgeId) || 999;
|
|
28700
|
+
if (edgeCount <= 1) newAlpha = 0;
|
|
28701
|
+
}
|
|
28681
28702
|
const ray = new Ray$1(pos, closestPointPos);
|
|
28682
28703
|
if (meshCollider.raycast(ray)) {
|
|
28683
|
-
|
|
28684
|
-
newUV[1] = -Infinity;
|
|
28704
|
+
newAlpha = 0;
|
|
28685
28705
|
}
|
|
28686
28706
|
if (magnitude(minus(closestPointPos, pos)) > 0.1) {
|
|
28687
|
-
|
|
28688
|
-
newUV[1] = -Infinity;
|
|
28707
|
+
newAlpha = 0;
|
|
28689
28708
|
}
|
|
28709
|
+
to.coreMesh.setColor(i, [255, 255, 255, newAlpha]);
|
|
28690
28710
|
to.coreMesh.setUV(i, newUV);
|
|
28691
28711
|
}
|
|
28692
28712
|
}
|
|
@@ -29505,7 +29525,7 @@ const FLAGS = {
|
|
|
29505
29525
|
//only used by linear algorithms
|
|
29506
29526
|
LAYERED_CLOTHING_ALGORITHM: "rbf",
|
|
29507
29527
|
SHOW_CAGE: false,
|
|
29508
|
-
LAYERED_CLOTHING_COOLDOWN: 0.
|
|
29528
|
+
LAYERED_CLOTHING_COOLDOWN: 0.25,
|
|
29509
29529
|
GET_WORKER_FUNC: DefaultGetWorkerFunc,
|
|
29510
29530
|
RBF_PATCH_COUNT: 300,
|
|
29511
29531
|
//amount of "patches" that are used for layered clothing, multiple verts share the same patch
|
|
@@ -29523,6 +29543,9 @@ const FLAGS = {
|
|
|
29523
29543
|
AUDIO_ENABLED: true,
|
|
29524
29544
|
LEGACY_WELD_BEHAVIOR: false,
|
|
29525
29545
|
USE_RENDERTARGET: true,
|
|
29546
|
+
AUTO_RESTORE_CONTEXT: true,
|
|
29547
|
+
RENDERTARGET_TO_CANVASTEXTURE: false,
|
|
29548
|
+
THUMBNAIL_TIMEOUT: 750,
|
|
29526
29549
|
//skeleton
|
|
29527
29550
|
SHOW_SKELETON_HELPER: false,
|
|
29528
29551
|
UPDATE_SKELETON: true,
|
|
@@ -33961,6 +33984,36 @@ class COREMESH {
|
|
|
33961
33984
|
}
|
|
33962
33985
|
return touchingVerts;
|
|
33963
33986
|
}
|
|
33987
|
+
getEdgeId(v0, v1) {
|
|
33988
|
+
const [x0, y0, z0] = this.getPos(v0);
|
|
33989
|
+
const [x1, y1, z1] = this.getPos(v1);
|
|
33990
|
+
const v0h = hashVec3Safe(Math.round(x0 * 1e3), Math.round(y0 * 1e3), Math.round(z0 * 1e3));
|
|
33991
|
+
const v1h = hashVec3Safe(Math.round(x1 * 1e3), Math.round(y1 * 1e3), Math.round(z1 * 1e3));
|
|
33992
|
+
const tv0 = v0h < v1h ? v0h : v1h;
|
|
33993
|
+
const tv1 = v0h > v1h ? v0h : v1h;
|
|
33994
|
+
return tv1 * 10000000n + tv0;
|
|
33995
|
+
}
|
|
33996
|
+
getFaceEdges(i) {
|
|
33997
|
+
const face = this.getFace(i);
|
|
33998
|
+
const edge0 = this.getEdgeId(face[0], face[1]);
|
|
33999
|
+
const edge1 = this.getEdgeId(face[1], face[2]);
|
|
34000
|
+
const edge2 = this.getEdgeId(face[2], face[0]);
|
|
34001
|
+
return [edge0, edge1, edge2];
|
|
34002
|
+
}
|
|
34003
|
+
getEdgeCounts() {
|
|
34004
|
+
const edgeCountMap = /* @__PURE__ */ new Map();
|
|
34005
|
+
for (let i = 0; i < this.numfaces; i++) {
|
|
34006
|
+
const edges = this.getFaceEdges(i);
|
|
34007
|
+
for (const edge of edges) {
|
|
34008
|
+
if (!edgeCountMap.has(edge)) {
|
|
34009
|
+
edgeCountMap.set(edge, 1);
|
|
34010
|
+
} else {
|
|
34011
|
+
edgeCountMap.set(edge, edgeCountMap.get(edge) + 1);
|
|
34012
|
+
}
|
|
34013
|
+
}
|
|
34014
|
+
}
|
|
34015
|
+
return edgeCountMap;
|
|
34016
|
+
}
|
|
33964
34017
|
}
|
|
33965
34018
|
class LODS {
|
|
33966
34019
|
lodType = LodType.Unknown;
|
|
@@ -36095,6 +36148,15 @@ const API = {
|
|
|
36095
36148
|
return await response.json();
|
|
36096
36149
|
}
|
|
36097
36150
|
},
|
|
36151
|
+
"Subscriptions": {
|
|
36152
|
+
HasPlus: async function() {
|
|
36153
|
+
const response = await RBLXGet("https://apis.roblox.com/subscriptions/v2/user/subscriptions?ProductType=Blackbird&ResultsPerPage=1");
|
|
36154
|
+
if (response.status !== 200) {
|
|
36155
|
+
return response;
|
|
36156
|
+
}
|
|
36157
|
+
return (await response.json()).subscriptions.length > 0;
|
|
36158
|
+
}
|
|
36159
|
+
},
|
|
36098
36160
|
"RBLXGet": RBLXGet,
|
|
36099
36161
|
"RBLXPost": RBLXPost,
|
|
36100
36162
|
"RBLXDelete": RBLXDelete,
|
|
@@ -42316,27 +42378,7 @@ class MeshDesc {
|
|
|
42316
42378
|
}
|
|
42317
42379
|
return true;
|
|
42318
42380
|
}
|
|
42319
|
-
async
|
|
42320
|
-
if (!this.mesh) {
|
|
42321
|
-
return void 0;
|
|
42322
|
-
}
|
|
42323
|
-
const meshToLoad = this.mesh;
|
|
42324
|
-
const mesh = await API.Asset.GetMesh(meshToLoad, void 0);
|
|
42325
|
-
if (mesh instanceof Response) {
|
|
42326
|
-
warn(true, "Failed to get mesh for compileMesh", mesh);
|
|
42327
|
-
return mesh;
|
|
42328
|
-
}
|
|
42329
|
-
if (!mesh.facs && this.headMesh && mesh.skinning.skinnings.length > 0) {
|
|
42330
|
-
const headMesh = await API.Asset.GetMesh(this.headMesh, void 0, true);
|
|
42331
|
-
if (headMesh instanceof Response) {
|
|
42332
|
-
warn(true, "Failed to get headMesh for compileMesh", headMesh);
|
|
42333
|
-
return headMesh;
|
|
42334
|
-
}
|
|
42335
|
-
if (headMesh.facs) {
|
|
42336
|
-
mesh.facs = headMesh.facs.clone();
|
|
42337
|
-
}
|
|
42338
|
-
}
|
|
42339
|
-
let the_ref_mesh = void 0;
|
|
42381
|
+
async wrapDeformer(mesh) {
|
|
42340
42382
|
if (this.deformerDesc) {
|
|
42341
42383
|
const meshMap = /* @__PURE__ */ new Map();
|
|
42342
42384
|
const meshPromises = [];
|
|
@@ -42365,6 +42407,9 @@ class MeshDesc {
|
|
|
42365
42407
|
await targetDeformer.solveAsync();
|
|
42366
42408
|
targetDeformer.deformMesh();
|
|
42367
42409
|
}
|
|
42410
|
+
}
|
|
42411
|
+
async wrapLayer(mesh) {
|
|
42412
|
+
let the_ref_mesh = void 0;
|
|
42368
42413
|
if (this.layerDesc && this.modelLayersDesc && this.modelLayersDesc.targetCages && this.modelLayersDesc.targetCages.length > 0 && this.modelLayersDesc.targetCFrames && this.modelLayersDesc.targetSizes && this.modelLayersDesc.layers) {
|
|
42369
42414
|
const meshMap = /* @__PURE__ */ new Map();
|
|
42370
42415
|
const meshPromises = [];
|
|
@@ -42502,8 +42547,11 @@ class MeshDesc {
|
|
|
42502
42547
|
offsetMesh(mesh, totalOffset);
|
|
42503
42548
|
}
|
|
42504
42549
|
if (!FLAGS.SHOW_CAGE) the_ref_mesh = void 0;
|
|
42505
|
-
if (FLAGS.HIDE_LAYERED_CLOTHING) return;
|
|
42550
|
+
if (FLAGS.HIDE_LAYERED_CLOTHING) return the_ref_mesh;
|
|
42506
42551
|
}
|
|
42552
|
+
return the_ref_mesh;
|
|
42553
|
+
}
|
|
42554
|
+
async wrapTarget(mesh) {
|
|
42507
42555
|
if (this.target && this.targetOrigin && this.hsrDesc) {
|
|
42508
42556
|
const meshMap = /* @__PURE__ */ new Map();
|
|
42509
42557
|
const meshPromises = [];
|
|
@@ -42536,6 +42584,8 @@ class MeshDesc {
|
|
|
42536
42584
|
doHSR(totalUvToHits, targetCage, mesh, true, `${this.target}-${this.mesh}`);
|
|
42537
42585
|
}
|
|
42538
42586
|
}
|
|
42587
|
+
}
|
|
42588
|
+
async wrapTextureTransfer(mesh) {
|
|
42539
42589
|
if (this.wrapTextureTarget && this.wrapTextureTargetOrigin && this.wrapTextureMinBound && this.wrapTextureMaxBound) {
|
|
42540
42590
|
const meshMap = /* @__PURE__ */ new Map();
|
|
42541
42591
|
const meshPromises = [];
|
|
@@ -42565,11 +42615,38 @@ class MeshDesc {
|
|
|
42565
42615
|
}
|
|
42566
42616
|
for (let i = mesh.coreMesh.numverts - 1; i >= 0; i--) {
|
|
42567
42617
|
const vertUV = mesh.coreMesh.getUV(i);
|
|
42568
|
-
if (vertUV[0] <
|
|
42569
|
-
mesh.coreMesh.
|
|
42618
|
+
if (vertUV[0] < 0.05 || vertUV[0] > 0.95 || vertUV[1] < 0.05 || vertUV[1] > 0.95) {
|
|
42619
|
+
mesh.coreMesh.setColor(i, [255, 255, 255, 0]);
|
|
42570
42620
|
}
|
|
42571
42621
|
}
|
|
42572
42622
|
}
|
|
42623
|
+
}
|
|
42624
|
+
async compileMesh() {
|
|
42625
|
+
if (!this.mesh) return;
|
|
42626
|
+
const meshToLoad = this.mesh;
|
|
42627
|
+
const mesh = await API.Asset.GetMesh(meshToLoad, void 0);
|
|
42628
|
+
if (mesh instanceof Response) {
|
|
42629
|
+
warn(true, "Failed to get mesh for compileMesh", mesh);
|
|
42630
|
+
return mesh;
|
|
42631
|
+
}
|
|
42632
|
+
if (!mesh.facs && this.headMesh && mesh.skinning.skinnings.length > 0) {
|
|
42633
|
+
const headMesh = await API.Asset.GetMesh(this.headMesh, void 0, true);
|
|
42634
|
+
if (headMesh instanceof Response) {
|
|
42635
|
+
warn(true, "Failed to get headMesh for compileMesh", headMesh);
|
|
42636
|
+
return headMesh;
|
|
42637
|
+
}
|
|
42638
|
+
if (headMesh.facs) {
|
|
42639
|
+
mesh.facs = headMesh.facs.clone();
|
|
42640
|
+
}
|
|
42641
|
+
}
|
|
42642
|
+
const wrapDeformerResult = await this.wrapDeformer(mesh);
|
|
42643
|
+
if (wrapDeformerResult instanceof Response) return wrapDeformerResult;
|
|
42644
|
+
const the_ref_mesh = await this.wrapLayer(mesh);
|
|
42645
|
+
if (the_ref_mesh instanceof Response) return the_ref_mesh;
|
|
42646
|
+
const wrapTargetResult = await this.wrapTarget(mesh);
|
|
42647
|
+
if (wrapTargetResult instanceof Response) return wrapTargetResult;
|
|
42648
|
+
const wrapTextureTransferResult = await this.wrapTextureTransfer(mesh);
|
|
42649
|
+
if (wrapTextureTransferResult instanceof Response) return wrapTextureTransferResult;
|
|
42573
42650
|
this.fileMesh = mesh;
|
|
42574
42651
|
const geometry = fileMeshToTHREEGeometry(the_ref_mesh || mesh, this.canHaveSkinning, this.forceVertexColor);
|
|
42575
42652
|
let threeMesh = void 0;
|
|
@@ -42609,6 +42686,9 @@ class MeshDesc {
|
|
|
42609
42686
|
break;
|
|
42610
42687
|
}
|
|
42611
42688
|
}
|
|
42689
|
+
if (child.className === "Decal") {
|
|
42690
|
+
this.forceVertexColor = void 0;
|
|
42691
|
+
}
|
|
42612
42692
|
}
|
|
42613
42693
|
fromPart(child) {
|
|
42614
42694
|
this.canHaveSkinning = false;
|
|
@@ -43125,6 +43205,26 @@ function fastMask(mask, image) {
|
|
|
43125
43205
|
ctx.drawImage(image, 0, 0, mask.width, mask.height);
|
|
43126
43206
|
return canvas;
|
|
43127
43207
|
}
|
|
43208
|
+
function imageDataToCanvas(data, width, height) {
|
|
43209
|
+
const offscreenCanvas = new OffscreenCanvas(width, height);
|
|
43210
|
+
const offscreenCtx = offscreenCanvas.getContext("2d");
|
|
43211
|
+
const canvas = document.createElement("canvas");
|
|
43212
|
+
const ctx = canvas.getContext("2d");
|
|
43213
|
+
canvas.width = width;
|
|
43214
|
+
canvas.height = height;
|
|
43215
|
+
if (!ctx || !offscreenCtx) {
|
|
43216
|
+
throw new Error("Failed to get CanvasContext");
|
|
43217
|
+
}
|
|
43218
|
+
const imgData = new ImageData(new Uint8ClampedArray(data.buffer), width, height);
|
|
43219
|
+
offscreenCtx.putImageData(imgData, 0, 0);
|
|
43220
|
+
ctx.translate(0, height);
|
|
43221
|
+
ctx.scale(1, -1);
|
|
43222
|
+
ctx.drawImage(offscreenCanvas, 0, 0);
|
|
43223
|
+
return canvas;
|
|
43224
|
+
}
|
|
43225
|
+
function imageDataToCanvasTexture(data, width, height) {
|
|
43226
|
+
return new CanvasTexture(imageDataToCanvas(data, width, height));
|
|
43227
|
+
}
|
|
43128
43228
|
class ColorLayer {
|
|
43129
43229
|
color;
|
|
43130
43230
|
bodyPart;
|
|
@@ -43169,9 +43269,11 @@ class MaterialDesc {
|
|
|
43169
43269
|
bodyPart;
|
|
43170
43270
|
//should only be accounted for if uvType != Normal in TextureLayer
|
|
43171
43271
|
avatarType;
|
|
43272
|
+
dirty = false;
|
|
43172
43273
|
//result
|
|
43173
43274
|
createdTextures = [];
|
|
43174
43275
|
isSame(other) {
|
|
43276
|
+
if (this.dirty || other.dirty) return false;
|
|
43175
43277
|
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;
|
|
43176
43278
|
let layersSame = true;
|
|
43177
43279
|
if (this.layers.length !== other.layers.length) {
|
|
@@ -43473,7 +43575,7 @@ class MaterialDesc {
|
|
|
43473
43575
|
}
|
|
43474
43576
|
let hasTransparency = false;
|
|
43475
43577
|
const rbxRenderer = RBXRenderer.getRenderer();
|
|
43476
|
-
if (!hasColorLayer && rbxRenderer) {
|
|
43578
|
+
if (!hasColorLayer && rbxRenderer || FLAGS.RENDERTARGET_TO_CANVASTEXTURE && rbxRenderer) {
|
|
43477
43579
|
const data = new Uint8Array(width * height * 4);
|
|
43478
43580
|
await rbxRenderer.readRenderTargetPixelsAsync(renderTarget, 0, 0, width, height, data);
|
|
43479
43581
|
for (let i = 3; i < data.length; i += 4) {
|
|
@@ -43482,6 +43584,15 @@ class MaterialDesc {
|
|
|
43482
43584
|
break;
|
|
43483
43585
|
}
|
|
43484
43586
|
}
|
|
43587
|
+
if (FLAGS.RENDERTARGET_TO_CANVASTEXTURE) {
|
|
43588
|
+
const ogTexture = texture;
|
|
43589
|
+
texture = imageDataToCanvasTexture(data, width, height);
|
|
43590
|
+
texture.colorSpace = textureType === "color" ? SRGBColorSpace : NoColorSpace;
|
|
43591
|
+
texture.wrapS = ogTexture.wrapS;
|
|
43592
|
+
texture.wrapT = ogTexture.wrapT;
|
|
43593
|
+
texture.minFilter = ogTexture.minFilter;
|
|
43594
|
+
texture.magFilter = ogTexture.magFilter;
|
|
43595
|
+
}
|
|
43485
43596
|
}
|
|
43486
43597
|
if (!this.transparent) {
|
|
43487
43598
|
hasTransparency = false;
|
|
@@ -43534,7 +43645,7 @@ class MaterialDesc {
|
|
|
43534
43645
|
}
|
|
43535
43646
|
}
|
|
43536
43647
|
let hasTransparency = false;
|
|
43537
|
-
if (this.transparent) {
|
|
43648
|
+
if (this.transparent || FLAGS.RENDERTARGET_TO_CANVASTEXTURE) {
|
|
43538
43649
|
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
|
43539
43650
|
const data = imageData.data;
|
|
43540
43651
|
for (let i = 3; i < data.length; i += 4) {
|
|
@@ -43549,7 +43660,32 @@ class MaterialDesc {
|
|
|
43549
43660
|
texture.needsUpdate = true;
|
|
43550
43661
|
return [texture, hasTransparency];
|
|
43551
43662
|
}
|
|
43552
|
-
async
|
|
43663
|
+
async compileTexture_DirectCompose(textureType) {
|
|
43664
|
+
let textureUrl = void 0;
|
|
43665
|
+
for (const layer of this.layers) {
|
|
43666
|
+
if (layer instanceof TextureLayer) {
|
|
43667
|
+
if (layer[textureType]) {
|
|
43668
|
+
textureUrl = layer[textureType];
|
|
43669
|
+
}
|
|
43670
|
+
}
|
|
43671
|
+
}
|
|
43672
|
+
if (textureUrl) {
|
|
43673
|
+
const image = await API.Generic.LoadImage(textureUrl);
|
|
43674
|
+
if (image) {
|
|
43675
|
+
let hasTransparency = true;
|
|
43676
|
+
if (!this.transparent) {
|
|
43677
|
+
hasTransparency = false;
|
|
43678
|
+
}
|
|
43679
|
+
const texture = new Texture(image);
|
|
43680
|
+
texture.wrapS = RepeatWrapping;
|
|
43681
|
+
texture.wrapT = RepeatWrapping;
|
|
43682
|
+
texture.colorSpace = textureType === "color" ? SRGBColorSpace : NoColorSpace;
|
|
43683
|
+
texture.needsUpdate = true;
|
|
43684
|
+
return [texture, hasTransparency];
|
|
43685
|
+
}
|
|
43686
|
+
}
|
|
43687
|
+
}
|
|
43688
|
+
getComposeType(textureType) {
|
|
43553
43689
|
let hasSpecialUVType = false;
|
|
43554
43690
|
let hasColorLayer = false;
|
|
43555
43691
|
let hasLayerOfType = false;
|
|
@@ -43571,33 +43707,23 @@ class MaterialDesc {
|
|
|
43571
43707
|
}
|
|
43572
43708
|
if (!hasLayerOfType) return;
|
|
43573
43709
|
if ((hasSpecialUVType || this.bodyPart !== void 0) && FLAGS.USE_RENDERTARGET) {
|
|
43574
|
-
return
|
|
43575
|
-
} else if (this.layers.length > 1 || hasColorLayer && FLAGS.USE_RENDERTARGET) {
|
|
43576
|
-
return
|
|
43710
|
+
return "full";
|
|
43711
|
+
} else if ((this.layers.length > 1 || hasColorLayer) && FLAGS.USE_RENDERTARGET) {
|
|
43712
|
+
return "simple";
|
|
43577
43713
|
} else {
|
|
43578
|
-
|
|
43579
|
-
|
|
43580
|
-
|
|
43581
|
-
|
|
43582
|
-
|
|
43583
|
-
|
|
43584
|
-
|
|
43585
|
-
|
|
43586
|
-
|
|
43587
|
-
|
|
43588
|
-
|
|
43589
|
-
|
|
43590
|
-
|
|
43591
|
-
hasTransparency = false;
|
|
43592
|
-
}
|
|
43593
|
-
const texture = new Texture(image);
|
|
43594
|
-
texture.wrapS = RepeatWrapping;
|
|
43595
|
-
texture.wrapT = RepeatWrapping;
|
|
43596
|
-
texture.colorSpace = textureType === "color" ? SRGBColorSpace : NoColorSpace;
|
|
43597
|
-
texture.needsUpdate = true;
|
|
43598
|
-
return [texture, hasTransparency];
|
|
43599
|
-
}
|
|
43600
|
-
}
|
|
43714
|
+
return "direct";
|
|
43715
|
+
}
|
|
43716
|
+
}
|
|
43717
|
+
async compileTexture(textureType, meshDesc) {
|
|
43718
|
+
const composeType = this.getComposeType(textureType);
|
|
43719
|
+
if (!composeType) return;
|
|
43720
|
+
switch (composeType) {
|
|
43721
|
+
case "full":
|
|
43722
|
+
return this.compileTexture_FullCompose(textureType, meshDesc);
|
|
43723
|
+
case "simple":
|
|
43724
|
+
return this.compileTexture_SimpleCompose(textureType);
|
|
43725
|
+
case "direct":
|
|
43726
|
+
return this.compileTexture_DirectCompose(textureType);
|
|
43601
43727
|
}
|
|
43602
43728
|
}
|
|
43603
43729
|
async compileMaterial(meshDesc) {
|
|
@@ -43639,13 +43765,15 @@ class MaterialDesc {
|
|
|
43639
43765
|
hasTransparency = true;
|
|
43640
43766
|
}
|
|
43641
43767
|
let material = void 0;
|
|
43768
|
+
const textureTemplate = {};
|
|
43769
|
+
if (colorTexture) textureTemplate.map = colorTexture;
|
|
43770
|
+
if (normalTexture) textureTemplate.normalMap = normalTexture;
|
|
43771
|
+
if (roughnessTexture) textureTemplate.roughnessMap = roughnessTexture;
|
|
43772
|
+
if (metalnessTexture) textureTemplate.metalnessMap = metalnessTexture;
|
|
43773
|
+
if (emissiveTexture) textureTemplate.emissiveMap = emissiveTexture;
|
|
43642
43774
|
if (normalTexture || roughnessTexture || metalnessTexture || emissiveTexture) {
|
|
43643
43775
|
material = new MeshStandardMaterial({
|
|
43644
|
-
|
|
43645
|
-
normalMap: normalTexture,
|
|
43646
|
-
roughnessMap: roughnessTexture,
|
|
43647
|
-
metalnessMap: metalnessTexture,
|
|
43648
|
-
emissiveMap: emissiveTexture,
|
|
43776
|
+
...textureTemplate,
|
|
43649
43777
|
emissiveIntensity: hasEmissive ? this.emissiveStrength : 0,
|
|
43650
43778
|
emissive: hasEmissive ? new Color(this.emissiveTint.R, this.emissiveTint.G, this.emissiveTint.B) : new Color(0, 0, 0),
|
|
43651
43779
|
transparent: hasTransparency,
|
|
@@ -43661,7 +43789,7 @@ class MaterialDesc {
|
|
|
43661
43789
|
});
|
|
43662
43790
|
} else {
|
|
43663
43791
|
material = new MeshPhongMaterial({
|
|
43664
|
-
|
|
43792
|
+
...textureTemplate,
|
|
43665
43793
|
specular: new Color(1 / 102, 1 / 102, 1 / 102),
|
|
43666
43794
|
shininess: 9,
|
|
43667
43795
|
transparent: hasTransparency,
|
|
@@ -44761,31 +44889,7 @@ class SkeletonDesc2 {
|
|
|
44761
44889
|
}
|
|
44762
44890
|
class DisposableDesc {
|
|
44763
44891
|
disposeMesh(scene, mesh) {
|
|
44764
|
-
|
|
44765
|
-
const materials = Array.isArray(mesh.material) ? mesh.material : [mesh.material];
|
|
44766
|
-
for (const material of materials) {
|
|
44767
|
-
for (const key of Object.keys(material)) {
|
|
44768
|
-
const value = material[key];
|
|
44769
|
-
if (value instanceof Texture) {
|
|
44770
|
-
value.dispose();
|
|
44771
|
-
}
|
|
44772
|
-
}
|
|
44773
|
-
if (material instanceof ShaderMaterial) {
|
|
44774
|
-
const uniforms = material.uniforms;
|
|
44775
|
-
for (const key of Object.keys(uniforms)) {
|
|
44776
|
-
const value = uniforms[key].value;
|
|
44777
|
-
if (value instanceof Texture) {
|
|
44778
|
-
value.dispose();
|
|
44779
|
-
}
|
|
44780
|
-
}
|
|
44781
|
-
}
|
|
44782
|
-
material.dispose();
|
|
44783
|
-
}
|
|
44784
|
-
}
|
|
44785
|
-
if (mesh.geometry) {
|
|
44786
|
-
mesh.geometry.dispose();
|
|
44787
|
-
}
|
|
44788
|
-
scene.remove(mesh);
|
|
44892
|
+
disposeMesh(scene, mesh);
|
|
44789
44893
|
}
|
|
44790
44894
|
disposeMeshes(scene, meshes) {
|
|
44791
44895
|
for (const mesh of meshes) {
|
|
@@ -47043,6 +47147,26 @@ class AnimatorWrapper extends InstanceWrapper {
|
|
|
47043
47147
|
return false;
|
|
47044
47148
|
}
|
|
47045
47149
|
}
|
|
47150
|
+
class AttachmentWrapper extends InstanceWrapper {
|
|
47151
|
+
static className = "Attachment";
|
|
47152
|
+
static requiredProperties = [
|
|
47153
|
+
"Name",
|
|
47154
|
+
"CFrame"
|
|
47155
|
+
];
|
|
47156
|
+
setup() {
|
|
47157
|
+
if (!this.instance.HasProperty("Name")) this.instance.addProperty(new Property("Name", DataType.String), this.instance.className);
|
|
47158
|
+
if (!this.instance.HasProperty("CFrame")) this.instance.addProperty(new Property("CFrame", DataType.CFrame), new CFrame());
|
|
47159
|
+
}
|
|
47160
|
+
getWorldCFrame() {
|
|
47161
|
+
if (this.instance.parent) {
|
|
47162
|
+
if (this.instance.parent.className.includes("Part")) {
|
|
47163
|
+
const parentCF = this.instance.parent.PropOrDefault("CFrame", new CFrame());
|
|
47164
|
+
return parentCF.multiply(this.instance.Prop("CFrame"));
|
|
47165
|
+
}
|
|
47166
|
+
}
|
|
47167
|
+
return this.instance.Prop("CFrame");
|
|
47168
|
+
}
|
|
47169
|
+
}
|
|
47046
47170
|
class BodyColorsWrapper extends InstanceWrapper {
|
|
47047
47171
|
static className = "BodyColors";
|
|
47048
47172
|
static requiredProperties = [
|
|
@@ -48592,6 +48716,7 @@ class HumanoidDescriptionWrapper extends InstanceWrapper {
|
|
|
48592
48716
|
toChange.push("dance2");
|
|
48593
48717
|
toChange.push("dance3");
|
|
48594
48718
|
toChange.push("toolnone");
|
|
48719
|
+
if (this.instance.Prop("IdleAnimation") <= 0) toChange.push("pose");
|
|
48595
48720
|
}
|
|
48596
48721
|
miniPromises.push(this._applyAnimations(humanoid, toChange));
|
|
48597
48722
|
}
|
|
@@ -48961,6 +49086,7 @@ function RegisterWrappers() {
|
|
|
48961
49086
|
WeldWrapper.register();
|
|
48962
49087
|
Motor6DWrapper.register();
|
|
48963
49088
|
ManualWeldWrapper.register();
|
|
49089
|
+
AttachmentWrapper.register();
|
|
48964
49090
|
AnimationConstraintWrapper.register();
|
|
48965
49091
|
AnimatorWrapper.register();
|
|
48966
49092
|
FaceControlsWrapper.register();
|
|
@@ -48971,11 +49097,40 @@ function RegisterWrappers() {
|
|
|
48971
49097
|
BodyColorsWrapper.register();
|
|
48972
49098
|
AccessoryWrapper.register();
|
|
48973
49099
|
}
|
|
49100
|
+
function disposeMesh(scene, mesh) {
|
|
49101
|
+
if (mesh.material) {
|
|
49102
|
+
const materials = Array.isArray(mesh.material) ? mesh.material : [mesh.material];
|
|
49103
|
+
for (const material of materials) {
|
|
49104
|
+
for (const key of Object.keys(material)) {
|
|
49105
|
+
const value = material[key];
|
|
49106
|
+
if (value instanceof Texture) {
|
|
49107
|
+
value.dispose();
|
|
49108
|
+
}
|
|
49109
|
+
}
|
|
49110
|
+
if (material instanceof ShaderMaterial) {
|
|
49111
|
+
const uniforms = material.uniforms;
|
|
49112
|
+
for (const key of Object.keys(uniforms)) {
|
|
49113
|
+
const value = uniforms[key].value;
|
|
49114
|
+
if (value instanceof Texture) {
|
|
49115
|
+
value.dispose();
|
|
49116
|
+
}
|
|
49117
|
+
}
|
|
49118
|
+
}
|
|
49119
|
+
material.dispose();
|
|
49120
|
+
}
|
|
49121
|
+
}
|
|
49122
|
+
if (mesh.geometry) {
|
|
49123
|
+
mesh.geometry.dispose();
|
|
49124
|
+
}
|
|
49125
|
+
scene.remove(mesh);
|
|
49126
|
+
}
|
|
48974
49127
|
class RBXRendererScene {
|
|
48975
49128
|
//important scene components
|
|
48976
49129
|
scene = new Scene();
|
|
48977
49130
|
camera = new PerspectiveCamera(70, 1 / 1, 0.1, 100);
|
|
48978
49131
|
controls;
|
|
49132
|
+
shouldAnimate = true;
|
|
49133
|
+
destroyed = false;
|
|
48979
49134
|
//renderer
|
|
48980
49135
|
effectComposer;
|
|
48981
49136
|
//viewport
|
|
@@ -49014,6 +49169,39 @@ class RBXRendererScene {
|
|
|
49014
49169
|
this.viewport = [0, 0, 0, 0];
|
|
49015
49170
|
this.scissor = [0, 0, 0, 0];
|
|
49016
49171
|
}
|
|
49172
|
+
destroy() {
|
|
49173
|
+
if (this.destroyed) return;
|
|
49174
|
+
this.destroyed = true;
|
|
49175
|
+
for (const instance of this.renderDescs.keys()) {
|
|
49176
|
+
RBXRenderer.removeInstance(instance, this);
|
|
49177
|
+
}
|
|
49178
|
+
RBXRenderer.scenes.splice(RBXRenderer.scenes.indexOf(this), 1);
|
|
49179
|
+
if (this.plane) {
|
|
49180
|
+
disposeMesh(this.scene, this.plane);
|
|
49181
|
+
this.plane = void 0;
|
|
49182
|
+
}
|
|
49183
|
+
if (this.shadowPlane) {
|
|
49184
|
+
disposeMesh(this.scene, this.shadowPlane);
|
|
49185
|
+
this.shadowPlane = void 0;
|
|
49186
|
+
}
|
|
49187
|
+
}
|
|
49188
|
+
async exportGLTF(name = "scene", autoDownload = true) {
|
|
49189
|
+
return new Promise((resolve, reject) => {
|
|
49190
|
+
const exporter = new GLTFExporter();
|
|
49191
|
+
exporter.parse(this.scene, (gltf) => {
|
|
49192
|
+
if (autoDownload) {
|
|
49193
|
+
if (gltf instanceof ArrayBuffer) {
|
|
49194
|
+
saveByteArray([gltf], `${name}.glb`);
|
|
49195
|
+
} else {
|
|
49196
|
+
download(`${name}.gltf`, JSON.stringify(gltf));
|
|
49197
|
+
}
|
|
49198
|
+
}
|
|
49199
|
+
resolve(gltf);
|
|
49200
|
+
}, (error2) => {
|
|
49201
|
+
reject(error2);
|
|
49202
|
+
});
|
|
49203
|
+
});
|
|
49204
|
+
}
|
|
49017
49205
|
}
|
|
49018
49206
|
class RBXRenderer {
|
|
49019
49207
|
static orbitControlsTarget = [0, 3, 0];
|
|
@@ -49200,8 +49388,8 @@ class RBXRenderer {
|
|
|
49200
49388
|
RBXRenderer.canvasContainer.style.height = `${RBXRenderer.resolution[1]}px`;
|
|
49201
49389
|
}
|
|
49202
49390
|
/**Sets up the THREE.js renderer */
|
|
49203
|
-
static create() {
|
|
49204
|
-
RBXRenderer.renderer = new WebGLRenderer({ antialias: true, alpha: true });
|
|
49391
|
+
static create(canvas) {
|
|
49392
|
+
RBXRenderer.renderer = new WebGLRenderer({ antialias: true, alpha: true, canvas });
|
|
49205
49393
|
RBXRenderer.renderer.setClearColor(new Color(1, 0, 1), 0);
|
|
49206
49394
|
RBXRenderer.renderer.outputColorSpace = SRGBColorSpace;
|
|
49207
49395
|
RBXRenderer.renderer.shadowMap.enabled = true;
|
|
@@ -49213,12 +49401,45 @@ class RBXRenderer {
|
|
|
49213
49401
|
}
|
|
49214
49402
|
RBXRenderer.renderer.domElement.setAttribute("id", "OutfitInfo-outfit-image-3d");
|
|
49215
49403
|
RBXRenderer.canvasContainer.appendChild(RBXRenderer.renderer.domElement);
|
|
49216
|
-
if (RBXRenderer.createLoadingIcon) {
|
|
49404
|
+
if (RBXRenderer.createLoadingIcon && !RBXRenderer.loadingIcon) {
|
|
49217
49405
|
RBXRenderer.createLoadingIconHTML();
|
|
49218
49406
|
}
|
|
49219
49407
|
if (FLAGS.USE_POST_PROCESSING) {
|
|
49220
49408
|
RBXRenderer._createEffectComposer();
|
|
49221
49409
|
}
|
|
49410
|
+
RBXRenderer.setupLostContextHandler();
|
|
49411
|
+
}
|
|
49412
|
+
static setupLostContextHandler() {
|
|
49413
|
+
if (!RBXRenderer.renderer) return;
|
|
49414
|
+
RBXRenderer.renderer.domElement.addEventListener("webglcontextlost", (e) => {
|
|
49415
|
+
e.preventDefault();
|
|
49416
|
+
error(true, "RBXRenderer's WebGL2 context was lost, consider optimizing your WebGL usage");
|
|
49417
|
+
if (FLAGS.AUTO_RESTORE_CONTEXT) {
|
|
49418
|
+
const newCanvas = document.createElement("canvas");
|
|
49419
|
+
if (RBXRenderer.renderer?.domElement) {
|
|
49420
|
+
RBXRenderer.canvasContainer.replaceChild(newCanvas, RBXRenderer.renderer.domElement);
|
|
49421
|
+
}
|
|
49422
|
+
RBXRenderer.renderer?.dispose();
|
|
49423
|
+
RBXRenderer.create(newCanvas);
|
|
49424
|
+
for (const renderScene of RBXRenderer.scenes) {
|
|
49425
|
+
const controls = renderScene.controls;
|
|
49426
|
+
if (controls) {
|
|
49427
|
+
controls.dispose();
|
|
49428
|
+
controls.domElement = newCanvas;
|
|
49429
|
+
controls.connect(newCanvas);
|
|
49430
|
+
}
|
|
49431
|
+
for (const renderDesc of renderScene.renderDescs.values()) {
|
|
49432
|
+
if (renderDesc instanceof ObjectDesc) {
|
|
49433
|
+
const materialDesc = renderDesc.materialDesc;
|
|
49434
|
+
const composeType = materialDesc.getComposeType("color");
|
|
49435
|
+
if (composeType === "full" || composeType === "simple") {
|
|
49436
|
+
materialDesc.dirty = true;
|
|
49437
|
+
}
|
|
49438
|
+
}
|
|
49439
|
+
}
|
|
49440
|
+
}
|
|
49441
|
+
}
|
|
49442
|
+
});
|
|
49222
49443
|
}
|
|
49223
49444
|
/**Sets up a basic scene with lighting
|
|
49224
49445
|
* @param lightingType "WellLit" is the default lighting for RoAvatar, "Thumbnail" tries to match the Roblox thumbnail lighting
|
|
@@ -49374,6 +49595,7 @@ class RBXRenderer {
|
|
|
49374
49595
|
}
|
|
49375
49596
|
static renderScene(renderScene, autoClear = true) {
|
|
49376
49597
|
if (!RBXRenderer.renderer) return;
|
|
49598
|
+
if (!renderScene.shouldAnimate) return;
|
|
49377
49599
|
RBXRenderer.renderer.autoClear = autoClear;
|
|
49378
49600
|
if (!autoClear) {
|
|
49379
49601
|
RBXRenderer.renderer.clearDepth();
|
|
@@ -49494,6 +49716,7 @@ class RBXRenderer {
|
|
|
49494
49716
|
}
|
|
49495
49717
|
/**Adds an instance to the renderer or updates it */
|
|
49496
49718
|
static addInstance(instance, auth, renderScene = RBXRenderer.firstScene) {
|
|
49719
|
+
if (renderScene.destroyed) return;
|
|
49497
49720
|
const isDecal = instance.className === "Decal";
|
|
49498
49721
|
const isBakedDecal = isDecal && !instance.FindFirstChildOfClass("WrapTextureTransfer");
|
|
49499
49722
|
let isFirstDecal = true;
|
|
@@ -49694,14 +49917,6 @@ class HSR {
|
|
|
49694
49917
|
}
|
|
49695
49918
|
}
|
|
49696
49919
|
}
|
|
49697
|
-
function exposeAPI() {
|
|
49698
|
-
globalThis.API = API;
|
|
49699
|
-
globalThis.APICACHE = CACHE;
|
|
49700
|
-
globalThis.Authentication = Authentication;
|
|
49701
|
-
}
|
|
49702
|
-
function exposeMesh() {
|
|
49703
|
-
globalThis.fileMeshToTHREEGeometry = fileMeshToTHREEGeometry;
|
|
49704
|
-
}
|
|
49705
49920
|
function getCorners(cframe, size) {
|
|
49706
49921
|
const halfX = size.X / 2;
|
|
49707
49922
|
const halfY = size.Y / 2;
|
|
@@ -49764,12 +49979,27 @@ function getExtents(cframe, parts) {
|
|
|
49764
49979
|
}
|
|
49765
49980
|
return [lowerExtents, higherExtents];
|
|
49766
49981
|
}
|
|
49982
|
+
function getExtentsCenter(extents) {
|
|
49983
|
+
return extents[1].minus(extents[0]).divide(new Vector32(2, 2, 2)).add(extents[0]);
|
|
49984
|
+
}
|
|
49767
49985
|
function zoomExtents(cameraCFrame, modelCFrame, modelSize, targetFOV, distanceScale) {
|
|
49768
49986
|
const largestSize = Math.max(modelSize.X, modelSize.Y, modelSize.Z);
|
|
49769
49987
|
const fovMultiplier = 70 / targetFOV;
|
|
49770
49988
|
const lookDir = multiply(normalize(minus(cameraCFrame.Position, modelCFrame.Position)), [distanceScale, distanceScale, distanceScale]);
|
|
49771
49989
|
cameraCFrame.Position = add(modelCFrame.Position, multiply(multiply(lookDir, [largestSize, largestSize, largestSize]), [fovMultiplier, fovMultiplier, fovMultiplier]));
|
|
49772
49990
|
}
|
|
49991
|
+
function getCameraOffset(fov2, extentsSize) {
|
|
49992
|
+
const halfSize = extentsSize.magnitude() / 2;
|
|
49993
|
+
const fovDivisor = Math.tan(rad(fov2 / 2));
|
|
49994
|
+
return halfSize / fovDivisor;
|
|
49995
|
+
}
|
|
49996
|
+
function zoomToExtents(cameraCFrame, modelCFrame, modelSize, fov2 = 70) {
|
|
49997
|
+
const cameraOffset = getCameraOffset(fov2, modelSize);
|
|
49998
|
+
const cameraRotation = new CFrame();
|
|
49999
|
+
cameraRotation.Orientation = cameraCFrame.Orientation;
|
|
50000
|
+
const instancePosition = modelCFrame.Position;
|
|
50001
|
+
cameraCFrame.Position = add(instancePosition, multiply(minus([0, 0, 0], cameraRotation.lookVector()), [cameraOffset, cameraOffset, cameraOffset]));
|
|
50002
|
+
}
|
|
49773
50003
|
function getHeadExtents(rig) {
|
|
49774
50004
|
const head = rig.FindFirstChild("Head");
|
|
49775
50005
|
if (!head) return;
|
|
@@ -49789,6 +50019,16 @@ function getHeadExtents(rig) {
|
|
|
49789
50019
|
const extents = getExtents(head.Prop("CFrame"), headParts);
|
|
49790
50020
|
return extents;
|
|
49791
50021
|
}
|
|
50022
|
+
function getRigExtentsWorld(rig) {
|
|
50023
|
+
const rigParts = [];
|
|
50024
|
+
for (const child of rig.GetDescendants()) {
|
|
50025
|
+
if (child.className === "Part" || child.className === "MeshPart") {
|
|
50026
|
+
rigParts.push(child);
|
|
50027
|
+
}
|
|
50028
|
+
}
|
|
50029
|
+
const extents = getExtents(new CFrame(), rigParts);
|
|
50030
|
+
return extents;
|
|
50031
|
+
}
|
|
49792
50032
|
function getCameraCFrameForHeadshotCustomized(rig, fov2, yRot, distance2) {
|
|
49793
50033
|
const head = rig.FindFirstChild("Head");
|
|
49794
50034
|
if (!head) return;
|
|
@@ -49815,6 +50055,34 @@ function getCameraCFrameForHeadshotCustomized(rig, fov2, yRot, distance2) {
|
|
|
49815
50055
|
zoomExtents(cameraCF, headCenterCF, headLocalExtents[1].minus(headLocalExtents[0]), fov2, distance2);
|
|
49816
50056
|
return cameraCF;
|
|
49817
50057
|
}
|
|
50058
|
+
function getCameraCFrameForAvatarNonCustomized(rig) {
|
|
50059
|
+
const thumbnailCamera = rig.FindFirstChildOfClass("Camera");
|
|
50060
|
+
if (thumbnailCamera) return thumbnailCamera.PropOrDefault("CFrame", new CFrame());
|
|
50061
|
+
let rootPart = rig.PropOrDefault("PrimaryPart", void 0);
|
|
50062
|
+
if (!rootPart) rootPart = rig.FindFirstChildOfClass("Part");
|
|
50063
|
+
if (!rootPart) rootPart = rig.FindFirstChildOfClass("MeshPart");
|
|
50064
|
+
if (!rootPart) return;
|
|
50065
|
+
const rootPartCF = rootPart.PropOrDefault("CFrame", new CFrame()).clone();
|
|
50066
|
+
const worldExtents = getRigExtentsWorld(rig);
|
|
50067
|
+
if (!worldExtents) return;
|
|
50068
|
+
const extentsSize = worldExtents[1].minus(worldExtents[0]);
|
|
50069
|
+
rootPartCF.Position = getExtentsCenter(worldExtents).toVec3();
|
|
50070
|
+
let lookVector = rootPartCF.lookVector();
|
|
50071
|
+
if (Math.abs(lookVector[1]) > 0.95) {
|
|
50072
|
+
lookVector = [0, 0, -1];
|
|
50073
|
+
} else {
|
|
50074
|
+
lookVector[1] = 0;
|
|
50075
|
+
lookVector = normalize(lookVector);
|
|
50076
|
+
}
|
|
50077
|
+
let lookCF = CFrame.lookAt([0, 0, 0], lookVector);
|
|
50078
|
+
lookCF = lookCF.multiply(CFrame.fromEulerAngles(25 * Math.PI / 180, 27.5 * Math.PI / 180, 0, "ZXY"));
|
|
50079
|
+
lookVector = lookCF.lookVector();
|
|
50080
|
+
lookCF.Position = add(rootPartCF.Position, multiply([10, 10, 10], lookVector));
|
|
50081
|
+
lookCF = CFrame.lookAt(lookCF.Position, rootPartCF.Position);
|
|
50082
|
+
const cameraCF = lookCF.clone();
|
|
50083
|
+
zoomExtents(cameraCF, rootPartCF, extentsSize, 70, 1);
|
|
50084
|
+
return cameraCF;
|
|
50085
|
+
}
|
|
49818
50086
|
class OutfitRenderer {
|
|
49819
50087
|
auth;
|
|
49820
50088
|
outfit;
|
|
@@ -50003,6 +50271,128 @@ class OutfitRenderer {
|
|
|
50003
50271
|
}
|
|
50004
50272
|
}
|
|
50005
50273
|
}
|
|
50274
|
+
function renderToRenderTarget(width, height, renderScene) {
|
|
50275
|
+
const renderTarget = new WebGLRenderTarget(width, height, {
|
|
50276
|
+
colorSpace: SRGBColorSpace,
|
|
50277
|
+
generateMipmaps: false,
|
|
50278
|
+
minFilter: LinearFilter,
|
|
50279
|
+
magFilter: LinearFilter,
|
|
50280
|
+
type: UnsignedByteType
|
|
50281
|
+
});
|
|
50282
|
+
const rbxRenderer = RBXRenderer.getRenderer();
|
|
50283
|
+
if (!rbxRenderer) return renderTarget;
|
|
50284
|
+
rbxRenderer.setRenderTarget(renderTarget);
|
|
50285
|
+
rbxRenderer.render(renderScene.scene, renderScene.camera);
|
|
50286
|
+
return renderTarget;
|
|
50287
|
+
}
|
|
50288
|
+
async function renderTargetToCanvas(renderTarget) {
|
|
50289
|
+
const rbxRenderer = RBXRenderer.getRenderer();
|
|
50290
|
+
if (!rbxRenderer) return;
|
|
50291
|
+
const width = renderTarget.width;
|
|
50292
|
+
const height = renderTarget.height;
|
|
50293
|
+
const data = new Uint8Array(width * height * 4);
|
|
50294
|
+
await rbxRenderer.readRenderTargetPixelsAsync(renderTarget, 0, 0, width, height, data);
|
|
50295
|
+
return imageDataToCanvas(data, width, height);
|
|
50296
|
+
}
|
|
50297
|
+
async function generateModelThumbnail(auth, renderScene, model, size = [150, 150], type = "png", quality = 1, gltfAutoDownload = false) {
|
|
50298
|
+
return new Promise((resolve) => {
|
|
50299
|
+
const cameraCFrame = getCameraCFrameForAvatarNonCustomized(model);
|
|
50300
|
+
if (cameraCFrame) {
|
|
50301
|
+
RBXRenderer.setCameraCFrame(cameraCFrame, renderScene);
|
|
50302
|
+
}
|
|
50303
|
+
RBXRenderer.addInstance(model, auth, renderScene);
|
|
50304
|
+
let exportTimeout = setTimeout(doExport, FLAGS.THUMBNAIL_TIMEOUT);
|
|
50305
|
+
const onLoadingConnection = API.Events.OnLoadingAssets.Connect((currentlyLoading) => {
|
|
50306
|
+
if (exportTimeout) {
|
|
50307
|
+
clearTimeout(exportTimeout);
|
|
50308
|
+
exportTimeout = void 0;
|
|
50309
|
+
}
|
|
50310
|
+
if (!currentlyLoading) {
|
|
50311
|
+
exportTimeout = setTimeout(doExport, FLAGS.THUMBNAIL_TIMEOUT);
|
|
50312
|
+
}
|
|
50313
|
+
});
|
|
50314
|
+
async function doExport() {
|
|
50315
|
+
onLoadingConnection.Disconnect();
|
|
50316
|
+
if (type === "gltf") {
|
|
50317
|
+
if (!FLAGS.RENDERTARGET_TO_CANVASTEXTURE && FLAGS.USE_RENDERTARGET) {
|
|
50318
|
+
warn(true, "FLAGS.RENDERTARGET_TO_CANVASTEXTURE is false, GLTF export cannot export render target textures, consider setting this flag to true");
|
|
50319
|
+
}
|
|
50320
|
+
resolve(await renderScene.exportGLTF(`result`, gltfAutoDownload));
|
|
50321
|
+
} else {
|
|
50322
|
+
const renderTarget = renderToRenderTarget(...size, renderScene);
|
|
50323
|
+
const canvasTarget = await renderTargetToCanvas(renderTarget);
|
|
50324
|
+
if (canvasTarget) {
|
|
50325
|
+
resolve(canvasTarget.toDataURL(`image/${type}`, quality));
|
|
50326
|
+
} else {
|
|
50327
|
+
resolve(void 0);
|
|
50328
|
+
}
|
|
50329
|
+
}
|
|
50330
|
+
renderScene.destroy();
|
|
50331
|
+
}
|
|
50332
|
+
});
|
|
50333
|
+
}
|
|
50334
|
+
async function generateOutfitThumbnail(auth, outfit, size = [150, 150], type = "png", quality = 1, gltfAutoDownload = false) {
|
|
50335
|
+
return new Promise((resolve) => {
|
|
50336
|
+
const renderScene = RBXRenderer.addScene();
|
|
50337
|
+
setupThumbnailScene(renderScene);
|
|
50338
|
+
const outfitRenderer = new OutfitRenderer(auth, outfit, renderScene);
|
|
50339
|
+
if (outfit.playerAvatarType === AvatarType.R6) outfitRenderer.deltaTimeMultiplier = 0;
|
|
50340
|
+
outfitRenderer.startAnimating();
|
|
50341
|
+
let exportTimeout = setTimeout(doExport, FLAGS.THUMBNAIL_TIMEOUT);
|
|
50342
|
+
const onLoadingConnection = API.Events.OnLoadingAssets.Connect((currentlyLoading) => {
|
|
50343
|
+
if (exportTimeout) {
|
|
50344
|
+
clearTimeout(exportTimeout);
|
|
50345
|
+
exportTimeout = void 0;
|
|
50346
|
+
}
|
|
50347
|
+
if (!currentlyLoading) {
|
|
50348
|
+
exportTimeout = setTimeout(doExport, FLAGS.THUMBNAIL_TIMEOUT);
|
|
50349
|
+
}
|
|
50350
|
+
});
|
|
50351
|
+
async function doExport() {
|
|
50352
|
+
onLoadingConnection.Disconnect();
|
|
50353
|
+
if (!outfit.containsAssetType("Gear")) {
|
|
50354
|
+
if (outfit.playerAvatarType === AvatarType.R15) {
|
|
50355
|
+
outfitRenderer.setMainAnimation("pose");
|
|
50356
|
+
}
|
|
50357
|
+
} else {
|
|
50358
|
+
outfitRenderer.setMainAnimation("toolnone");
|
|
50359
|
+
}
|
|
50360
|
+
if (outfitRenderer.currentRig) {
|
|
50361
|
+
const thumbnailResult = await generateModelThumbnail(auth, renderScene, outfitRenderer.currentRig, size, type, quality, gltfAutoDownload);
|
|
50362
|
+
resolve(thumbnailResult);
|
|
50363
|
+
outfitRenderer.stopAnimating();
|
|
50364
|
+
if (outfitRenderer.currentRig) outfitRenderer.currentRig.Destroy();
|
|
50365
|
+
} else {
|
|
50366
|
+
resolve(void 0);
|
|
50367
|
+
}
|
|
50368
|
+
}
|
|
50369
|
+
});
|
|
50370
|
+
}
|
|
50371
|
+
function setupThumbnailScene(renderScene) {
|
|
50372
|
+
renderScene.shouldAnimate = false;
|
|
50373
|
+
renderScene.wellLitDirectionalLightIntensity *= 2;
|
|
50374
|
+
renderScene.shadowEnabled = false;
|
|
50375
|
+
RBXRenderer.setupScene("WellLit", 16777215, renderScene);
|
|
50376
|
+
if (renderScene.plane) renderScene.scene.remove(renderScene.plane);
|
|
50377
|
+
if (renderScene.shadowPlane) renderScene.scene.remove(renderScene.shadowPlane);
|
|
50378
|
+
renderScene.scene.background = null;
|
|
50379
|
+
}
|
|
50380
|
+
function exposeAPI() {
|
|
50381
|
+
globalThis.API = API;
|
|
50382
|
+
globalThis.APICACHE = CACHE;
|
|
50383
|
+
globalThis.Authentication = Authentication;
|
|
50384
|
+
}
|
|
50385
|
+
function exposeMesh() {
|
|
50386
|
+
globalThis.fileMeshToTHREEGeometry = fileMeshToTHREEGeometry;
|
|
50387
|
+
}
|
|
50388
|
+
function exposeFLAGS() {
|
|
50389
|
+
globalThis.FLAGS = FLAGS;
|
|
50390
|
+
}
|
|
50391
|
+
function exposeThumbnailGenerator() {
|
|
50392
|
+
globalThis.generateOutfitThumbnail = generateOutfitThumbnail;
|
|
50393
|
+
globalThis.generateModelThumbnail = generateModelThumbnail;
|
|
50394
|
+
globalThis.setupThumbnailScene = setupThumbnailScene;
|
|
50395
|
+
}
|
|
50006
50396
|
export {
|
|
50007
50397
|
API,
|
|
50008
50398
|
AbbreviationToFaceControlProperty,
|
|
@@ -50032,6 +50422,7 @@ export {
|
|
|
50032
50422
|
AssetTypeToAccessoryType,
|
|
50033
50423
|
AssetTypeToMakeupType,
|
|
50034
50424
|
AssetTypes,
|
|
50425
|
+
AttachmentWrapper,
|
|
50035
50426
|
Authentication,
|
|
50036
50427
|
AvatarType,
|
|
50037
50428
|
BodyColor3s,
|
|
@@ -50069,6 +50460,7 @@ export {
|
|
|
50069
50460
|
FileMesh,
|
|
50070
50461
|
FileMeshSkinning,
|
|
50071
50462
|
FileMeshSubset,
|
|
50463
|
+
FindFirstMatchingAttachment,
|
|
50072
50464
|
FullBodyColors,
|
|
50073
50465
|
GetAttachedPart,
|
|
50074
50466
|
HSR,
|
|
@@ -50166,24 +50558,35 @@ export {
|
|
|
50166
50558
|
defaultShirtTemplateAssetIds,
|
|
50167
50559
|
deformReferenceToBaseBodyParts,
|
|
50168
50560
|
deg,
|
|
50561
|
+
disposeMesh,
|
|
50169
50562
|
distance,
|
|
50170
50563
|
divide,
|
|
50171
50564
|
dot,
|
|
50172
50565
|
download,
|
|
50173
50566
|
exposeAPI,
|
|
50567
|
+
exposeFLAGS,
|
|
50174
50568
|
exposeMesh,
|
|
50569
|
+
exposeThumbnailGenerator,
|
|
50175
50570
|
fileMeshToTHREEGeometry,
|
|
50176
50571
|
floor,
|
|
50177
50572
|
gaussian_rbf,
|
|
50573
|
+
generateModelThumbnail,
|
|
50574
|
+
generateOutfitThumbnail,
|
|
50178
50575
|
generateUUIDv4,
|
|
50576
|
+
getCameraCFrameForAvatarNonCustomized,
|
|
50179
50577
|
getCameraCFrameForHeadshotCustomized,
|
|
50578
|
+
getCameraOffset,
|
|
50180
50579
|
getDistIndexArray,
|
|
50181
50580
|
getExtents,
|
|
50581
|
+
getExtentsCenter,
|
|
50182
50582
|
getExtentsForParts,
|
|
50183
50583
|
getHeadExtents,
|
|
50184
50584
|
getOffsetArray,
|
|
50585
|
+
getOriginalAttachmentOrientation,
|
|
50586
|
+
getOriginalAttachmentPosition,
|
|
50185
50587
|
getOriginalSize,
|
|
50186
50588
|
getRandomBetweenInclusive,
|
|
50589
|
+
getRigExtentsWorld,
|
|
50187
50590
|
getUVtoIndexMap,
|
|
50188
50591
|
getUVtoIndicesMap,
|
|
50189
50592
|
getWorkerOnMessage,
|
|
@@ -50227,6 +50630,7 @@ export {
|
|
|
50227
50630
|
rotationMatrixToEulerAngles,
|
|
50228
50631
|
saveByteArray,
|
|
50229
50632
|
scaleMesh,
|
|
50633
|
+
setupThumbnailScene,
|
|
50230
50634
|
snapToNumber,
|
|
50231
50635
|
specialClamp,
|
|
50232
50636
|
transferSkeleton,
|
|
@@ -50236,5 +50640,6 @@ export {
|
|
|
50236
50640
|
versionToNumber,
|
|
50237
50641
|
vertPosToChunkPos,
|
|
50238
50642
|
xmlMagic,
|
|
50239
|
-
zoomExtents
|
|
50643
|
+
zoomExtents,
|
|
50644
|
+
zoomToExtents
|
|
50240
50645
|
};
|