roavatar-renderer 1.2.15 → 1.3.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/README.md +1 -1
- package/dist/index.d.ts +151 -36
- package/dist/index.js +366 -196
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -287,6 +287,11 @@ const LayeredClothingAssetOrder = {
|
|
|
287
287
|
90: 16
|
|
288
288
|
// EyeMakeup
|
|
289
289
|
};
|
|
290
|
+
const MakeupAssetTypes = [
|
|
291
|
+
"FaceMakeup",
|
|
292
|
+
"LipMakeup",
|
|
293
|
+
"EyeMakeup"
|
|
294
|
+
];
|
|
290
295
|
const MaxPerAsset = {
|
|
291
296
|
"Head": 1,
|
|
292
297
|
"TShirt": 1,
|
|
@@ -26700,6 +26705,7 @@ class WebGLRenderer {
|
|
|
26700
26705
|
gl.unpackColorSpace = ColorManagement._getUnpackColorSpace();
|
|
26701
26706
|
}
|
|
26702
26707
|
}
|
|
26708
|
+
const textDecoder$1 = new TextDecoder();
|
|
26703
26709
|
class SimpleView {
|
|
26704
26710
|
view;
|
|
26705
26711
|
viewOffset;
|
|
@@ -26757,7 +26763,7 @@ class SimpleView {
|
|
|
26757
26763
|
if (!stringLength) {
|
|
26758
26764
|
stringLength = this.readUint32();
|
|
26759
26765
|
}
|
|
26760
|
-
const string =
|
|
26766
|
+
const string = textDecoder$1.decode(new Uint8Array(this.view.buffer).subarray(this.viewOffset, this.viewOffset + stringLength));
|
|
26761
26767
|
this.viewOffset += stringLength;
|
|
26762
26768
|
return string;
|
|
26763
26769
|
}
|
|
@@ -26889,6 +26895,7 @@ function intToRgb(colorInt) {
|
|
|
26889
26895
|
const B = colorInt & 255;
|
|
26890
26896
|
return { R, G, B };
|
|
26891
26897
|
}
|
|
26898
|
+
const textDecoder = new TextDecoder();
|
|
26892
26899
|
class RBXSimpleView {
|
|
26893
26900
|
view;
|
|
26894
26901
|
viewOffset;
|
|
@@ -26926,7 +26933,7 @@ class RBXSimpleView {
|
|
|
26926
26933
|
if (!stringLength) {
|
|
26927
26934
|
stringLength = this.readUint32();
|
|
26928
26935
|
}
|
|
26929
|
-
const string =
|
|
26936
|
+
const string = textDecoder.decode(new Uint8Array(this.view.buffer).subarray(this.viewOffset, this.viewOffset + stringLength));
|
|
26930
26937
|
this.viewOffset += stringLength;
|
|
26931
26938
|
return string;
|
|
26932
26939
|
}
|
|
@@ -29238,7 +29245,7 @@ function nearestSearch(node, target, best = { dist: Infinity, index: -1 }) {
|
|
|
29238
29245
|
}
|
|
29239
29246
|
return best;
|
|
29240
29247
|
}
|
|
29241
|
-
const jsContent = '(function() {\n "use strict";\n const FullBodyColorPalette = [\n {\n "brickColorId": 361,\n "hexColor": "#564236",\n "name": "Dirt brown"\n },\n {\n "brickColorId": 192,\n "hexColor": "#694028",\n "name": "Reddish brown"\n },\n {\n "brickColorId": 217,\n "hexColor": "#7C5C46",\n "name": "Brown"\n },\n {\n "brickColorId": 153,\n "hexColor": "#957977",\n "name": "Sand red"\n },\n {\n "brickColorId": 359,\n "hexColor": "#AF9483",\n "name": "Linen"\n },\n {\n "brickColorId": 352,\n "hexColor": "#C7AC78",\n "name": "Burlap"\n },\n {\n "brickColorId": 5,\n "hexColor": "#D7C59A",\n "name": "Brick yellow"\n },\n {\n "brickColorId": 101,\n "hexColor": "#DA867A",\n "name": "Medium red"\n },\n {\n "brickColorId": 1007,\n "hexColor": "#A34B4B",\n "name": "Dusty Rose"\n },\n {\n "brickColorId": 1014,\n "hexColor": "#AA5500",\n "name": "CGA brown"\n },\n {\n "brickColorId": 38,\n "hexColor": "#A05F35",\n "name": "Dark orange"\n },\n {\n "brickColorId": 18,\n "hexColor": "#CC8E69",\n "name": "Nougat"\n },\n {\n "brickColorId": 125,\n "hexColor": "#EAB892",\n "name": "Light orange"\n },\n {\n "brickColorId": 1030,\n "hexColor": "#FFCC99",\n "name": "Pastel brown"\n },\n {\n "brickColorId": 133,\n "hexColor": "#D5733D",\n "name": "Neon orange"\n },\n {\n "brickColorId": 106,\n "hexColor": "#DA8541",\n "name": "Bright orange"\n },\n {\n "brickColorId": 105,\n "hexColor": "#E29B40",\n "name": "Br. yellowish orange"\n },\n {\n "brickColorId": 1017,\n "hexColor": "#FFAF00",\n "name": "Deep orange"\n },\n {\n "brickColorId": 24,\n "hexColor": "#F5CD30",\n "name": "Bright yellow"\n },\n {\n "brickColorId": 334,\n "hexColor": "#F8D96D",\n "name": "Daisy orange"\n },\n {\n "brickColorId": 226,\n "hexColor": "#FDEA8D",\n "name": "Cool yellow"\n },\n {\n "brickColorId": 141,\n "hexColor": "#27462D",\n "name": "Earth green"\n },\n {\n "brickColorId": 1021,\n "hexColor": "#3A7D15",\n "name": "Camo"\n },\n {\n "brickColorId": 28,\n "hexColor": "#287F47",\n "name": "Dark green"\n },\n {\n "brickColorId": 37,\n "hexColor": "#4B974B",\n "name": "Bright green"\n },\n {\n "brickColorId": 310,\n "hexColor": "#5B9A4C",\n "name": "Shamrock"\n },\n {\n "brickColorId": 317,\n "hexColor": "#7C9C6B",\n "name": "Moss"\n },\n {\n "brickColorId": 119,\n "hexColor": "#A4BD47",\n "name": "Br. yellowish green"\n },\n {\n "brickColorId": 1011,\n "hexColor": "#002060",\n "name": "Navy blue"\n },\n {\n "brickColorId": 1012,\n "hexColor": "#2154B9",\n "name": "Deep blue"\n },\n {\n "brickColorId": 1010,\n "hexColor": "#0000FF",\n "name": "Really blue"\n },\n {\n "brickColorId": 23,\n "hexColor": "#0D69AC",\n "name": "Bright blue"\n },\n {\n "brickColorId": 305,\n "hexColor": "#527CAE",\n "name": "Steel blue"\n },\n {\n "brickColorId": 102,\n "hexColor": "#6E99CA",\n "name": "Medium blue"\n },\n {\n "brickColorId": 45,\n "hexColor": "#B4D2E4",\n "name": "Light blue"\n },\n {\n "brickColorId": 107,\n "hexColor": "#008F9C",\n "name": "Bright bluish green"\n },\n {\n "brickColorId": 1018,\n "hexColor": "#12EED4",\n "name": "Teal"\n },\n {\n "brickColorId": 1027,\n "hexColor": "#9FF3E9",\n "name": "Pastel blue-green"\n },\n {\n "brickColorId": 1019,\n "hexColor": "#00FFFF",\n "name": "Toothpaste"\n },\n {\n "brickColorId": 1013,\n "hexColor": "#04AFEC",\n "name": "Cyan"\n },\n {\n "brickColorId": 11,\n "hexColor": "#80BBDC",\n "name": "Pastel Blue"\n },\n {\n "brickColorId": 1024,\n "hexColor": "#AFDDFF",\n "name": "Pastel light blue"\n },\n {\n "brickColorId": 104,\n "hexColor": "#6B327C",\n "name": "Bright violet"\n },\n {\n "brickColorId": 1023,\n "hexColor": "#8C5B9F",\n "name": "Lavender"\n },\n {\n "brickColorId": 321,\n "hexColor": "#A75E9B",\n "name": "Lilac"\n },\n {\n "brickColorId": 1015,\n "hexColor": "#AA00AA",\n "name": "Magenta"\n },\n {\n "brickColorId": 1031,\n "hexColor": "#6225D1",\n "name": "Royal purple"\n },\n {\n "brickColorId": 1006,\n "hexColor": "#B480FF",\n "name": "Alder"\n },\n {\n "brickColorId": 1026,\n "hexColor": "#B1A7FF",\n "name": "Pastel violet"\n },\n {\n "brickColorId": 21,\n "hexColor": "#C4281C",\n "name": "Bright red"\n },\n {\n "brickColorId": 1004,\n "hexColor": "#FF0000",\n "name": "Really red"\n },\n {\n "brickColorId": 1032,\n "hexColor": "#FF00BF",\n "name": "Hot pink"\n },\n {\n "brickColorId": 1016,\n "hexColor": "#FF66CC",\n "name": "Pink"\n },\n {\n "brickColorId": 330,\n "hexColor": "#FF98DC",\n "name": "Carnation pink"\n },\n {\n "brickColorId": 9,\n "hexColor": "#E8BAC8",\n "name": "Light reddish violet"\n },\n {\n "brickColorId": 1025,\n "hexColor": "#FFC9C9",\n "name": "Pastel orange"\n },\n {\n "brickColorId": 364,\n "hexColor": "#5A4C42",\n "name": "Dark taupe"\n },\n {\n "brickColorId": 351,\n "hexColor": "#BC9B5D",\n "name": "Cork"\n },\n {\n "brickColorId": 1008,\n "hexColor": "#C1BE42",\n "name": "Olive"\n },\n {\n "brickColorId": 29,\n "hexColor": "#A1C48C",\n "name": "Medium green"\n },\n {\n "brickColorId": 1022,\n "hexColor": "#7F8E64",\n "name": "Grime"\n },\n {\n "brickColorId": 151,\n "hexColor": "#789082",\n "name": "Sand green"\n },\n {\n "brickColorId": 135,\n "hexColor": "#74869D",\n "name": "Sand blue"\n },\n {\n "brickColorId": 1020,\n "hexColor": "#00FF00",\n "name": "Lime green"\n },\n {\n "brickColorId": 1028,\n "hexColor": "#CCFFCC",\n "name": "Pastel green"\n },\n {\n "brickColorId": 1009,\n "hexColor": "#FFFF00",\n "name": "New Yeller"\n },\n {\n "brickColorId": 1029,\n "hexColor": "#FFFFCC",\n "name": "Pastel yellow"\n },\n {\n "brickColorId": 1003,\n "hexColor": "#111111",\n "name": "Really black"\n },\n {\n "brickColorId": 26,\n "hexColor": "#1B2A35",\n "name": "Black"\n },\n {\n "brickColorId": 199,\n "hexColor": "#635F62",\n "name": "Dark stone grey"\n },\n {\n "brickColorId": 194,\n "hexColor": "#A3A2A5",\n "name": "Medium stone grey"\n },\n {\n "brickColorId": 1002,\n "hexColor": "#CDCDCD",\n "name": "Mid gray"\n },\n {\n "brickColorId": 208,\n "hexColor": "#E5E4DF",\n "name": "Light stone grey"\n },\n {\n "brickColorId": 1,\n "hexColor": "#F2F3F3",\n "name": "White"\n },\n {\n "brickColorId": 1001,\n "hexColor": "#F8F8F8",\n "name": "Institutional white"\n }\n ];\n const RegularBodyColors = [\n "5A4C42",\n "7C5C46",\n "AF9483",\n "CC8E69",\n "EAB892",\n "564236",\n "694028",\n "BC9B5D",\n "c7ac78",\n "d7c59a",\n "957977",\n "a34b4b",\n "da867a",\n "ffc9c9",\n "ff98dc",\n "74869d",\n "527cae",\n "80bbdc",\n "b1a7ff",\n "a75e9b",\n "008f9c",\n "5b9a4c",\n "7c9c6b",\n "a1c48c",\n "e29b40",\n "f5cd30",\n "f8d96d",\n "635f62",\n "cdcdcd",\n "f8f8f8"\n ];\n for (let i = 0; i < RegularBodyColors.length; i++) {\n const color = RegularBodyColors[i];\n RegularBodyColors[i] = color.toUpperCase();\n }\n const FullBodyColors = [];\n for (const colorDetails of FullBodyColorPalette) {\n FullBodyColors.push(colorDetails.hexColor.substring(1));\n }\n function calculateMagnitude3D(x, y, z) {\n return Math.sqrt(x * x + y * y + z * z);\n }\n function magnitude(v) {\n return calculateMagnitude3D(v[0], v[1], v[2]);\n }\n function minus(v0, v1) {\n return [v0[0] - v1[0], v0[1] - v1[1], v0[2] - v1[2]];\n }\n function distance(v0, v1) {\n return magnitude(minus(v1, v0));\n }\n class KDNode {\n point;\n index;\n axis;\n left = null;\n right = null;\n constructor(point, index, axis) {\n this.point = point;\n this.index = index;\n this.axis = axis;\n }\n }\n function buildKDTree(points, indices, depth = 0) {\n if (points.length === 0) return null;\n const axis = depth % 3;\n const sorted = points.map((p, i) => ({ p, index: indices[i] })).sort((a, b) => a.p[axis] - b.p[axis]);\n const mid = Math.floor(sorted.length / 2);\n const node = new KDNode(sorted[mid].p, sorted[mid].index, axis);\n const leftPoints = sorted.slice(0, mid).map((x) => x.p);\n const leftIndices = sorted.slice(0, mid).map((x) => x.index);\n const rightPoints = sorted.slice(mid + 1).map((x) => x.p);\n const rightIndices = sorted.slice(mid + 1).map((x) => x.index);\n node.left = buildKDTree(leftPoints, leftIndices, depth + 1);\n node.right = buildKDTree(rightPoints, rightIndices, depth + 1);\n return node;\n }\n function siftUp(heap, i) {\n while (i > 0) {\n const p = i - 1 >> 1;\n if (heap[p].dist >= heap[i].dist) break;\n const tmp = heap[p];\n heap[p] = heap[i];\n heap[i] = tmp;\n i = p;\n }\n }\n function siftDown(heap, i) {\n const n = heap.length;\n while (true) {\n let largest = i;\n const l = (i << 1) + 1;\n const r = l + 1;\n if (l < n && heap[l].dist > heap[largest].dist) largest = l;\n if (r < n && heap[r].dist > heap[largest].dist) largest = r;\n if (largest === i) break;\n const tmp = heap[i];\n heap[i] = heap[largest];\n heap[largest] = tmp;\n i = largest;\n }\n }\n function heapPushMax(heap, item, k) {\n if (heap.length < k) {\n heap.push(item);\n siftUp(heap, heap.length - 1);\n return;\n }\n if (item.dist >= heap[0].dist) return;\n heap[0] = item;\n siftDown(heap, 0);\n }\n function distSq(a, b) {\n const dx = a[0] - b[0];\n const dy = a[1] - b[1];\n const dz = a[2] - b[2];\n return dx * dx + dy * dy + dz * dz;\n }\n function knnSearch(node, target, k, heap = []) {\n if (!node) return heap;\n const axis = node.axis;\n const dist = distSq(target, node.point);\n heapPushMax(heap, { dist, index: node.index }, k);\n const diff = target[axis] - node.point[axis];\n const primary = diff < 0 ? node.left : node.right;\n const secondary = diff < 0 ? node.right : node.left;\n knnSearch(primary, target, k, heap);\n const worstDist = heap.length < k ? Infinity : heap[0].dist;\n if (diff * diff < worstDist) {\n knnSearch(secondary, target, k, heap);\n }\n if (node === null) {\n heap.sort((a, b) => a.dist - b.dist);\n }\n return heap;\n }\n function nearestSearch(node, target, best = { dist: Infinity, index: -1 }) {\n if (!node) return best;\n const dist = distance(target, node.point);\n if (dist < best.dist) {\n best = { dist, index: node.index };\n }\n const axis = node.axis;\n const diff = target[axis] - node.point[axis];\n const primary = diff < 0 ? node.left : node.right;\n const secondary = diff < 0 ? node.right : node.left;\n best = nearestSearch(primary, target, best);\n if (Math.abs(diff) < best.dist) {\n best = nearestSearch(secondary, target, best);\n }\n return best;\n }\n function luDecompose(A) {\n const n = A.length;\n const LU = A;\n const P = new Int32Array(n);\n for (let i = 0; i < n; i++) P[i] = i;\n for (let k = 0; k < n; k++) {\n let pivot = k;\n for (let i = k + 1; i < n; i++) {\n if (Math.abs(LU[i][k]) > Math.abs(LU[pivot][k])) {\n pivot = i;\n }\n }\n if (pivot !== k) {\n const tmpRow = LU[k];\n LU[k] = LU[pivot];\n LU[pivot] = tmpRow;\n const tmpP = P[k];\n P[k] = P[pivot];\n P[pivot] = tmpP;\n }\n const pivotVal = LU[k][k];\n for (let i = k + 1; i < n; i++) {\n LU[i][k] /= pivotVal;\n const mult = LU[i][k];\n const rowI = LU[i];\n const rowK = LU[k];\n for (let j = k + 1; j < n; j++) {\n rowI[j] -= mult * rowK[j];\n }\n }\n }\n return { LU, P };\n }\n function luSolve({ LU, P }, b) {\n const n = LU.length;\n const x = new Float32Array(n);\n for (let i = 0; i < n; i++) {\n x[i] = b[P[i]];\n }\n for (let i = 0; i < n; i++) {\n const row = LU[i];\n let sum = x[i];\n for (let j = 0; j < i; j++) {\n sum -= row[j] * x[j];\n }\n x[i] = sum;\n }\n for (let i = n - 1; i >= 0; i--) {\n const row = LU[i];\n let sum = x[i];\n for (let j = i + 1; j < n; j++) {\n sum -= row[j] * x[j];\n }\n x[i] = sum / row[i];\n }\n return x;\n }\n function patchRBFWorkerFunc([_A, _bx, _by, _bz]) {\n const A = _A.map((r) => new Float32Array(r));\n const bx = new Float32Array(_bx);\n const by = new Float32Array(_by);\n const bz = new Float32Array(_bz);\n const LU = luDecompose(A);\n const wx = luSolve(LU, bx);\n const wy = luSolve(LU, by);\n const wz = luSolve(LU, bz);\n const n = wx.length;\n const result = new Float32Array(n * 3);\n for (let i = 0; i < n; i++) {\n result[i * 3 + 0] = wx[i];\n result[i * 3 + 1] = wy[i];\n result[i * 3 + 2] = wz[i];\n }\n return result.buffer;\n }\n function RBFDeformerSolveAsync([patchCount, detailsCount, epsilon, importantIndicesBuf, refVertsBuf, distVertsBuf, meshVertsBuf, meshBonesBuf]) {\n const importantIndices = new Uint16Array(importantIndicesBuf);\n const refVerts = new Float32Array(refVertsBuf);\n const distVerts = new Float32Array(distVertsBuf);\n const meshVerts = new Float32Array(meshVertsBuf);\n const meshBones = new Float32Array(meshBonesBuf);\n const refCount = refVerts.length / 3;\n const meshVertCount = meshVerts.length / 3;\n const meshBoneCount = meshBones.length / 3;\n const points = new Array(refCount);\n const indices = new Array(refCount);\n for (let i = 0; i < refCount; i++) {\n const refPos = [refVerts[i * 3 + 0], refVerts[i * 3 + 1], refVerts[i * 3 + 2]];\n points[i] = refPos;\n indices[i] = i;\n }\n const controlKD = buildKDTree(points, indices);\n const step = Math.max(1, Math.floor(refCount / patchCount));\n const patchCenters = [];\n for (let i = 0; i < refCount; i += step) {\n const refPos = [refVerts[i * 3 + 0], refVerts[i * 3 + 1], refVerts[i * 3 + 2]];\n patchCenters.push(refPos);\n if (patchCenters.length >= patchCount) break;\n }\n const neighborIndices = new Array(patchCenters.length);\n const weights = new Array(patchCenters.length);\n const patchIndices = patchCenters.map((_, i) => i);\n const patchKD = buildKDTree(patchCenters, patchIndices);\n const isUsedArr = new Array(patchCenters.length).fill(false);\n const nearestPatch = new Uint16Array(meshVertCount + meshBoneCount);\n for (let i = 0; i < meshVertCount; i++) {\n const vec = [meshVerts[i * 3 + 0], meshVerts[i * 3 + 1], meshVerts[i * 3 + 2]];\n const nearestPatchNode = nearestSearch(patchKD, vec);\n isUsedArr[nearestPatchNode.index] = true;\n nearestPatch[i] = nearestPatchNode.index;\n }\n for (let i = 0; i < meshBoneCount; i++) {\n const vec = [meshBones[i * 3 + 0], meshBones[i * 3 + 1], meshBones[i * 3 + 2]];\n const nearestPatchNode = nearestSearch(patchKD, vec);\n isUsedArr[nearestPatchNode.index] = true;\n nearestPatch[i + meshVertCount] = nearestPatchNode.index;\n }\n for (let i = 0; i < patchCenters.length; i++) {\n if (!isUsedArr[i]) {\n continue;\n }\n const centerPos = patchCenters[i];\n const neighbors = knnSearch(controlKD, centerPos, detailsCount);\n const foundNeighborIndices = neighbors.map((n) => n.index);\n for (const important of importantIndices) {\n if (!foundNeighborIndices.includes(important)) {\n foundNeighborIndices.push(important);\n }\n }\n neighborIndices[i] = new Uint16Array(foundNeighborIndices);\n }\n const A_array = new Array(patchCenters.length);\n for (let p = 0; p < patchCenters.length; p++) {\n const patchNeighborIndices = neighborIndices[p];\n if (!patchNeighborIndices) continue;\n const K = patchNeighborIndices.length;\n const positions = new Array(patchNeighborIndices.length);\n for (let i = 0; i < patchNeighborIndices.length; i++) {\n const j = patchNeighborIndices[i];\n const refPos = [refVerts[j * 3 + 0], refVerts[j * 3 + 1], refVerts[j * 3 + 2]];\n positions[i] = refPos;\n }\n const A = new Array(K);\n for (let i = 0; i < K; i++) {\n A[i] = new Float32Array(K);\n }\n for (let i = 0; i < K; i++) {\n const [pix, piy, piz] = positions[i];\n for (let j = i + 1; j < K; j++) {\n const [pjx, pjy, pjz] = positions[j];\n const dist = Math.sqrt((pix - pjx) * (pix - pjx) + (piy - pjy) * (piy - pjy) + (piz - pjz) * (piz - pjz));\n A[i][j] = dist;\n A[j][i] = dist;\n }\n A[i][i] = epsilon;\n }\n A_array[p] = A;\n }\n for (let p = 0; p < patchCenters.length; p++) {\n if (!isUsedArr[p]) {\n continue;\n }\n const patchNeighborIndices = neighborIndices[p];\n const K = patchNeighborIndices.length;\n const usedRef = new Array(K);\n const usedDist = new Array(K);\n for (let i = 0; i < K; i++) {\n const idx = patchNeighborIndices[i];\n const j = idx;\n const refPos = [refVerts[j * 3 + 0], refVerts[j * 3 + 1], refVerts[j * 3 + 2]];\n const distPos = [distVerts[j * 3 + 0], distVerts[j * 3 + 1], distVerts[j * 3 + 2]];\n usedRef[i] = refPos;\n usedDist[i] = distPos;\n }\n const A = A_array[p];\n const bx = new Float32Array(K);\n const by = new Float32Array(K);\n const bz = new Float32Array(K);\n for (let i = 0; i < K; i++) {\n const dr = usedDist[i];\n const rr = usedRef[i];\n bx[i] = dr[0] - rr[0];\n by[i] = dr[1] - rr[1];\n bz[i] = dr[2] - rr[2];\n }\n const Abuffers = A.map((r) => r.buffer);\n weights[p] = new Float32Array(patchRBFWorkerFunc([Abuffers, bx.buffer, by.buffer, bz.buffer]));\n }\n const neighborIndicesBuf = neighborIndices.map((a) => {\n return a.buffer;\n });\n const weightsBuf = weights.map((a) => {\n return a.buffer;\n });\n return [neighborIndicesBuf, weightsBuf, nearestPatch.buffer];\n }\n const WorkerTypeToFunction = {\n "patchRBF": patchRBFWorkerFunc,\n "RBFDeformerSolveAsync": RBFDeformerSolveAsync\n };\n function getWorkerOnMessage() {\n return function(event) {\n const [id, type, data] = event.data;\n const func = WorkerTypeToFunction[type];\n self.postMessage([id, func(data)]);\n };\n }\n onmessage = getWorkerOnMessage();\n})();\n';
|
|
29248
|
+
const jsContent = '(function() {\n "use strict";\n new TextDecoder();\n new TextDecoder();\n const FullBodyColorPalette = [\n {\n "brickColorId": 361,\n "hexColor": "#564236",\n "name": "Dirt brown"\n },\n {\n "brickColorId": 192,\n "hexColor": "#694028",\n "name": "Reddish brown"\n },\n {\n "brickColorId": 217,\n "hexColor": "#7C5C46",\n "name": "Brown"\n },\n {\n "brickColorId": 153,\n "hexColor": "#957977",\n "name": "Sand red"\n },\n {\n "brickColorId": 359,\n "hexColor": "#AF9483",\n "name": "Linen"\n },\n {\n "brickColorId": 352,\n "hexColor": "#C7AC78",\n "name": "Burlap"\n },\n {\n "brickColorId": 5,\n "hexColor": "#D7C59A",\n "name": "Brick yellow"\n },\n {\n "brickColorId": 101,\n "hexColor": "#DA867A",\n "name": "Medium red"\n },\n {\n "brickColorId": 1007,\n "hexColor": "#A34B4B",\n "name": "Dusty Rose"\n },\n {\n "brickColorId": 1014,\n "hexColor": "#AA5500",\n "name": "CGA brown"\n },\n {\n "brickColorId": 38,\n "hexColor": "#A05F35",\n "name": "Dark orange"\n },\n {\n "brickColorId": 18,\n "hexColor": "#CC8E69",\n "name": "Nougat"\n },\n {\n "brickColorId": 125,\n "hexColor": "#EAB892",\n "name": "Light orange"\n },\n {\n "brickColorId": 1030,\n "hexColor": "#FFCC99",\n "name": "Pastel brown"\n },\n {\n "brickColorId": 133,\n "hexColor": "#D5733D",\n "name": "Neon orange"\n },\n {\n "brickColorId": 106,\n "hexColor": "#DA8541",\n "name": "Bright orange"\n },\n {\n "brickColorId": 105,\n "hexColor": "#E29B40",\n "name": "Br. yellowish orange"\n },\n {\n "brickColorId": 1017,\n "hexColor": "#FFAF00",\n "name": "Deep orange"\n },\n {\n "brickColorId": 24,\n "hexColor": "#F5CD30",\n "name": "Bright yellow"\n },\n {\n "brickColorId": 334,\n "hexColor": "#F8D96D",\n "name": "Daisy orange"\n },\n {\n "brickColorId": 226,\n "hexColor": "#FDEA8D",\n "name": "Cool yellow"\n },\n {\n "brickColorId": 141,\n "hexColor": "#27462D",\n "name": "Earth green"\n },\n {\n "brickColorId": 1021,\n "hexColor": "#3A7D15",\n "name": "Camo"\n },\n {\n "brickColorId": 28,\n "hexColor": "#287F47",\n "name": "Dark green"\n },\n {\n "brickColorId": 37,\n "hexColor": "#4B974B",\n "name": "Bright green"\n },\n {\n "brickColorId": 310,\n "hexColor": "#5B9A4C",\n "name": "Shamrock"\n },\n {\n "brickColorId": 317,\n "hexColor": "#7C9C6B",\n "name": "Moss"\n },\n {\n "brickColorId": 119,\n "hexColor": "#A4BD47",\n "name": "Br. yellowish green"\n },\n {\n "brickColorId": 1011,\n "hexColor": "#002060",\n "name": "Navy blue"\n },\n {\n "brickColorId": 1012,\n "hexColor": "#2154B9",\n "name": "Deep blue"\n },\n {\n "brickColorId": 1010,\n "hexColor": "#0000FF",\n "name": "Really blue"\n },\n {\n "brickColorId": 23,\n "hexColor": "#0D69AC",\n "name": "Bright blue"\n },\n {\n "brickColorId": 305,\n "hexColor": "#527CAE",\n "name": "Steel blue"\n },\n {\n "brickColorId": 102,\n "hexColor": "#6E99CA",\n "name": "Medium blue"\n },\n {\n "brickColorId": 45,\n "hexColor": "#B4D2E4",\n "name": "Light blue"\n },\n {\n "brickColorId": 107,\n "hexColor": "#008F9C",\n "name": "Bright bluish green"\n },\n {\n "brickColorId": 1018,\n "hexColor": "#12EED4",\n "name": "Teal"\n },\n {\n "brickColorId": 1027,\n "hexColor": "#9FF3E9",\n "name": "Pastel blue-green"\n },\n {\n "brickColorId": 1019,\n "hexColor": "#00FFFF",\n "name": "Toothpaste"\n },\n {\n "brickColorId": 1013,\n "hexColor": "#04AFEC",\n "name": "Cyan"\n },\n {\n "brickColorId": 11,\n "hexColor": "#80BBDC",\n "name": "Pastel Blue"\n },\n {\n "brickColorId": 1024,\n "hexColor": "#AFDDFF",\n "name": "Pastel light blue"\n },\n {\n "brickColorId": 104,\n "hexColor": "#6B327C",\n "name": "Bright violet"\n },\n {\n "brickColorId": 1023,\n "hexColor": "#8C5B9F",\n "name": "Lavender"\n },\n {\n "brickColorId": 321,\n "hexColor": "#A75E9B",\n "name": "Lilac"\n },\n {\n "brickColorId": 1015,\n "hexColor": "#AA00AA",\n "name": "Magenta"\n },\n {\n "brickColorId": 1031,\n "hexColor": "#6225D1",\n "name": "Royal purple"\n },\n {\n "brickColorId": 1006,\n "hexColor": "#B480FF",\n "name": "Alder"\n },\n {\n "brickColorId": 1026,\n "hexColor": "#B1A7FF",\n "name": "Pastel violet"\n },\n {\n "brickColorId": 21,\n "hexColor": "#C4281C",\n "name": "Bright red"\n },\n {\n "brickColorId": 1004,\n "hexColor": "#FF0000",\n "name": "Really red"\n },\n {\n "brickColorId": 1032,\n "hexColor": "#FF00BF",\n "name": "Hot pink"\n },\n {\n "brickColorId": 1016,\n "hexColor": "#FF66CC",\n "name": "Pink"\n },\n {\n "brickColorId": 330,\n "hexColor": "#FF98DC",\n "name": "Carnation pink"\n },\n {\n "brickColorId": 9,\n "hexColor": "#E8BAC8",\n "name": "Light reddish violet"\n },\n {\n "brickColorId": 1025,\n "hexColor": "#FFC9C9",\n "name": "Pastel orange"\n },\n {\n "brickColorId": 364,\n "hexColor": "#5A4C42",\n "name": "Dark taupe"\n },\n {\n "brickColorId": 351,\n "hexColor": "#BC9B5D",\n "name": "Cork"\n },\n {\n "brickColorId": 1008,\n "hexColor": "#C1BE42",\n "name": "Olive"\n },\n {\n "brickColorId": 29,\n "hexColor": "#A1C48C",\n "name": "Medium green"\n },\n {\n "brickColorId": 1022,\n "hexColor": "#7F8E64",\n "name": "Grime"\n },\n {\n "brickColorId": 151,\n "hexColor": "#789082",\n "name": "Sand green"\n },\n {\n "brickColorId": 135,\n "hexColor": "#74869D",\n "name": "Sand blue"\n },\n {\n "brickColorId": 1020,\n "hexColor": "#00FF00",\n "name": "Lime green"\n },\n {\n "brickColorId": 1028,\n "hexColor": "#CCFFCC",\n "name": "Pastel green"\n },\n {\n "brickColorId": 1009,\n "hexColor": "#FFFF00",\n "name": "New Yeller"\n },\n {\n "brickColorId": 1029,\n "hexColor": "#FFFFCC",\n "name": "Pastel yellow"\n },\n {\n "brickColorId": 1003,\n "hexColor": "#111111",\n "name": "Really black"\n },\n {\n "brickColorId": 26,\n "hexColor": "#1B2A35",\n "name": "Black"\n },\n {\n "brickColorId": 199,\n "hexColor": "#635F62",\n "name": "Dark stone grey"\n },\n {\n "brickColorId": 194,\n "hexColor": "#A3A2A5",\n "name": "Medium stone grey"\n },\n {\n "brickColorId": 1002,\n "hexColor": "#CDCDCD",\n "name": "Mid gray"\n },\n {\n "brickColorId": 208,\n "hexColor": "#E5E4DF",\n "name": "Light stone grey"\n },\n {\n "brickColorId": 1,\n "hexColor": "#F2F3F3",\n "name": "White"\n },\n {\n "brickColorId": 1001,\n "hexColor": "#F8F8F8",\n "name": "Institutional white"\n }\n ];\n const RegularBodyColors = [\n "5A4C42",\n "7C5C46",\n "AF9483",\n "CC8E69",\n "EAB892",\n "564236",\n "694028",\n "BC9B5D",\n "c7ac78",\n "d7c59a",\n "957977",\n "a34b4b",\n "da867a",\n "ffc9c9",\n "ff98dc",\n "74869d",\n "527cae",\n "80bbdc",\n "b1a7ff",\n "a75e9b",\n "008f9c",\n "5b9a4c",\n "7c9c6b",\n "a1c48c",\n "e29b40",\n "f5cd30",\n "f8d96d",\n "635f62",\n "cdcdcd",\n "f8f8f8"\n ];\n for (let i = 0; i < RegularBodyColors.length; i++) {\n const color = RegularBodyColors[i];\n RegularBodyColors[i] = color.toUpperCase();\n }\n const FullBodyColors = [];\n for (const colorDetails of FullBodyColorPalette) {\n FullBodyColors.push(colorDetails.hexColor.substring(1));\n }\n function calculateMagnitude3D(x, y, z) {\n return Math.sqrt(x * x + y * y + z * z);\n }\n function magnitude(v) {\n return calculateMagnitude3D(v[0], v[1], v[2]);\n }\n function minus(v0, v1) {\n return [v0[0] - v1[0], v0[1] - v1[1], v0[2] - v1[2]];\n }\n function distance(v0, v1) {\n return magnitude(minus(v1, v0));\n }\n class KDNode {\n point;\n index;\n axis;\n left = null;\n right = null;\n constructor(point, index, axis) {\n this.point = point;\n this.index = index;\n this.axis = axis;\n }\n }\n function buildKDTree(points, indices, depth = 0) {\n if (points.length === 0) return null;\n const axis = depth % 3;\n const sorted = points.map((p, i) => ({ p, index: indices[i] })).sort((a, b) => a.p[axis] - b.p[axis]);\n const mid = Math.floor(sorted.length / 2);\n const node = new KDNode(sorted[mid].p, sorted[mid].index, axis);\n const leftPoints = sorted.slice(0, mid).map((x) => x.p);\n const leftIndices = sorted.slice(0, mid).map((x) => x.index);\n const rightPoints = sorted.slice(mid + 1).map((x) => x.p);\n const rightIndices = sorted.slice(mid + 1).map((x) => x.index);\n node.left = buildKDTree(leftPoints, leftIndices, depth + 1);\n node.right = buildKDTree(rightPoints, rightIndices, depth + 1);\n return node;\n }\n function siftUp(heap, i) {\n while (i > 0) {\n const p = i - 1 >> 1;\n if (heap[p].dist >= heap[i].dist) break;\n const tmp = heap[p];\n heap[p] = heap[i];\n heap[i] = tmp;\n i = p;\n }\n }\n function siftDown(heap, i) {\n const n = heap.length;\n while (true) {\n let largest = i;\n const l = (i << 1) + 1;\n const r = l + 1;\n if (l < n && heap[l].dist > heap[largest].dist) largest = l;\n if (r < n && heap[r].dist > heap[largest].dist) largest = r;\n if (largest === i) break;\n const tmp = heap[i];\n heap[i] = heap[largest];\n heap[largest] = tmp;\n i = largest;\n }\n }\n function heapPushMax(heap, item, k) {\n if (heap.length < k) {\n heap.push(item);\n siftUp(heap, heap.length - 1);\n return;\n }\n if (item.dist >= heap[0].dist) return;\n heap[0] = item;\n siftDown(heap, 0);\n }\n function distSq(a, b) {\n const dx = a[0] - b[0];\n const dy = a[1] - b[1];\n const dz = a[2] - b[2];\n return dx * dx + dy * dy + dz * dz;\n }\n function knnSearch(node, target, k, heap = []) {\n if (!node) return heap;\n const axis = node.axis;\n const dist = distSq(target, node.point);\n heapPushMax(heap, { dist, index: node.index }, k);\n const diff = target[axis] - node.point[axis];\n const primary = diff < 0 ? node.left : node.right;\n const secondary = diff < 0 ? node.right : node.left;\n knnSearch(primary, target, k, heap);\n const worstDist = heap.length < k ? Infinity : heap[0].dist;\n if (diff * diff < worstDist) {\n knnSearch(secondary, target, k, heap);\n }\n if (node === null) {\n heap.sort((a, b) => a.dist - b.dist);\n }\n return heap;\n }\n function nearestSearch(node, target, best = { dist: Infinity, index: -1 }) {\n if (!node) return best;\n const dist = distance(target, node.point);\n if (dist < best.dist) {\n best = { dist, index: node.index };\n }\n const axis = node.axis;\n const diff = target[axis] - node.point[axis];\n const primary = diff < 0 ? node.left : node.right;\n const secondary = diff < 0 ? node.right : node.left;\n best = nearestSearch(primary, target, best);\n if (Math.abs(diff) < best.dist) {\n best = nearestSearch(secondary, target, best);\n }\n return best;\n }\n function luDecompose(A) {\n const n = A.length;\n const LU = A;\n const P = new Int32Array(n);\n for (let i = 0; i < n; i++) P[i] = i;\n for (let k = 0; k < n; k++) {\n let pivot = k;\n for (let i = k + 1; i < n; i++) {\n if (Math.abs(LU[i][k]) > Math.abs(LU[pivot][k])) {\n pivot = i;\n }\n }\n if (pivot !== k) {\n const tmpRow = LU[k];\n LU[k] = LU[pivot];\n LU[pivot] = tmpRow;\n const tmpP = P[k];\n P[k] = P[pivot];\n P[pivot] = tmpP;\n }\n const pivotVal = LU[k][k];\n for (let i = k + 1; i < n; i++) {\n LU[i][k] /= pivotVal;\n const mult = LU[i][k];\n const rowI = LU[i];\n const rowK = LU[k];\n for (let j = k + 1; j < n; j++) {\n rowI[j] -= mult * rowK[j];\n }\n }\n }\n return { LU, P };\n }\n function luSolve({ LU, P }, b) {\n const n = LU.length;\n const x = new Float32Array(n);\n for (let i = 0; i < n; i++) {\n x[i] = b[P[i]];\n }\n for (let i = 0; i < n; i++) {\n const row = LU[i];\n let sum = x[i];\n for (let j = 0; j < i; j++) {\n sum -= row[j] * x[j];\n }\n x[i] = sum;\n }\n for (let i = n - 1; i >= 0; i--) {\n const row = LU[i];\n let sum = x[i];\n for (let j = i + 1; j < n; j++) {\n sum -= row[j] * x[j];\n }\n x[i] = sum / row[i];\n }\n return x;\n }\n function patchRBFWorkerFunc([_A, _bx, _by, _bz]) {\n const A = _A.map((r) => new Float32Array(r));\n const bx = new Float32Array(_bx);\n const by = new Float32Array(_by);\n const bz = new Float32Array(_bz);\n const LU = luDecompose(A);\n const wx = luSolve(LU, bx);\n const wy = luSolve(LU, by);\n const wz = luSolve(LU, bz);\n const n = wx.length;\n const result = new Float32Array(n * 3);\n for (let i = 0; i < n; i++) {\n result[i * 3 + 0] = wx[i];\n result[i * 3 + 1] = wy[i];\n result[i * 3 + 2] = wz[i];\n }\n return result.buffer;\n }\n function RBFDeformerSolveAsync([patchCount, detailsCount, epsilon, importantIndicesBuf, refVertsBuf, distVertsBuf, meshVertsBuf, meshBonesBuf]) {\n const importantIndices = new Uint16Array(importantIndicesBuf);\n const refVerts = new Float32Array(refVertsBuf);\n const distVerts = new Float32Array(distVertsBuf);\n const meshVerts = new Float32Array(meshVertsBuf);\n const meshBones = new Float32Array(meshBonesBuf);\n const refCount = refVerts.length / 3;\n const meshVertCount = meshVerts.length / 3;\n const meshBoneCount = meshBones.length / 3;\n const points = new Array(refCount);\n const indices = new Array(refCount);\n for (let i = 0; i < refCount; i++) {\n const refPos = [refVerts[i * 3 + 0], refVerts[i * 3 + 1], refVerts[i * 3 + 2]];\n points[i] = refPos;\n indices[i] = i;\n }\n const controlKD = buildKDTree(points, indices);\n const step = Math.max(1, Math.floor(refCount / patchCount));\n const patchCenters = [];\n for (let i = 0; i < refCount; i += step) {\n const refPos = [refVerts[i * 3 + 0], refVerts[i * 3 + 1], refVerts[i * 3 + 2]];\n patchCenters.push(refPos);\n if (patchCenters.length >= patchCount) break;\n }\n const neighborIndices = new Array(patchCenters.length);\n const weights = new Array(patchCenters.length);\n const patchIndices = patchCenters.map((_, i) => i);\n const patchKD = buildKDTree(patchCenters, patchIndices);\n const isUsedArr = new Array(patchCenters.length).fill(false);\n const nearestPatch = new Uint16Array(meshVertCount + meshBoneCount);\n for (let i = 0; i < meshVertCount; i++) {\n const vec = [meshVerts[i * 3 + 0], meshVerts[i * 3 + 1], meshVerts[i * 3 + 2]];\n const nearestPatchNode = nearestSearch(patchKD, vec);\n isUsedArr[nearestPatchNode.index] = true;\n nearestPatch[i] = nearestPatchNode.index;\n }\n for (let i = 0; i < meshBoneCount; i++) {\n const vec = [meshBones[i * 3 + 0], meshBones[i * 3 + 1], meshBones[i * 3 + 2]];\n const nearestPatchNode = nearestSearch(patchKD, vec);\n isUsedArr[nearestPatchNode.index] = true;\n nearestPatch[i + meshVertCount] = nearestPatchNode.index;\n }\n for (let i = 0; i < patchCenters.length; i++) {\n if (!isUsedArr[i]) {\n continue;\n }\n const centerPos = patchCenters[i];\n const neighbors = knnSearch(controlKD, centerPos, detailsCount);\n const foundNeighborIndices = neighbors.map((n) => n.index);\n for (const important of importantIndices) {\n if (!foundNeighborIndices.includes(important)) {\n foundNeighborIndices.push(important);\n }\n }\n neighborIndices[i] = new Uint16Array(foundNeighborIndices);\n }\n const A_array = new Array(patchCenters.length);\n for (let p = 0; p < patchCenters.length; p++) {\n const patchNeighborIndices = neighborIndices[p];\n if (!patchNeighborIndices) continue;\n const K = patchNeighborIndices.length;\n const positions = new Array(patchNeighborIndices.length);\n for (let i = 0; i < patchNeighborIndices.length; i++) {\n const j = patchNeighborIndices[i];\n const refPos = [refVerts[j * 3 + 0], refVerts[j * 3 + 1], refVerts[j * 3 + 2]];\n positions[i] = refPos;\n }\n const A = new Array(K);\n for (let i = 0; i < K; i++) {\n A[i] = new Float32Array(K);\n }\n for (let i = 0; i < K; i++) {\n const [pix, piy, piz] = positions[i];\n for (let j = i + 1; j < K; j++) {\n const [pjx, pjy, pjz] = positions[j];\n const dist = Math.sqrt((pix - pjx) * (pix - pjx) + (piy - pjy) * (piy - pjy) + (piz - pjz) * (piz - pjz));\n A[i][j] = dist;\n A[j][i] = dist;\n }\n A[i][i] = epsilon;\n }\n A_array[p] = A;\n }\n for (let p = 0; p < patchCenters.length; p++) {\n if (!isUsedArr[p]) {\n continue;\n }\n const patchNeighborIndices = neighborIndices[p];\n const K = patchNeighborIndices.length;\n const usedRef = new Array(K);\n const usedDist = new Array(K);\n for (let i = 0; i < K; i++) {\n const idx = patchNeighborIndices[i];\n const j = idx;\n const refPos = [refVerts[j * 3 + 0], refVerts[j * 3 + 1], refVerts[j * 3 + 2]];\n const distPos = [distVerts[j * 3 + 0], distVerts[j * 3 + 1], distVerts[j * 3 + 2]];\n usedRef[i] = refPos;\n usedDist[i] = distPos;\n }\n const A = A_array[p];\n const bx = new Float32Array(K);\n const by = new Float32Array(K);\n const bz = new Float32Array(K);\n for (let i = 0; i < K; i++) {\n const dr = usedDist[i];\n const rr = usedRef[i];\n bx[i] = dr[0] - rr[0];\n by[i] = dr[1] - rr[1];\n bz[i] = dr[2] - rr[2];\n }\n const Abuffers = A.map((r) => r.buffer);\n weights[p] = new Float32Array(patchRBFWorkerFunc([Abuffers, bx.buffer, by.buffer, bz.buffer]));\n }\n const neighborIndicesBuf = neighborIndices.map((a) => {\n return a.buffer;\n });\n const weightsBuf = weights.map((a) => {\n return a.buffer;\n });\n return [neighborIndicesBuf, weightsBuf, nearestPatch.buffer];\n }\n const WorkerTypeToFunction = {\n "patchRBF": patchRBFWorkerFunc,\n "RBFDeformerSolveAsync": RBFDeformerSolveAsync\n };\n function getWorkerOnMessage() {\n return function(event) {\n const [id, type, data] = event.data;\n const func = WorkerTypeToFunction[type];\n self.postMessage([id, func(data)]);\n };\n }\n onmessage = getWorkerOnMessage();\n})();\n';
|
|
29242
29249
|
const blob = typeof self !== "undefined" && self.Blob && new Blob(["(self.URL || self.webkitURL).revokeObjectURL(self.location.href);", jsContent], { type: "text/javascript;charset=utf-8" });
|
|
29243
29250
|
function WorkerWrapper(options) {
|
|
29244
29251
|
let objURL;
|
|
@@ -32588,6 +32595,7 @@ class Outfit {
|
|
|
32588
32595
|
const usedIds = [];
|
|
32589
32596
|
let totalAccessories = 0;
|
|
32590
32597
|
let totalLayered = 0;
|
|
32598
|
+
let totalMakeup = 0;
|
|
32591
32599
|
for (let i = 0; i < this.assets.length; i++) {
|
|
32592
32600
|
const asset = this.assets[i];
|
|
32593
32601
|
if (!(asset instanceof Asset)) {
|
|
@@ -32628,7 +32636,7 @@ class Outfit {
|
|
|
32628
32636
|
});
|
|
32629
32637
|
}
|
|
32630
32638
|
}
|
|
32631
|
-
if (LayeredAssetTypes.includes(asset.assetType.name)) {
|
|
32639
|
+
if (LayeredAssetTypes.includes(asset.assetType.name) && !MakeupAssetTypes.includes(asset.assetType.name)) {
|
|
32632
32640
|
totalLayered += 1;
|
|
32633
32641
|
if (totalLayered > 10) {
|
|
32634
32642
|
issues.push({
|
|
@@ -32638,6 +32646,16 @@ class Outfit {
|
|
|
32638
32646
|
});
|
|
32639
32647
|
}
|
|
32640
32648
|
}
|
|
32649
|
+
if (MakeupAssetTypes.includes(asset.assetType.name)) {
|
|
32650
|
+
totalMakeup += 1;
|
|
32651
|
+
if (totalMakeup > 6) {
|
|
32652
|
+
issues.push({
|
|
32653
|
+
"type": "MakeupLimit",
|
|
32654
|
+
"text": "Too much makeup",
|
|
32655
|
+
assetIndex: i
|
|
32656
|
+
});
|
|
32657
|
+
}
|
|
32658
|
+
}
|
|
32641
32659
|
if (MaxOneOfAssetTypes.includes(asset.assetType.name)) {
|
|
32642
32660
|
for (let j = 0; j < this.assets.length; j++) {
|
|
32643
32661
|
const otherAsset = this.assets[j];
|
|
@@ -34532,7 +34550,7 @@ class FileMesh {
|
|
|
34532
34550
|
decoderModule.destroy(faceArray);
|
|
34533
34551
|
decoderModule.destroy(mesh);
|
|
34534
34552
|
decoderModule.destroy(decoder);
|
|
34535
|
-
|
|
34553
|
+
log(false, this.coreMesh);
|
|
34536
34554
|
}
|
|
34537
34555
|
}
|
|
34538
34556
|
readChunkFACS(view, version) {
|
|
@@ -36074,7 +36092,11 @@ const API = {
|
|
|
36074
36092
|
}
|
|
36075
36093
|
return await response.json();
|
|
36076
36094
|
}
|
|
36077
|
-
}
|
|
36095
|
+
},
|
|
36096
|
+
"RBLXGet": RBLXGet,
|
|
36097
|
+
"RBLXPost": RBLXPost,
|
|
36098
|
+
"RBLXDelete": RBLXDelete,
|
|
36099
|
+
"RBLXPatch": RBLXPatch
|
|
36078
36100
|
};
|
|
36079
36101
|
let currentLoadingThumbnails = false;
|
|
36080
36102
|
function requestIdFromThumbnailInfo(thumbnailInfo) {
|
|
@@ -41198,7 +41220,6 @@ function TraverseRigFromAttachmentsInternal(self2, part, characterParts, buildJo
|
|
|
41198
41220
|
if (part !== characterPart) {
|
|
41199
41221
|
const matchingAttachment = characterPart.FindFirstChild(attachmentName);
|
|
41200
41222
|
if (matchingAttachment && matchingAttachment.className === "Attachment") {
|
|
41201
|
-
log(false, "matchingAtt", part, characterPart, attachmentName);
|
|
41202
41223
|
AdjustRootRigAttachmentPosition(self2, part, characterPart, attachment, matchingAttachment);
|
|
41203
41224
|
{
|
|
41204
41225
|
createJoint(jointName, attachment, matchingAttachment);
|
|
@@ -44775,8 +44796,13 @@ class DisposableDesc {
|
|
|
44775
44796
|
}
|
|
44776
44797
|
}
|
|
44777
44798
|
class RenderDesc extends DisposableDesc {
|
|
44799
|
+
renderScene;
|
|
44778
44800
|
results;
|
|
44779
44801
|
instance;
|
|
44802
|
+
constructor(renderScene) {
|
|
44803
|
+
super();
|
|
44804
|
+
this.renderScene = renderScene;
|
|
44805
|
+
}
|
|
44780
44806
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
44781
44807
|
isSame(_other) {
|
|
44782
44808
|
throw new Error("Virtual method isSame called");
|
|
@@ -45121,14 +45147,14 @@ class Particle {
|
|
|
45121
45147
|
this.velocity = velocity;
|
|
45122
45148
|
this.rotationSpeed = rotationSpeed;
|
|
45123
45149
|
}
|
|
45124
|
-
camDistance() {
|
|
45125
|
-
const cameraPos = new Vector32(...
|
|
45150
|
+
camDistance(renderScene) {
|
|
45151
|
+
const cameraPos = new Vector32(...renderScene.camera.position.toArray());
|
|
45126
45152
|
const particlePos = this.position;
|
|
45127
45153
|
const distance2 = cameraPos.minus(particlePos).magnitude();
|
|
45128
45154
|
return distance2;
|
|
45129
45155
|
}
|
|
45130
|
-
getMatrix(size, orientation) {
|
|
45131
|
-
const camera =
|
|
45156
|
+
getMatrix(renderScene, size, orientation) {
|
|
45157
|
+
const camera = renderScene.camera;
|
|
45132
45158
|
const particlePos = new Vector3$1(...this.position.toVec3());
|
|
45133
45159
|
const translation = new Matrix4().makeTranslation(particlePos);
|
|
45134
45160
|
const scale = new Matrix4().makeScale(size, size, 1);
|
|
@@ -45373,7 +45399,7 @@ class EmitterDesc extends DisposableDesc {
|
|
|
45373
45399
|
this.passedTime -= 1 / this.rate;
|
|
45374
45400
|
}
|
|
45375
45401
|
}
|
|
45376
|
-
updateResult() {
|
|
45402
|
+
updateResult(renderScene) {
|
|
45377
45403
|
if (!this.result || !this.instanceColorBuffer || !this.instanceOpacityBuffer || !this.instanceSeedTimeBuffer) return;
|
|
45378
45404
|
this.result.count = this.particles.length;
|
|
45379
45405
|
for (let i = 0; i < this.result.count; i++) {
|
|
@@ -45383,7 +45409,7 @@ class EmitterDesc extends DisposableDesc {
|
|
|
45383
45409
|
const color = this.color.getValue(normalizedTime);
|
|
45384
45410
|
const size = this.size.getValue(this.normalizeSizeKeypointTime ? normalizedTime : time2, particle.seed + 0);
|
|
45385
45411
|
const opacity = 1 - this.transparency.getValue(normalizedTime, particle.seed + 1);
|
|
45386
|
-
this.result.setMatrixAt(i, particle.getMatrix(size, this.orientation));
|
|
45412
|
+
this.result.setMatrixAt(i, particle.getMatrix(renderScene, size, this.orientation));
|
|
45387
45413
|
this.instanceColorBuffer.setXYZ(i, color.R, color.G, color.B);
|
|
45388
45414
|
this.instanceOpacityBuffer.setX(i, opacity);
|
|
45389
45415
|
this.instanceSeedTimeBuffer.setXY(i, particle.seed, normalizedTime);
|
|
@@ -45681,7 +45707,7 @@ class EmitterGroupDesc extends RenderDesc {
|
|
|
45681
45707
|
this.lastTime = this.time;
|
|
45682
45708
|
for (const emitterDesc of this.emitterDescs) {
|
|
45683
45709
|
emitterDesc.tick(dt, this);
|
|
45684
|
-
emitterDesc.updateResult();
|
|
45710
|
+
emitterDesc.updateResult(this.renderScene);
|
|
45685
45711
|
}
|
|
45686
45712
|
this.lastCframe = this.cframe.clone();
|
|
45687
45713
|
}
|
|
@@ -46174,7 +46200,6 @@ class AnimationTrack {
|
|
|
46174
46200
|
partKeyframe.easingStyle = pose.Prop("EasingStyle");
|
|
46175
46201
|
}
|
|
46176
46202
|
} else {
|
|
46177
|
-
warn(false, `Missing either part0 or part1 with names: ${part0Name} ${part1Name}`);
|
|
46178
46203
|
return [void 0, void 0, void 0];
|
|
46179
46204
|
}
|
|
46180
46205
|
if (!motorName || !motorParentName || !partKeyframe) {
|
|
@@ -48941,42 +48966,104 @@ function RegisterWrappers() {
|
|
|
48941
48966
|
BodyColorsWrapper.register();
|
|
48942
48967
|
AccessoryWrapper.register();
|
|
48943
48968
|
}
|
|
48969
|
+
class RBXRendererScene {
|
|
48970
|
+
//important scene components
|
|
48971
|
+
scene = new Scene();
|
|
48972
|
+
camera = new PerspectiveCamera(70, 1 / 1, 0.1, 100);
|
|
48973
|
+
controls;
|
|
48974
|
+
//renderer
|
|
48975
|
+
effectComposer;
|
|
48976
|
+
//viewport
|
|
48977
|
+
scissor;
|
|
48978
|
+
viewport;
|
|
48979
|
+
//renderables data
|
|
48980
|
+
isRenderingMesh = /* @__PURE__ */ new Map();
|
|
48981
|
+
renderDescs = /* @__PURE__ */ new Map();
|
|
48982
|
+
destroyConnections = /* @__PURE__ */ new Map();
|
|
48983
|
+
//scene appearance config
|
|
48984
|
+
lookAwayVector = [0.406, 0.306, -0.819];
|
|
48985
|
+
lookAwayDistance = 6;
|
|
48986
|
+
shadowEnabled = true;
|
|
48987
|
+
shadowResolution = [256, 256];
|
|
48988
|
+
_wellLitDirectionalLightIntensity = Math.PI / 2;
|
|
48989
|
+
set wellLitDirectionalLightIntensity(v) {
|
|
48990
|
+
this._wellLitDirectionalLightIntensity = v;
|
|
48991
|
+
if (this.directionalLight) {
|
|
48992
|
+
this.directionalLight.intensity = this._wellLitDirectionalLightIntensity;
|
|
48993
|
+
}
|
|
48994
|
+
}
|
|
48995
|
+
get wellLitDirectionalLightIntensity() {
|
|
48996
|
+
return this._wellLitDirectionalLightIntensity;
|
|
48997
|
+
}
|
|
48998
|
+
//scene appearance
|
|
48999
|
+
plane;
|
|
49000
|
+
shadowPlane;
|
|
49001
|
+
ambientLight;
|
|
49002
|
+
directionalLight;
|
|
49003
|
+
directionalLight2;
|
|
49004
|
+
setRect(bounds) {
|
|
49005
|
+
this.viewport = [bounds.left, document.body.clientHeight - bounds.bottom, bounds.width, bounds.height];
|
|
49006
|
+
this.scissor = [...this.viewport];
|
|
49007
|
+
}
|
|
49008
|
+
noRect() {
|
|
49009
|
+
this.viewport = [0, 0, 0, 0];
|
|
49010
|
+
this.scissor = [0, 0, 0, 0];
|
|
49011
|
+
}
|
|
49012
|
+
}
|
|
48944
49013
|
class RBXRenderer {
|
|
48945
|
-
static isRenderingMesh = /* @__PURE__ */ new Map();
|
|
48946
|
-
static renderDescs = /* @__PURE__ */ new Map();
|
|
48947
|
-
static destroyConnections = /* @__PURE__ */ new Map();
|
|
48948
|
-
static lookAwayVector = [0.406, 0.306, -0.819];
|
|
48949
|
-
static lookAwayDistance = 6;
|
|
48950
49014
|
static orbitControlsTarget = [0, 3, 0];
|
|
48951
|
-
static
|
|
48952
|
-
static
|
|
48953
|
-
|
|
49015
|
+
static scenes = [new RBXRendererScene()];
|
|
49016
|
+
static get firstScene() {
|
|
49017
|
+
return RBXRenderer.scenes[0];
|
|
49018
|
+
}
|
|
49019
|
+
/**@deprecated This can only get the first renderScene's scene */
|
|
49020
|
+
static get scene() {
|
|
49021
|
+
return RBXRenderer.firstScene.scene;
|
|
49022
|
+
}
|
|
49023
|
+
/**@deprecated This can only get the first renderScene's camera */
|
|
49024
|
+
static get camera() {
|
|
49025
|
+
return RBXRenderer.firstScene.camera;
|
|
49026
|
+
}
|
|
49027
|
+
/**@deprecated This can only get the first renderScene's controls */
|
|
49028
|
+
static get controls() {
|
|
49029
|
+
return RBXRenderer.firstScene.controls;
|
|
49030
|
+
}
|
|
48954
49031
|
static renderer;
|
|
48955
|
-
static effectComposer;
|
|
48956
|
-
static shadowEnabled = true;
|
|
48957
|
-
static shadowResolution = [256, 256];
|
|
48958
49032
|
static resolution = [420, 420];
|
|
48959
49033
|
static backgroundColorHex = 2829619;
|
|
48960
49034
|
static backgroundTransparent = false;
|
|
48961
|
-
static _wellLitDirectionalLightIntensity = Math.PI / 2;
|
|
48962
|
-
static set wellLitDirectionalLightIntensity(v) {
|
|
48963
|
-
RBXRenderer._wellLitDirectionalLightIntensity = v;
|
|
48964
|
-
if (RBXRenderer.directionalLight) {
|
|
48965
|
-
RBXRenderer.directionalLight.intensity = RBXRenderer._wellLitDirectionalLightIntensity;
|
|
48966
|
-
}
|
|
48967
|
-
}
|
|
48968
|
-
static get wellLitDirectionalLightIntensity() {
|
|
48969
|
-
return RBXRenderer._wellLitDirectionalLightIntensity;
|
|
48970
|
-
}
|
|
48971
49035
|
static createLoadingIcon = true;
|
|
48972
49036
|
static canvasContainer;
|
|
48973
49037
|
static loadingIcon;
|
|
48974
49038
|
static loadingIconStyle;
|
|
48975
|
-
|
|
48976
|
-
static
|
|
48977
|
-
|
|
48978
|
-
|
|
48979
|
-
|
|
49039
|
+
/**@deprecated This can only get the first renderScene's plane */
|
|
49040
|
+
static get plane() {
|
|
49041
|
+
return RBXRenderer.firstScene.plane;
|
|
49042
|
+
}
|
|
49043
|
+
/**@deprecated This can only get the first renderScene's shadowPlane */
|
|
49044
|
+
static get shadowPlane() {
|
|
49045
|
+
return RBXRenderer.firstScene.shadowPlane;
|
|
49046
|
+
}
|
|
49047
|
+
/**@deprecated This can only get the first renderScene's ambientLight */
|
|
49048
|
+
static get ambientLight() {
|
|
49049
|
+
return RBXRenderer.firstScene.ambientLight;
|
|
49050
|
+
}
|
|
49051
|
+
/**@deprecated This can only get the first renderScene's directionalLight */
|
|
49052
|
+
static get directionalLight() {
|
|
49053
|
+
return RBXRenderer.firstScene.directionalLight;
|
|
49054
|
+
}
|
|
49055
|
+
/**@deprecated This can only get the first renderScene's directionalLight2 */
|
|
49056
|
+
static get directionalLight2() {
|
|
49057
|
+
return RBXRenderer.firstScene.directionalLight2;
|
|
49058
|
+
}
|
|
49059
|
+
/**@deprecated This can only set the first renderScene's wellLitDirectionalLightIntensity*/
|
|
49060
|
+
static set wellLitDirectionalLightIntensity(v) {
|
|
49061
|
+
RBXRenderer.firstScene.wellLitDirectionalLightIntensity = v;
|
|
49062
|
+
}
|
|
49063
|
+
/**@deprecated This can only gey the first renderScene's wellLitDirectionalLightIntensity*/
|
|
49064
|
+
static get wellLitDirectionalLightIntensity() {
|
|
49065
|
+
return RBXRenderer.firstScene.wellLitDirectionalLightIntensity;
|
|
49066
|
+
}
|
|
48980
49067
|
static failedToCreate = false;
|
|
48981
49068
|
static error;
|
|
48982
49069
|
static async boilerplateSetup() {
|
|
@@ -49030,17 +49117,67 @@ class RBXRenderer {
|
|
|
49030
49117
|
errorDiv.appendChild(errorLink);
|
|
49031
49118
|
RBXRenderer.canvasContainer.append(errorDiv);
|
|
49032
49119
|
}
|
|
49120
|
+
static createLoadingIconHTML() {
|
|
49121
|
+
RBXRenderer.loadingIcon = document.createElement("span");
|
|
49122
|
+
RBXRenderer.loadingIcon.className = "roavatar-loader";
|
|
49123
|
+
RBXRenderer.loadingIcon.style.opacity = "0";
|
|
49124
|
+
RBXRenderer.loadingIcon.style.position = "absolute";
|
|
49125
|
+
RBXRenderer.loadingIcon.style.bottom = "12px";
|
|
49126
|
+
RBXRenderer.loadingIcon.style.right = "12px";
|
|
49127
|
+
RBXRenderer.loadingIcon.style.width = "24px";
|
|
49128
|
+
RBXRenderer.loadingIcon.style.height = "24px";
|
|
49129
|
+
RBXRenderer.loadingIcon.style.transition = "0.1s";
|
|
49130
|
+
RBXRenderer.loadingIconStyle = document.createElement("style");
|
|
49131
|
+
RBXRenderer.loadingIconStyle.textContent = `
|
|
49132
|
+
/*Loader source: https://cssloaders.github.io/ */
|
|
49133
|
+
.roavatar-loader {
|
|
49134
|
+
width: 48px;
|
|
49135
|
+
height: 48px;
|
|
49136
|
+
display: inline-block;
|
|
49137
|
+
position: relative;
|
|
49138
|
+
background: #FFF;
|
|
49139
|
+
box-sizing: border-box;
|
|
49140
|
+
animation: rooavatarFlipX 1s linear infinite;
|
|
49141
|
+
}
|
|
49142
|
+
|
|
49143
|
+
@keyframes rooavatarFlipX {
|
|
49144
|
+
0% {
|
|
49145
|
+
transform: perspective(200px) rotateX(0deg) rotateY(0deg);
|
|
49146
|
+
}
|
|
49147
|
+
50% {
|
|
49148
|
+
transform: perspective(200px) rotateX(-180deg) rotateY(0deg);
|
|
49149
|
+
}
|
|
49150
|
+
100% {
|
|
49151
|
+
transform: perspective(200px) rotateX(-180deg) rotateY(-180deg);
|
|
49152
|
+
}
|
|
49153
|
+
}
|
|
49154
|
+
`;
|
|
49155
|
+
document.head.appendChild(RBXRenderer.loadingIconStyle);
|
|
49156
|
+
RBXRenderer.canvasContainer.appendChild(RBXRenderer.loadingIcon);
|
|
49157
|
+
const onLoadConnection = API.Events.OnLoadingAssets.Connect((newIsLoading) => {
|
|
49158
|
+
if (RBXRenderer.loadingIcon) {
|
|
49159
|
+
RBXRenderer.loadingIcon.style.opacity = newIsLoading ? "1" : "0";
|
|
49160
|
+
} else {
|
|
49161
|
+
onLoadConnection.Disconnect();
|
|
49162
|
+
}
|
|
49163
|
+
});
|
|
49164
|
+
}
|
|
49165
|
+
static addScene() {
|
|
49166
|
+
const renderScene = new RBXRendererScene();
|
|
49167
|
+
RBXRenderer.scenes.push(renderScene);
|
|
49168
|
+
return renderScene;
|
|
49169
|
+
}
|
|
49033
49170
|
/**Fully sets up renderer with scene, camera and frame rendering
|
|
49034
49171
|
* @returns success
|
|
49035
49172
|
*/
|
|
49036
|
-
static async fullSetup(
|
|
49173
|
+
static async fullSetup(includeSceneAppearance = true, includeControls = true, includeAnimate = true) {
|
|
49037
49174
|
try {
|
|
49038
49175
|
RBXRenderer.createContainer();
|
|
49039
49176
|
await RBXRenderer.boilerplateSetup();
|
|
49040
49177
|
RBXRenderer.create();
|
|
49041
|
-
if (
|
|
49178
|
+
if (includeSceneAppearance) RBXRenderer.setupScene();
|
|
49042
49179
|
if (includeControls) RBXRenderer.setupControls();
|
|
49043
|
-
RBXRenderer.
|
|
49180
|
+
if (includeAnimate) RBXRenderer.animateAll();
|
|
49044
49181
|
} catch (err2) {
|
|
49045
49182
|
error(err2);
|
|
49046
49183
|
RBXRenderer.failedToCreate = true;
|
|
@@ -49071,49 +49208,7 @@ class RBXRenderer {
|
|
|
49071
49208
|
RBXRenderer.renderer.domElement.setAttribute("id", "OutfitInfo-outfit-image-3d");
|
|
49072
49209
|
RBXRenderer.canvasContainer.appendChild(RBXRenderer.renderer.domElement);
|
|
49073
49210
|
if (RBXRenderer.createLoadingIcon) {
|
|
49074
|
-
RBXRenderer.
|
|
49075
|
-
RBXRenderer.loadingIcon.className = "roavatar-loader";
|
|
49076
|
-
RBXRenderer.loadingIcon.style.opacity = "0";
|
|
49077
|
-
RBXRenderer.loadingIcon.style.position = "absolute";
|
|
49078
|
-
RBXRenderer.loadingIcon.style.bottom = "12px";
|
|
49079
|
-
RBXRenderer.loadingIcon.style.right = "12px";
|
|
49080
|
-
RBXRenderer.loadingIcon.style.width = "24px";
|
|
49081
|
-
RBXRenderer.loadingIcon.style.height = "24px";
|
|
49082
|
-
RBXRenderer.loadingIcon.style.transition = "0.1s";
|
|
49083
|
-
RBXRenderer.loadingIconStyle = document.createElement("style");
|
|
49084
|
-
RBXRenderer.loadingIconStyle.textContent = `
|
|
49085
|
-
/*Loader source: https://cssloaders.github.io/ */
|
|
49086
|
-
.roavatar-loader {
|
|
49087
|
-
width: 48px;
|
|
49088
|
-
height: 48px;
|
|
49089
|
-
display: inline-block;
|
|
49090
|
-
position: relative;
|
|
49091
|
-
background: #FFF;
|
|
49092
|
-
box-sizing: border-box;
|
|
49093
|
-
animation: rooavatarFlipX 1s linear infinite;
|
|
49094
|
-
}
|
|
49095
|
-
|
|
49096
|
-
@keyframes rooavatarFlipX {
|
|
49097
|
-
0% {
|
|
49098
|
-
transform: perspective(200px) rotateX(0deg) rotateY(0deg);
|
|
49099
|
-
}
|
|
49100
|
-
50% {
|
|
49101
|
-
transform: perspective(200px) rotateX(-180deg) rotateY(0deg);
|
|
49102
|
-
}
|
|
49103
|
-
100% {
|
|
49104
|
-
transform: perspective(200px) rotateX(-180deg) rotateY(-180deg);
|
|
49105
|
-
}
|
|
49106
|
-
}
|
|
49107
|
-
`;
|
|
49108
|
-
document.head.appendChild(RBXRenderer.loadingIconStyle);
|
|
49109
|
-
RBXRenderer.canvasContainer.appendChild(RBXRenderer.loadingIcon);
|
|
49110
|
-
const onLoadConnection = API.Events.OnLoadingAssets.Connect((newIsLoading) => {
|
|
49111
|
-
if (RBXRenderer.loadingIcon) {
|
|
49112
|
-
RBXRenderer.loadingIcon.style.opacity = newIsLoading ? "1" : "0";
|
|
49113
|
-
} else {
|
|
49114
|
-
onLoadConnection.Disconnect();
|
|
49115
|
-
}
|
|
49116
|
-
});
|
|
49211
|
+
RBXRenderer.createLoadingIconHTML();
|
|
49117
49212
|
}
|
|
49118
49213
|
if (FLAGS.USE_POST_PROCESSING) {
|
|
49119
49214
|
RBXRenderer._createEffectComposer();
|
|
@@ -49123,10 +49218,10 @@ class RBXRenderer {
|
|
|
49123
49218
|
* @param lightingType "WellLit" is the default lighting for RoAvatar, "Thumbnail" tries to match the Roblox thumbnail lighting
|
|
49124
49219
|
* @param backgroundColorHex is the hex code for the background color, for example 0x2b2d33
|
|
49125
49220
|
*/
|
|
49126
|
-
static setupScene(lightingType = "WellLit", backgroundColorHex = RBXRenderer.backgroundColorHex) {
|
|
49221
|
+
static setupScene(lightingType = "WellLit", backgroundColorHex = RBXRenderer.backgroundColorHex, renderScene = RBXRenderer.firstScene) {
|
|
49127
49222
|
RBXRenderer.backgroundColorHex = backgroundColorHex;
|
|
49128
49223
|
const backgroundColor = new Color(backgroundColorHex);
|
|
49129
|
-
|
|
49224
|
+
renderScene.scene.background = backgroundColor;
|
|
49130
49225
|
let thumbnailAmbientVal = 138;
|
|
49131
49226
|
thumbnailAmbientVal = 128;
|
|
49132
49227
|
let ambientLightColor = void 0;
|
|
@@ -49136,8 +49231,8 @@ class RBXRenderer {
|
|
|
49136
49231
|
ambientLightColor = new Color(100 / 255, 100 / 255, 100 / 255);
|
|
49137
49232
|
}
|
|
49138
49233
|
const ambientLight = new AmbientLight(ambientLightColor, Math.PI / 2);
|
|
49139
|
-
|
|
49140
|
-
|
|
49234
|
+
renderScene.scene.add(ambientLight);
|
|
49235
|
+
renderScene.ambientLight = ambientLight;
|
|
49141
49236
|
let directionalLightColor = void 0;
|
|
49142
49237
|
const directionalLightVal = 0.7 * 0.9 * 2 * 0.4;
|
|
49143
49238
|
if (lightingType === "Thumbnail") {
|
|
@@ -49147,7 +49242,7 @@ class RBXRenderer {
|
|
|
49147
49242
|
}
|
|
49148
49243
|
let directionalLightIntensity = 1;
|
|
49149
49244
|
if (lightingType === "WellLit") {
|
|
49150
|
-
directionalLightIntensity =
|
|
49245
|
+
directionalLightIntensity = renderScene._wellLitDirectionalLightIntensity;
|
|
49151
49246
|
}
|
|
49152
49247
|
const directionalLight = new DirectionalLight(directionalLightColor, directionalLightIntensity);
|
|
49153
49248
|
if (lightingType === "WellLit") {
|
|
@@ -49156,10 +49251,10 @@ class RBXRenderer {
|
|
|
49156
49251
|
directionalLight.position.set(-0.47489210963249207 * 10, 0.8225368857383728 * 10, 0.3129066228866577 * 10);
|
|
49157
49252
|
}
|
|
49158
49253
|
if (lightingType === "WellLit") {
|
|
49159
|
-
directionalLight.castShadow =
|
|
49254
|
+
directionalLight.castShadow = renderScene.shadowEnabled;
|
|
49160
49255
|
}
|
|
49161
|
-
directionalLight.shadow.mapSize.width =
|
|
49162
|
-
directionalLight.shadow.mapSize.height =
|
|
49256
|
+
directionalLight.shadow.mapSize.width = renderScene.shadowResolution[0];
|
|
49257
|
+
directionalLight.shadow.mapSize.height = renderScene.shadowResolution[1];
|
|
49163
49258
|
const bottomOffset = 1.6;
|
|
49164
49259
|
const shadowPhysicalSize = 5;
|
|
49165
49260
|
directionalLight.shadow.camera.left = -shadowPhysicalSize;
|
|
@@ -49170,20 +49265,20 @@ class RBXRenderer {
|
|
|
49170
49265
|
directionalLight.shadow.camera.far = 25;
|
|
49171
49266
|
directionalLight.shadow.intensity = 0.5;
|
|
49172
49267
|
directionalLight.target.position.set(0, 0, 0);
|
|
49173
|
-
|
|
49174
|
-
|
|
49268
|
+
renderScene.scene.add(directionalLight);
|
|
49269
|
+
renderScene.directionalLight = directionalLight;
|
|
49175
49270
|
if (lightingType === "WellLit") {
|
|
49176
49271
|
const directionalLight2 = new DirectionalLight(16777215, 0.3);
|
|
49177
49272
|
directionalLight2.position.set(5, -7, 5);
|
|
49178
49273
|
directionalLight2.target.position.set(0, 0, 0);
|
|
49179
|
-
|
|
49180
|
-
|
|
49274
|
+
renderScene.scene.add(directionalLight2);
|
|
49275
|
+
renderScene.directionalLight2 = directionalLight2;
|
|
49181
49276
|
} else if (lightingType === "Thumbnail") {
|
|
49182
49277
|
const directionalLight2 = new DirectionalLight(directionalLightColor, directionalLightIntensity * 0.5);
|
|
49183
49278
|
directionalLight2.position.set(-0.47489210963249207 * -10, 0.8225368857383728 * -10, 0.3129066228866577 * -10);
|
|
49184
49279
|
directionalLight2.target.position.set(0, 0, 0);
|
|
49185
|
-
|
|
49186
|
-
|
|
49280
|
+
renderScene.scene.add(directionalLight2);
|
|
49281
|
+
renderScene.directionalLight2 = directionalLight2;
|
|
49187
49282
|
}
|
|
49188
49283
|
const planeGeometry = new PlaneGeometry(100, 100, 1, 1);
|
|
49189
49284
|
const planeShadowMaterial = new ShadowMaterial({ opacity: 1 });
|
|
@@ -49191,27 +49286,27 @@ class RBXRenderer {
|
|
|
49191
49286
|
shadowPlane.rotation.set(rad(-90), 0, 0);
|
|
49192
49287
|
shadowPlane.position.set(0, 0, 0);
|
|
49193
49288
|
shadowPlane.receiveShadow = true;
|
|
49194
|
-
|
|
49195
|
-
|
|
49289
|
+
renderScene.shadowPlane = shadowPlane;
|
|
49290
|
+
renderScene.scene.add(shadowPlane);
|
|
49196
49291
|
const planeSolidColorMaterial = new MeshBasicMaterial({ color: backgroundColor });
|
|
49197
49292
|
const plane = new Mesh(planeGeometry, planeSolidColorMaterial);
|
|
49198
49293
|
plane.rotation.set(rad(-90), 0, 0);
|
|
49199
49294
|
plane.position.set(0, 0, 0);
|
|
49200
49295
|
plane.receiveShadow = false;
|
|
49201
|
-
|
|
49202
|
-
|
|
49296
|
+
renderScene.plane = plane;
|
|
49297
|
+
renderScene.scene.add(plane);
|
|
49203
49298
|
}
|
|
49204
49299
|
/**Sets up orbit controls */
|
|
49205
|
-
static setupControls() {
|
|
49300
|
+
static setupControls(renderScene = RBXRenderer.firstScene) {
|
|
49206
49301
|
if (!RBXRenderer.renderer) return;
|
|
49207
|
-
const controls = new OrbitControls(
|
|
49302
|
+
const controls = new OrbitControls(renderScene.camera, RBXRenderer.renderer.domElement);
|
|
49208
49303
|
controls.maxDistance = 25;
|
|
49209
49304
|
controls.zoomSpeed = 2;
|
|
49210
49305
|
controls.target.set(...RBXRenderer.orbitControlsTarget);
|
|
49211
49306
|
log(false, controls.target);
|
|
49212
|
-
|
|
49213
|
-
|
|
49214
|
-
|
|
49307
|
+
renderScene.controls = controls;
|
|
49308
|
+
renderScene.camera.position.set(renderScene.lookAwayVector[0] * renderScene.lookAwayDistance, 3 + renderScene.lookAwayVector[1] * renderScene.lookAwayDistance, renderScene.lookAwayVector[2] * renderScene.lookAwayDistance);
|
|
49309
|
+
renderScene.camera.lookAt(new Vector3$1(...RBXRenderer.orbitControlsTarget));
|
|
49215
49310
|
controls.update();
|
|
49216
49311
|
}
|
|
49217
49312
|
/**
|
|
@@ -49219,16 +49314,18 @@ class RBXRenderer {
|
|
|
49219
49314
|
*/
|
|
49220
49315
|
static setBackgroundColor(colorHex) {
|
|
49221
49316
|
RBXRenderer.backgroundColorHex = colorHex;
|
|
49222
|
-
|
|
49223
|
-
RBXRenderer.
|
|
49224
|
-
|
|
49225
|
-
|
|
49226
|
-
|
|
49227
|
-
|
|
49228
|
-
|
|
49229
|
-
|
|
49230
|
-
|
|
49231
|
-
|
|
49317
|
+
for (const renderScene of RBXRenderer.scenes) {
|
|
49318
|
+
if (RBXRenderer.backgroundTransparent) {
|
|
49319
|
+
renderScene.scene.background = null;
|
|
49320
|
+
} else {
|
|
49321
|
+
renderScene.scene.background = new Color(RBXRenderer.backgroundColorHex);
|
|
49322
|
+
}
|
|
49323
|
+
if (renderScene.plane) {
|
|
49324
|
+
renderScene.plane.visible = !RBXRenderer.backgroundTransparent;
|
|
49325
|
+
}
|
|
49326
|
+
if (renderScene.plane) {
|
|
49327
|
+
renderScene.plane.material = new MeshBasicMaterial({ color: colorHex });
|
|
49328
|
+
}
|
|
49232
49329
|
}
|
|
49233
49330
|
}
|
|
49234
49331
|
/**
|
|
@@ -49237,60 +49334,103 @@ class RBXRenderer {
|
|
|
49237
49334
|
*/
|
|
49238
49335
|
static setBackgroundTransparent(transparent) {
|
|
49239
49336
|
RBXRenderer.backgroundTransparent = transparent;
|
|
49240
|
-
|
|
49241
|
-
RBXRenderer.
|
|
49242
|
-
|
|
49243
|
-
|
|
49244
|
-
|
|
49245
|
-
|
|
49246
|
-
|
|
49337
|
+
for (const renderScene of RBXRenderer.scenes) {
|
|
49338
|
+
if (RBXRenderer.backgroundTransparent) {
|
|
49339
|
+
renderScene.scene.background = null;
|
|
49340
|
+
} else {
|
|
49341
|
+
renderScene.scene.background = new Color(RBXRenderer.backgroundColorHex);
|
|
49342
|
+
}
|
|
49343
|
+
if (renderScene.plane) {
|
|
49344
|
+
renderScene.plane.visible = !RBXRenderer.backgroundTransparent;
|
|
49345
|
+
}
|
|
49247
49346
|
}
|
|
49248
49347
|
}
|
|
49249
49348
|
/**Makes the renderer render a new frame on every animationFrame */
|
|
49250
|
-
static animate() {
|
|
49349
|
+
static animate(shouldRequestAnimationFrame = true) {
|
|
49350
|
+
if (!RBXRenderer.renderer) return;
|
|
49351
|
+
RBXRenderer.renderScene(RBXRenderer.firstScene);
|
|
49352
|
+
if (shouldRequestAnimationFrame) {
|
|
49353
|
+
requestAnimationFrame(() => {
|
|
49354
|
+
RBXRenderer.animate();
|
|
49355
|
+
});
|
|
49356
|
+
}
|
|
49357
|
+
}
|
|
49358
|
+
static animateAll(shouldRequestAnimationFrame = true) {
|
|
49359
|
+
if (!RBXRenderer.renderer) return;
|
|
49360
|
+
for (const renderScene of RBXRenderer.scenes) {
|
|
49361
|
+
RBXRenderer.renderScene(renderScene, renderScene === RBXRenderer.firstScene);
|
|
49362
|
+
}
|
|
49363
|
+
if (shouldRequestAnimationFrame) {
|
|
49364
|
+
requestAnimationFrame(() => {
|
|
49365
|
+
RBXRenderer.animateAll();
|
|
49366
|
+
});
|
|
49367
|
+
}
|
|
49368
|
+
}
|
|
49369
|
+
static renderScene(renderScene, autoClear = true) {
|
|
49251
49370
|
if (!RBXRenderer.renderer) return;
|
|
49371
|
+
RBXRenderer.renderer.autoClear = autoClear;
|
|
49372
|
+
if (!autoClear) {
|
|
49373
|
+
RBXRenderer.renderer.clearDepth();
|
|
49374
|
+
}
|
|
49252
49375
|
RBXRenderer.renderer.setRenderTarget(null);
|
|
49253
|
-
|
|
49254
|
-
|
|
49376
|
+
let [x, y] = [0, 0];
|
|
49377
|
+
let [width, height] = RBXRenderer.resolution;
|
|
49378
|
+
if (renderScene.viewport) {
|
|
49379
|
+
x = renderScene.viewport[0];
|
|
49380
|
+
y = renderScene.viewport[1];
|
|
49381
|
+
width = renderScene.viewport[2];
|
|
49382
|
+
height = renderScene.viewport[3];
|
|
49383
|
+
}
|
|
49384
|
+
RBXRenderer.renderer.setViewport(x, y, width, height);
|
|
49385
|
+
if (renderScene.scissor) {
|
|
49386
|
+
RBXRenderer.renderer.setScissorTest(true);
|
|
49387
|
+
RBXRenderer.renderer.setScissor(...renderScene.scissor);
|
|
49255
49388
|
} else {
|
|
49256
|
-
RBXRenderer.renderer.
|
|
49389
|
+
RBXRenderer.renderer.setScissorTest(false);
|
|
49257
49390
|
}
|
|
49258
|
-
|
|
49259
|
-
|
|
49260
|
-
|
|
49391
|
+
renderScene.camera.aspect = width / height;
|
|
49392
|
+
renderScene.camera.updateProjectionMatrix();
|
|
49393
|
+
if (width > 0 && height > 0) {
|
|
49394
|
+
if (renderScene.effectComposer) {
|
|
49395
|
+
renderScene.effectComposer.render();
|
|
49396
|
+
} else {
|
|
49397
|
+
RBXRenderer.renderer.render(renderScene.scene, renderScene.camera);
|
|
49398
|
+
}
|
|
49399
|
+
}
|
|
49400
|
+
RBXRenderer.renderer.autoClear = true;
|
|
49261
49401
|
}
|
|
49262
|
-
static _createEffectComposer() {
|
|
49402
|
+
static _createEffectComposer(renderScene = RBXRenderer.firstScene) {
|
|
49263
49403
|
if (!RBXRenderer.renderer) return;
|
|
49264
|
-
|
|
49265
|
-
const renderPass = new RenderPass(
|
|
49266
|
-
|
|
49404
|
+
renderScene.effectComposer = new EffectComposer(RBXRenderer.renderer);
|
|
49405
|
+
const renderPass = new RenderPass(renderScene.scene, renderScene.camera);
|
|
49406
|
+
renderScene.effectComposer.addPass(renderPass);
|
|
49267
49407
|
const resolution = new Vector2$1(420, 420);
|
|
49268
49408
|
const bloomPass = new UnrealBloomPass(resolution, 0.15, 1e-4, 0.9);
|
|
49269
|
-
|
|
49409
|
+
renderScene.effectComposer.addPass(bloomPass);
|
|
49270
49410
|
if (!FLAGS.POST_PROCESSING_IS_DOUBLE_SIZE) {
|
|
49271
49411
|
const fxaaPass = new FXAAPass();
|
|
49272
|
-
|
|
49412
|
+
renderScene.effectComposer.addPass(fxaaPass);
|
|
49273
49413
|
}
|
|
49274
49414
|
const outputPass = new OutputPass();
|
|
49275
|
-
|
|
49415
|
+
renderScene.effectComposer.addPass(outputPass);
|
|
49276
49416
|
}
|
|
49277
49417
|
/**Removes an instance from the renderer */
|
|
49278
|
-
static removeInstance(instance) {
|
|
49418
|
+
static removeInstance(instance, renderScene = RBXRenderer.firstScene) {
|
|
49279
49419
|
if (!RBXRenderer.renderer) return;
|
|
49280
|
-
const desc =
|
|
49420
|
+
const desc = renderScene.renderDescs.get(instance);
|
|
49281
49421
|
if (desc) {
|
|
49282
|
-
desc.dispose(RBXRenderer.renderer,
|
|
49422
|
+
desc.dispose(RBXRenderer.renderer, renderScene.scene);
|
|
49283
49423
|
}
|
|
49284
|
-
|
|
49285
|
-
|
|
49424
|
+
renderScene.renderDescs.delete(instance);
|
|
49425
|
+
renderScene.isRenderingMesh.delete(instance);
|
|
49286
49426
|
for (const child of instance.GetChildren()) {
|
|
49287
|
-
RBXRenderer.removeInstance(child);
|
|
49427
|
+
RBXRenderer.removeInstance(child, renderScene);
|
|
49288
49428
|
}
|
|
49289
49429
|
}
|
|
49290
|
-
static _addRenderDesc(instance, auth, DescClass) {
|
|
49430
|
+
static _addRenderDesc(instance, auth, DescClass, renderScene) {
|
|
49291
49431
|
if (!RBXRenderer.renderer) return;
|
|
49292
|
-
const oldDesc =
|
|
49293
|
-
const newDesc = new DescClass();
|
|
49432
|
+
const oldDesc = renderScene.renderDescs.get(instance);
|
|
49433
|
+
const newDesc = new DescClass(renderScene);
|
|
49294
49434
|
newDesc.fromInstance(instance);
|
|
49295
49435
|
if (oldDesc && !oldDesc.needsRegeneration(newDesc)) {
|
|
49296
49436
|
if (!oldDesc.isSame(newDesc)) {
|
|
@@ -49298,15 +49438,15 @@ class RBXRenderer {
|
|
|
49298
49438
|
oldDesc.updateResults();
|
|
49299
49439
|
}
|
|
49300
49440
|
} else {
|
|
49301
|
-
if (!
|
|
49441
|
+
if (!renderScene.isRenderingMesh.get(instance)) {
|
|
49302
49442
|
newDesc.results = oldDesc?.results;
|
|
49303
|
-
|
|
49304
|
-
|
|
49305
|
-
newDesc.compileResults(RBXRenderer.renderer,
|
|
49443
|
+
renderScene.renderDescs.set(instance, newDesc);
|
|
49444
|
+
renderScene.isRenderingMesh.set(instance, true);
|
|
49445
|
+
newDesc.compileResults(RBXRenderer.renderer, renderScene.scene).then((results) => {
|
|
49306
49446
|
if (results && !(results instanceof Response)) {
|
|
49307
49447
|
newDesc.updateResults();
|
|
49308
|
-
if (
|
|
49309
|
-
oldDesc?.dispose(RBXRenderer.renderer,
|
|
49448
|
+
if (renderScene.renderDescs.get(instance) && RBXRenderer.renderer) {
|
|
49449
|
+
oldDesc?.dispose(RBXRenderer.renderer, renderScene.scene);
|
|
49310
49450
|
for (const result of results) {
|
|
49311
49451
|
if (result instanceof SkinnedMesh && newDesc instanceof ObjectDesc) {
|
|
49312
49452
|
const skeleton = newDesc.skeletonDesc?.skeleton;
|
|
@@ -49316,20 +49456,20 @@ class RBXRenderer {
|
|
|
49316
49456
|
if (FLAGS.USE_LOCAL_SKELETONDESC) {
|
|
49317
49457
|
result.add(newDesc.skeletonDesc.rootBone);
|
|
49318
49458
|
} else {
|
|
49319
|
-
|
|
49459
|
+
renderScene.scene.add(newDesc.skeletonDesc.rootBone);
|
|
49320
49460
|
}
|
|
49321
49461
|
}
|
|
49322
49462
|
result.bind(skeleton);
|
|
49323
|
-
|
|
49463
|
+
renderScene.scene.add(result);
|
|
49324
49464
|
}
|
|
49325
49465
|
} else {
|
|
49326
|
-
|
|
49466
|
+
renderScene.scene.add(result);
|
|
49327
49467
|
}
|
|
49328
49468
|
}
|
|
49329
|
-
|
|
49330
|
-
RBXRenderer.addInstance(instance, auth);
|
|
49469
|
+
renderScene.isRenderingMesh.set(instance, false);
|
|
49470
|
+
RBXRenderer.addInstance(instance, auth, renderScene);
|
|
49331
49471
|
} else if (RBXRenderer.renderer) {
|
|
49332
|
-
newDesc.dispose(RBXRenderer.renderer,
|
|
49472
|
+
newDesc.dispose(RBXRenderer.renderer, renderScene.scene);
|
|
49333
49473
|
}
|
|
49334
49474
|
} else {
|
|
49335
49475
|
warn(false, "Failed to compile mesh", this, results);
|
|
@@ -49337,17 +49477,17 @@ class RBXRenderer {
|
|
|
49337
49477
|
});
|
|
49338
49478
|
}
|
|
49339
49479
|
}
|
|
49340
|
-
if (!
|
|
49341
|
-
|
|
49342
|
-
RBXRenderer.removeInstance(instance);
|
|
49343
|
-
const connection =
|
|
49480
|
+
if (!renderScene.destroyConnections.get(instance)) {
|
|
49481
|
+
renderScene.destroyConnections.set(instance, instance.Destroying.Connect(() => {
|
|
49482
|
+
RBXRenderer.removeInstance(instance, renderScene);
|
|
49483
|
+
const connection = renderScene.destroyConnections.get(instance);
|
|
49344
49484
|
connection?.Disconnect();
|
|
49345
|
-
|
|
49485
|
+
renderScene.destroyConnections.delete(instance);
|
|
49346
49486
|
}));
|
|
49347
49487
|
}
|
|
49348
49488
|
}
|
|
49349
49489
|
/**Adds an instance to the renderer or updates it */
|
|
49350
|
-
static addInstance(instance, auth) {
|
|
49490
|
+
static addInstance(instance, auth, renderScene = RBXRenderer.firstScene) {
|
|
49351
49491
|
const isDecal = instance.className === "Decal";
|
|
49352
49492
|
const isBakedDecal = isDecal && !instance.FindFirstChildOfClass("WrapTextureTransfer");
|
|
49353
49493
|
let isFirstDecal = true;
|
|
@@ -49360,12 +49500,12 @@ class RBXRenderer {
|
|
|
49360
49500
|
}
|
|
49361
49501
|
}
|
|
49362
49502
|
if (ObjectDescClassTypes.includes(instance.className) && !isBakedDecal && (!isDecal || isFirstDecal)) {
|
|
49363
|
-
RBXRenderer._addRenderDesc(instance, auth, ObjectDesc);
|
|
49503
|
+
RBXRenderer._addRenderDesc(instance, auth, ObjectDesc, renderScene);
|
|
49364
49504
|
} else if (EmitterGroupDescClassTypes.includes(instance.className)) {
|
|
49365
|
-
RBXRenderer._addRenderDesc(instance, auth, EmitterGroupDesc);
|
|
49505
|
+
RBXRenderer._addRenderDesc(instance, auth, EmitterGroupDesc, renderScene);
|
|
49366
49506
|
}
|
|
49367
49507
|
for (const child of instance.GetChildren()) {
|
|
49368
|
-
RBXRenderer.addInstance(child, auth);
|
|
49508
|
+
RBXRenderer.addInstance(child, auth, renderScene);
|
|
49369
49509
|
}
|
|
49370
49510
|
}
|
|
49371
49511
|
static setRendererSize(width, height) {
|
|
@@ -49378,8 +49518,6 @@ class RBXRenderer {
|
|
|
49378
49518
|
if (FLAGS.USE_POST_PROCESSING && FLAGS.POST_PROCESSING_IS_DOUBLE_SIZE) {
|
|
49379
49519
|
RBXRenderer.renderer.setSize(RBXRenderer.resolution[0] * 2, RBXRenderer.resolution[1] * 2);
|
|
49380
49520
|
}
|
|
49381
|
-
RBXRenderer.camera.aspect = width / height;
|
|
49382
|
-
RBXRenderer.camera.updateProjectionMatrix();
|
|
49383
49521
|
}
|
|
49384
49522
|
/**
|
|
49385
49523
|
* @deprecated Use getRendererElement instead which includes the loading icon
|
|
@@ -49395,11 +49533,12 @@ class RBXRenderer {
|
|
|
49395
49533
|
static getRendererElement() {
|
|
49396
49534
|
return RBXRenderer.canvasContainer;
|
|
49397
49535
|
}
|
|
49536
|
+
/**@deprecated This can only get the first renderScene's camera */
|
|
49398
49537
|
static getRendererCamera() {
|
|
49399
49538
|
return RBXRenderer.camera;
|
|
49400
49539
|
}
|
|
49401
|
-
static getCameraCFrame() {
|
|
49402
|
-
const camera =
|
|
49540
|
+
static getCameraCFrame(renderScene = RBXRenderer.firstScene) {
|
|
49541
|
+
const camera = renderScene.camera;
|
|
49403
49542
|
const pos = camera.position;
|
|
49404
49543
|
let rot = camera.rotation.clone();
|
|
49405
49544
|
rot = rot.reorder("YXZ");
|
|
@@ -49408,34 +49547,36 @@ class RBXRenderer {
|
|
|
49408
49547
|
cf.Orientation = [deg(rot.x), deg(rot.y), deg(rot.z)];
|
|
49409
49548
|
return cf;
|
|
49410
49549
|
}
|
|
49411
|
-
static setCameraCFrame(cameraCF) {
|
|
49550
|
+
static setCameraCFrame(cameraCF, renderScene = RBXRenderer.firstScene) {
|
|
49412
49551
|
const camPos = new Vector3$1();
|
|
49413
49552
|
const camQuat = new Quaternion();
|
|
49414
49553
|
const camScale = new Vector3$1();
|
|
49415
49554
|
const camMatrix = cameraCF.getTHREEMatrix();
|
|
49416
49555
|
camMatrix.decompose(camPos, camQuat, camScale);
|
|
49417
|
-
|
|
49418
|
-
|
|
49419
|
-
|
|
49556
|
+
renderScene.camera.position.set(...camPos.toArray());
|
|
49557
|
+
renderScene.camera.quaternion.set(...camQuat.toArray());
|
|
49558
|
+
renderScene.camera.updateMatrixWorld();
|
|
49420
49559
|
}
|
|
49421
|
-
static setCameraFov(fov2) {
|
|
49422
|
-
|
|
49560
|
+
static setCameraFov(fov2, renderScene = RBXRenderer.firstScene) {
|
|
49561
|
+
renderScene.camera.fov = fov2;
|
|
49423
49562
|
}
|
|
49563
|
+
/**@deprecated This can only get the first renderScene's controls */
|
|
49424
49564
|
static getRendererControls() {
|
|
49425
49565
|
return RBXRenderer.controls;
|
|
49426
49566
|
}
|
|
49427
49567
|
static getRenderer() {
|
|
49428
49568
|
return RBXRenderer.renderer;
|
|
49429
49569
|
}
|
|
49570
|
+
/**@deprecated This can only get the first renderScene's scene */
|
|
49430
49571
|
static getScene() {
|
|
49431
|
-
return RBXRenderer.
|
|
49572
|
+
return RBXRenderer.firstScene;
|
|
49432
49573
|
}
|
|
49433
49574
|
/**@deprecated
|
|
49434
49575
|
* This function is unstable and can throw errors, but might work
|
|
49435
49576
|
*/
|
|
49436
|
-
static exportScene() {
|
|
49577
|
+
static exportScene(renderScene = RBXRenderer.firstScene) {
|
|
49437
49578
|
const exporter = new GLTFExporter();
|
|
49438
|
-
exporter.parse(
|
|
49579
|
+
exporter.parse(renderScene.scene, (gltf) => {
|
|
49439
49580
|
if (gltf instanceof ArrayBuffer) {
|
|
49440
49581
|
saveByteArray([gltf], "scene.glb");
|
|
49441
49582
|
} else {
|
|
@@ -49524,7 +49665,7 @@ class HSR {
|
|
|
49524
49665
|
if (FLAGS.HSR_SHOW_RAY) {
|
|
49525
49666
|
const geometry = new BufferGeometry().setFromPoints([new Vector3$1(...ray.origin), new Vector3$1(...ray.end)]);
|
|
49526
49667
|
const line = new Line(geometry, rayHit ? hitMaterial : missMaterial);
|
|
49527
|
-
RBXRenderer.
|
|
49668
|
+
RBXRenderer.scene.add(line);
|
|
49528
49669
|
}
|
|
49529
49670
|
}
|
|
49530
49671
|
this.innerHits[i] = hits;
|
|
@@ -49584,6 +49725,22 @@ function getHigher(a, b) {
|
|
|
49584
49725
|
a.Z > b.Z ? a.Z : b.Z
|
|
49585
49726
|
);
|
|
49586
49727
|
}
|
|
49728
|
+
function getExtentsForParts(parts, includeTransform) {
|
|
49729
|
+
let lowerExtents = new Vector32(0, 0, 0);
|
|
49730
|
+
let higherExtents = new Vector32(0, 0, 0);
|
|
49731
|
+
for (const child of parts) {
|
|
49732
|
+
if (child.className === "Part" || child.className === "MeshPart") {
|
|
49733
|
+
const cframe = traverseRigCFrame(child, includeTransform, true);
|
|
49734
|
+
const size = child.Prop("Size");
|
|
49735
|
+
const corners = getCorners(cframe, size);
|
|
49736
|
+
for (const corner of corners) {
|
|
49737
|
+
lowerExtents = getLower(lowerExtents, new Vector32().fromVec3(corner.Position));
|
|
49738
|
+
higherExtents = getHigher(higherExtents, new Vector32().fromVec3(corner.Position));
|
|
49739
|
+
}
|
|
49740
|
+
}
|
|
49741
|
+
}
|
|
49742
|
+
return [lowerExtents, higherExtents];
|
|
49743
|
+
}
|
|
49587
49744
|
function getExtents(cframe, parts) {
|
|
49588
49745
|
const inverseCF = cframe.inverse();
|
|
49589
49746
|
let lowerExtents = new Vector32(0, 0, 0);
|
|
@@ -49658,7 +49815,6 @@ class OutfitRenderer {
|
|
|
49658
49815
|
currentRig;
|
|
49659
49816
|
/**Instance for the Model of the current outfit */
|
|
49660
49817
|
currentRigType;
|
|
49661
|
-
rigPath;
|
|
49662
49818
|
doCameraUpdateOnLoad = true;
|
|
49663
49819
|
/**Makes camera update when new avatar has loaded */
|
|
49664
49820
|
doCameraUpdate = false;
|
|
@@ -49670,17 +49826,18 @@ class OutfitRenderer {
|
|
|
49670
49826
|
animationInterval;
|
|
49671
49827
|
animationFPS = 60;
|
|
49672
49828
|
deltaTimeMultiplier = 1;
|
|
49829
|
+
renderScene = RBXRenderer.firstScene;
|
|
49673
49830
|
/**
|
|
49674
49831
|
* Creates a new OutfitRenderer which makes it easy to render outfits
|
|
49675
49832
|
* @param auth The authentication object, you should have one you use for everything
|
|
49676
49833
|
* @param outfit The outfit you want to render, it can be updated later by calling setOutfit()
|
|
49677
|
-
* @param
|
|
49834
|
+
* @param renderScene The scene the outfit should be rendered in
|
|
49678
49835
|
*/
|
|
49679
|
-
constructor(auth, outfit,
|
|
49836
|
+
constructor(auth, outfit, renderScene = RBXRenderer.firstScene) {
|
|
49680
49837
|
this.auth = auth;
|
|
49681
49838
|
this.outfit = outfit;
|
|
49682
49839
|
this.currentRigType = outfit.playerAvatarType;
|
|
49683
|
-
this.
|
|
49840
|
+
this.renderScene = renderScene;
|
|
49684
49841
|
this._updateOutfit();
|
|
49685
49842
|
}
|
|
49686
49843
|
/**
|
|
@@ -49695,12 +49852,12 @@ class OutfitRenderer {
|
|
|
49695
49852
|
this.currentRig = void 0;
|
|
49696
49853
|
}
|
|
49697
49854
|
this.currentRigType = newRigType;
|
|
49698
|
-
API.Asset.GetRBX(
|
|
49855
|
+
API.Asset.GetRBX(`roavatar://Rig${this.currentRigType}.rbxm`, void 0).then((result) => {
|
|
49699
49856
|
if (result instanceof RBX) {
|
|
49700
49857
|
const newRig = result.generateTree().GetChildren()[0];
|
|
49701
49858
|
this.currentRig = newRig;
|
|
49702
49859
|
this.currentlyChangingRig = false;
|
|
49703
|
-
RBXRenderer.addInstance(this.currentRig, this.auth);
|
|
49860
|
+
RBXRenderer.addInstance(this.currentRig, this.auth, this.renderScene);
|
|
49704
49861
|
resolve(newRig);
|
|
49705
49862
|
} else {
|
|
49706
49863
|
resolve(result);
|
|
@@ -49733,7 +49890,7 @@ class OutfitRenderer {
|
|
|
49733
49890
|
hrpWrapper.applyDescription(humanoid).then((result) => {
|
|
49734
49891
|
this.currentlyUpdating = false;
|
|
49735
49892
|
if (this.currentRig) {
|
|
49736
|
-
RBXRenderer.addInstance(this.currentRig, this.auth);
|
|
49893
|
+
RBXRenderer.addInstance(this.currentRig, this.auth, this.renderScene);
|
|
49737
49894
|
if (this.doCameraUpdateOnLoad) {
|
|
49738
49895
|
this.centerCamera();
|
|
49739
49896
|
}
|
|
@@ -49770,8 +49927,8 @@ class OutfitRenderer {
|
|
|
49770
49927
|
if (this.currentRig) {
|
|
49771
49928
|
const upperTorso = this.currentRig.FindFirstChild("HumanoidRootPart");
|
|
49772
49929
|
if (upperTorso) {
|
|
49773
|
-
const controls =
|
|
49774
|
-
const camera =
|
|
49930
|
+
const controls = this.renderScene.controls;
|
|
49931
|
+
const camera = this.renderScene.camera;
|
|
49775
49932
|
const pos = upperTorso.Prop("Position");
|
|
49776
49933
|
if (controls) {
|
|
49777
49934
|
const offset = new Vector3$1().subVectors(camera.position, controls.target);
|
|
@@ -49802,7 +49959,7 @@ class OutfitRenderer {
|
|
|
49802
49959
|
const animatorW = new AnimatorWrapper(animator);
|
|
49803
49960
|
animatorW.renderAnimation(deltaTime);
|
|
49804
49961
|
this.currentRig.preRender();
|
|
49805
|
-
RBXRenderer.addInstance(this.currentRig, this.auth);
|
|
49962
|
+
RBXRenderer.addInstance(this.currentRig, this.auth, this.renderScene);
|
|
49806
49963
|
}
|
|
49807
49964
|
}
|
|
49808
49965
|
}
|
|
@@ -49846,6 +50003,7 @@ export {
|
|
|
49846
50003
|
AccessoryAssetTypes,
|
|
49847
50004
|
AccessoryDescriptionWrapper,
|
|
49848
50005
|
AccessoryType,
|
|
50006
|
+
AccessoryWrapper,
|
|
49849
50007
|
ActualBundleTypes,
|
|
49850
50008
|
AllAccessorySorts,
|
|
49851
50009
|
AllAnimationSorts,
|
|
@@ -49857,6 +50015,7 @@ export {
|
|
|
49857
50015
|
AllHeadShapes,
|
|
49858
50016
|
AllInstances,
|
|
49859
50017
|
AlphaMode,
|
|
50018
|
+
AnimationConstraintWrapper,
|
|
49860
50019
|
AnimationPropToName,
|
|
49861
50020
|
AnimationTrack,
|
|
49862
50021
|
AnimatorWrapper,
|
|
@@ -49871,6 +50030,7 @@ export {
|
|
|
49871
50030
|
AvatarType,
|
|
49872
50031
|
BodyColor3s,
|
|
49873
50032
|
BodyColors,
|
|
50033
|
+
BodyColorsWrapper,
|
|
49874
50034
|
BodyPart,
|
|
49875
50035
|
BodyPartDescriptionWrapper,
|
|
49876
50036
|
BodyPartEnumToNames,
|
|
@@ -49890,6 +50050,7 @@ export {
|
|
|
49890
50050
|
Content,
|
|
49891
50051
|
ContentMap,
|
|
49892
50052
|
DataType,
|
|
50053
|
+
DecalWrapper,
|
|
49893
50054
|
DefaultAnimations,
|
|
49894
50055
|
DefaultAnimationsR6,
|
|
49895
50056
|
DefaultGetWorkerFunc,
|
|
@@ -49913,12 +50074,15 @@ export {
|
|
|
49913
50074
|
LayeredAssetTypes,
|
|
49914
50075
|
LayeredClothingAssetOrder,
|
|
49915
50076
|
LocalOutfit,
|
|
50077
|
+
MakeupAssetTypes,
|
|
49916
50078
|
MakeupDescriptionWrapper,
|
|
49917
50079
|
MakeupType,
|
|
50080
|
+
ManualWeldWrapper,
|
|
49918
50081
|
MaxOneOfAssetTypes,
|
|
49919
50082
|
MaxPerAsset,
|
|
49920
50083
|
MeshType,
|
|
49921
50084
|
ModelWrapper,
|
|
50085
|
+
Motor6DWrapper,
|
|
49922
50086
|
NeverLayeredAccessoryTypes,
|
|
49923
50087
|
NormalId,
|
|
49924
50088
|
NumberRange,
|
|
@@ -49935,6 +50099,7 @@ export {
|
|
|
49935
50099
|
RBFDeformerPatch,
|
|
49936
50100
|
RBX,
|
|
49937
50101
|
RBXRenderer,
|
|
50102
|
+
RBXRendererScene,
|
|
49938
50103
|
RNG,
|
|
49939
50104
|
Ray3 as Ray,
|
|
49940
50105
|
RegisterWrappers,
|
|
@@ -49962,6 +50127,7 @@ export {
|
|
|
49962
50127
|
Vector32 as Vector3,
|
|
49963
50128
|
Wait,
|
|
49964
50129
|
WearableAssetTypes,
|
|
50130
|
+
WeldWrapper,
|
|
49965
50131
|
WorkerTypeToFunction,
|
|
49966
50132
|
WrapLayerAutoSkin,
|
|
49967
50133
|
accessoryRefinementLowerBounds,
|
|
@@ -50000,11 +50166,14 @@ export {
|
|
|
50000
50166
|
download,
|
|
50001
50167
|
exposeAPI,
|
|
50002
50168
|
exposeMesh,
|
|
50169
|
+
fileMeshToTHREEGeometry,
|
|
50003
50170
|
floor,
|
|
50004
50171
|
gaussian_rbf,
|
|
50005
50172
|
generateUUIDv4,
|
|
50006
50173
|
getCameraCFrameForHeadshotCustomized,
|
|
50007
50174
|
getDistIndexArray,
|
|
50175
|
+
getExtents,
|
|
50176
|
+
getExtentsForParts,
|
|
50008
50177
|
getHeadExtents,
|
|
50009
50178
|
getOffsetArray,
|
|
50010
50179
|
getOriginalSize,
|
|
@@ -50060,5 +50229,6 @@ export {
|
|
|
50060
50229
|
triangleNormal,
|
|
50061
50230
|
versionToNumber,
|
|
50062
50231
|
vertPosToChunkPos,
|
|
50063
|
-
xmlMagic
|
|
50232
|
+
xmlMagic,
|
|
50233
|
+
zoomExtents
|
|
50064
50234
|
};
|