mirror of
https://github.com/misskey-dev/misskey.git
synced 2026-06-05 18:44:09 +02:00
wip
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -7,23 +7,55 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
<div :class="$style.root">
|
<div :class="$style.root">
|
||||||
<div class="_gaps">
|
<div class="_gaps">
|
||||||
<MkFolder>
|
<MkFolder>
|
||||||
<template #label>Wall N</template>
|
<template #label>Walls</template>
|
||||||
<XWallOption :options="options.walls.n" @update="v => { update({ walls: { ...options.walls, n: v } }); }"></XWallOption>
|
|
||||||
|
<div class="_gaps_s">
|
||||||
|
<MkFolder>
|
||||||
|
<template #label>Wall N</template>
|
||||||
|
<XWallOption :options="options.walls.n" @update="v => { update({ walls: { ...options.walls, n: v } }); }"></XWallOption>
|
||||||
|
</MkFolder>
|
||||||
|
|
||||||
|
<MkFolder>
|
||||||
|
<template #label>Wall S</template>
|
||||||
|
<XWallOption :options="options.walls.s" @update="v => { update({ walls: { ...options.walls, s: v } }); }"></XWallOption>
|
||||||
|
</MkFolder>
|
||||||
|
|
||||||
|
<MkFolder>
|
||||||
|
<template #label>Wall W</template>
|
||||||
|
<XWallOption :options="options.walls.w" @update="v => { update({ walls: { ...options.walls, w: v } }); }"></XWallOption>
|
||||||
|
</MkFolder>
|
||||||
|
|
||||||
|
<MkFolder>
|
||||||
|
<template #label>Wall E</template>
|
||||||
|
<XWallOption :options="options.walls.e" @update="v => { update({ walls: { ...options.walls, e: v } }); }"></XWallOption>
|
||||||
|
</MkFolder>
|
||||||
|
</div>
|
||||||
</MkFolder>
|
</MkFolder>
|
||||||
|
|
||||||
<MkFolder>
|
<MkFolder>
|
||||||
<template #label>Wall S</template>
|
<template #label>Pillars</template>
|
||||||
<XWallOption :options="options.walls.s" @update="v => { update({ walls: { ...options.walls, s: v } }); }"></XWallOption>
|
|
||||||
</MkFolder>
|
|
||||||
|
|
||||||
<MkFolder>
|
<div class="_gaps_s">
|
||||||
<template #label>Wall W</template>
|
<MkFolder>
|
||||||
<XWallOption :options="options.walls.w" @update="v => { update({ walls: { ...options.walls, w: v } }); }"></XWallOption>
|
<template #label>Pillar NW</template>
|
||||||
</MkFolder>
|
<XPillarOption :options="options.pillars.nw" @update="v => { update({ pillars: { ...options.pillars, nw: v } }); }"></XPillarOption>
|
||||||
|
</MkFolder>
|
||||||
|
|
||||||
<MkFolder>
|
<MkFolder>
|
||||||
<template #label>Wall E</template>
|
<template #label>Pillar NE</template>
|
||||||
<XWallOption :options="options.walls.e" @update="v => { update({ walls: { ...options.walls, e: v } }); }"></XWallOption>
|
<XPillarOption :options="options.pillars.ne" @update="v => { update({ pillars: { ...options.pillars, ne: v } }); }"></XPillarOption>
|
||||||
|
</MkFolder>
|
||||||
|
|
||||||
|
<MkFolder>
|
||||||
|
<template #label>Pillar SW</template>
|
||||||
|
<XPillarOption :options="options.pillars.sw" @update="v => { update({ pillars: { ...options.pillars, sw: v } }); }"></XPillarOption>
|
||||||
|
</MkFolder>
|
||||||
|
|
||||||
|
<MkFolder>
|
||||||
|
<template #label>Pillar SE</template>
|
||||||
|
<XPillarOption :options="options.pillars.se" @update="v => { update({ pillars: { ...options.pillars, se: v } }); }"></XPillarOption>
|
||||||
|
</MkFolder>
|
||||||
|
</div>
|
||||||
</MkFolder>
|
</MkFolder>
|
||||||
|
|
||||||
<MkFolder>
|
<MkFolder>
|
||||||
@@ -64,6 +96,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, defineAsyncComponent, nextTick, onMounted, onUnmounted, ref, shallowRef, useTemplateRef, watch } from 'vue';
|
import { computed, defineAsyncComponent, nextTick, onMounted, onUnmounted, ref, shallowRef, useTemplateRef, watch } from 'vue';
|
||||||
import XWallOption from './room.default-heya-wall-options.vue';
|
import XWallOption from './room.default-heya-wall-options.vue';
|
||||||
|
import XPillarOption from './room.default-heya-pillar-options.vue';
|
||||||
import type { ObjectDef } from '@/world/room/object.js';
|
import type { ObjectDef } from '@/world/room/object.js';
|
||||||
import type { SimpleHeyaOptions } from '@/world/room/heya.js';
|
import type { SimpleHeyaOptions } from '@/world/room/heya.js';
|
||||||
import { i18n } from '@/i18n.js';
|
import { i18n } from '@/i18n.js';
|
||||||
|
|||||||
@@ -0,0 +1,57 @@
|
|||||||
|
<!--
|
||||||
|
SPDX-FileCopyrightText: syuilo and misskey-project
|
||||||
|
SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
-->
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div :class="$style.root">
|
||||||
|
<div class="_gaps">
|
||||||
|
<MkSelect
|
||||||
|
:items="[
|
||||||
|
{ label: 'None', value: null },
|
||||||
|
{ label: 'Wood', value: 'wood' },
|
||||||
|
{ label: 'Concrete', value: 'concrete' },
|
||||||
|
]" :modelValue="options.material" @update:modelValue="v => { update({ material: v }); }"
|
||||||
|
>
|
||||||
|
<template #label>wallpaper</template>
|
||||||
|
</MkSelect>
|
||||||
|
<MkInput :modelValue="getHex(options.color)" type="color" @update:modelValue="v => { const c = getRgb(v); if (c != null) update({ color: c }); }">
|
||||||
|
<template #label>color</template>
|
||||||
|
</MkInput>
|
||||||
|
<MkSwitch :modelValue="options.show" @update:modelValue="v => { update({ show: v }); }">
|
||||||
|
<template #label>show</template>
|
||||||
|
</MkSwitch>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { computed, defineAsyncComponent, nextTick, onMounted, onUnmounted, ref, shallowRef, useTemplateRef, watch } from 'vue';
|
||||||
|
import type { ObjectDef } from '@/world/room/object.js';
|
||||||
|
import type { SimpleHeyaOptions } from '@/world/room/heya.js';
|
||||||
|
import { i18n } from '@/i18n.js';
|
||||||
|
import MkButton from '@/components/MkButton.vue';
|
||||||
|
import MkSelect from '@/components/MkSelect.vue';
|
||||||
|
import * as os from '@/os.js';
|
||||||
|
import MkInput from '@/components/MkInput.vue';
|
||||||
|
import MkSwitch from '@/components/MkSwitch.vue';
|
||||||
|
import MkRange from '@/components/MkRange.vue';
|
||||||
|
import { getHex, getRgb } from '@/world/utility.js';
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
options: SimpleHeyaOptions['pillars']['nw' | 'ne' | 'sw' | 'se'];
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(ev: 'update', v: SimpleHeyaOptions['pillars']['nw' | 'ne' | 'sw' | 'se']): void;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
function update(v: Partial<SimpleHeyaOptions['pillars']['nw' | 'ne' | 'sw' | 'se']>) {
|
||||||
|
emit('update', { ...props.options, ...v });
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" module>
|
||||||
|
.root {
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -207,6 +207,28 @@ const data = localStorage.getItem('roomData') != null ? JSON.parse(localStorage.
|
|||||||
withHabaki: false,
|
withHabaki: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
pillars: {
|
||||||
|
nw: {
|
||||||
|
material: null,
|
||||||
|
color: [0.9, 0.9, 0.9],
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
ne: {
|
||||||
|
material: null,
|
||||||
|
color: [0.9, 0.9, 0.9],
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
sw: {
|
||||||
|
material: null,
|
||||||
|
color: [0.9, 0.9, 0.9],
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
se: {
|
||||||
|
material: null,
|
||||||
|
color: [0.9, 0.9, 0.9],
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
flooring: {
|
flooring: {
|
||||||
material: 'wood',
|
material: 'wood',
|
||||||
color: [0.9, 0.9, 0.9],
|
color: [0.9, 0.9, 0.9],
|
||||||
@@ -257,6 +279,30 @@ if (data.heya.options.walls == null) {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
if (data.heya.options.pillars == null) {
|
||||||
|
data.heya.options.pillars = {
|
||||||
|
nw: {
|
||||||
|
material: null,
|
||||||
|
color: [0.9, 0.9, 0.9],
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
ne: {
|
||||||
|
material: null,
|
||||||
|
color: [0.9, 0.9, 0.9],
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
sw: {
|
||||||
|
material: null,
|
||||||
|
color: [0.9, 0.9, 0.9],
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
se: {
|
||||||
|
material: null,
|
||||||
|
color: [0.9, 0.9, 0.9],
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
let latestData = deepClone(data);
|
let latestData = deepClone(data);
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable id-denylist */
|
||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
@@ -26,24 +27,22 @@ export abstract class HeyaManager<T = any> {
|
|||||||
abstract dispose(): void;
|
abstract dispose(): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
type SimpleHeyaWallBase = {
|
|
||||||
material: null | 'wood' | 'concrete';
|
|
||||||
color: [number, number, number];
|
|
||||||
withHari: boolean;
|
|
||||||
hariMaterial: null | 'wood' | 'concrete';
|
|
||||||
hariColor: [number, number, number];
|
|
||||||
withHabaki: boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type SimpleHeyaOptions = {
|
export type SimpleHeyaOptions = {
|
||||||
dimension: [number, number];
|
dimension: [number, number];
|
||||||
window: 'none' | 'kosidakamado' | 'demado' | 'hakidasimado';
|
window: 'none' | 'kosidakamado' | 'demado' | 'hakidasimado';
|
||||||
walls: {
|
walls: Record<'n' | 's' | 'w' | 'e', {
|
||||||
n: SimpleHeyaWallBase;
|
material: null | 'wood' | 'concrete';
|
||||||
s: SimpleHeyaWallBase;
|
color: [number, number, number];
|
||||||
w: SimpleHeyaWallBase;
|
withHari: boolean;
|
||||||
e: SimpleHeyaWallBase;
|
hariMaterial: null | 'wood' | 'concrete';
|
||||||
};
|
hariColor: [number, number, number];
|
||||||
|
withHabaki: boolean;
|
||||||
|
}>;
|
||||||
|
pillars: Record<'nw' | 'ne' | 'sw' | 'se', {
|
||||||
|
material: null | 'wood' | 'concrete';
|
||||||
|
color: [number, number, number];
|
||||||
|
show: boolean;
|
||||||
|
}>;
|
||||||
flooring: {
|
flooring: {
|
||||||
material: null | 'wood' | 'concrete';
|
material: null | 'wood' | 'concrete';
|
||||||
color: [number, number, number];
|
color: [number, number, number];
|
||||||
@@ -58,27 +57,16 @@ export type JapaneseHeyaOptions = {
|
|||||||
window: 'none' | 'kosidakamado' | 'demado' | 'hakidasimado';
|
window: 'none' | 'kosidakamado' | 'demado' | 'hakidasimado';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// TODO: マテリアルは必要になるまで作成しないようにする
|
||||||
|
|
||||||
export class SimpleHeyaManager extends HeyaManager<SimpleHeyaOptions> {
|
export class SimpleHeyaManager extends HeyaManager<SimpleHeyaOptions> {
|
||||||
private loaderResult: BABYLON.ISceneLoaderAsyncResult | null = null;
|
private loaderResult: BABYLON.ISceneLoaderAsyncResult | null = null;
|
||||||
private meshes: BABYLON.Mesh[] = [];
|
private meshes: BABYLON.Mesh[] = [];
|
||||||
private wallRoots: {
|
private wallRoots: Record<'n' | 's' | 'w' | 'e', BABYLON.TransformNode> = null as any;
|
||||||
n: BABYLON.TransformNode;
|
private wallMaterials: Record<'n' | 's' | 'w' | 'e', BABYLON.PBRMaterial> | null = null;
|
||||||
s: BABYLON.TransformNode;
|
private wallHariMaterials: Record<'n' | 's' | 'w' | 'e', BABYLON.PBRMaterial> | null = null;
|
||||||
w: BABYLON.TransformNode;
|
private pillarRoots: Record<'nw' | 'ne' | 'sw' | 'se', BABYLON.TransformNode> | null = null;
|
||||||
e: BABYLON.TransformNode;
|
private pillarMaterials: Record<'nw' | 'ne' | 'sw' | 'se', BABYLON.PBRMaterial> | null = null;
|
||||||
} | null = null;
|
|
||||||
private wallMaterials: {
|
|
||||||
n: BABYLON.PBRMaterial;
|
|
||||||
s: BABYLON.PBRMaterial;
|
|
||||||
w: BABYLON.PBRMaterial;
|
|
||||||
e: BABYLON.PBRMaterial;
|
|
||||||
} | null = null;
|
|
||||||
private wallHariMaterials: {
|
|
||||||
n: BABYLON.PBRMaterial;
|
|
||||||
s: BABYLON.PBRMaterial;
|
|
||||||
w: BABYLON.PBRMaterial;
|
|
||||||
e: BABYLON.PBRMaterial;
|
|
||||||
} | null = null;
|
|
||||||
private ceilingMaterial: BABYLON.PBRMaterial | null = null;
|
private ceilingMaterial: BABYLON.PBRMaterial | null = null;
|
||||||
private floorMaterial: BABYLON.PBRMaterial | null = null;
|
private floorMaterial: BABYLON.PBRMaterial | null = null;
|
||||||
|
|
||||||
@@ -121,6 +109,13 @@ export class SimpleHeyaManager extends HeyaManager<SimpleHeyaOptions> {
|
|||||||
e: this.loaderResult.transformNodes.find(t => t.name.includes('__WALL_E__'))!,
|
e: this.loaderResult.transformNodes.find(t => t.name.includes('__WALL_E__'))!,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.pillarRoots = {
|
||||||
|
nw: this.loaderResult.transformNodes.find(t => t.name.includes('__PILLAR_NW__'))!,
|
||||||
|
ne: this.loaderResult.transformNodes.find(t => t.name.includes('__PILLAR_NE__'))!,
|
||||||
|
sw: this.loaderResult.transformNodes.find(t => t.name.includes('__PILLAR_SW__'))!,
|
||||||
|
se: this.loaderResult.transformNodes.find(t => t.name.includes('__PILLAR_SE__'))!,
|
||||||
|
};
|
||||||
|
|
||||||
const wallMaterial = findMaterial(this.meshes[0], '__X_WALL__');
|
const wallMaterial = findMaterial(this.meshes[0], '__X_WALL__');
|
||||||
this.wallMaterials = {
|
this.wallMaterials = {
|
||||||
n: wallMaterial.clone('wallNMaterial'),
|
n: wallMaterial.clone('wallNMaterial'),
|
||||||
@@ -137,6 +132,14 @@ export class SimpleHeyaManager extends HeyaManager<SimpleHeyaOptions> {
|
|||||||
e: hariMaterial.clone('wallEHariMaterial'),
|
e: hariMaterial.clone('wallEHariMaterial'),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const pillarMaterial = findMaterial(this.meshes[0], '__X_PILLAR__');
|
||||||
|
this.pillarMaterials = {
|
||||||
|
nw: pillarMaterial.clone('pillarNWMaterial'),
|
||||||
|
ne: pillarMaterial.clone('pillarNEMaterial'),
|
||||||
|
sw: pillarMaterial.clone('pillarSWMaterial'),
|
||||||
|
se: pillarMaterial.clone('pillarSEMaterial'),
|
||||||
|
};
|
||||||
|
|
||||||
for (const [k, v] of Object.entries(this.wallRoots)) {
|
for (const [k, v] of Object.entries(this.wallRoots)) {
|
||||||
for (const m of v.getChildMeshes().filter(m => m.material === wallMaterial)) {
|
for (const m of v.getChildMeshes().filter(m => m.material === wallMaterial)) {
|
||||||
m.material = this.wallMaterials[k];
|
m.material = this.wallMaterials[k];
|
||||||
@@ -145,6 +148,11 @@ export class SimpleHeyaManager extends HeyaManager<SimpleHeyaOptions> {
|
|||||||
m.material = this.wallHariMaterials[k];
|
m.material = this.wallHariMaterials[k];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (const [k, v] of Object.entries(this.pillarRoots)) {
|
||||||
|
for (const m of v.getChildMeshes().filter(m => m.material === pillarMaterial)) {
|
||||||
|
m.material = this.pillarMaterials[k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.ceilingMaterial = findMaterial(this.meshes[0], '__X_CEILING__');
|
this.ceilingMaterial = findMaterial(this.meshes[0], '__X_CEILING__');
|
||||||
this.floorMaterial = findMaterial(this.meshes[0], '__X_FLOOR__');
|
this.floorMaterial = findMaterial(this.meshes[0], '__X_FLOOR__');
|
||||||
@@ -161,9 +169,9 @@ export class SimpleHeyaManager extends HeyaManager<SimpleHeyaOptions> {
|
|||||||
|
|
||||||
for (const mesh of wallRoot.getChildMeshes()) {
|
for (const mesh of wallRoot.getChildMeshes()) {
|
||||||
if (mesh.name.includes('__X_HARI__')) {
|
if (mesh.name.includes('__X_HARI__')) {
|
||||||
mesh.isVisible = wallOptions.withHari;
|
mesh.setEnabled(wallOptions.withHari);
|
||||||
} else if (mesh.name.includes('__X_HABAKI__')) {
|
} else if (mesh.name.includes('__X_HABAKI__')) {
|
||||||
mesh.isVisible = wallOptions.withHabaki;
|
mesh.setEnabled(wallOptions.withHabaki);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,6 +216,31 @@ export class SimpleHeyaManager extends HeyaManager<SimpleHeyaOptions> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (const type of ['nw', 'ne', 'sw', 'se'] as const) {
|
||||||
|
const pillarRoot = this.pillarRoots[type];
|
||||||
|
const pillarOptions = options.pillars[type];
|
||||||
|
|
||||||
|
pillarRoot.setEnabled(pillarOptions.show);
|
||||||
|
|
||||||
|
const targetMaterial = this.pillarMaterials[type];
|
||||||
|
|
||||||
|
targetMaterial.unfreeze();
|
||||||
|
targetMaterial.albedoColor = new BABYLON.Color3(...pillarOptions.color);
|
||||||
|
|
||||||
|
const texPath = pillarOptions.material === 'wood' ? '/client-assets/room/textures/wall-wood2.png'
|
||||||
|
: pillarOptions.material === 'concrete' ? '/client-assets/room/textures/wall-concrete.png'
|
||||||
|
: null;
|
||||||
|
|
||||||
|
if (texPath != null) {
|
||||||
|
const tex = new BABYLON.Texture(texPath, this.meshes[0].getScene(), false, false);
|
||||||
|
targetMaterial.albedoTexture = tex;
|
||||||
|
} else {
|
||||||
|
targetMaterial.albedoTexture = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
targetMaterial.freeze();
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
this.ceilingMaterial.unfreeze();
|
this.ceilingMaterial.unfreeze();
|
||||||
this.ceilingMaterial.albedoColor = new BABYLON.Color3(...options.ceiling.color);
|
this.ceilingMaterial.albedoColor = new BABYLON.Color3(...options.ceiling.color);
|
||||||
@@ -250,14 +283,14 @@ export class SimpleHeyaManager extends HeyaManager<SimpleHeyaOptions> {
|
|||||||
public dispose() {
|
public dispose() {
|
||||||
if (this.loaderResult != null) {
|
if (this.loaderResult != null) {
|
||||||
for (const m of this.loaderResult.meshes) {
|
for (const m of this.loaderResult.meshes) {
|
||||||
m.dispose();
|
m.dispose(false, true);
|
||||||
}
|
}
|
||||||
for (const t of this.loaderResult.transformNodes) {
|
for (const t of this.loaderResult.transformNodes) {
|
||||||
t.dispose();
|
t.dispose(false, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (const m of this.meshes) {
|
for (const m of this.meshes) {
|
||||||
m.dispose();
|
m.dispose(false, true);
|
||||||
}
|
}
|
||||||
for (const m of Object.values(this.wallMaterials ?? {})) {
|
for (const m of Object.values(this.wallMaterials ?? {})) {
|
||||||
m.dispose();
|
m.dispose();
|
||||||
@@ -265,5 +298,8 @@ export class SimpleHeyaManager extends HeyaManager<SimpleHeyaOptions> {
|
|||||||
for (const m of Object.values(this.wallHariMaterials ?? {})) {
|
for (const m of Object.values(this.wallHariMaterials ?? {})) {
|
||||||
m.dispose();
|
m.dispose();
|
||||||
}
|
}
|
||||||
|
for (const m of Object.values(this.pillarMaterials ?? {})) {
|
||||||
|
m.dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user