Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release #708

Merged
merged 11 commits into from
Mar 9, 2022
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@
},
"main": "background.js",
"dependencies": {
"@electron/remote": "^2.0.4",
"animated-gif-detector": "^1.2.0",
"animejs": "3.2.0",
"aws-sdk": "^2.580.0",
"aws-sdk": "^2.814.0",
"canvas-text-wrapper": "github:cyberj/canvas-text-wrapper#master",
"color": "^3.1.2",
"dotenv": "^8.2.0",
Expand All @@ -53,6 +54,7 @@
"recursive-deps": "^1.1.1",
"stream-to-blob": "^2.0.0",
"tap-tempo": "^0.1.1",
"three": "^0.131.3",
"uuid": "^3.3.3",
"vue": "^2.6.10",
"vue-class-component": "^7.2.3",
Expand All @@ -77,7 +79,7 @@
"@vue/eslint-config-prettier": "^4.0.1",
"babel-eslint": "^10.0.3",
"core-js": "^3.19.1",
"electron": "^11.2.0",
"electron": "^17.0.0",
"electron-builder": "^22.9.1",
"electron-notarize": "^1.0.0",
"eslint": "^5.16.0",
Expand Down
5 changes: 3 additions & 2 deletions src/application/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import use from "./use";

import PromiseWorker from "promise-worker-transferable";
import Vue from "vue";
import { ipcRenderer, remote } from "electron";
import { ipcRenderer } from "electron";
import { app } from "@electron/remote";

let imageBitmap;
const imageBitmapQueue = [];
Expand Down Expand Up @@ -58,7 +59,7 @@ export default class ModV {

this.$worker.postMessage({
type: "__dirname",
payload: remote.app.getAppPath()
payload: app.getAppPath()
});

this.$worker.addEventListener("message", e => {
Expand Down
115 changes: 115 additions & 0 deletions src/application/renderers/three.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import store from "../worker/store";
import * as THREE from "three/build/three.module.js";

const threeCanvas = new OffscreenCanvas(300, 300);
const threeContext = threeCanvas.getContext("webgl2", {
antialias: true,
desynchronized: true,
powerPreference: "high-performance",
premultipliedAlpha: false
});

store.dispatch("outputs/addAuxillaryOutput", {
name: "three-buffer",
context: threeContext,
group: "buffer"
});

const renderer = new THREE.WebGLRenderer({
alpha: true,
antialias: true,
canvas: threeCanvas
});
renderer.setPixelRatio(1);

const inputTextureCanvas = new OffscreenCanvas(300, 300);
const inputTextureContext = inputTextureCanvas.getContext("2d");
store.dispatch("outputs/addAuxillaryOutput", {
name: "three-inputTexture-buffer",
context: inputTextureContext,
group: "buffer"
});

const inputTexture = new THREE.CanvasTexture(inputTextureCanvas);

/**
* Called each frame to update the Module
* @param {Object} Module A three Module
* @param {HTMLCanvas} canvas The Canvas to draw to
* @param {WebGL2RenderingContext} context The Context of the Canvas
* @param {HTMLVideoElement} video The video stream requested by modV
* @param {Array<MeydaFeatures>} features Requested Meyda features
* @param {Meyda} meyda The Meyda instance
* (for Windowing functions etc.)
*
* @param {DOMHighResTimeStamp} delta Timestamp returned by requestAnimationFrame
* @param {Number} bpm The detected or tapped BPM
* @param {Boolean} kick Indicates if BeatDetektor detected a kick in
* the audio stream
*/
function render({
module,
canvas,
context,
video,
features,
meyda,
delta,
bpm,
kick,
props,
data,
fftCanvas,
pipeline
}) {
inputTextureContext.drawImage(canvas, 0, 0, canvas.width, canvas.height);
inputTexture.image = inputTextureCanvas.transferToImageBitmap();
inputTexture.needsUpdate = true;

const { scene, camera } = module.draw({
THREE,
inputTexture,
canvas,
video,
features,
meyda,
delta,
bpm,
kick,
props,
data,
fftCanvas
});

renderer.render(scene, camera);

// clear context if we're in pipeline mode
if (pipeline) {
context.clearRect(0, 0, canvas.width, canvas.height);
}

// Copy three Canvas to Main Canvas
context.drawImage(threeCanvas, 0, 0, canvas.width, canvas.height);
}

function setupModule(module) {
const moduleData = module.setupThree({
THREE,
inputTexture,
data: module.data || {},
width: renderer.domElement.width,
height: renderer.domElement.height
});

module.data = moduleData;

return module;
}

function resize({ width, height }) {
inputTextureCanvas.width = width;
inputTextureCanvas.height = height;
renderer.setSize(width, height, false);
}

export default { render, resize, setupModule };
125 changes: 125 additions & 0 deletions src/application/sample-modules/Cube.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
export default {
meta: {
name: "Cube",
author: "2xAA",
type: "three"
},

props: {
rotation: {
type: "vec3",
default: [0, 0, 0],
min: 0,
max: 1
},

scale: {
type: "vec3",
default: [1, 1, 1],
min: 0,
max: 1
},

position: {
type: "vec3",
default: [0, 0, 0],
min: 0,
max: 1
},

color: {
type: "color",
default: {
r: 1,
g: 1,
b: 1,
a: 1
}
},

useMap: {
type: "bool",
default: false
}
},

data: {
camera: null,
scene: null,
cubeMesh: null
},

setupThree({ THREE, data, width, height, inputTexture }) {
const camera = new THREE.PerspectiveCamera(40, width / height, 1, 1000);
camera.position.z = 5;

const scene = new THREE.Scene();
scene.background = null;

const light = new THREE.AmbientLight(0xffffff);
scene.add(light);

const pointLight = new THREE.PointLight(0xffffff, 1, 100);
pointLight.position.set(50, 50, 50);
scene.add(pointLight);

const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshStandardMaterial({
color: "#ffffff",
roughness: 0.351,
map: inputTexture
});
const cubeMesh = new THREE.Mesh(geometry, material);

scene.add(cubeMesh);

return { ...data, camera, scene, cubeMesh };
},

resize({ canvas: { width, height }, data }) {
data.camera.aspect = width / height;
data.camera.updateProjectionMatrix();

return { ...data };
},

draw({
THREE,
data,
data: { scene, camera },
props: {
scale,
position,
rotation,
color: { r, g, b },
useMap
},
inputTexture
}) {
data.cubeMesh.position.x = position[0];
data.cubeMesh.position.y = position[1];
data.cubeMesh.position.z = position[2];

data.cubeMesh.scale.x = scale[0];
data.cubeMesh.scale.y = scale[1];
data.cubeMesh.scale.z = scale[2];

data.cubeMesh.rotation.x = rotation[0] * 360 * THREE.Math.DEG2RAD;
data.cubeMesh.rotation.y = rotation[1] * 360 * THREE.Math.DEG2RAD;
data.cubeMesh.rotation.z = rotation[2] * 360 * THREE.Math.DEG2RAD;

if (useMap && !data.cubeMesh.material.map) {
data.cubeMesh.material.map = inputTexture;
data.cubeMesh.material.needsUpdate = true;
} else if (!useMap && data.cubeMesh.material.map) {
data.cubeMesh.material.map = undefined;
data.cubeMesh.material.needsUpdate = true;
}

data.cubeMesh.material.color.r = r;
data.cubeMesh.material.color.g = g;
data.cubeMesh.material.color.b = b;

return { scene, camera };
}
};
4 changes: 2 additions & 2 deletions src/application/worker/store/modules/dataTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ const state = {
const { path } = options;
let id;
try {
id = await store.dispatch("images/createImageFromPath", {
({ id } = await store.dispatch("images/createImageFromPath", {
path
}).id;
}));
} catch (e) {
console.error(e);
}
Expand Down
2 changes: 2 additions & 0 deletions src/background/background.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { APP_SCHEME } from "./background-constants";
import { openFile } from "./open-file";
import { createWindow } from "./windows";

require("@electron/remote/main").initialize();

const isDevelopment = process.env.NODE_ENV !== "production";

// Scheme must be registered before the app is ready
Expand Down
13 changes: 10 additions & 3 deletions src/background/menu-bar.js
Original file line number Diff line number Diff line change
Expand Up @@ -217,10 +217,17 @@ export function generateMenuTemplate() {
role: "help",
submenu: [
{
label: "Learn More",
click: async () => {
label: "Learn modV",
click() {
const { shell } = require("electron");
await shell.openExternal("https://modv.js.org");
shell.openExternal("https://modv.js.org");
}
},
{
label: "Search or ask a question",
click() {
const { shell } = require("electron");
shell.openExternal("https://github.com/vcync/modV/discussions");
}
}
]
Expand Down
5 changes: 5 additions & 0 deletions src/background/window-prefs.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ const windowPrefs = {
show: isDevelopment,
webPreferences: {
enableRemoteModule: true,
// electron 12 sets contextIsolation to true by default, this breaks modV
contextIsolation: false,
// Use pluginOptions.nodeIntegration, leave this alone
// See nklayman.github.io/vue-cli-plugin-electron-builder/guide/security.html#node-integration for more info
nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION,
Expand All @@ -60,6 +62,8 @@ const windowPrefs = {
},

async create(window) {
require("@electron/remote/main").enable(window.webContents);

// Configure child windows to open without a menubar (windows/linux)
window.webContents.on(
"new-window",
Expand Down Expand Up @@ -198,6 +202,7 @@ const windowPrefs = {
console.error(e);
}

windows["mainWindow"].maximize();
windows["mainWindow"].show();
});
}
Expand Down
3 changes: 2 additions & 1 deletion vue.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ module.exports = {
"This app requires camera access to record video.",
NSMicrophoneUsageDescription:
"This app requires microphone access to record audio."
}
},
target: ["dmg"]
},

dmg: {
Expand Down
Loading