mirror of
https://github.com/misskey-dev/misskey.git
synced 2026-03-21 03:30:42 +00:00
114 lines
2.3 KiB
TypeScript
114 lines
2.3 KiB
TypeScript
/*
|
|
* SPDX-FileCopyrightText: syuilo and misskey-project
|
|
* SPDX-License-Identifier: AGPL-3.0-only
|
|
*/
|
|
|
|
import * as BABYLON from '@babylonjs/core';
|
|
import { defineObject, WORLD_SCALE } from '../engine.js';
|
|
import { createOverridedStates } from '../utility.js';
|
|
|
|
export const blind = defineObject({
|
|
id: 'blind',
|
|
name: 'Blind',
|
|
options: {
|
|
schema: {
|
|
blades: {
|
|
type: 'number',
|
|
label: 'Number of blades',
|
|
min: 1,
|
|
max: 100,
|
|
},
|
|
angle: {
|
|
type: 'number',
|
|
label: 'Blade rotation angle (radian)',
|
|
min: -Math.PI / 2,
|
|
max: Math.PI / 2,
|
|
step: 0.01,
|
|
},
|
|
open: {
|
|
type: 'number',
|
|
label: 'Opening state',
|
|
min: 0,
|
|
max: 1,
|
|
step: 0.01,
|
|
},
|
|
},
|
|
default: {
|
|
blades: 24,
|
|
angle: 0,
|
|
open: 1,
|
|
},
|
|
},
|
|
placement: 'bottom',
|
|
createInstance: ({ options, loaderResult, meshUpdated }) => {
|
|
const temp = createOverridedStates({
|
|
angle: () => options.angle,
|
|
open: () => options.open,
|
|
});
|
|
|
|
const blade = loaderResult.meshes[0].getChildMeshes().find(m => m.name === 'Blade') as BABYLON.Mesh;
|
|
blade.rotation = new BABYLON.Vector3(options.angle, 0, 0);
|
|
|
|
let blades = [] as BABYLON.Mesh[];
|
|
|
|
const applyOpeningState = () => {
|
|
for (const b of blades) {
|
|
b.dispose();
|
|
}
|
|
blades = [];
|
|
|
|
for (let i = 0; i < options.blades; i++) {
|
|
const b = blade.clone();
|
|
if (i / options.blades < temp.open) {
|
|
b.position.y -= (i * 4/*cm*/) / WORLD_SCALE;
|
|
} else {
|
|
b.position.y -= (((options.blades - 1) * temp.open * 4/*cm*/) + (i * 0.3/*cm*/)) / WORLD_SCALE;
|
|
}
|
|
blades.push(b);
|
|
}
|
|
|
|
meshUpdated();
|
|
};
|
|
|
|
const applyAngle = () => {
|
|
for (const b of [blade, ...blades]) {
|
|
b.rotation.x = temp.angle;
|
|
b.rotation.x += Math.random() * 0.3 - 0.15;
|
|
}
|
|
};
|
|
|
|
applyOpeningState();
|
|
applyAngle();
|
|
|
|
return {
|
|
onInited: () => {
|
|
|
|
},
|
|
interactions: {
|
|
adjustBladeRotation: {
|
|
label: 'Adjust blade rotation',
|
|
fn: () => {
|
|
temp.angle += Math.PI / 8;
|
|
if (temp.angle >= Math.PI / 2) temp.angle = -Math.PI / 2;
|
|
applyAngle();
|
|
},
|
|
},
|
|
openClose: {
|
|
label: 'Open/close',
|
|
fn: () => {
|
|
temp.open -= 0.25;
|
|
if (temp.open < 0) temp.open = 1;
|
|
applyOpeningState();
|
|
},
|
|
},
|
|
},
|
|
resetTemporaryState: () => {
|
|
temp.$reset();
|
|
applyAngle();
|
|
applyOpeningState();
|
|
},
|
|
primaryInteraction: 'openClose',
|
|
};
|
|
},
|
|
});
|