gitframes 1.3.0 → 1.3.1
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/audio/index.mjs +4 -4
- package/dist/{audio-C4kiPbrV.mjs → audio-DvL7gQQ8.mjs} +3 -3
- package/dist/{audio-C4kiPbrV.mjs.map → audio-DvL7gQQ8.mjs.map} +1 -1
- package/dist/{audio-CiXUMGyk.mjs → audio-sZdRh_qg.mjs} +3 -3
- package/dist/{audio-CiXUMGyk.mjs.map → audio-sZdRh_qg.mjs.map} +1 -1
- package/dist/{dist-C37594c6.mjs → dist-8vbhZYqX.mjs} +471 -152
- package/dist/dist-8vbhZYqX.mjs.map +1 -0
- package/dist/{dist-CMF9eNLB.mjs → dist-B0vCkDzJ.mjs} +37 -3
- package/dist/dist-B0vCkDzJ.mjs.map +1 -0
- package/dist/effects/index.mjs +2 -2
- package/dist/{effects-C9connag.mjs → effects-C3nV-k4T.mjs} +4 -4
- package/dist/{effects-C9connag.mjs.map → effects-C3nV-k4T.mjs.map} +1 -1
- package/dist/fonts/index.mjs +1 -1
- package/dist/{fonts-Dn18r_ST.mjs → fonts-dn-pl4Pe.mjs} +3 -3
- package/dist/{fonts-Dn18r_ST.mjs.map → fonts-dn-pl4Pe.mjs.map} +1 -1
- package/dist/{index-YZsTjqut.d.mts → index-D-O2kwLx.d.mts} +3 -3
- package/dist/{index-YZsTjqut.d.mts.map → index-D-O2kwLx.d.mts.map} +1 -1
- package/dist/index.d.mts +67 -49
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +96 -52
- package/dist/index.mjs.map +1 -1
- package/dist/react/index.mjs +2 -2
- package/dist/renderer/index.d.mts +2 -2
- package/dist/renderer/index.mjs +3 -3
- package/dist/{renderer-DgY7XBYE.mjs → renderer-CMDIVxhv.mjs} +315 -12
- package/dist/renderer-CMDIVxhv.mjs.map +1 -0
- package/dist/{renderers-CLJQRPVU-CMZnHNK0.mjs → renderers-CLJQRPVU-DuQ7-PaC.mjs} +3 -3
- package/dist/{renderers-CLJQRPVU-CMZnHNK0.mjs.map → renderers-CLJQRPVU-DuQ7-PaC.mjs.map} +1 -1
- package/dist/signals/index.mjs +5 -5
- package/dist/{signals-BB_kdndF.mjs → signals-CLaCq092.mjs} +2 -2
- package/dist/{signals-BB_kdndF.mjs.map → signals-CLaCq092.mjs.map} +1 -1
- package/package.json +52 -52
- package/dist/dist-C37594c6.mjs.map +0 -1
- package/dist/dist-CMF9eNLB.mjs.map +0 -1
- package/dist/renderer-DgY7XBYE.mjs.map +0 -1
|
@@ -5234,6 +5234,8 @@ var SlugGenerator = class {
|
|
|
5234
5234
|
return buffer;
|
|
5235
5235
|
}
|
|
5236
5236
|
};
|
|
5237
|
+
/** Per-font load timings are debug output: shown only with LOG_LEVEL=debug or trace. */
|
|
5238
|
+
const VERBOSE_FONT_LOGS = typeof process !== "undefined" && /^(debug|trace)$/i.test(process.env?.LOG_LEVEL ?? "");
|
|
5237
5239
|
function parseFontWeight(fontWeight) {
|
|
5238
5240
|
if (!fontWeight) return 400;
|
|
5239
5241
|
if (fontWeight === "bold") return 700;
|
|
@@ -5307,6 +5309,10 @@ var SlugFontCache = class SlugFontCache$1 {
|
|
|
5307
5309
|
static get parsedFontCache() {
|
|
5308
5310
|
return g[GLOBAL_PARSED_KEY];
|
|
5309
5311
|
}
|
|
5312
|
+
/** Register an already parsed font (e.g. by FontManager) under a family name. */
|
|
5313
|
+
static setParsed(fontFamily, font) {
|
|
5314
|
+
SlugFontCache$1.parsedFontCache.set(fontFamily, font);
|
|
5315
|
+
}
|
|
5310
5316
|
static getParsed(fontFamily) {
|
|
5311
5317
|
return SlugFontCache$1.parsedFontCache.get(fontFamily) || null;
|
|
5312
5318
|
}
|
|
@@ -5693,7 +5699,7 @@ var SlugFontCache = class SlugFontCache$1 {
|
|
|
5693
5699
|
whitelist: whitelist || null
|
|
5694
5700
|
}).generate(device, font);
|
|
5695
5701
|
const generateTime = performance.now();
|
|
5696
|
-
console.log(`[SlugFontCache] Preloaded and parsed font "${fontFamily}":\n - fontkit parse: ${(parseTime - startTime).toFixed(2)}ms\n - slug generation: ${(generateTime - parseTime).toFixed(2)}ms\n - total: ${(generateTime - startTime).toFixed(2)}ms`);
|
|
5702
|
+
if (VERBOSE_FONT_LOGS) console.log(`[SlugFontCache] Preloaded and parsed font "${fontFamily}":\n - fontkit parse: ${(parseTime - startTime).toFixed(2)}ms\n - slug generation: ${(generateTime - parseTime).toFixed(2)}ms\n - total: ${(generateTime - startTime).toFixed(2)}ms`);
|
|
5697
5703
|
generated.fontFamily = fontFamily;
|
|
5698
5704
|
SlugFontCache$1.cache.set(fontFamily, generated);
|
|
5699
5705
|
SlugFontCache$1.listeners.forEach((l) => {
|
|
@@ -6622,10 +6628,11 @@ function getKernOffset(font, a, b) {
|
|
|
6622
6628
|
let v = 0;
|
|
6623
6629
|
if (src) try {
|
|
6624
6630
|
const s = String.fromCodePoint(a) + String.fromCodePoint(b);
|
|
6625
|
-
const laid = src.layout(s);
|
|
6631
|
+
const laid = src.layout?.(s);
|
|
6632
|
+
if (!laid) throw new Error("font cannot shape text");
|
|
6626
6633
|
const total = laid.positions.reduce((acc, p) => acc + p.xAdvance, 0);
|
|
6627
|
-
const advA = src.glyphForCodePoint(a)?.advanceWidth ?? 0;
|
|
6628
|
-
const advB = src.glyphForCodePoint(b)?.advanceWidth ?? 0;
|
|
6634
|
+
const advA = src.glyphForCodePoint?.(a)?.advanceWidth ?? 0;
|
|
6635
|
+
const advB = src.glyphForCodePoint?.(b)?.advanceWidth ?? 0;
|
|
6629
6636
|
v = laid.glyphs.length === 2 ? total - (advA + advB) : 0;
|
|
6630
6637
|
} catch {
|
|
6631
6638
|
v = 0;
|
|
@@ -11448,6 +11455,7 @@ const ExtendedGlyphPropertiesSchema = object({
|
|
|
11448
11455
|
rotationX: number().optional(),
|
|
11449
11456
|
rotationY: number().optional(),
|
|
11450
11457
|
rotationZ: number().optional(),
|
|
11458
|
+
formation: VolumetricFormationConfigSchema.optional(),
|
|
11451
11459
|
skew: number().optional(),
|
|
11452
11460
|
skewAxis: number().optional(),
|
|
11453
11461
|
tracking: number().optional(),
|
|
@@ -12723,7 +12731,7 @@ function drawParagraphNode(ctx, pass, props) {
|
|
|
12723
12731
|
if (slugFont && hasStroke && ctx.device) {
|
|
12724
12732
|
const alignMultiplier = props.strokeAlign === "outside" ? 2 : 1;
|
|
12725
12733
|
const strokeWidthInFontUnits = (props.strokeWidth ?? 0) * alignMultiplier * (slugFont.unitsPerEm / fontSize);
|
|
12726
|
-
strokeFont = SlugFontCache.getFont(fontFamily, props.fontWeight, ctx.device, strokeWidthInFontUnits, fontSize, props.variableAxes);
|
|
12734
|
+
strokeFont = SlugFontCache.getFont(fontFamily, props.fontWeight, ctx.device, strokeWidthInFontUnits, fontSize, props.variableAxes) ?? null;
|
|
12727
12735
|
}
|
|
12728
12736
|
if (!slugFont?.curvesTex || hasStroke && !strokeFont?.curvesTex) {
|
|
12729
12737
|
const fontUrl = GetFontAssetUrl(fontFamily);
|
|
@@ -12762,6 +12770,12 @@ function drawParagraphNode(ctx, pass, props) {
|
|
|
12762
12770
|
const alignWidth = props.isCaption ? props.dstRect.width : maxWidth;
|
|
12763
12771
|
const animApplyBy = props.animation?.applyBy ?? "word";
|
|
12764
12772
|
const layout = align === "left" && (alignWidth === void 0 || alignWidth === maxWidth) && !pathOptions && animApplyBy === "word" && Boolean(measured?.layout) && measured.layout ? measured.layout : SlugGeometry.layout(textToRender, slugFont, fontSize, letterSpacing, lineHeight, maxWidth, align, animApplyBy, alignWidth, pathOptions, props.spans);
|
|
12773
|
+
const vAlign = props.verticalAlign ?? "top";
|
|
12774
|
+
const slack = props.height != null && !pathOptions && !props.isCaption ? props.height - (measured.height + padding * 2) : 0;
|
|
12775
|
+
const textRect = {
|
|
12776
|
+
...props.dstRect,
|
|
12777
|
+
y: props.dstRect.y + (vAlign === "middle" ? slack / 2 : vAlign === "bottom" ? slack : 0)
|
|
12778
|
+
};
|
|
12765
12779
|
const anim = props.animation;
|
|
12766
12780
|
const isBold = props.fontWeight === "bold" || typeof props.fontWeight === "number" && props.fontWeight >= 600 || typeof props.fontWeight === "string" && parseInt(props.fontWeight, 10) >= 600;
|
|
12767
12781
|
const hasTrueWeight = "hasTrueWeight" in slugFont && Boolean(slugFont.hasTrueWeight);
|
|
@@ -12829,7 +12843,7 @@ function drawParagraphNode(ctx, pass, props) {
|
|
|
12829
12843
|
ctx.renderer.drawRRect(pass, {
|
|
12830
12844
|
rect: {
|
|
12831
12845
|
x: props.dstRect.x + padding + m.x,
|
|
12832
|
-
y:
|
|
12846
|
+
y: textRect.y + padding + m.y,
|
|
12833
12847
|
width: m.width,
|
|
12834
12848
|
height: m.height
|
|
12835
12849
|
},
|
|
@@ -13001,10 +13015,10 @@ function drawParagraphNode(ctx, pass, props) {
|
|
|
13001
13015
|
const rotatedR0x = r0x * cosT - r0y * sinT;
|
|
13002
13016
|
const rotatedR0y = r0x * sinT + r0y * cosT;
|
|
13003
13017
|
biasX = glyphX + rotatedR0x + props.dstRect.x + padding + offsetX + boldShift;
|
|
13004
|
-
biasY = glyph.y + rotatedR0y +
|
|
13018
|
+
biasY = glyph.y + rotatedR0y + textRect.y + padding + offsetY;
|
|
13005
13019
|
} else {
|
|
13006
13020
|
biasX = glyphX + cp.bearingX * fontScale + scaleX + props.dstRect.x + padding + offsetX + boldShift;
|
|
13007
|
-
biasY = glyph.y - cp.bearingY * fontScale + scaleY +
|
|
13021
|
+
biasY = glyph.y - cp.bearingY * fontScale + scaleY + textRect.y + padding + offsetY;
|
|
13008
13022
|
}
|
|
13009
13023
|
if (anchorConfig) {
|
|
13010
13024
|
const pivot = computeAnchorPivotOffset({
|
|
@@ -13210,7 +13224,7 @@ function drawParagraphNode(ctx, pass, props) {
|
|
|
13210
13224
|
const offsetAdjustment = (localEmojiSize - emoji$1.size) / 2;
|
|
13211
13225
|
const emojiDstRect = {
|
|
13212
13226
|
x: props.dstRect.x + emoji$1.x + padding - offsetAdjustment,
|
|
13213
|
-
y:
|
|
13227
|
+
y: textRect.y + emoji$1.y + padding - offsetAdjustment,
|
|
13214
13228
|
width: localEmojiSize,
|
|
13215
13229
|
height: localEmojiSize
|
|
13216
13230
|
};
|
|
@@ -13239,13 +13253,13 @@ function drawParagraphNode(ctx, pass, props) {
|
|
|
13239
13253
|
const cursorWidth = cursorCfg.width ?? 2.5;
|
|
13240
13254
|
const cursorSpacing = cursorCfg.spacing ?? 3;
|
|
13241
13255
|
let cursorX = props.dstRect.x + padding;
|
|
13242
|
-
let cursorY =
|
|
13256
|
+
let cursorY = textRect.y + padding;
|
|
13243
13257
|
if (layout.glyphs.length > 0) {
|
|
13244
13258
|
const lastG = layout.glyphs[layout.glyphs.length - 1];
|
|
13245
13259
|
const fontScale = fontSize / slugFont.unitsPerEm;
|
|
13246
13260
|
const adv = (lastG.cp?.advanceWidth || 0) * fontScale;
|
|
13247
13261
|
cursorX = lastG.x + props.dstRect.x + padding + adv + cursorSpacing;
|
|
13248
|
-
cursorY = lastG.y +
|
|
13262
|
+
cursorY = lastG.y + textRect.y + padding;
|
|
13249
13263
|
}
|
|
13250
13264
|
if (cursorCfg.style === "underscore") ctx.renderer.drawRect(pass, {
|
|
13251
13265
|
x: cursorX,
|
|
@@ -15339,6 +15353,15 @@ const clearVideoNodeState = (nodeId, device) => {
|
|
|
15339
15353
|
lastSourceUrl.delete(key);
|
|
15340
15354
|
}
|
|
15341
15355
|
};
|
|
15356
|
+
const clearAllVideoCache = (device) => {
|
|
15357
|
+
for (const key of lastGoodFrameKey.values()) {
|
|
15358
|
+
textureCache.evict(key, device);
|
|
15359
|
+
textureCache.activeKeys.delete(key);
|
|
15360
|
+
}
|
|
15361
|
+
lastGoodFrameKey.clear();
|
|
15362
|
+
lastSourceUrl.clear();
|
|
15363
|
+
pendingDecodes.clear();
|
|
15364
|
+
};
|
|
15342
15365
|
var BufferPool = class {
|
|
15343
15366
|
buffers = [];
|
|
15344
15367
|
index = 0;
|
|
@@ -19963,7 +19986,7 @@ var Path3D = class Path3D$1 {
|
|
|
19963
19986
|
/**
|
|
19964
19987
|
* Extracts pitch, yaw, roll Euler angles in degrees from the orthonormal frame.
|
|
19965
19988
|
*/
|
|
19966
|
-
eulerFromFrame(tangent, normal,
|
|
19989
|
+
eulerFromFrame(tangent, normal, _binormal) {
|
|
19967
19990
|
return [
|
|
19968
19991
|
Math.asin(Math.max(-1, Math.min(1, -tangent[1]))) * (180 / Math.PI),
|
|
19969
19992
|
Math.atan2(tangent[0], tangent[2]) * (180 / Math.PI),
|
|
@@ -20908,14 +20931,12 @@ var FbxLoader = class FbxLoader$1 {
|
|
|
20908
20931
|
if (offset + 25 > u8.byteLength) return null;
|
|
20909
20932
|
endOffset = Number(view.getBigUint64(offset, true));
|
|
20910
20933
|
numProperties = Number(view.getBigUint64(offset + 8, true));
|
|
20911
|
-
Number(view.getBigUint64(offset + 16, true));
|
|
20912
20934
|
nameLen = view.getUint8(offset + 24);
|
|
20913
20935
|
offset += 25;
|
|
20914
20936
|
} else {
|
|
20915
20937
|
if (offset + 13 > u8.byteLength) return null;
|
|
20916
20938
|
endOffset = view.getUint32(offset, true);
|
|
20917
20939
|
numProperties = view.getUint32(offset + 4, true);
|
|
20918
|
-
view.getUint32(offset + 8, true);
|
|
20919
20940
|
nameLen = view.getUint8(offset + 12);
|
|
20920
20941
|
offset += 13;
|
|
20921
20942
|
}
|
|
@@ -21125,7 +21146,6 @@ var FbxLoader = class FbxLoader$1 {
|
|
|
21125
21146
|
const indicesNode = geomNode.children.find((c) => c.name === "PolygonVertexIndex");
|
|
21126
21147
|
const normalLayer = geomNode.children.find((c) => c.name === "LayerElementNormal");
|
|
21127
21148
|
const uvLayer = geomNode.children.find((c) => c.name === "LayerElementUV");
|
|
21128
|
-
geomNode.children.find((c) => c.name === "LayerElementMaterial");
|
|
21129
21149
|
if (!verticesNode || !indicesNode) continue;
|
|
21130
21150
|
const rawVerts = extractArrayProp(verticesNode);
|
|
21131
21151
|
const rawPolyIndices = extractArrayProp(indicesNode);
|
|
@@ -21242,7 +21262,6 @@ var FbxLoader = class FbxLoader$1 {
|
|
|
21242
21262
|
const cIndexes = extractArrayProp(indexesNode);
|
|
21243
21263
|
const cWeights = extractArrayProp(weightsNode);
|
|
21244
21264
|
for (let k = 0; k < cIndexes.length; k++) {
|
|
21245
|
-
cIndexes[k];
|
|
21246
21265
|
const weight = cWeights[k] ?? 0;
|
|
21247
21266
|
for (let v = 0; v < numVerts; v++) for (let slot = 0; slot < 4; slot++) if (jointWeights[v * 4 + slot] === 0) {
|
|
21248
21267
|
jointIndices[v * 4 + slot] = boneIdx;
|
|
@@ -21266,7 +21285,7 @@ var FbxLoader = class FbxLoader$1 {
|
|
|
21266
21285
|
materialName: entry.name
|
|
21267
21286
|
});
|
|
21268
21287
|
}
|
|
21269
|
-
for (const [
|
|
21288
|
+
for (const [, entry] of objects) if (entry.node.name === "Material") {
|
|
21270
21289
|
const props70 = entry.node.children.find((c) => c.name === "Properties70");
|
|
21271
21290
|
let diffuseColor = [
|
|
21272
21291
|
1,
|
|
@@ -21306,37 +21325,48 @@ var FbxLoader = class FbxLoader$1 {
|
|
|
21306
21325
|
const layerConn = connections.find((c) => c.parentId === id && objects.get(c.childId)?.node.name === "AnimationLayer");
|
|
21307
21326
|
if (layerConn) {
|
|
21308
21327
|
const curveNodeConns = connections.filter((c) => c.parentId === layerConn.childId && objects.get(c.childId)?.node.name === "AnimationCurveNode");
|
|
21328
|
+
const groups = /* @__PURE__ */ new Map();
|
|
21309
21329
|
for (const cnc of curveNodeConns) {
|
|
21310
21330
|
const curveNodeObj = objects.get(cnc.childId);
|
|
21311
21331
|
if (!curveNodeObj) continue;
|
|
21312
21332
|
const modelConn = connections.find((c) => c.childId === curveNodeObj.id && objects.get(c.parentId)?.node.name === "Model");
|
|
21313
|
-
const
|
|
21314
|
-
const
|
|
21315
|
-
|
|
21316
|
-
|
|
21317
|
-
|
|
21318
|
-
|
|
21319
|
-
const
|
|
21320
|
-
|
|
21321
|
-
|
|
21322
|
-
|
|
21323
|
-
|
|
21324
|
-
|
|
21325
|
-
|
|
21326
|
-
|
|
21327
|
-
|
|
21328
|
-
|
|
21329
|
-
|
|
21330
|
-
|
|
21331
|
-
|
|
21332
|
-
nodeName,
|
|
21333
|
-
times,
|
|
21334
|
-
translations: !isRotation && !isScaling ? values : void 0,
|
|
21335
|
-
rotations: isRotation ? values : void 0,
|
|
21336
|
-
scalings: isScaling ? values : void 0
|
|
21337
|
-
});
|
|
21338
|
-
}
|
|
21333
|
+
const targetModel = modelConn ? objects.get(modelConn.parentId) : void 0;
|
|
21334
|
+
const kind = transformKindFromProperty(modelConn?.propName) ?? transformKindFromProperty(curveNodeObj.name);
|
|
21335
|
+
if (!kind) continue;
|
|
21336
|
+
const key = `${targetModel?.id ?? curveNodeObj.id}|${kind}`;
|
|
21337
|
+
let group = groups.get(key);
|
|
21338
|
+
if (!group) {
|
|
21339
|
+
const model = targetModel?.node;
|
|
21340
|
+
group = {
|
|
21341
|
+
nodeName: targetModel?.name ?? curveNodeObj.name,
|
|
21342
|
+
model,
|
|
21343
|
+
kind,
|
|
21344
|
+
defaults: staticTransform(model, curveNodeObj.node, kind),
|
|
21345
|
+
channels: [
|
|
21346
|
+
void 0,
|
|
21347
|
+
void 0,
|
|
21348
|
+
void 0
|
|
21349
|
+
]
|
|
21350
|
+
};
|
|
21351
|
+
groups.set(key, group);
|
|
21339
21352
|
}
|
|
21353
|
+
connections.filter((c) => c.parentId === curveNodeObj.id && objects.get(c.childId)?.node.name === "AnimationCurve").forEach((cc, order) => {
|
|
21354
|
+
const axis = axisFromProperty(cc.propName) ?? order;
|
|
21355
|
+
if (axis > 2) return;
|
|
21356
|
+
const curveObj = objects.get(cc.childId)?.node;
|
|
21357
|
+
const times = extractArrayProp(curveObj?.children.find((c) => c.name === "KeyTime"));
|
|
21358
|
+
const values = extractArrayProp(curveObj?.children.find((c) => c.name === "KeyValueFloat"));
|
|
21359
|
+
const n = Math.min(times.length, values.length);
|
|
21360
|
+
if (n === 0) return;
|
|
21361
|
+
group.channels[axis] = {
|
|
21362
|
+
times: Array.from(times.slice(0, n), (t) => Number(t)),
|
|
21363
|
+
values: Array.from(values.slice(0, n), (v) => Number(v))
|
|
21364
|
+
};
|
|
21365
|
+
});
|
|
21366
|
+
}
|
|
21367
|
+
for (const group of groups.values()) {
|
|
21368
|
+
const track = buildTransformTrack(group);
|
|
21369
|
+
if (track) tracks.push(track);
|
|
21340
21370
|
}
|
|
21341
21371
|
}
|
|
21342
21372
|
let maxDuration = 1;
|
|
@@ -21413,6 +21443,151 @@ var FbxLoader = class FbxLoader$1 {
|
|
|
21413
21443
|
};
|
|
21414
21444
|
}
|
|
21415
21445
|
};
|
|
21446
|
+
/**
|
|
21447
|
+
* Classifies a curve node from its OP connection property ("Lcl Translation",
|
|
21448
|
+
* "Lcl Rotation", "Lcl Scaling") or, failing that, its short name ("T", "R", "S").
|
|
21449
|
+
*/
|
|
21450
|
+
function transformKindFromProperty(name) {
|
|
21451
|
+
switch (name) {
|
|
21452
|
+
case "Lcl Translation":
|
|
21453
|
+
case "T": return "T";
|
|
21454
|
+
case "Lcl Rotation":
|
|
21455
|
+
case "R": return "R";
|
|
21456
|
+
case "Lcl Scaling":
|
|
21457
|
+
case "S": return "S";
|
|
21458
|
+
default: return;
|
|
21459
|
+
}
|
|
21460
|
+
}
|
|
21461
|
+
/** Channel index of a curve from its curve-node connection property ("d|X" → 0). */
|
|
21462
|
+
function axisFromProperty(name) {
|
|
21463
|
+
switch (name) {
|
|
21464
|
+
case "d|X": return 0;
|
|
21465
|
+
case "d|Y": return 1;
|
|
21466
|
+
case "d|Z": return 2;
|
|
21467
|
+
default: return;
|
|
21468
|
+
}
|
|
21469
|
+
}
|
|
21470
|
+
/** Numeric values of a Properties70 `P` entry (they start at props[4]). */
|
|
21471
|
+
function readProperty70(node, name) {
|
|
21472
|
+
const p = (node?.children.find((c) => c.name === "Properties70"))?.children.find((c) => c.name === "P" && c.props[0] === name);
|
|
21473
|
+
if (!p) return void 0;
|
|
21474
|
+
return p.props.slice(4).map((v) => Number(v));
|
|
21475
|
+
}
|
|
21476
|
+
/** A model's rest value for one transform, used where a channel has no curve. */
|
|
21477
|
+
function staticTransform(model, curveNode, kind) {
|
|
21478
|
+
const fallback = kind === "S" ? 1 : 0;
|
|
21479
|
+
const modelProp = readProperty70(model, kind === "T" ? "Lcl Translation" : kind === "R" ? "Lcl Rotation" : "Lcl Scaling");
|
|
21480
|
+
const out = [
|
|
21481
|
+
fallback,
|
|
21482
|
+
fallback,
|
|
21483
|
+
fallback
|
|
21484
|
+
];
|
|
21485
|
+
for (let axis = 0; axis < 3; axis++) {
|
|
21486
|
+
const fromModel = modelProp?.[axis];
|
|
21487
|
+
const fromCurveNode = readProperty70(curveNode, `d|${"XYZ"[axis]}`)?.[0];
|
|
21488
|
+
const value = fromModel ?? fromCurveNode;
|
|
21489
|
+
if (value !== void 0 && Number.isFinite(value)) out[axis] = value;
|
|
21490
|
+
}
|
|
21491
|
+
return out;
|
|
21492
|
+
}
|
|
21493
|
+
/** FBX EOrder enum (Model "RotationOrder"): axes in the order they are applied. */
|
|
21494
|
+
const FBX_ROTATION_ORDERS = [
|
|
21495
|
+
"XYZ",
|
|
21496
|
+
"XZY",
|
|
21497
|
+
"YZX",
|
|
21498
|
+
"YXZ",
|
|
21499
|
+
"ZXY",
|
|
21500
|
+
"ZYX"
|
|
21501
|
+
];
|
|
21502
|
+
function rotationOrder(model) {
|
|
21503
|
+
return FBX_ROTATION_ORDERS[readProperty70(model, "RotationOrder")?.[0] ?? 0] ?? "XYZ";
|
|
21504
|
+
}
|
|
21505
|
+
/**
|
|
21506
|
+
* Euler degrees → [x, y, z, w] quaternion. FBX applies the axes in `order`
|
|
21507
|
+
* (XYZ: X first, so R = Rz·Ry·Rx).
|
|
21508
|
+
*/
|
|
21509
|
+
function fbxEulerToQuat(degrees, order = "XYZ") {
|
|
21510
|
+
let q = [
|
|
21511
|
+
0,
|
|
21512
|
+
0,
|
|
21513
|
+
0,
|
|
21514
|
+
1
|
|
21515
|
+
];
|
|
21516
|
+
for (const axisName of order) {
|
|
21517
|
+
const axis = "XYZ".indexOf(axisName);
|
|
21518
|
+
const half = (degrees[axis] ?? 0) * Math.PI / 360;
|
|
21519
|
+
const s = Math.sin(half);
|
|
21520
|
+
const a = [
|
|
21521
|
+
0,
|
|
21522
|
+
0,
|
|
21523
|
+
0,
|
|
21524
|
+
Math.cos(half)
|
|
21525
|
+
];
|
|
21526
|
+
a[axis] = s;
|
|
21527
|
+
q = [
|
|
21528
|
+
a[3] * q[0] + a[0] * q[3] + a[1] * q[2] - a[2] * q[1],
|
|
21529
|
+
a[3] * q[1] - a[0] * q[2] + a[1] * q[3] + a[2] * q[0],
|
|
21530
|
+
a[3] * q[2] + a[0] * q[1] - a[1] * q[0] + a[2] * q[3],
|
|
21531
|
+
a[3] * q[3] - a[0] * q[0] - a[1] * q[1] - a[2] * q[2]
|
|
21532
|
+
];
|
|
21533
|
+
}
|
|
21534
|
+
return q;
|
|
21535
|
+
}
|
|
21536
|
+
/** Linear sample of a curve at `t` (KTime ticks), clamped to its ends. */
|
|
21537
|
+
function sampleCurve(curve, t) {
|
|
21538
|
+
const { times, values } = curve;
|
|
21539
|
+
const last = times.length - 1;
|
|
21540
|
+
if (t <= times[0]) return values[0];
|
|
21541
|
+
if (t >= times[last]) return values[last];
|
|
21542
|
+
let k = 0;
|
|
21543
|
+
while (k < last - 1 && times[k + 1] <= t) k++;
|
|
21544
|
+
const t0 = times[k];
|
|
21545
|
+
const t1 = times[k + 1];
|
|
21546
|
+
const u = t1 > t0 ? (t - t0) / (t1 - t0) : 0;
|
|
21547
|
+
return values[k] + (values[k + 1] - values[k]) * u;
|
|
21548
|
+
}
|
|
21549
|
+
/**
|
|
21550
|
+
* Merges a transform's X/Y/Z curves onto one sorted key set: channels without
|
|
21551
|
+
* a key at some time are interpolated, channels without a curve keep the
|
|
21552
|
+
* static value. Rotations become quaternions in the model's RotationOrder.
|
|
21553
|
+
*/
|
|
21554
|
+
function buildTransformTrack(group) {
|
|
21555
|
+
const keySet = /* @__PURE__ */ new Set();
|
|
21556
|
+
for (const channel of group.channels) for (const t of channel?.times ?? []) keySet.add(t);
|
|
21557
|
+
if (keySet.size === 0) return void 0;
|
|
21558
|
+
const keys = [...keySet].sort((a, b) => a - b);
|
|
21559
|
+
const times = new Float32Array(keys.length);
|
|
21560
|
+
const isRotation = group.kind === "R";
|
|
21561
|
+
const values = new Float32Array(keys.length * (isRotation ? 4 : 3));
|
|
21562
|
+
const order = isRotation ? rotationOrder(group.model) : "XYZ";
|
|
21563
|
+
let prev;
|
|
21564
|
+
keys.forEach((key, k) => {
|
|
21565
|
+
times[k] = key / FbxLoader.FBX_KTIME;
|
|
21566
|
+
const v = [
|
|
21567
|
+
0,
|
|
21568
|
+
1,
|
|
21569
|
+
2
|
|
21570
|
+
].map((axis) => {
|
|
21571
|
+
const channel = group.channels[axis];
|
|
21572
|
+
return channel ? sampleCurve(channel, key) : group.defaults[axis];
|
|
21573
|
+
});
|
|
21574
|
+
if (!isRotation) {
|
|
21575
|
+
values.set(v, k * 3);
|
|
21576
|
+
return;
|
|
21577
|
+
}
|
|
21578
|
+
const q = fbxEulerToQuat(v, order);
|
|
21579
|
+
if (prev && prev[0] * q[0] + prev[1] * q[1] + prev[2] * q[2] + prev[3] * q[3] < 0) for (let i = 0; i < 4; i++) q[i] = -q[i];
|
|
21580
|
+
prev = q;
|
|
21581
|
+
values.set(q, k * 4);
|
|
21582
|
+
});
|
|
21583
|
+
return {
|
|
21584
|
+
nodeName: group.nodeName,
|
|
21585
|
+
times,
|
|
21586
|
+
translations: group.kind === "T" ? values : void 0,
|
|
21587
|
+
rotations: isRotation ? values : void 0,
|
|
21588
|
+
scales: group.kind === "S" ? values : void 0
|
|
21589
|
+
};
|
|
21590
|
+
}
|
|
21416
21591
|
function parseFBX(bufferOrText, options = {}) {
|
|
21417
21592
|
return FbxLoader.parse(bufferOrText, options);
|
|
21418
21593
|
}
|
|
@@ -22365,7 +22540,6 @@ var GltfLoader = class GltfLoader$1 {
|
|
|
22365
22540
|
static unpackGlb(bytes) {
|
|
22366
22541
|
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
22367
22542
|
const magic = view.getUint32(0, true);
|
|
22368
|
-
view.getUint32(4, true);
|
|
22369
22543
|
const totalLength = view.getUint32(8, true);
|
|
22370
22544
|
if (magic !== GLB_MAGIC) throw new Error("Invalid GLB header: magic mismatch");
|
|
22371
22545
|
let offset = 12;
|
|
@@ -22747,6 +22921,9 @@ var GltfLoader = class GltfLoader$1 {
|
|
|
22747
22921
|
function loadGLTF(srcOrData, options = {}) {
|
|
22748
22922
|
return GltfLoader.load(srcOrData, options);
|
|
22749
22923
|
}
|
|
22924
|
+
function loadGLB(srcOrData, options = {}) {
|
|
22925
|
+
return GltfLoader.load(srcOrData, options);
|
|
22926
|
+
}
|
|
22750
22927
|
const DEFAULT_PALETTE = [[
|
|
22751
22928
|
0,
|
|
22752
22929
|
0,
|
|
@@ -22784,7 +22961,6 @@ var VoxLoader = class VoxLoader$1 {
|
|
|
22784
22961
|
while (offset + 12 <= bytes.byteLength) {
|
|
22785
22962
|
const chunkId = new TextDecoder("ascii").decode(bytes.subarray(offset, offset + 4));
|
|
22786
22963
|
const contentSize = view.getUint32(offset + 4, true);
|
|
22787
|
-
view.getUint32(offset + 8, true);
|
|
22788
22964
|
offset += 12;
|
|
22789
22965
|
const chunkDataOffset = offset;
|
|
22790
22966
|
if (chunkId === "SIZE") {
|
|
@@ -22827,7 +23003,7 @@ var VoxLoader = class VoxLoader$1 {
|
|
|
22827
23003
|
}
|
|
22828
23004
|
return VoxLoader$1.buildModel(voxels, palette, sizeX, sizeY, sizeZ, options);
|
|
22829
23005
|
}
|
|
22830
|
-
static buildModel(voxels, palette,
|
|
23006
|
+
static buildModel(voxels, palette, _sizeX, _sizeY, _sizeZ, options) {
|
|
22831
23007
|
const voxelSet = /* @__PURE__ */ new Set();
|
|
22832
23008
|
voxels.forEach((v) => voxelSet.add(`${v.x},${v.y},${v.z}`));
|
|
22833
23009
|
const rawPositions = [];
|
|
@@ -23177,7 +23353,7 @@ var ThreeDSLoader = class ThreeDSLoader$1 {
|
|
|
23177
23353
|
offset = nextChunkOffset;
|
|
23178
23354
|
}
|
|
23179
23355
|
}
|
|
23180
|
-
static readTriMesh(view, startOffset, endOffset, mesh,
|
|
23356
|
+
static readTriMesh(view, startOffset, endOffset, mesh, _materials) {
|
|
23181
23357
|
let offset = startOffset;
|
|
23182
23358
|
while (offset + 6 <= endOffset) {
|
|
23183
23359
|
const chunkId = view.getUint16(offset, true);
|
|
@@ -24359,7 +24535,7 @@ var Mesh3DPipeline = class {
|
|
|
24359
24535
|
defaultWhiteTexture;
|
|
24360
24536
|
defaultSkinningBuffer;
|
|
24361
24537
|
modelData = new Float32Array(48);
|
|
24362
|
-
constructor(device, format, depthFormat = "depth24plus", cameraLayout, lightsLayout) {
|
|
24538
|
+
constructor(device, format, depthFormat = "depth24plus", cameraLayout, lightsLayout, sampleCount = 1) {
|
|
24363
24539
|
this.device = device;
|
|
24364
24540
|
this.modelPool = new BufferPool(192, GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST);
|
|
24365
24541
|
this.skinningPool = new BufferPool(8192, GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST);
|
|
@@ -24478,7 +24654,8 @@ var Mesh3DPipeline = class {
|
|
|
24478
24654
|
primitive: {
|
|
24479
24655
|
topology: "triangle-list",
|
|
24480
24656
|
cullMode: "none"
|
|
24481
|
-
}
|
|
24657
|
+
},
|
|
24658
|
+
multisample: { count: sampleCount }
|
|
24482
24659
|
});
|
|
24483
24660
|
this.pipelineMrt = device.createRenderPipeline({
|
|
24484
24661
|
label: "Mesh3DPipelineMrt",
|
|
@@ -24511,7 +24688,8 @@ var Mesh3DPipeline = class {
|
|
|
24511
24688
|
primitive: {
|
|
24512
24689
|
topology: "triangle-list",
|
|
24513
24690
|
cullMode: "none"
|
|
24514
|
-
}
|
|
24691
|
+
},
|
|
24692
|
+
multisample: { count: sampleCount }
|
|
24515
24693
|
});
|
|
24516
24694
|
this.defaultWhiteTexture = device.createTexture({
|
|
24517
24695
|
label: "Mesh3DDefaultWhiteTexture",
|
|
@@ -25146,7 +25324,7 @@ var Quad3DPipeline = class {
|
|
|
25146
25324
|
vertexBuffer;
|
|
25147
25325
|
indexBuffer;
|
|
25148
25326
|
modelData = new Float32Array(52);
|
|
25149
|
-
constructor(device, format, depthFormat = "depth24plus") {
|
|
25327
|
+
constructor(device, format, depthFormat = "depth24plus", sampleCount = 1) {
|
|
25150
25328
|
this.device = device;
|
|
25151
25329
|
this.modelPool = new BufferPool(208, GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST);
|
|
25152
25330
|
const module = device.createShaderModule({
|
|
@@ -25250,7 +25428,8 @@ var Quad3DPipeline = class {
|
|
|
25250
25428
|
primitive: {
|
|
25251
25429
|
topology: "triangle-list",
|
|
25252
25430
|
cullMode: "none"
|
|
25253
|
-
}
|
|
25431
|
+
},
|
|
25432
|
+
multisample: { count: sampleCount }
|
|
25254
25433
|
});
|
|
25255
25434
|
this.pipelineMrt = device.createRenderPipeline({
|
|
25256
25435
|
label: "Quad3DPipelineMrt",
|
|
@@ -25283,7 +25462,8 @@ var Quad3DPipeline = class {
|
|
|
25283
25462
|
primitive: {
|
|
25284
25463
|
topology: "triangle-list",
|
|
25285
25464
|
cullMode: "none"
|
|
25286
|
-
}
|
|
25465
|
+
},
|
|
25466
|
+
multisample: { count: sampleCount }
|
|
25287
25467
|
});
|
|
25288
25468
|
const vertices = new Float32Array([
|
|
25289
25469
|
-.5,
|
|
@@ -25688,7 +25868,7 @@ var Slug3DPipeline = class {
|
|
|
25688
25868
|
instancePool;
|
|
25689
25869
|
fontBindGroups = /* @__PURE__ */ new WeakMap();
|
|
25690
25870
|
modelData = new Float32Array(40);
|
|
25691
|
-
constructor(device, format, depthFormat, cameraLayout, lightsLayout) {
|
|
25871
|
+
constructor(device, format, depthFormat, cameraLayout, lightsLayout, sampleCount = 1) {
|
|
25692
25872
|
this.device = device;
|
|
25693
25873
|
this.modelPool = new BufferPool(160, GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST);
|
|
25694
25874
|
this.instancePool = new BufferPool(65536, GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST);
|
|
@@ -25783,6 +25963,7 @@ var Slug3DPipeline = class {
|
|
|
25783
25963
|
topology: "triangle-list",
|
|
25784
25964
|
cullMode: "none"
|
|
25785
25965
|
};
|
|
25966
|
+
const multisample = { count: sampleCount };
|
|
25786
25967
|
this.pipelineSingle = device.createRenderPipeline({
|
|
25787
25968
|
label: "Slug3DPipelineSingle",
|
|
25788
25969
|
layout,
|
|
@@ -25796,7 +25977,8 @@ var Slug3DPipeline = class {
|
|
|
25796
25977
|
}]
|
|
25797
25978
|
},
|
|
25798
25979
|
depthStencil,
|
|
25799
|
-
primitive
|
|
25980
|
+
primitive,
|
|
25981
|
+
multisample
|
|
25800
25982
|
});
|
|
25801
25983
|
this.pipelineMrt = device.createRenderPipeline({
|
|
25802
25984
|
label: "Slug3DPipelineMrt",
|
|
@@ -25811,7 +25993,8 @@ var Slug3DPipeline = class {
|
|
|
25811
25993
|
}, { format: "rgba16float" }]
|
|
25812
25994
|
},
|
|
25813
25995
|
depthStencil,
|
|
25814
|
-
primitive
|
|
25996
|
+
primitive,
|
|
25997
|
+
multisample
|
|
25815
25998
|
});
|
|
25816
25999
|
}
|
|
25817
26000
|
resetPools() {
|
|
@@ -25894,6 +26077,8 @@ var Renderer3D = class {
|
|
|
25894
26077
|
samplerCache = new SamplerCache();
|
|
25895
26078
|
depthTexture = null;
|
|
25896
26079
|
linearDepthTexture = null;
|
|
26080
|
+
msaaColorTexture = null;
|
|
26081
|
+
msaaLinearDepthTexture = null;
|
|
25897
26082
|
cameraUniformData = new Float32Array(80);
|
|
25898
26083
|
meshBuffersCache = /* @__PURE__ */ new WeakMap();
|
|
25899
26084
|
materialTextures = /* @__PURE__ */ new WeakMap();
|
|
@@ -25901,12 +26086,19 @@ var Renderer3D = class {
|
|
|
25901
26086
|
modelCache = /* @__PURE__ */ new Map();
|
|
25902
26087
|
lastCameraPose = null;
|
|
25903
26088
|
lastCameraBuffer = null;
|
|
25904
|
-
|
|
26089
|
+
/**
|
|
26090
|
+
* Samples per pixel in the 3D pass. Mesh silhouettes (extruded text,
|
|
26091
|
+
* models) are rasterized triangles: without MSAA every edge is a hard
|
|
26092
|
+
* stair-step. 4 is the count every WebGPU device supports; 1 turns it off.
|
|
26093
|
+
*/
|
|
26094
|
+
sampleCount;
|
|
26095
|
+
constructor(device, format, sampleCount = 4) {
|
|
25905
26096
|
this.device = device;
|
|
25906
26097
|
this.format = format;
|
|
25907
|
-
this.
|
|
25908
|
-
this.
|
|
25909
|
-
this.
|
|
26098
|
+
this.sampleCount = sampleCount;
|
|
26099
|
+
this.quad3dPipeline = new Quad3DPipeline(device, format, "depth24plus", sampleCount);
|
|
26100
|
+
this.slug3dPipeline = new Slug3DPipeline(device, format, "depth24plus", this.quad3dPipeline.cameraLayout, this.quad3dPipeline.lightsLayout, sampleCount);
|
|
26101
|
+
this.mesh3dPipeline = new Mesh3DPipeline(device, format, "depth24plus", this.quad3dPipeline.cameraLayout, this.quad3dPipeline.lightsLayout, sampleCount);
|
|
25910
26102
|
this.audioMeshDeformPipeline = new AudioMeshDeformPipeline(device);
|
|
25911
26103
|
this.cameraPool = new BufferPool(320, GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST);
|
|
25912
26104
|
this.lightsPool = new BufferPool(LIGHT_UNIFORM_SIZE_BYTES, GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST);
|
|
@@ -25972,11 +26164,26 @@ var Renderer3D = class {
|
|
|
25972
26164
|
height
|
|
25973
26165
|
},
|
|
25974
26166
|
format: "depth24plus",
|
|
26167
|
+
sampleCount: this.sampleCount,
|
|
25975
26168
|
usage: GPUTextureUsage.RENDER_ATTACHMENT
|
|
25976
26169
|
});
|
|
25977
26170
|
}
|
|
25978
26171
|
return this.depthTexture;
|
|
25979
26172
|
}
|
|
26173
|
+
getOrCreateMsaaTexture(current, label, format, width, height) {
|
|
26174
|
+
if (current && current.width === width && current.height === height) return current;
|
|
26175
|
+
current?.destroy();
|
|
26176
|
+
return this.device.createTexture({
|
|
26177
|
+
label,
|
|
26178
|
+
size: {
|
|
26179
|
+
width,
|
|
26180
|
+
height
|
|
26181
|
+
},
|
|
26182
|
+
format,
|
|
26183
|
+
sampleCount: this.sampleCount,
|
|
26184
|
+
usage: GPUTextureUsage.RENDER_ATTACHMENT
|
|
26185
|
+
});
|
|
26186
|
+
}
|
|
25980
26187
|
getOrCreateLinearDepthTexture(width, height) {
|
|
25981
26188
|
if (!this.linearDepthTexture || this.linearDepthTexture.width !== width || this.linearDepthTexture.height !== height) {
|
|
25982
26189
|
this.linearDepthTexture?.destroy();
|
|
@@ -26042,23 +26249,31 @@ var Renderer3D = class {
|
|
|
26042
26249
|
const cameraBindGroup = this.createCameraBindGroup(cameraBuffer);
|
|
26043
26250
|
const lightsBuffer = this.getOrCreateLightsBuffer(lights);
|
|
26044
26251
|
const lightsBindGroup = this.lightsUniformBindGroupCache.getBindGroup(this.device, this.quad3dPipeline.lightsLayout, lightsBuffer);
|
|
26045
|
-
const
|
|
26046
|
-
|
|
26047
|
-
|
|
26048
|
-
|
|
26049
|
-
|
|
26050
|
-
}];
|
|
26051
|
-
if (linearDepthTargetView) colorAttachments.push({
|
|
26052
|
-
view: linearDepthTargetView,
|
|
26252
|
+
const msaa = this.sampleCount > 1;
|
|
26253
|
+
if (msaa && loadOp === "load") throw new Error("Renderer3D.beginPass: loadOp 'load' needs a Renderer3D built with sampleCount 1");
|
|
26254
|
+
const attach = (view, msaaTex, clearValue, attachmentLoadOp) => msaaTex ? {
|
|
26255
|
+
view: msaaTex.createView(),
|
|
26256
|
+
resolveTarget: view,
|
|
26053
26257
|
loadOp: "clear",
|
|
26258
|
+
storeOp: "discard",
|
|
26259
|
+
clearValue
|
|
26260
|
+
} : {
|
|
26261
|
+
view,
|
|
26262
|
+
loadOp: attachmentLoadOp,
|
|
26054
26263
|
storeOp: "store",
|
|
26055
|
-
clearValue
|
|
26264
|
+
clearValue
|
|
26265
|
+
};
|
|
26266
|
+
if (msaa) this.msaaColorTexture = this.getOrCreateMsaaTexture(this.msaaColorTexture, "Renderer3DMsaaColor", this.format, surfaceWidth, surfaceHeight);
|
|
26267
|
+
const colorAttachments = [attach(colorTargetView, msaa ? this.msaaColorTexture : null, clearColor, loadOp)];
|
|
26268
|
+
if (linearDepthTargetView) {
|
|
26269
|
+
if (msaa) this.msaaLinearDepthTexture = this.getOrCreateMsaaTexture(this.msaaLinearDepthTexture, "Renderer3DMsaaLinearDepth", "rgba16float", surfaceWidth, surfaceHeight);
|
|
26270
|
+
colorAttachments.push(attach(linearDepthTargetView, msaa ? this.msaaLinearDepthTexture : null, {
|
|
26056
26271
|
r: camera.far,
|
|
26057
26272
|
g: 0,
|
|
26058
26273
|
b: 0,
|
|
26059
26274
|
a: 1
|
|
26060
|
-
}
|
|
26061
|
-
}
|
|
26275
|
+
}, "clear"));
|
|
26276
|
+
}
|
|
26062
26277
|
return {
|
|
26063
26278
|
pass: encoder.beginRenderPass({
|
|
26064
26279
|
colorAttachments,
|
|
@@ -26066,7 +26281,7 @@ var Renderer3D = class {
|
|
|
26066
26281
|
view: depthTex.createView(),
|
|
26067
26282
|
depthClearValue: 1,
|
|
26068
26283
|
depthLoadOp: "clear",
|
|
26069
|
-
depthStoreOp: "store"
|
|
26284
|
+
depthStoreOp: msaa ? "discard" : "store"
|
|
26070
26285
|
}
|
|
26071
26286
|
}),
|
|
26072
26287
|
cameraBindGroup,
|
|
@@ -26438,6 +26653,8 @@ var Renderer3D = class {
|
|
|
26438
26653
|
destroy() {
|
|
26439
26654
|
this.depthTexture?.destroy();
|
|
26440
26655
|
this.linearDepthTexture?.destroy();
|
|
26656
|
+
this.msaaColorTexture?.destroy();
|
|
26657
|
+
this.msaaLinearDepthTexture?.destroy();
|
|
26441
26658
|
this.quad3dPipeline.destroy();
|
|
26442
26659
|
this.slug3dPipeline.destroy();
|
|
26443
26660
|
this.mesh3dPipeline.destroy();
|
|
@@ -26489,13 +26706,11 @@ function loadModel3D(srcOrData, format = "auto", options = {}) {
|
|
|
26489
26706
|
* Directional and Point Light Shadow Map Generator with Percentage Closer Filtering (PCF).
|
|
26490
26707
|
*/
|
|
26491
26708
|
var ShadowPipeline = class {
|
|
26492
|
-
device;
|
|
26493
26709
|
shadowDepthTexture;
|
|
26494
26710
|
shadowDepthView;
|
|
26495
26711
|
shadowComparisonSampler;
|
|
26496
26712
|
lightViewProjMatrix;
|
|
26497
26713
|
constructor(device, resolution = 2048) {
|
|
26498
|
-
this.device = device;
|
|
26499
26714
|
this.lightViewProjMatrix = Matrix4Math.identity();
|
|
26500
26715
|
this.shadowDepthTexture = device.createTexture({
|
|
26501
26716
|
label: "shadow-depth-map",
|
|
@@ -26522,7 +26737,7 @@ var ShadowPipeline = class {
|
|
|
26522
26737
|
0
|
|
26523
26738
|
]);
|
|
26524
26739
|
const half = orthoSize * .5;
|
|
26525
|
-
const projMatrix = Matrix4Math.
|
|
26740
|
+
const projMatrix = Matrix4Math.orthographic(-half, half, -half, half, near, far);
|
|
26526
26741
|
this.lightViewProjMatrix = Matrix4Math.multiply(projMatrix, viewMatrix);
|
|
26527
26742
|
return this.lightViewProjMatrix;
|
|
26528
26743
|
}
|
|
@@ -26703,7 +26918,7 @@ var SSAOPipeline = class {
|
|
|
26703
26918
|
});
|
|
26704
26919
|
}
|
|
26705
26920
|
render(commandEncoder, depthView, normalView, rawAOView, finalAOView, options) {
|
|
26706
|
-
const invProj = options.invProjMatrix ?? Matrix4Math.invert(options.projMatrix);
|
|
26921
|
+
const invProj = options.invProjMatrix ?? Matrix4Math.invert(options.projMatrix) ?? Matrix4Math.identity();
|
|
26707
26922
|
const uBuf = new Float32Array(64);
|
|
26708
26923
|
uBuf.set(options.projMatrix, 0);
|
|
26709
26924
|
uBuf.set(invProj, 16);
|
|
@@ -26878,7 +27093,19 @@ function isPointInsidePolygon(p, poly) {
|
|
|
26878
27093
|
}
|
|
26879
27094
|
return inside;
|
|
26880
27095
|
}
|
|
26881
|
-
|
|
27096
|
+
const DEFAULT_CURVE_TOLERANCE = .1;
|
|
27097
|
+
const MAX_CURVE_SEGMENTS = 64;
|
|
27098
|
+
/**
|
|
27099
|
+
* Segments needed for a polyline through n uniform steps of a curve to stay
|
|
27100
|
+
* within `tolerance`: the chord error is at most max|B''| / (8 n^2).
|
|
27101
|
+
*/
|
|
27102
|
+
function curveSegmentCount(maxSecondDerivative, flattening) {
|
|
27103
|
+
if (flattening.segments !== void 0) return flattening.segments;
|
|
27104
|
+
const n = Math.ceil(Math.sqrt(maxSecondDerivative / (8 * flattening.tolerance)));
|
|
27105
|
+
return Math.min(MAX_CURVE_SEGMENTS, Math.max(1, n));
|
|
27106
|
+
}
|
|
27107
|
+
function processCurveQuadratic(p0, cp, end, flattening, out) {
|
|
27108
|
+
const segments = curveSegmentCount(2 * Math.hypot(p0.x - 2 * cp.x + end.x, p0.y - 2 * cp.y + end.y), flattening);
|
|
26882
27109
|
for (let s = 1; s <= segments; s++) {
|
|
26883
27110
|
const t = s / segments;
|
|
26884
27111
|
const mt = 1 - t;
|
|
@@ -26888,7 +27115,8 @@ function processCurveQuadratic(p0, cp, end, segments, out) {
|
|
|
26888
27115
|
});
|
|
26889
27116
|
}
|
|
26890
27117
|
}
|
|
26891
|
-
function processCurveCubic(p0, cp1, cp2, end,
|
|
27118
|
+
function processCurveCubic(p0, cp1, cp2, end, flattening, out) {
|
|
27119
|
+
const segments = curveSegmentCount(6 * Math.max(Math.hypot(p0.x - 2 * cp1.x + cp2.x, p0.y - 2 * cp1.y + cp2.y), Math.hypot(cp1.x - 2 * cp2.x + end.x, cp1.y - 2 * cp2.y + end.y)), flattening);
|
|
26892
27120
|
for (let s = 1; s <= segments; s++) {
|
|
26893
27121
|
const t = s / segments;
|
|
26894
27122
|
const mt = 1 - t;
|
|
@@ -26898,7 +27126,7 @@ function processCurveCubic(p0, cp1, cp2, end, segments, out) {
|
|
|
26898
27126
|
});
|
|
26899
27127
|
}
|
|
26900
27128
|
}
|
|
26901
|
-
function extractGlyphContours(glyph, glyphX, glyphY, scale,
|
|
27129
|
+
function extractGlyphContours(glyph, glyphX, glyphY, scale, flattening) {
|
|
26902
27130
|
const svg = glyph.path?.toSVG();
|
|
26903
27131
|
if (!svg) return [];
|
|
26904
27132
|
let edges;
|
|
@@ -26947,7 +27175,7 @@ function extractGlyphContours(glyph, glyphX, glyphY, scale, curveSegments) {
|
|
|
26947
27175
|
x: (glyphX + args[2]) * scale,
|
|
26948
27176
|
y: -(glyphY + args[3]) * scale
|
|
26949
27177
|
};
|
|
26950
|
-
processCurveQuadratic(curr, cp, end,
|
|
27178
|
+
processCurveQuadratic(curr, cp, end, flattening, current);
|
|
26951
27179
|
curr = end;
|
|
26952
27180
|
} else if (name === "bezierCurveTo") {
|
|
26953
27181
|
const cp1 = {
|
|
@@ -26962,45 +27190,90 @@ function extractGlyphContours(glyph, glyphX, glyphY, scale, curveSegments) {
|
|
|
26962
27190
|
x: (glyphX + args[4]) * scale,
|
|
26963
27191
|
y: -(glyphY + args[5]) * scale
|
|
26964
27192
|
};
|
|
26965
|
-
processCurveCubic(curr, cp1, cp2, end,
|
|
27193
|
+
processCurveCubic(curr, cp1, cp2, end, flattening, current);
|
|
26966
27194
|
curr = end;
|
|
26967
27195
|
} else if (name === "closePath") finishCurrent();
|
|
26968
27196
|
}
|
|
26969
27197
|
finishCurrent();
|
|
26970
27198
|
return contours;
|
|
26971
27199
|
}
|
|
27200
|
+
/** Side-wall segments meeting at more than this angle (30°) keep a hard edge. */
|
|
27201
|
+
const SIDE_CREASE_COS = Math.cos(30 * Math.PI / 180);
|
|
27202
|
+
/**
|
|
27203
|
+
* Group a glyph's contours into filled outlines and their holes by nesting
|
|
27204
|
+
* depth: a contour inside an even number of others is an outline (the ring
|
|
27205
|
+
* of "O", or the "R" sitting in the counter of "®"), one inside an odd number
|
|
27206
|
+
* is a hole of the smallest outline around it.
|
|
27207
|
+
*/
|
|
26972
27208
|
function organizeGlyphPolygons(glyphContours) {
|
|
26973
|
-
|
|
26974
|
-
|
|
26975
|
-
|
|
26976
|
-
|
|
26977
|
-
|
|
26978
|
-
|
|
26979
|
-
|
|
26980
|
-
|
|
26981
|
-
|
|
26982
|
-
|
|
26983
|
-
|
|
26984
|
-
|
|
26985
|
-
if (isPointInsidePolygon(
|
|
26986
|
-
parent = out;
|
|
26987
|
-
break;
|
|
26988
|
-
}
|
|
27209
|
+
const contours = glyphContours.map((contour) => ({
|
|
27210
|
+
contour,
|
|
27211
|
+
area: Math.abs(computeContourSignedArea(contour))
|
|
27212
|
+
}));
|
|
27213
|
+
contours.sort((a, b) => b.area - a.area);
|
|
27214
|
+
const containers = contours.map(() => []);
|
|
27215
|
+
for (let i = 0; i < contours.length; i++) {
|
|
27216
|
+
const inner = contours[i].contour;
|
|
27217
|
+
const mid = inner[Math.floor(inner.length / 2)];
|
|
27218
|
+
for (let j = 0; j < i; j++) {
|
|
27219
|
+
if (contours[j].area <= contours[i].area) continue;
|
|
27220
|
+
const outer = contours[j].contour;
|
|
27221
|
+
if (isPointInsidePolygon(inner[0], outer) || isPointInsidePolygon(mid, outer)) containers[i].push(j);
|
|
26989
27222
|
}
|
|
26990
|
-
if (parent) parent.holes.push(contour);
|
|
26991
|
-
else outers.push({
|
|
26992
|
-
outer: contour,
|
|
26993
|
-
holes: []
|
|
26994
|
-
});
|
|
26995
27223
|
}
|
|
26996
|
-
|
|
27224
|
+
const polygons = [];
|
|
27225
|
+
const polygonOf = /* @__PURE__ */ new Map();
|
|
27226
|
+
for (let i = 0; i < contours.length; i++) {
|
|
27227
|
+
const around = containers[i];
|
|
27228
|
+
if (around.length % 2 === 0) {
|
|
27229
|
+
const poly = {
|
|
27230
|
+
outer: contours[i].contour,
|
|
27231
|
+
holes: []
|
|
27232
|
+
};
|
|
27233
|
+
polygons.push(poly);
|
|
27234
|
+
polygonOf.set(i, poly);
|
|
27235
|
+
} else polygonOf.get(around[around.length - 1])?.holes.push(contours[i].contour);
|
|
27236
|
+
}
|
|
27237
|
+
return polygons;
|
|
27238
|
+
}
|
|
27239
|
+
/**
|
|
27240
|
+
* A glyph's outlines are flattened and sorted into outlines and holes once per
|
|
27241
|
+
* font, size and flattening, at the glyph origin; each use gets a translated
|
|
27242
|
+
* copy (callers reorder and move the points they are given).
|
|
27243
|
+
*/
|
|
27244
|
+
const glyphOutlineCache = /* @__PURE__ */ new WeakMap();
|
|
27245
|
+
function glyphPolygonsAt(font, glyph, glyphX, glyphY, scale, flattening) {
|
|
27246
|
+
let byGlyph = glyphOutlineCache.get(font);
|
|
27247
|
+
if (!byGlyph) {
|
|
27248
|
+
byGlyph = /* @__PURE__ */ new Map();
|
|
27249
|
+
glyphOutlineCache.set(font, byGlyph);
|
|
27250
|
+
}
|
|
27251
|
+
const key = `${glyph.id}|${scale}|${flattening.segments ?? ""}|${flattening.tolerance}`;
|
|
27252
|
+
let atOrigin = byGlyph.get(key);
|
|
27253
|
+
if (!atOrigin) {
|
|
27254
|
+
atOrigin = organizeGlyphPolygons(extractGlyphContours(glyph, 0, 0, scale, flattening));
|
|
27255
|
+
byGlyph.set(key, atOrigin);
|
|
27256
|
+
}
|
|
27257
|
+
const dx = glyphX * scale;
|
|
27258
|
+
const dy = -glyphY * scale;
|
|
27259
|
+
const moved = (c) => c.map((p) => ({
|
|
27260
|
+
x: p.x + dx,
|
|
27261
|
+
y: p.y + dy
|
|
27262
|
+
}));
|
|
27263
|
+
return atOrigin.map((poly) => ({
|
|
27264
|
+
outer: moved(poly.outer),
|
|
27265
|
+
holes: poly.holes.map(moved)
|
|
27266
|
+
}));
|
|
26997
27267
|
}
|
|
26998
27268
|
function generateExtrudedTextGeometry(options) {
|
|
26999
27269
|
const font = options.font;
|
|
27000
27270
|
const fontSize = options.fontSize ?? 48;
|
|
27001
27271
|
const depth = options.depth ?? 20;
|
|
27002
27272
|
const halfDepth = depth / 2;
|
|
27003
|
-
const
|
|
27273
|
+
const flattening = {
|
|
27274
|
+
segments: options.curveSegments !== void 0 ? Math.max(2, options.curveSegments) : void 0,
|
|
27275
|
+
tolerance: Math.max(.001, options.curveTolerance ?? DEFAULT_CURVE_TOLERANCE)
|
|
27276
|
+
};
|
|
27004
27277
|
const scale = fontSize / (font.unitsPerEm || 1e3);
|
|
27005
27278
|
const run = font.layout(options.text);
|
|
27006
27279
|
let cursorX = 0;
|
|
@@ -27008,7 +27281,7 @@ function generateExtrudedTextGeometry(options) {
|
|
|
27008
27281
|
for (let i = 0; i < run.glyphs.length; i++) {
|
|
27009
27282
|
const glyph = run.glyphs[i];
|
|
27010
27283
|
const pos = run.positions[i];
|
|
27011
|
-
const glyphPolys =
|
|
27284
|
+
const glyphPolys = glyphPolygonsAt(font, glyph, cursorX + (pos.xOffset ?? 0), pos.yOffset ?? 0, scale, flattening);
|
|
27012
27285
|
for (const gp of glyphPolys) polygons.push(gp);
|
|
27013
27286
|
cursorX += (pos.xAdvance ?? glyph.advanceWidth ?? 0) + (options.letterSpacing ? options.letterSpacing / scale : 0);
|
|
27014
27287
|
}
|
|
@@ -27039,8 +27312,8 @@ function generateExtrudedTextGeometry(options) {
|
|
|
27039
27312
|
const w = maxX - minX;
|
|
27040
27313
|
const h = maxY - minY;
|
|
27041
27314
|
let alignOffsetX = (minX + maxX) / 2;
|
|
27042
|
-
if (options.align === "left") alignOffsetX = minX;
|
|
27043
|
-
if (options.align === "right") alignOffsetX = maxX;
|
|
27315
|
+
if (options.align === "left" || options.align === "start") alignOffsetX = minX;
|
|
27316
|
+
if (options.align === "right" || options.align === "end") alignOffsetX = maxX;
|
|
27044
27317
|
let alignOffsetY = (minY + maxY) / 2;
|
|
27045
27318
|
if (options.verticalAlign === "top") alignOffsetY = minY;
|
|
27046
27319
|
if (options.verticalAlign === "bottom") alignOffsetY = maxY;
|
|
@@ -27054,6 +27327,10 @@ function generateExtrudedTextGeometry(options) {
|
|
|
27054
27327
|
p.y -= alignOffsetY;
|
|
27055
27328
|
}
|
|
27056
27329
|
}
|
|
27330
|
+
minX -= alignOffsetX;
|
|
27331
|
+
maxX -= alignOffsetX;
|
|
27332
|
+
minY -= alignOffsetY;
|
|
27333
|
+
maxY -= alignOffsetY;
|
|
27057
27334
|
const frontPositions = [];
|
|
27058
27335
|
const frontNormals = [];
|
|
27059
27336
|
const frontUvs = [];
|
|
@@ -27062,28 +27339,57 @@ function generateExtrudedTextGeometry(options) {
|
|
|
27062
27339
|
const sideNormals = [];
|
|
27063
27340
|
const sideUvs = [];
|
|
27064
27341
|
const sideIndices = [];
|
|
27065
|
-
const
|
|
27066
|
-
const
|
|
27067
|
-
|
|
27068
|
-
|
|
27069
|
-
|
|
27070
|
-
|
|
27071
|
-
|
|
27072
|
-
|
|
27073
|
-
|
|
27074
|
-
|
|
27075
|
-
|
|
27076
|
-
|
|
27077
|
-
|
|
27078
|
-
|
|
27079
|
-
|
|
27080
|
-
|
|
27081
|
-
|
|
27082
|
-
|
|
27083
|
-
|
|
27084
|
-
|
|
27085
|
-
|
|
27086
|
-
|
|
27342
|
+
const addColumn = (p, n, u) => {
|
|
27343
|
+
const index = sidePositions.length / 3;
|
|
27344
|
+
sidePositions.push(p.x, p.y, halfDepth, p.x, p.y, -halfDepth);
|
|
27345
|
+
sideNormals.push(n.x, n.y, 0, n.x, n.y, 0);
|
|
27346
|
+
sideUvs.push(u, 0, u, 1);
|
|
27347
|
+
return index;
|
|
27348
|
+
};
|
|
27349
|
+
const addSideWall = (contour) => {
|
|
27350
|
+
const pts = contour.filter((p, k) => {
|
|
27351
|
+
const next = contour[(k + 1) % contour.length];
|
|
27352
|
+
return Math.hypot(next.x - p.x, next.y - p.y) >= 1e-6;
|
|
27353
|
+
});
|
|
27354
|
+
const count = pts.length;
|
|
27355
|
+
if (count < 2) return;
|
|
27356
|
+
const edgeLengths = [];
|
|
27357
|
+
const faceNormals = pts.map((p, k) => {
|
|
27358
|
+
const next = pts[(k + 1) % count];
|
|
27359
|
+
const len = Math.hypot(next.x - p.x, next.y - p.y);
|
|
27360
|
+
edgeLengths.push(len);
|
|
27361
|
+
return {
|
|
27362
|
+
x: (next.y - p.y) / len,
|
|
27363
|
+
y: -(next.x - p.x) / len
|
|
27364
|
+
};
|
|
27365
|
+
});
|
|
27366
|
+
const perimeter = edgeLengths.reduce((a, b) => a + b, 0);
|
|
27367
|
+
const startColumn = [];
|
|
27368
|
+
const endColumn = [];
|
|
27369
|
+
let along = 0;
|
|
27370
|
+
for (let k = 0; k < count; k++) {
|
|
27371
|
+
const incoming = faceNormals[(k - 1 + count) % count];
|
|
27372
|
+
const outgoing = faceNormals[k];
|
|
27373
|
+
const u = along / perimeter;
|
|
27374
|
+
const sx = incoming.x + outgoing.x;
|
|
27375
|
+
const sy = incoming.y + outgoing.y;
|
|
27376
|
+
const averaged = incoming.x * outgoing.x + incoming.y * outgoing.y >= SIDE_CREASE_COS ? {
|
|
27377
|
+
x: sx / Math.hypot(sx, sy),
|
|
27378
|
+
y: sy / Math.hypot(sx, sy)
|
|
27379
|
+
} : null;
|
|
27380
|
+
if (averaged && k > 0) startColumn[k] = endColumn[k] = addColumn(pts[k], averaged, u);
|
|
27381
|
+
else {
|
|
27382
|
+
endColumn[k] = addColumn(pts[k], averaged ?? incoming, k === 0 ? 1 : u);
|
|
27383
|
+
startColumn[k] = addColumn(pts[k], averaged ?? outgoing, u);
|
|
27384
|
+
}
|
|
27385
|
+
along += edgeLengths[k];
|
|
27386
|
+
}
|
|
27387
|
+
for (let k = 0; k < count; k++) {
|
|
27388
|
+
const a = startColumn[k];
|
|
27389
|
+
const b = endColumn[(k + 1) % count];
|
|
27390
|
+
sideIndices.push(a, b + 1, b);
|
|
27391
|
+
sideIndices.push(a, a + 1, b + 1);
|
|
27392
|
+
}
|
|
27087
27393
|
};
|
|
27088
27394
|
for (const poly of polygons) {
|
|
27089
27395
|
const outer = poly.outer;
|
|
@@ -27102,28 +27408,22 @@ function generateExtrudedTextGeometry(options) {
|
|
|
27102
27408
|
for (let v = 0; v < vertCount; v++) {
|
|
27103
27409
|
const vx = earcutCoords[v * 2];
|
|
27104
27410
|
const vy = earcutCoords[v * 2 + 1];
|
|
27105
|
-
frontPositions.push(vx, vy, halfDepth);
|
|
27106
|
-
frontNormals.push(0, 0, 1);
|
|
27411
|
+
frontPositions.push(vx, vy, -halfDepth);
|
|
27412
|
+
frontNormals.push(0, 0, -1);
|
|
27107
27413
|
frontUvs.push((vx - minX) / (w || 1), (vy - minY) / (h || 1));
|
|
27108
27414
|
}
|
|
27109
|
-
for (let t = 0; t < triangles.length; t += 3) frontIndices.push(frontBaseIdx + triangles[t], frontBaseIdx + triangles[t +
|
|
27110
|
-
const backBaseIdx =
|
|
27415
|
+
for (let t = 0; t < triangles.length; t += 3) frontIndices.push(frontBaseIdx + triangles[t], frontBaseIdx + triangles[t + 2], frontBaseIdx + triangles[t + 1]);
|
|
27416
|
+
const backBaseIdx = frontPositions.length / 3;
|
|
27111
27417
|
for (let v = 0; v < vertCount; v++) {
|
|
27112
27418
|
const vx = earcutCoords[v * 2];
|
|
27113
27419
|
const vy = earcutCoords[v * 2 + 1];
|
|
27114
|
-
|
|
27115
|
-
|
|
27116
|
-
|
|
27117
|
-
}
|
|
27118
|
-
for (let t = 0; t < triangles.length; t += 3) sideIndices.push(backBaseIdx + triangles[t], backBaseIdx + triangles[t + 2], backBaseIdx + triangles[t + 1]);
|
|
27119
|
-
for (let k = 0; k < outer.length; k++) {
|
|
27120
|
-
const next = (k + 1) % outer.length;
|
|
27121
|
-
addSideQuad(outer[k], outer[next]);
|
|
27122
|
-
}
|
|
27123
|
-
for (const hole of poly.holes) for (let k = 0; k < hole.length; k++) {
|
|
27124
|
-
const next = (k + 1) % hole.length;
|
|
27125
|
-
addSideQuad(hole[k], hole[next]);
|
|
27420
|
+
frontPositions.push(vx, vy, halfDepth);
|
|
27421
|
+
frontNormals.push(0, 0, 1);
|
|
27422
|
+
frontUvs.push((vx - minX) / (w || 1), (vy - minY) / (h || 1));
|
|
27126
27423
|
}
|
|
27424
|
+
for (let t = 0; t < triangles.length; t += 3) frontIndices.push(backBaseIdx + triangles[t], backBaseIdx + triangles[t + 1], backBaseIdx + triangles[t + 2]);
|
|
27425
|
+
addSideWall(outer);
|
|
27426
|
+
for (const hole of poly.holes) addSideWall(hole);
|
|
27127
27427
|
}
|
|
27128
27428
|
const frontColor = parseHexOrRgbColor(options.fill ?? "#ffffff");
|
|
27129
27429
|
const sideColor = parseHexOrRgbColor(options.bevelColor ?? options.fill ?? "#ffffff");
|
|
@@ -27133,8 +27433,6 @@ function generateExtrudedTextGeometry(options) {
|
|
|
27133
27433
|
shading: options.material ?? "lit",
|
|
27134
27434
|
shininess: options.shininess ?? 32,
|
|
27135
27435
|
roughness: options.roughness,
|
|
27136
|
-
specularIntensity: options.specularIntensity ?? .8,
|
|
27137
|
-
ambientIntensity: options.ambientIntensity ?? 1,
|
|
27138
27436
|
metallic: options.metallic,
|
|
27139
27437
|
twoSided: true
|
|
27140
27438
|
};
|
|
@@ -27144,8 +27442,6 @@ function generateExtrudedTextGeometry(options) {
|
|
|
27144
27442
|
shading: options.material ?? "lit",
|
|
27145
27443
|
shininess: options.shininess ?? 32,
|
|
27146
27444
|
roughness: options.roughness,
|
|
27147
|
-
specularIntensity: options.specularIntensity ?? .8,
|
|
27148
|
-
ambientIntensity: options.ambientIntensity ?? 1,
|
|
27149
27445
|
metallic: options.metallic,
|
|
27150
27446
|
twoSided: true
|
|
27151
27447
|
};
|
|
@@ -27176,7 +27472,30 @@ function generateExtrudedTextGeometry(options) {
|
|
|
27176
27472
|
"front-material": frontMaterial,
|
|
27177
27473
|
"side-material": sideMaterial
|
|
27178
27474
|
},
|
|
27179
|
-
animations: []
|
|
27475
|
+
animations: [],
|
|
27476
|
+
bounds: {
|
|
27477
|
+
min: [
|
|
27478
|
+
minX,
|
|
27479
|
+
minY,
|
|
27480
|
+
-halfDepth
|
|
27481
|
+
],
|
|
27482
|
+
max: [
|
|
27483
|
+
maxX,
|
|
27484
|
+
maxY,
|
|
27485
|
+
halfDepth
|
|
27486
|
+
],
|
|
27487
|
+
center: [
|
|
27488
|
+
(minX + maxX) / 2,
|
|
27489
|
+
(minY + maxY) / 2,
|
|
27490
|
+
0
|
|
27491
|
+
],
|
|
27492
|
+
size: [
|
|
27493
|
+
w,
|
|
27494
|
+
h,
|
|
27495
|
+
depth
|
|
27496
|
+
],
|
|
27497
|
+
boundingSphereRadius: Math.hypot(w, h, depth) / 2
|
|
27498
|
+
}
|
|
27180
27499
|
},
|
|
27181
27500
|
bounds: {
|
|
27182
27501
|
minX,
|
|
@@ -27191,5 +27510,5 @@ function generateExtrudedTextGeometry(options) {
|
|
|
27191
27510
|
}
|
|
27192
27511
|
|
|
27193
27512
|
//#endregion
|
|
27194
|
-
export {
|
|
27195
|
-
//# sourceMappingURL=dist-
|
|
27513
|
+
export { parseMTL as $, colorMatrixWgsl as A, ensureDevice as B, SlugGeometry as C, chartBridgeCache as D, buildWGSLSignalFn as E, drawLottieNode as F, inputStore as G, getHeadlessFontPath as H, drawParagraphNode as I, loadOBJ as J, loadFBX as K, drawSignalNode as L, drawChartNode as M, drawGifNode as N, clearAllVideoCache as O, drawImageNode as P, parseFBX as Q, drawSvgNode as R, SlugFontCache as S, WebGPUAudioProcessor as T, getRenderer2D as U, generateExtrudedTextGeometry as V, initHeadlessWebGPU as W, mediaDecoderCache as X, lutStore as Y, parseColor as Z, Renderer2D as _, Camera3D as a, useRenderContext as at, ShadowPipeline as b, GlassPipeline as c, getEnv as ct, HeadlessGPUCanvasContextMock as d, parseOBJ as et, Light3D as f, RenderProvider as g, Path3D as h, AudioSignalComputePipeline as i, textureCache as it, drawCaptionNode as j, clearVideoNodeState as k, HeadlessChartCanvasElementMock as l, resolveMediaSourceUrl as lt, NodeSurfaceProvider as m, AudioLatentTrackCache as n, shaderStore as nt, ChartGPUEngineBridge as o, GetFontAssetUrl as ot, MotionBlurPipeline as p, loadModel3D as q, AudioMeshDeformPipeline as r, signalRegistry as rt, EffectPipeline as s, R2_CUSTOM_DOMAIN as st, AudioLatentEngine as t, registerHeadlessFont as tt, HeadlessChartContainerMock as u, Renderer3D as v, SlugPipeline as w, SignalRegistry as x, SSAOPipeline as y, drawVideoNode as z };
|
|
27514
|
+
//# sourceMappingURL=dist-8vbhZYqX.mjs.map
|