mirror of
https://github.com/misskey-dev/misskey.git
synced 2026-06-06 21:34:15 +02:00
wip
This commit is contained in:
@@ -21,6 +21,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
<template v-for="interaction in interacions" :key="interaction.id">
|
<template v-for="interaction in interacions" :key="interaction.id">
|
||||||
<MkButton @click="interaction.fn()">{{ interaction.label }}</MkButton>
|
<MkButton @click="interaction.fn()">{{ interaction.label }}</MkButton>
|
||||||
</template>
|
</template>
|
||||||
|
<MkButton @click="addObject">addObject</MkButton>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -33,6 +34,7 @@ import { ensureSignin } from '@/i';
|
|||||||
import MkButton from '@/components/MkButton.vue';
|
import MkButton from '@/components/MkButton.vue';
|
||||||
import { RoomEngine } from '@/utility/room/engine.js';
|
import { RoomEngine } from '@/utility/room/engine.js';
|
||||||
import { getObjectDef } from '@/utility/room/object-defs.js';
|
import { getObjectDef } from '@/utility/room/object-defs.js';
|
||||||
|
import MkSelect from '@/components/MkSelect.vue';
|
||||||
|
|
||||||
const canvas = useTemplateRef('canvas');
|
const canvas = useTemplateRef('canvas');
|
||||||
|
|
||||||
@@ -291,8 +293,7 @@ onMounted(() => {
|
|||||||
if (v == null) {
|
if (v == null) {
|
||||||
interacions.value = [];
|
interacions.value = [];
|
||||||
} else {
|
} else {
|
||||||
const o = engine.value.roomSetting.objects.find(o => o.id === v)!;
|
const obji = engine.value.objectInstances.get(v)!;
|
||||||
const obji = engine.value.objectInstances.get(o.id)!;
|
|
||||||
interacions.value = Object.entries(obji.interactions).map(([interactionId, interactionInfo]) => ({
|
interacions.value = Object.entries(obji.interactions).map(([interactionId, interactionInfo]) => ({
|
||||||
id: interactionId,
|
id: interactionId,
|
||||||
label: interactionInfo.label,
|
label: interactionInfo.label,
|
||||||
@@ -328,6 +329,11 @@ function toggleEditMode() {
|
|||||||
canvas.value!.focus();
|
canvas.value!.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function addObject() {
|
||||||
|
engine.value?.addObject('mug');
|
||||||
|
canvas.value!.focus();
|
||||||
|
}
|
||||||
|
|
||||||
definePage(() => ({
|
definePage(() => ({
|
||||||
title: 'Room',
|
title: 'Room',
|
||||||
icon: 'ti ti-door',
|
icon: 'ti ti-door',
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import { getObjectDef, OBJECT_DEFS } from './object-defs.js';
|
|||||||
import { HorizontalCameraKeyboardMoveInput } from './utility.js';
|
import { HorizontalCameraKeyboardMoveInput } from './utility.js';
|
||||||
import * as sound from '@/utility/sound.js';
|
import * as sound from '@/utility/sound.js';
|
||||||
|
|
||||||
|
// babylonのドメイン知識は持たない
|
||||||
type RoomSettingObject<Options = any> = {
|
type RoomSettingObject<Options = any> = {
|
||||||
id: string;
|
id: string;
|
||||||
type: string;
|
type: string;
|
||||||
@@ -105,9 +106,11 @@ export class RoomEngine {
|
|||||||
public objectInstances: Map<string, RoomObjectInstance<any>> = new Map();
|
public objectInstances: Map<string, RoomObjectInstance<any>> = new Map();
|
||||||
private grabbingCtx: {
|
private grabbingCtx: {
|
||||||
objectId: string;
|
objectId: string;
|
||||||
|
objectType: string;
|
||||||
mesh: BABYLON.Mesh;
|
mesh: BABYLON.Mesh;
|
||||||
initialPosition: BABYLON.Vector3;
|
initialPosition: BABYLON.Vector3;
|
||||||
initialRotation: BABYLON.Vector3;
|
initialRotation: BABYLON.Vector3;
|
||||||
|
initialSticky: string | null;
|
||||||
originalDiffOfPosition: BABYLON.Vector3;
|
originalDiffOfPosition: BABYLON.Vector3;
|
||||||
originalDiffOfRotationY: number;
|
originalDiffOfRotationY: number;
|
||||||
distance: number;
|
distance: number;
|
||||||
@@ -122,6 +125,7 @@ export class RoomEngine {
|
|||||||
private time: 0 | 1 | 2 = 2; // 0: 昼, 1: 夕, 2: 夜
|
private time: 0 | 1 | 2 = 2; // 0: 昼, 1: 夕, 2: 夜
|
||||||
private roomCollisionMeshes: BABYLON.AbstractMesh[] = [];
|
private roomCollisionMeshes: BABYLON.AbstractMesh[] = [];
|
||||||
public roomSetting: RoomSetting;
|
public roomSetting: RoomSetting;
|
||||||
|
private stickyMap: Map<string, string | null> = new Map(); // 何が何に吸着しているか
|
||||||
public enableGridSnapping = ref(true);
|
public enableGridSnapping = ref(true);
|
||||||
public gridSnappingScale = ref(8/*cm*/);
|
public gridSnappingScale = ref(8/*cm*/);
|
||||||
private putParticleSystem: BABYLON.ParticleSystem;
|
private putParticleSystem: BABYLON.ParticleSystem;
|
||||||
@@ -437,6 +441,10 @@ export class RoomEngine {
|
|||||||
isMainLight: o.isMainLight,
|
isMainLight: o.isMainLight,
|
||||||
})));
|
})));
|
||||||
|
|
||||||
|
for (const o of this.roomSetting.objects) {
|
||||||
|
this.stickyMap.set(o.id, o.sticky ?? null);
|
||||||
|
}
|
||||||
|
|
||||||
//const sphere = BABYLON.MeshBuilder.CreateSphere('sphere', { diameter: 1/*cm*/ }, this.scene);
|
//const sphere = BABYLON.MeshBuilder.CreateSphere('sphere', { diameter: 1/*cm*/ }, this.scene);
|
||||||
|
|
||||||
// update tv texure
|
// update tv texure
|
||||||
@@ -526,7 +534,7 @@ export class RoomEngine {
|
|||||||
if (this.grabbingCtx == null) return;
|
if (this.grabbingCtx == null) return;
|
||||||
const grabbing = this.grabbingCtx;
|
const grabbing = this.grabbingCtx;
|
||||||
|
|
||||||
const placement = getObjectDef(this.roomSetting.objects.find(o => o.id === grabbing.objectId)!.type).placement;
|
const placement = getObjectDef(grabbing.objectType).placement;
|
||||||
|
|
||||||
const dir = this.camera.getDirection(BABYLON.Axis.Z).scale(this.scene.useRightHandedSystem ? -1 : 1);
|
const dir = this.camera.getDirection(BABYLON.Axis.Z).scale(this.scene.useRightHandedSystem ? -1 : 1);
|
||||||
const newPos = this.camera.position.add(dir.scale(grabbing.distance)).add(grabbing.originalDiffOfPosition);
|
const newPos = this.camera.position.add(dir.scale(grabbing.distance)).add(grabbing.originalDiffOfPosition);
|
||||||
@@ -613,11 +621,7 @@ export class RoomEngine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sticky != null) {
|
this.stickyMap.set(grabbing.objectId, sticky);
|
||||||
this.roomSetting.objects.find(o => o.id === grabbing.objectId)!.sticky = sticky;
|
|
||||||
} else {
|
|
||||||
this.roomSetting.objects.find(o => o.id === grabbing.objectId)!.sticky = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
grabbing.mesh.rotation = newRotation;
|
grabbing.mesh.rotation = newRotation;
|
||||||
grabbing.mesh.position = newPos;
|
grabbing.mesh.position = newPos;
|
||||||
@@ -871,7 +875,7 @@ export class RoomEngine {
|
|||||||
if (this.grabbingCtx != null) {
|
if (this.grabbingCtx != null) {
|
||||||
// 親から先に外していく
|
// 親から先に外していく
|
||||||
const removeStickyParentRecursively = (mesh: BABYLON.Mesh) => {
|
const removeStickyParentRecursively = (mesh: BABYLON.Mesh) => {
|
||||||
const stickyObjectIds = Array.from(this.roomSetting.objects.filter(o => o.sticky === mesh.metadata.objectId)).map(o => o.id);
|
const stickyObjectIds = this.stickyMap.entries().filter(([k, v]) => v === mesh.metadata.objectId).map(([k, v]) => k);
|
||||||
for (const soid of stickyObjectIds) {
|
for (const soid of stickyObjectIds) {
|
||||||
const soMesh = this.objectMeshs.get(soid)!;
|
const soMesh = this.objectMeshs.get(soid)!;
|
||||||
soMesh.setParent(null);
|
soMesh.setParent(null);
|
||||||
@@ -923,7 +927,7 @@ export class RoomEngine {
|
|||||||
|
|
||||||
// 子から先に適用していく
|
// 子から先に適用していく
|
||||||
const setStickyParentRecursively = (mesh: BABYLON.AbstractMesh) => {
|
const setStickyParentRecursively = (mesh: BABYLON.AbstractMesh) => {
|
||||||
const stickyObjectIds = Array.from(this.roomSetting.objects.filter(o => o.sticky === mesh.metadata.objectId)).map(o => o.id);
|
const stickyObjectIds = this.stickyMap.entries().filter(([k, v]) => v === mesh.metadata.objectId).map(([k, v]) => k);
|
||||||
for (const soid of stickyObjectIds) {
|
for (const soid of stickyObjectIds) {
|
||||||
const soMesh = this.objectMeshs.get(soid)!;
|
const soMesh = this.objectMeshs.get(soid)!;
|
||||||
setStickyParentRecursively(soMesh);
|
setStickyParentRecursively(soMesh);
|
||||||
@@ -934,7 +938,7 @@ export class RoomEngine {
|
|||||||
|
|
||||||
const descendantStickyObjectIds: string[] = [];
|
const descendantStickyObjectIds: string[] = [];
|
||||||
const collectDescendantStickyObjectIds = (parentId: string) => {
|
const collectDescendantStickyObjectIds = (parentId: string) => {
|
||||||
const childIds = Array.from(this.roomSetting.objects.filter(o => o.sticky === parentId)).map(o => o.id);
|
const childIds = this.stickyMap.entries().filter(([k, v]) => v === parentId).map(([k, v]) => k);
|
||||||
for (const cid of childIds) {
|
for (const cid of childIds) {
|
||||||
descendantStickyObjectIds.push(cid);
|
descendantStickyObjectIds.push(cid);
|
||||||
collectDescendantStickyObjectIds(cid);
|
collectDescendantStickyObjectIds(cid);
|
||||||
@@ -946,9 +950,11 @@ export class RoomEngine {
|
|||||||
|
|
||||||
this.grabbingCtx = {
|
this.grabbingCtx = {
|
||||||
objectId: selectedObject.metadata.objectId,
|
objectId: selectedObject.metadata.objectId,
|
||||||
|
objectType: selectedObject.metadata.objectType,
|
||||||
mesh: selectedObject,
|
mesh: selectedObject,
|
||||||
initialPosition: selectedObject.position.clone(),
|
initialPosition: selectedObject.position.clone(),
|
||||||
initialRotation: selectedObject.rotation.clone(),
|
initialRotation: selectedObject.rotation.clone(),
|
||||||
|
initialSticky: this.stickyMap.get(selectedObject.metadata.objectId) ?? null,
|
||||||
originalDiffOfPosition: selectedObject.position.subtract(this.camera.position.add(dir.scale(distance))),
|
originalDiffOfPosition: selectedObject.position.subtract(this.camera.position.add(dir.scale(distance))),
|
||||||
originalDiffOfRotationY: selectedObject.rotation.subtract(this.camera.rotation).y,
|
originalDiffOfRotationY: selectedObject.rotation.subtract(this.camera.rotation).y,
|
||||||
distance: distance,
|
distance: distance,
|
||||||
@@ -1018,16 +1024,35 @@ export class RoomEngine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public addObject() {
|
public async addObject(type: string) {
|
||||||
|
this.isEditMode.value = true;
|
||||||
const dir = this.camera.getDirection(BABYLON.Axis.Z).scale(this.scene.useRightHandedSystem ? -1 : 1);
|
const dir = this.camera.getDirection(BABYLON.Axis.Z).scale(this.scene.useRightHandedSystem ? -1 : 1);
|
||||||
|
|
||||||
const id = genId();
|
const id = genId();
|
||||||
|
|
||||||
this.loadObject({
|
const def = getObjectDef(type);
|
||||||
id: id,
|
|
||||||
|
|
||||||
|
await this.loadObject({
|
||||||
|
id: id,
|
||||||
|
type,
|
||||||
|
position: new BABYLON.Vector3(0, 0, 0),
|
||||||
|
rotation: new BABYLON.Vector3(0, 0, 0),
|
||||||
|
options: def.defaultOptions,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.selectedObjectId.value = id;
|
||||||
|
|
||||||
|
this.toggleGrab();
|
||||||
|
|
||||||
|
// todo: grab確定したら
|
||||||
|
//this.roomSetting.objects.push({
|
||||||
|
// id,
|
||||||
|
// type,
|
||||||
|
// position: [0, 0, 0],
|
||||||
|
// rotation: [0, 0, 0],
|
||||||
|
// options: def.defaultOptions,
|
||||||
|
//});
|
||||||
|
|
||||||
sound.playUrl('/client-assets/room/sfx/grab.mp3', {
|
sound.playUrl('/client-assets/room/sfx/grab.mp3', {
|
||||||
volume: 1,
|
volume: 1,
|
||||||
playbackRate: 1,
|
playbackRate: 1,
|
||||||
|
|||||||
Reference in New Issue
Block a user