mirror of
https://github.com/misskey-dev/misskey.git
synced 2026-06-25 17:10:43 +00:00
wip
This commit is contained in:
parent
1701e993cf
commit
1154bb5370
19 changed files with 153 additions and 307 deletions
|
|
@ -20,22 +20,22 @@ import { ModerationLogService } from '@/core/ModerationLogService.js';
|
|||
import { QueryService } from '@/core/QueryService.js';
|
||||
|
||||
const driveFileReferencingOptions = {
|
||||
clippedPicture: ['customPicture'],
|
||||
tapestry: ['customPicture'],
|
||||
poster: ['customPicture'],
|
||||
pictureFrame: ['customPicture'],
|
||||
tabletopPictureFrame: ['customPicture'],
|
||||
tabletopGlassPictureFrame: ['customPicture'],
|
||||
wallCanvas: ['customPicture'],
|
||||
wallGlassPictureFrame: ['customPicture'],
|
||||
tabletopFlag: ['customPicture'],
|
||||
tabletopLcdButtonsController: ['customPicture'],
|
||||
djPlayer: ['customPicture'],
|
||||
monitor: ['customPicture'],
|
||||
allInOnePc: ['customPicture'],
|
||||
laptopPc: ['customPicture'],
|
||||
handheldGameConsole: ['customPicture'],
|
||||
largeMousepad: ['customPicture'],
|
||||
clippedPicture: ['image'],
|
||||
tapestry: ['image'],
|
||||
poster: ['image'],
|
||||
pictureFrame: ['image'],
|
||||
tabletopPictureFrame: ['image'],
|
||||
tabletopGlassPictureFrame: ['image'],
|
||||
wallCanvas: ['image'],
|
||||
wallGlassPictureFrame: ['image'],
|
||||
tabletopFlag: ['image'],
|
||||
tabletopLcdButtonsController: ['image'],
|
||||
djPlayer: ['image'],
|
||||
monitor: ['image'],
|
||||
allInOnePc: ['image'],
|
||||
laptopPc: ['image'],
|
||||
handheldGameConsole: ['image'],
|
||||
largeMousepad: ['image'],
|
||||
} as Record<string, string[]>;
|
||||
|
||||
@Injectable()
|
||||
|
|
@ -124,8 +124,8 @@ export class WorldRoomService {
|
|||
if (def == null) continue;
|
||||
for (const key of def) {
|
||||
const optionValue = o.options[key];
|
||||
if (optionValue != null && optionValue !== '') {
|
||||
fileIds.add(optionValue);
|
||||
if (optionValue != null && optionValue.driveFileId != null && optionValue.driveFileId !== '') {
|
||||
fileIds.add(optionValue.driveFileId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<MkSwitch :modelValue="options[k]" @update:modelValue="v => emit('update', k, v)"></MkSwitch>
|
||||
</div>
|
||||
<div v-else-if="s.type === 'enum'">
|
||||
<MkSelect :items="s.enum.map(e => ({ label: e, value: e }))" :modelValue="options[k]" @update:modelValue="v => emit('update', k, v)"></MkSelect>
|
||||
<MkSelect :items="s.enum.map(e => ({ label: e.label, value: e.value }))" :modelValue="options[k]" @update:modelValue="v => emit('update', k, v)"></MkSelect>
|
||||
</div>
|
||||
<div v-else-if="s.type === 'string'">
|
||||
<MkInput type="text" :modelValue="options[k]" @update:modelValue="v => emit('update', k, v)"></MkInput>
|
||||
|
|
@ -25,8 +25,14 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<MkRange :continuousUpdate="true" :min="s.min" :max="s.max" :step="s.step" :modelValue="options[k]" @update:modelValue="v => emit('update', k, v)"></MkRange>
|
||||
</div>
|
||||
<div v-else-if="s.type === 'image'">
|
||||
<MkButton primary inline @click="changeImage(k)">Change</MkButton>
|
||||
<MkButton v-if="options[k] != null" danger inline iconOnly @click="clearImage(k)"><i class="ti ti-x"></i></MkButton>
|
||||
<MkSelect :items="[{ label: i18n.ts.none, value: null }, { label: i18n.ts.custom, value: '_custom_' }, ...(s.presets.length > 0 ? [{ type: 'divider' } as const] : []), ...s.presets.map(e => ({ label: e.label, value: e.value }))]" :modelValue="options[k].type" @update:modelValue="v => changeImageType(k, v)"></MkSelect>
|
||||
|
||||
<div v-if="options[k].type === '_custom_'">
|
||||
<MkButton primary inline @click="changeImage(k)">Change</MkButton>
|
||||
<MkButton v-if="options[k].driveFileId != null" danger inline iconOnly @click="clearImage(k)"><i class="ti ti-x"></i></MkButton>
|
||||
</div>
|
||||
|
||||
<MkRadios :options="[{ label: 'cover', value: 'cover' }, { label: 'contain', value: 'contain' }, { label: 'stretch', value: 'stretch' }]" :modelValue="options[k].fit ?? 'cover'" @update:modelValue="v => changeImageFit(k, v)"></MkRadios>
|
||||
</div>
|
||||
<div v-else-if="s.type === 'seed'">
|
||||
<MkRange :continuousUpdate="true" :min="0" :max="1000" :step="1" :modelValue="options[k]" @update:modelValue="v => emit('update', k, v)"></MkRange>
|
||||
|
|
@ -37,7 +43,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, defineAsyncComponent, nextTick, onMounted, onUnmounted, ref, shallowRef, useTemplateRef, watch } from 'vue';
|
||||
import { } from 'vue';
|
||||
import * as Misskey from 'misskey-js';
|
||||
import type { ObjectDef } from '@/world/room/object.js';
|
||||
import { i18n } from '@/i18n.js';
|
||||
|
|
@ -49,6 +55,7 @@ import MkSwitch from '@/components/MkSwitch.vue';
|
|||
import MkRange from '@/components/MkRange.vue';
|
||||
import { getHex, getRgb } from '@/world/utility.js';
|
||||
import { chooseDriveFile } from '@/utility/drive.js';
|
||||
import MkRadios from '@/components/MkRadios.vue';
|
||||
|
||||
const props = defineProps<{
|
||||
schema: ObjectDef['options']['schema'];
|
||||
|
|
@ -60,6 +67,10 @@ const emit = defineEmits<{
|
|||
(ev: 'update', k: string, v: any): void;
|
||||
}>();
|
||||
|
||||
function changeImageType(k: string, type: string) {
|
||||
emit('update', k, { ...props.options[k], type, driveFileId: type === '_custom_' ? props.options[k].driveFileId : null });
|
||||
}
|
||||
|
||||
async function changeImage(k: string) {
|
||||
chooseDriveFile({ multiple: false }).then((fileResponse) => {
|
||||
if (fileResponse.length === 0) return;
|
||||
|
|
@ -79,12 +90,19 @@ async function changeImage(k: string) {
|
|||
return;
|
||||
}
|
||||
props.addFileAttachment(file);
|
||||
emit('update', k, file.id);
|
||||
emit('update', k, {
|
||||
...props.options[k],
|
||||
driveFileId: file.id,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function clearImage(k: string) {
|
||||
emit('update', k, null);
|
||||
emit('update', k, { ...props.options[k], driveFileId: null });
|
||||
}
|
||||
|
||||
function changeImageFit(k: string, fit: string) {
|
||||
emit('update', k, { ...props.options[k], fit });
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -4,8 +4,9 @@
|
|||
*/
|
||||
|
||||
import * as BABYLON from '@babylonjs/core';
|
||||
import type { ModelManager, RoomAttachments } from './utility.js';
|
||||
import { createPlaneUvMapper } from '../utility.js';
|
||||
import type { Timer } from '../utility.js';
|
||||
import type { ModelManager, RoomAttachments } from './utility.js';
|
||||
|
||||
// babylonのドメイン知識は持たない
|
||||
export type RoomStateObject = {
|
||||
|
|
@ -76,6 +77,10 @@ type RangeOptionSchema = {
|
|||
type ImageOptionSchema = {
|
||||
type: 'image';
|
||||
label: string;
|
||||
presets: {
|
||||
label: string;
|
||||
value: string | number;
|
||||
}[];
|
||||
};
|
||||
|
||||
type SeedOptionSchema = {
|
||||
|
|
@ -101,7 +106,7 @@ type GetRawOptionsSchemaValues<T extends OptionsSchema> = {
|
|||
T[K] extends ColorOptionSchema ? [number, number, number] :
|
||||
T[K] extends EnumOptionSchema ? T[K]['enum'][number]['value'] :
|
||||
T[K] extends RangeOptionSchema ? number :
|
||||
T[K] extends ImageOptionSchema ? string | null :
|
||||
T[K] extends ImageOptionSchema ? { type: T[K]['presets'][number]['value'] | null | '_custom_'; driveFileId?: string | null; fit?: 'cover' | 'contain' | 'stretch'; } :
|
||||
T[K] extends SeedOptionSchema ? number :
|
||||
never;
|
||||
};
|
||||
|
|
@ -113,7 +118,7 @@ type GetConvertedOptionsSchemaValues<T extends OptionsSchema> = {
|
|||
T[K] extends ColorOptionSchema ? [number, number, number] :
|
||||
T[K] extends EnumOptionSchema ? T[K]['enum'][number]['value'] :
|
||||
T[K] extends RangeOptionSchema ? number :
|
||||
T[K] extends ImageOptionSchema ? { url: string; } | null :
|
||||
T[K] extends ImageOptionSchema ? { type: T[K]['presets'][number]['value'] | null | '_custom_'; custom?: { url: string; } | null; fit?: 'cover' | 'contain' | 'stretch'; } :
|
||||
T[K] extends SeedOptionSchema ? number :
|
||||
never;
|
||||
};
|
||||
|
|
@ -174,24 +179,69 @@ export function convertRawOptions<OpSc extends OptionsSchema>(schema: OpSc, raw:
|
|||
for (const record of Object.entries(schema)) {
|
||||
const k = record[0];
|
||||
const v = raw[k];
|
||||
if (record[1].type === 'image' && v != null) {
|
||||
if (v === '') {
|
||||
converted[k] = null;
|
||||
continue;
|
||||
}
|
||||
const file = attachments.files.find(f => f.id === v);
|
||||
if (file != null) {
|
||||
if (file.url.startsWith('http://syu-win.local:3000/')) { // debug
|
||||
converted[k] = { url: file.url.replace('http://syu-win.local:3000/', 'https://local-mi.syuilo.dev/') };
|
||||
} else {
|
||||
converted[k] = { url: file.url };
|
||||
}
|
||||
} else {
|
||||
converted[k] = null;
|
||||
if (record[1].type === 'image') {
|
||||
const file = v.type === '_custom_' ? attachments.files.find(f => f.id === v.driveFileId) : null;
|
||||
if (file != null && file.url.startsWith('http://syu-win.local:3000/')) { // debug
|
||||
file.url = file.url.replace('http://syu-win.local:3000/', 'https://local-mi.syuilo.dev/');
|
||||
}
|
||||
|
||||
converted[k] = { type: v.type, custom: file != null ? { url: file.url } : null, fit: v.fit };
|
||||
} else {
|
||||
converted[k] = v;
|
||||
}
|
||||
}
|
||||
return converted;
|
||||
}
|
||||
|
||||
export const createTextureManager = (targetMesh: BABYLON.Mesh, targetAspect: number, scene: BABYLON.Scene) => {
|
||||
let currentUrl: string | null = null;
|
||||
let currentTexture: BABYLON.Texture | null = null;
|
||||
|
||||
const updateUv = createPlaneUvMapper(targetMesh);
|
||||
|
||||
const applyFit = (method?: 'cover' | 'contain' | 'stretch') => {
|
||||
if (currentTexture == null) return;
|
||||
|
||||
const srcAspect = currentTexture.getSize().width / currentTexture.getSize().height;
|
||||
|
||||
updateUv(srcAspect, targetAspect, method ?? 'cover');
|
||||
};
|
||||
|
||||
const change = (url: string | null, fit?: 'cover' | 'contain' | 'stretch') => new Promise<BABYLON.Texture | null>((resolve) => {
|
||||
if (currentUrl === url) {
|
||||
applyFit(fit);
|
||||
resolve(currentTexture);
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentTexture != null) {
|
||||
currentTexture.dispose();
|
||||
}
|
||||
|
||||
currentUrl = url;
|
||||
if (url == null) {
|
||||
currentTexture = null;
|
||||
resolve(null);
|
||||
return;
|
||||
}
|
||||
currentTexture = new BABYLON.Texture(url, scene, false, false, undefined, () => {
|
||||
currentTexture!.level = 0.5;
|
||||
applyFit(fit);
|
||||
resolve(currentTexture);
|
||||
}, (message, exception) => {
|
||||
console.warn('Failed to load texture:', message, exception);
|
||||
currentTexture!.dispose();
|
||||
currentTexture = null;
|
||||
resolve(null);
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
change,
|
||||
dispose: () => {
|
||||
if (currentTexture != null) {
|
||||
currentTexture.dispose();
|
||||
}
|
||||
},
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
*/
|
||||
|
||||
import * as BABYLON from '@babylonjs/core';
|
||||
import { defineObject } from '../object.js';
|
||||
import { createTextureManager, defineObject } from '../object.js';
|
||||
import { cm, WORLD_SCALE, createPlaneUvMapper } from '../../utility.js';
|
||||
import { getLightRangeFactorByGraphicsQuality } from '../utility.js';
|
||||
|
||||
|
|
@ -28,22 +28,22 @@ export const allInOnePc = defineObject({
|
|||
max: 1,
|
||||
step: 0.01,
|
||||
},
|
||||
customPicture: {
|
||||
image: {
|
||||
type: 'image',
|
||||
label: 'Custom picture',
|
||||
},
|
||||
fit: {
|
||||
type: 'enum',
|
||||
label: 'Custom picture fit',
|
||||
enum: ['cover', 'contain', 'stretch'],
|
||||
label: 'Screen image',
|
||||
presets: [{
|
||||
label: 'Desktop',
|
||||
value: 'desktop',
|
||||
}],
|
||||
},
|
||||
},
|
||||
default: {
|
||||
bodyColor: [1, 1, 1],
|
||||
bezelColor: [0, 0, 0],
|
||||
screenBrightness: 0.5,
|
||||
customPicture: null,
|
||||
fit: 'cover',
|
||||
image: {
|
||||
type: null,
|
||||
},
|
||||
},
|
||||
},
|
||||
placement: 'top',
|
||||
|
|
@ -69,22 +69,9 @@ export const allInOnePc = defineObject({
|
|||
|
||||
screenMaterial.ambientColor = new BABYLON.Color3(0, 0, 0);
|
||||
screenMaterial.albedoColor = new BABYLON.Color3(0, 0, 0);
|
||||
screenMaterial.emissiveColor = new BABYLON.Color3(1, 1, 1);
|
||||
|
||||
const updateUv = createPlaneUvMapper(screenMesh);
|
||||
|
||||
const applyFit = () => {
|
||||
const tex = screenMaterial.emissiveTexture;
|
||||
if (tex == null) return;
|
||||
|
||||
const srcAspect = tex.getSize().width / tex.getSize().height;
|
||||
const targetAspect = 50 / 27.5;
|
||||
|
||||
updateUv(srcAspect, targetAspect, options.fit);
|
||||
|
||||
model.updated();
|
||||
};
|
||||
|
||||
applyFit();
|
||||
const textureManager = createTextureManager(screenMesh, 50 / 27.5, scene);
|
||||
|
||||
const applyScreenBrightness = () => {
|
||||
const b = options.screenBrightness;
|
||||
|
|
@ -94,29 +81,20 @@ export const allInOnePc = defineObject({
|
|||
|
||||
applyScreenBrightness();
|
||||
|
||||
const applyCustomPicture = () => new Promise<void>((resolve) => {
|
||||
if (options.customPicture != null) {
|
||||
screenMaterial.unfreeze();
|
||||
const tex = new BABYLON.Texture(options.customPicture.url, scene, false, false, undefined, () => {
|
||||
screenMaterial.emissiveColor = new BABYLON.Color3(1, 1, 1);
|
||||
screenMaterial.emissiveTexture = tex;
|
||||
applyFit();
|
||||
applyScreenBrightness();
|
||||
resolve();
|
||||
}, (message, exception) => {
|
||||
console.warn('Failed to load texture:', message, exception);
|
||||
screenMaterial.emissiveColor = new BABYLON.Color3(0, 1, 0);
|
||||
screenMaterial.emissiveTexture = null;
|
||||
resolve();
|
||||
});
|
||||
tex.level = 0.5;
|
||||
} else {
|
||||
screenMaterial.emissiveTexture = null;
|
||||
resolve();
|
||||
const applyImage = () => {
|
||||
screenMaterial.unfreeze();
|
||||
let url: string | null = null;
|
||||
if (options.image.type === '_custom_') {
|
||||
url = options.image.custom?.url ?? null;
|
||||
} else if (options.image.type === 'desktop') {
|
||||
url = '/assets/objects/all-in-one-pc/desktop.png';
|
||||
}
|
||||
});
|
||||
return textureManager.change(url, options.image.fit).then((tex) => {
|
||||
screenMaterial.emissiveTexture = tex;
|
||||
});
|
||||
};
|
||||
|
||||
await applyCustomPicture();
|
||||
await applyImage();
|
||||
|
||||
const applyBodyColor = () => {
|
||||
const [r, g, b] = options.bodyColor;
|
||||
|
|
@ -137,8 +115,7 @@ export const allInOnePc = defineObject({
|
|||
case 'bodyColor': applyBodyColor(); break;
|
||||
case 'bezelColor': applyBezelColor(); break;
|
||||
case 'screenBrightness': applyScreenBrightness(); break;
|
||||
case 'customPicture': applyCustomPicture(); break;
|
||||
case 'fit': applyFit(); break;
|
||||
case 'image': applyImage(); break;
|
||||
}
|
||||
},
|
||||
interactions: {},
|
||||
|
|
@ -146,6 +123,8 @@ export const allInOnePc = defineObject({
|
|||
light.dispose();
|
||||
if (lc != null) lc.removeLight(light);
|
||||
scene.removeLight(light); // lc使用時はsceneには追加してないはずだが、これがないとクラッシュする babylonのバグ?
|
||||
|
||||
textureManager.dispose();
|
||||
},
|
||||
};
|
||||
},
|
||||
|
|
|
|||
|
|
@ -30,17 +30,11 @@ export const clippedPicture = defineObject({
|
|||
type: 'image',
|
||||
label: 'Custom picture',
|
||||
},
|
||||
fit: {
|
||||
type: 'enum',
|
||||
label: 'Custom picture fit',
|
||||
enum: ['cover', 'contain', 'stretch'],
|
||||
},
|
||||
},
|
||||
default: {
|
||||
width: 0.1,
|
||||
height: 0.1,
|
||||
customPicture: null,
|
||||
fit: 'cover',
|
||||
},
|
||||
},
|
||||
placement: 'side',
|
||||
|
|
@ -121,7 +115,6 @@ export const clippedPicture = defineObject({
|
|||
case 'width': applySize(); break;
|
||||
case 'height': applySize(); break;
|
||||
case 'customPicture': applyCustomPicture(); break;
|
||||
case 'fit': applyFit(); break;
|
||||
}
|
||||
},
|
||||
interactions: {},
|
||||
|
|
|
|||
|
|
@ -23,16 +23,10 @@ export const djPlayer = defineObject({
|
|||
type: 'image',
|
||||
label: 'Custom picture',
|
||||
},
|
||||
fit: {
|
||||
type: 'enum',
|
||||
label: 'Custom picture fit',
|
||||
enum: ['cover', 'contain', 'stretch'],
|
||||
},
|
||||
},
|
||||
default: {
|
||||
screenBrightness: 0.5,
|
||||
customPicture: null,
|
||||
fit: 'cover',
|
||||
},
|
||||
},
|
||||
placement: 'top',
|
||||
|
|
@ -98,7 +92,6 @@ export const djPlayer = defineObject({
|
|||
switch (k) {
|
||||
case 'screenBrightness': applyScreenBrightness(); break;
|
||||
case 'customPicture': applyCustomPicture(); break;
|
||||
case 'fit': applyFit(); break;
|
||||
}
|
||||
},
|
||||
interactions: {},
|
||||
|
|
|
|||
|
|
@ -28,17 +28,11 @@ export const handheldGameConsole = defineObject({
|
|||
type: 'image',
|
||||
label: 'Custom picture',
|
||||
},
|
||||
fit: {
|
||||
type: 'enum',
|
||||
label: 'Custom picture fit',
|
||||
enum: ['cover', 'contain', 'stretch'],
|
||||
},
|
||||
},
|
||||
default: {
|
||||
bodyColor: [1, 1, 1],
|
||||
screenBrightness: 0.5,
|
||||
customPicture: null,
|
||||
fit: 'cover',
|
||||
},
|
||||
},
|
||||
placement: 'top',
|
||||
|
|
@ -113,7 +107,6 @@ export const handheldGameConsole = defineObject({
|
|||
case 'bodyColor': applyBodyColor(); break;
|
||||
case 'screenBrightness': applyScreenBrightness(); break;
|
||||
case 'customPicture': applyCustomPicture(); break;
|
||||
case 'fit': applyFit(); break;
|
||||
}
|
||||
},
|
||||
interactions: {},
|
||||
|
|
|
|||
|
|
@ -32,11 +32,6 @@ export const laptopPc = defineObject({
|
|||
type: 'image',
|
||||
label: 'Custom picture',
|
||||
},
|
||||
fit: {
|
||||
type: 'enum',
|
||||
label: 'Custom picture fit',
|
||||
enum: ['cover', 'contain', 'stretch'],
|
||||
},
|
||||
openAngle: {
|
||||
type: 'range',
|
||||
label: 'Open',
|
||||
|
|
@ -50,7 +45,6 @@ export const laptopPc = defineObject({
|
|||
bezelColor: [0, 0, 0],
|
||||
screenBrightness: 0.5,
|
||||
customPicture: null,
|
||||
fit: 'cover',
|
||||
openAngle: 0,
|
||||
},
|
||||
},
|
||||
|
|
@ -162,7 +156,6 @@ export const laptopPc = defineObject({
|
|||
case 'bezelColor': applyBezelColor(); break;
|
||||
case 'screenBrightness': applyScreenBrightness(); break;
|
||||
case 'customPicture': applyCustomPicture(); break;
|
||||
case 'fit': applyFit(); break;
|
||||
case 'openAngle': applyOpenAngle(); break;
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -16,15 +16,9 @@ export const largeMousepad = defineObject({
|
|||
type: 'image',
|
||||
label: 'Custom picture',
|
||||
},
|
||||
fit: {
|
||||
type: 'enum',
|
||||
label: 'Custom picture fit',
|
||||
enum: ['cover', 'contain', 'stretch'],
|
||||
},
|
||||
},
|
||||
default: {
|
||||
customPicture: null,
|
||||
fit: 'cover',
|
||||
},
|
||||
},
|
||||
placement: 'top',
|
||||
|
|
@ -79,7 +73,6 @@ export const largeMousepad = defineObject({
|
|||
onOptionsUpdated: ([k, v]) => {
|
||||
switch (k) {
|
||||
case 'customPicture': applyCustomPicture(); break;
|
||||
case 'fit': applyFit(); break;
|
||||
}
|
||||
},
|
||||
interactions: {},
|
||||
|
|
|
|||
|
|
@ -28,17 +28,11 @@ export const monitor = defineObject({
|
|||
type: 'image',
|
||||
label: 'Custom picture',
|
||||
},
|
||||
fit: {
|
||||
type: 'enum',
|
||||
label: 'Custom picture fit',
|
||||
enum: ['cover', 'contain', 'stretch'],
|
||||
},
|
||||
},
|
||||
default: {
|
||||
bodyColor: [0.1, 0.1, 0.1],
|
||||
screenBrightness: 0.5,
|
||||
customPicture: null,
|
||||
fit: 'cover',
|
||||
},
|
||||
},
|
||||
placement: 'top',
|
||||
|
|
@ -126,7 +120,6 @@ export const monitor = defineObject({
|
|||
case 'bodyColor': applyBodyColor(); break;
|
||||
case 'screenBrightness': applyScreenBrightness(); break;
|
||||
case 'customPicture': applyCustomPicture(); break;
|
||||
case 'fit': applyFit(); break;
|
||||
}
|
||||
},
|
||||
interactions: {},
|
||||
|
|
|
|||
|
|
@ -68,11 +68,6 @@ export const pictureFrame = defineObject({
|
|||
type: 'image',
|
||||
label: 'Custom picture',
|
||||
},
|
||||
fit: {
|
||||
type: 'enum',
|
||||
label: 'Custom picture fit',
|
||||
enum: ['cover', 'contain', 'stretch'],
|
||||
},
|
||||
},
|
||||
default: {
|
||||
frameColor: [0.71, 0.58, 0.39],
|
||||
|
|
@ -84,7 +79,6 @@ export const pictureFrame = defineObject({
|
|||
matVThickness: 0.35,
|
||||
withCover: true,
|
||||
customPicture: null,
|
||||
fit: 'cover',
|
||||
},
|
||||
},
|
||||
placement: 'side',
|
||||
|
|
@ -221,48 +215,9 @@ export const pictureFrame = defineObject({
|
|||
case 'depth': applyDepth(); break;
|
||||
case 'withCover': applyWithCover(); break;
|
||||
case 'customPicture':
|
||||
case 'fit': applyCustomPicture(); break;
|
||||
}
|
||||
},
|
||||
interactions: {},
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
/*
|
||||
|
||||
const applyDirection = () => {
|
||||
if (options.direction === 'vertical') {
|
||||
frameMesh.rotation.z = 0;
|
||||
matMesh.rotation.z = 0;
|
||||
coverMesh.rotation.z = 0;
|
||||
pictureMesh.rotation.z = 0;
|
||||
|
||||
uvs[6] = ax;
|
||||
uvs[7] = ay;
|
||||
uvs[2] = bx;
|
||||
uvs[3] = by;
|
||||
uvs[4] = cx;
|
||||
uvs[5] = cy;
|
||||
uvs[0] = dx;
|
||||
uvs[1] = dy;
|
||||
} else if (options.direction === 'horizontal') {
|
||||
frameMesh.rotation.z = -Math.PI / 2;
|
||||
matMesh.rotation.z = -Math.PI / 2;
|
||||
coverMesh.rotation.z = -Math.PI / 2;
|
||||
pictureMesh.rotation.z = -Math.PI / 2;
|
||||
|
||||
uvs[6] = cy;
|
||||
uvs[7] = cx;
|
||||
uvs[2] = dy;
|
||||
uvs[3] = dx;
|
||||
uvs[4] = ay;
|
||||
uvs[5] = ax;
|
||||
uvs[0] = by;
|
||||
uvs[1] = bx;
|
||||
}
|
||||
|
||||
pictureMesh.updateVerticesData(BABYLON.VertexBuffer.UVKind, uvs);
|
||||
};
|
||||
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -34,17 +34,11 @@ export const poster = defineObject({
|
|||
type: 'image',
|
||||
label: 'Custom picture',
|
||||
},
|
||||
fit: {
|
||||
type: 'enum',
|
||||
label: 'Custom picture fit',
|
||||
enum: ['cover', 'contain', 'stretch'],
|
||||
},
|
||||
},
|
||||
default: {
|
||||
width: 0.15,
|
||||
height: 0.15,
|
||||
customPicture: null,
|
||||
fit: 'cover',
|
||||
},
|
||||
},
|
||||
placement: 'side',
|
||||
|
|
@ -122,14 +116,10 @@ export const poster = defineObject({
|
|||
|
||||
},
|
||||
onOptionsUpdated: ([k, v]) => {
|
||||
if (k === 'width' || k === 'height') {
|
||||
applySize();
|
||||
}
|
||||
if (k === 'customPicture') {
|
||||
applyCustomPicture();
|
||||
}
|
||||
if (k === 'fit') {
|
||||
applyFit();
|
||||
switch (k) {
|
||||
case 'width':
|
||||
case 'height': applySize(); break;
|
||||
case 'customPicture': applyCustomPicture(); break;
|
||||
}
|
||||
},
|
||||
interactions: {},
|
||||
|
|
|
|||
|
|
@ -16,15 +16,9 @@ export const tabletopFlag = defineObject({
|
|||
type: 'image',
|
||||
label: 'Custom picture',
|
||||
},
|
||||
fit: {
|
||||
type: 'enum',
|
||||
label: 'Custom picture fit',
|
||||
enum: ['cover', 'contain', 'stretch'],
|
||||
},
|
||||
},
|
||||
default: {
|
||||
customPicture: null,
|
||||
fit: 'cover',
|
||||
},
|
||||
},
|
||||
placement: 'top',
|
||||
|
|
@ -80,7 +74,6 @@ export const tabletopFlag = defineObject({
|
|||
onOptionsUpdated: ([k, v]) => {
|
||||
switch (k) {
|
||||
case 'customPicture': applyCustomPicture(); break;
|
||||
case 'fit': applyFit(); break;
|
||||
}
|
||||
},
|
||||
interactions: {},
|
||||
|
|
|
|||
|
|
@ -34,17 +34,11 @@ export const tabletopGlassPictureFrame = defineObject({
|
|||
type: 'image',
|
||||
label: 'Custom picture',
|
||||
},
|
||||
fit: {
|
||||
type: 'enum',
|
||||
label: 'Custom picture fit',
|
||||
enum: ['cover', 'contain', 'stretch'],
|
||||
},
|
||||
},
|
||||
default: {
|
||||
width: 0.1,
|
||||
height: 0.1,
|
||||
customPicture: null,
|
||||
fit: 'cover',
|
||||
},
|
||||
},
|
||||
placement: 'top',
|
||||
|
|
@ -130,9 +124,6 @@ export const tabletopGlassPictureFrame = defineObject({
|
|||
case 'customPicture':
|
||||
applyCustomPicture();
|
||||
break;
|
||||
case 'fit':
|
||||
applyFit();
|
||||
break;
|
||||
}
|
||||
},
|
||||
interactions: {},
|
||||
|
|
|
|||
|
|
@ -27,17 +27,11 @@ export const tabletopLcdButtonsController = defineObject({
|
|||
type: 'image',
|
||||
label: 'Custom picture',
|
||||
},
|
||||
fit: {
|
||||
type: 'enum',
|
||||
label: 'Custom picture fit',
|
||||
enum: ['cover', 'contain', 'stretch'],
|
||||
},
|
||||
},
|
||||
default: {
|
||||
bodyColor: [0.05, 0.05, 0.05],
|
||||
screenBrightness: 0.5,
|
||||
customPicture: null,
|
||||
fit: 'cover',
|
||||
},
|
||||
},
|
||||
placement: 'top',
|
||||
|
|
@ -111,7 +105,6 @@ export const tabletopLcdButtonsController = defineObject({
|
|||
case 'bodyColor': applyBodyColor(); break;
|
||||
case 'screenBrightness': applyScreenBrightness(); break;
|
||||
case 'customPicture': applyCustomPicture(); break;
|
||||
case 'fit': applyFit(); break;
|
||||
}
|
||||
},
|
||||
interactions: {},
|
||||
|
|
|
|||
|
|
@ -64,11 +64,6 @@ export const tabletopPictureFrame = defineObject({
|
|||
type: 'image',
|
||||
label: 'Custom picture',
|
||||
},
|
||||
fit: {
|
||||
type: 'enum',
|
||||
label: 'Custom picture fit',
|
||||
enum: ['cover', 'contain', 'stretch'],
|
||||
},
|
||||
},
|
||||
default: {
|
||||
frameColor: [0.71, 0.58, 0.39],
|
||||
|
|
@ -79,7 +74,6 @@ export const tabletopPictureFrame = defineObject({
|
|||
matHThickness: 0,
|
||||
matVThickness: 0,
|
||||
customPicture: null,
|
||||
fit: 'cover',
|
||||
},
|
||||
},
|
||||
placement: 'top',
|
||||
|
|
@ -204,67 +198,18 @@ export const tabletopPictureFrame = defineObject({
|
|||
|
||||
},
|
||||
onOptionsUpdated: ([k, v]) => {
|
||||
if (k === 'frameColor') {
|
||||
applyFrameColor();
|
||||
}
|
||||
if (k === 'width' || k === 'height') {
|
||||
applySize();
|
||||
}
|
||||
if (k === 'frameThickness') {
|
||||
applyFrameThickness();
|
||||
}
|
||||
if (k === 'depth') {
|
||||
applyDepth();
|
||||
}
|
||||
if (k === 'matHThickness' || k === 'matVThickness') {
|
||||
applyMatThickness();
|
||||
}
|
||||
if (k === 'customPicture') {
|
||||
applyCustomPicture();
|
||||
}
|
||||
if (k === 'fit') {
|
||||
applyFit();
|
||||
switch (k) {
|
||||
case 'frameColor': applyFrameColor(); break;
|
||||
case 'width':
|
||||
case 'height': applySize(); break;
|
||||
case 'frameThickness': applyFrameThickness(); break;
|
||||
case 'depth': applyDepth(); break;
|
||||
case 'matHThickness':
|
||||
case 'matVThickness': applyMatThickness(); break;
|
||||
case 'customPicture': applyCustomPicture(); break;
|
||||
}
|
||||
},
|
||||
interactions: {},
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
/*
|
||||
|
||||
const applyDirection = () => {
|
||||
if (options.direction === 'vertical') {
|
||||
frameMesh.rotation.z = 0;
|
||||
matMesh.rotation.z = 0;
|
||||
coverMesh.rotation.z = 0;
|
||||
pictureMesh.rotation.z = 0;
|
||||
|
||||
uvs[6] = ax;
|
||||
uvs[7] = ay;
|
||||
uvs[2] = bx;
|
||||
uvs[3] = by;
|
||||
uvs[4] = cx;
|
||||
uvs[5] = cy;
|
||||
uvs[0] = dx;
|
||||
uvs[1] = dy;
|
||||
} else if (options.direction === 'horizontal') {
|
||||
frameMesh.rotation.z = -Math.PI / 2;
|
||||
matMesh.rotation.z = -Math.PI / 2;
|
||||
coverMesh.rotation.z = -Math.PI / 2;
|
||||
pictureMesh.rotation.z = -Math.PI / 2;
|
||||
|
||||
uvs[6] = cy;
|
||||
uvs[7] = cx;
|
||||
uvs[2] = dy;
|
||||
uvs[3] = dx;
|
||||
uvs[4] = ay;
|
||||
uvs[5] = ax;
|
||||
uvs[0] = by;
|
||||
uvs[1] = bx;
|
||||
}
|
||||
|
||||
pictureMesh.updateVerticesData(BABYLON.VertexBuffer.UVKind, uvs);
|
||||
};
|
||||
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -34,17 +34,11 @@ export const tapestry = defineObject({
|
|||
type: 'image',
|
||||
label: 'Custom picture',
|
||||
},
|
||||
fit: {
|
||||
type: 'enum',
|
||||
label: 'Custom picture fit',
|
||||
enum: ['cover', 'contain', 'stretch'],
|
||||
},
|
||||
},
|
||||
default: {
|
||||
width: 0.15,
|
||||
height: 0.15,
|
||||
customPicture: null,
|
||||
fit: 'cover',
|
||||
},
|
||||
},
|
||||
placement: 'side',
|
||||
|
|
@ -126,14 +120,10 @@ export const tapestry = defineObject({
|
|||
|
||||
},
|
||||
onOptionsUpdated: ([k, v]) => {
|
||||
if (k === 'width' || k === 'height') {
|
||||
applySize();
|
||||
}
|
||||
if (k === 'customPicture') {
|
||||
applyCustomPicture();
|
||||
}
|
||||
if (k === 'fit') {
|
||||
applyFit();
|
||||
switch (k) {
|
||||
case 'width':
|
||||
case 'height': applySize(); break;
|
||||
case 'customPicture': applyCustomPicture(); break;
|
||||
}
|
||||
},
|
||||
interactions: {},
|
||||
|
|
|
|||
|
|
@ -30,17 +30,11 @@ export const wallCanvas = defineObject({
|
|||
type: 'image',
|
||||
label: 'Custom picture',
|
||||
},
|
||||
fit: {
|
||||
type: 'enum',
|
||||
label: 'Custom picture fit',
|
||||
enum: ['cover', 'contain', 'stretch'],
|
||||
},
|
||||
},
|
||||
default: {
|
||||
width: 0.15,
|
||||
height: 0.15,
|
||||
customPicture: null,
|
||||
fit: 'cover',
|
||||
},
|
||||
},
|
||||
placement: 'side',
|
||||
|
|
@ -118,7 +112,6 @@ export const wallCanvas = defineObject({
|
|||
applySize();
|
||||
break;
|
||||
case 'customPicture':
|
||||
case 'fit':
|
||||
applyCustomPicture();
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,17 +34,11 @@ export const wallGlassPictureFrame = defineObject({
|
|||
type: 'image',
|
||||
label: 'Custom picture',
|
||||
},
|
||||
fit: {
|
||||
type: 'enum',
|
||||
label: 'Custom picture fit',
|
||||
enum: ['cover', 'contain', 'stretch'],
|
||||
},
|
||||
},
|
||||
default: {
|
||||
width: 0.1,
|
||||
height: 0.1,
|
||||
customPicture: null,
|
||||
fit: 'cover',
|
||||
},
|
||||
},
|
||||
placement: 'wall',
|
||||
|
|
@ -130,9 +124,6 @@ export const wallGlassPictureFrame = defineObject({
|
|||
case 'customPicture':
|
||||
applyCustomPicture();
|
||||
break;
|
||||
case 'fit':
|
||||
applyFit();
|
||||
break;
|
||||
}
|
||||
},
|
||||
interactions: {},
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue