@twick/core 0.15.20 → 0.15.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +115 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +41 -1
- package/dist/index.d.ts +41 -1
- package/dist/index.js +117 -1
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
package/dist/index.cjs
CHANGED
|
@@ -95,6 +95,7 @@ __export(index_exports, {
|
|
|
95
95
|
ValueDispatcher: () => ValueDispatcher,
|
|
96
96
|
Variables: () => Variables,
|
|
97
97
|
Vector2: () => Vector2,
|
|
98
|
+
WasmEffectsExporter: () => WasmEffectsExporter,
|
|
98
99
|
WasmExporter: () => WasmExporter,
|
|
99
100
|
addEditorToProject: () => addEditorToProject,
|
|
100
101
|
all: () => all,
|
|
@@ -1594,6 +1595,117 @@ _WasmExporter.id = "@twick/core/wasm";
|
|
|
1594
1595
|
_WasmExporter.displayName = "Video (Wasm)";
|
|
1595
1596
|
var WasmExporter = _WasmExporter;
|
|
1596
1597
|
|
|
1598
|
+
// src/exporter/WasmEffectsExporter.ts
|
|
1599
|
+
var import_gl_runtime = require("@twick/gl-runtime");
|
|
1600
|
+
var _WasmEffectsExporter = class _WasmEffectsExporter {
|
|
1601
|
+
constructor(project, settings, inner) {
|
|
1602
|
+
this.project = project;
|
|
1603
|
+
this.settings = settings;
|
|
1604
|
+
this.inner = inner;
|
|
1605
|
+
this.effectGlCanvas = null;
|
|
1606
|
+
this.effectContext = null;
|
|
1607
|
+
this.effectReadbackFbo = null;
|
|
1608
|
+
}
|
|
1609
|
+
static async create(project, settings) {
|
|
1610
|
+
const inner = await WasmExporter.create(project, settings);
|
|
1611
|
+
return new _WasmEffectsExporter(project, settings, inner);
|
|
1612
|
+
}
|
|
1613
|
+
async start() {
|
|
1614
|
+
return this.inner.start();
|
|
1615
|
+
}
|
|
1616
|
+
async handleFrame(canvas, frame, sceneFrame, sceneName, signal) {
|
|
1617
|
+
const variables = this.project.variables;
|
|
1618
|
+
const fps = this.settings.fps ?? this.project.settings.rendering.fps ?? 30;
|
|
1619
|
+
const activeEffects = this.project.getActiveEffectsForFrame?.(variables ?? {}, frame, fps) ?? [];
|
|
1620
|
+
if (activeEffects.length === 0) {
|
|
1621
|
+
return this.inner.handleFrame(canvas, frame, sceneFrame, sceneName, signal);
|
|
1622
|
+
}
|
|
1623
|
+
const w = canvas.width;
|
|
1624
|
+
const h = canvas.height;
|
|
1625
|
+
if (w <= 0 || h <= 0) {
|
|
1626
|
+
return this.inner.handleFrame(canvas, frame, sceneFrame, sceneName, signal);
|
|
1627
|
+
}
|
|
1628
|
+
if (!this.effectGlCanvas) {
|
|
1629
|
+
this.effectGlCanvas = typeof OffscreenCanvas !== "undefined" ? new OffscreenCanvas(w, h) : document.createElement("canvas");
|
|
1630
|
+
this.effectGlCanvas.width = w;
|
|
1631
|
+
this.effectGlCanvas.height = h;
|
|
1632
|
+
}
|
|
1633
|
+
const glCanvas = this.effectGlCanvas;
|
|
1634
|
+
if (glCanvas.width !== w || glCanvas.height !== h) {
|
|
1635
|
+
glCanvas.width = w;
|
|
1636
|
+
glCanvas.height = h;
|
|
1637
|
+
}
|
|
1638
|
+
if (!this.effectContext) {
|
|
1639
|
+
this.effectContext = (0, import_gl_runtime.createEffectContext)(glCanvas);
|
|
1640
|
+
}
|
|
1641
|
+
const gl = this.effectContext.gl;
|
|
1642
|
+
const sourceTexture = gl.createTexture();
|
|
1643
|
+
if (!sourceTexture) {
|
|
1644
|
+
return this.inner.handleFrame(canvas, frame, sceneFrame, sceneName, signal);
|
|
1645
|
+
}
|
|
1646
|
+
gl.bindTexture(gl.TEXTURE_2D, sourceTexture);
|
|
1647
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
1648
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
1649
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
|
1650
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
|
1651
|
+
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
|
|
1652
|
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, canvas);
|
|
1653
|
+
const resultTexture = (0, import_gl_runtime.applyEffects)({
|
|
1654
|
+
ctx: this.effectContext,
|
|
1655
|
+
sourceTexture,
|
|
1656
|
+
width: w,
|
|
1657
|
+
height: h,
|
|
1658
|
+
effects: activeEffects
|
|
1659
|
+
});
|
|
1660
|
+
gl.deleteTexture(sourceTexture);
|
|
1661
|
+
if (!this.effectReadbackFbo) {
|
|
1662
|
+
this.effectReadbackFbo = gl.createFramebuffer();
|
|
1663
|
+
}
|
|
1664
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, this.effectReadbackFbo);
|
|
1665
|
+
gl.framebufferTexture2D(
|
|
1666
|
+
gl.FRAMEBUFFER,
|
|
1667
|
+
gl.COLOR_ATTACHMENT0,
|
|
1668
|
+
gl.TEXTURE_2D,
|
|
1669
|
+
resultTexture,
|
|
1670
|
+
0
|
|
1671
|
+
);
|
|
1672
|
+
const pixels = new Uint8Array(w * h * 4);
|
|
1673
|
+
gl.readPixels(0, 0, w, h, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
|
|
1674
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
|
1675
|
+
const outCanvas = document.createElement("canvas");
|
|
1676
|
+
outCanvas.width = w;
|
|
1677
|
+
outCanvas.height = h;
|
|
1678
|
+
const ctx2d = outCanvas.getContext("2d");
|
|
1679
|
+
if (ctx2d) {
|
|
1680
|
+
const imageData = ctx2d.createImageData(w, h);
|
|
1681
|
+
const rowBytes = w * 4;
|
|
1682
|
+
for (let y = 0; y < h; y++) {
|
|
1683
|
+
imageData.data.set(
|
|
1684
|
+
pixels.subarray((h - 1 - y) * rowBytes, (h - y) * rowBytes),
|
|
1685
|
+
y * rowBytes
|
|
1686
|
+
);
|
|
1687
|
+
}
|
|
1688
|
+
ctx2d.putImageData(imageData, 0, 0);
|
|
1689
|
+
}
|
|
1690
|
+
return this.inner.handleFrame(outCanvas, frame, sceneFrame, sceneName, signal);
|
|
1691
|
+
}
|
|
1692
|
+
async stop(result) {
|
|
1693
|
+
return this.inner.stop?.();
|
|
1694
|
+
}
|
|
1695
|
+
async generateAudio(assets, startFrame, endFrame) {
|
|
1696
|
+
return this.inner.generateAudio?.(assets, startFrame, endFrame);
|
|
1697
|
+
}
|
|
1698
|
+
async mergeMedia() {
|
|
1699
|
+
return this.inner.mergeMedia?.();
|
|
1700
|
+
}
|
|
1701
|
+
async downloadVideos(assets) {
|
|
1702
|
+
return this.inner.downloadVideos?.(assets);
|
|
1703
|
+
}
|
|
1704
|
+
};
|
|
1705
|
+
_WasmEffectsExporter.id = "@twick/core/wasm-effects";
|
|
1706
|
+
_WasmEffectsExporter.displayName = "Video (Wasm + Effects)";
|
|
1707
|
+
var WasmEffectsExporter = _WasmEffectsExporter;
|
|
1708
|
+
|
|
1597
1709
|
// src/plugin/makePlugin.ts
|
|
1598
1710
|
function makePlugin(plugin) {
|
|
1599
1711
|
return typeof plugin === "function" ? plugin : () => plugin;
|
|
@@ -5016,7 +5128,8 @@ var Renderer = class {
|
|
|
5016
5128
|
const exporters = [
|
|
5017
5129
|
FFmpegExporterClient,
|
|
5018
5130
|
ImageExporter,
|
|
5019
|
-
WasmExporter
|
|
5131
|
+
WasmExporter,
|
|
5132
|
+
WasmEffectsExporter
|
|
5020
5133
|
];
|
|
5021
5134
|
const exporterClass = exporters.find(
|
|
5022
5135
|
(exporter) => exporter.id === settings.exporter.name
|
|
@@ -6330,6 +6443,7 @@ function* zoomOutTransition(area, duration = 0.6) {
|
|
|
6330
6443
|
ValueDispatcher,
|
|
6331
6444
|
Variables,
|
|
6332
6445
|
Vector2,
|
|
6446
|
+
WasmEffectsExporter,
|
|
6333
6447
|
WasmExporter,
|
|
6334
6448
|
addEditorToProject,
|
|
6335
6449
|
all,
|