mirror of
https://github.com/misskey-dev/misskey.git
synced 2026-05-20 15:15:37 +02:00
wip
This commit is contained in:
@@ -9,6 +9,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
<div class="_buttons" :class="$style.controls">
|
<div class="_buttons" :class="$style.controls">
|
||||||
<MkButton @click="grab">Grab</MkButton>
|
<MkButton @click="grab">Grab</MkButton>
|
||||||
<MkButton @click="toggleLight">Toggle Light</MkButton>
|
<MkButton @click="toggleLight">Toggle Light</MkButton>
|
||||||
|
<MkButton @click="toggleGridSnapping">Grid Snap: {{ gridSnapping }}</MkButton>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -180,6 +181,7 @@ onMounted(() => {
|
|||||||
type: 'ceiling-fan-light',
|
type: 'ceiling-fan-light',
|
||||||
position: [0, 250, 0],
|
position: [0, 250, 0],
|
||||||
rotation: [0, 0, 0],
|
rotation: [0, 0, 0],
|
||||||
|
isMainLight: true,
|
||||||
}],
|
}],
|
||||||
}, {
|
}, {
|
||||||
canvas: canvas.value!,
|
canvas: canvas.value!,
|
||||||
@@ -198,30 +200,6 @@ onUnmounted(() => {
|
|||||||
window.removeEventListener('resize', resize);
|
window.removeEventListener('resize', resize);
|
||||||
});
|
});
|
||||||
|
|
||||||
function onKeydown(ev: KeyboardEvent) {
|
|
||||||
if (ev.key === 'w') {
|
|
||||||
engine.moveForward = true;
|
|
||||||
} else if (ev.key === 's') {
|
|
||||||
engine.moveBackward = true;
|
|
||||||
} else if (ev.key === 'a') {
|
|
||||||
engine.moveLeft = true;
|
|
||||||
} else if (ev.key === 'd') {
|
|
||||||
engine.moveRight = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function onKeyup(ev: KeyboardEvent) {
|
|
||||||
if (ev.key === 'w') {
|
|
||||||
engine.moveForward = false;
|
|
||||||
} else if (ev.key === 's') {
|
|
||||||
engine.moveBackward = false;
|
|
||||||
} else if (ev.key === 'a') {
|
|
||||||
engine.moveLeft = false;
|
|
||||||
} else if (ev.key === 'd') {
|
|
||||||
engine.moveRight = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function grab() {
|
function grab() {
|
||||||
engine.toggleGrab();
|
engine.toggleGrab();
|
||||||
canvas.value!.focus();
|
canvas.value!.focus();
|
||||||
@@ -232,6 +210,14 @@ function toggleLight() {
|
|||||||
canvas.value!.focus();
|
canvas.value!.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const gridSnapping = ref(false);
|
||||||
|
|
||||||
|
function toggleGridSnapping() {
|
||||||
|
gridSnapping.value = !gridSnapping.value;
|
||||||
|
engine.enableGridSnapping = gridSnapping.value;
|
||||||
|
canvas.value!.focus();
|
||||||
|
}
|
||||||
|
|
||||||
definePage(() => ({
|
definePage(() => ({
|
||||||
title: 'Room',
|
title: 'Room',
|
||||||
icon: 'ti ti-door',
|
icon: 'ti ti-door',
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ type RoomDef = {
|
|||||||
position: [number, number, number];
|
position: [number, number, number];
|
||||||
rotation: [number, number, number];
|
rotation: [number, number, number];
|
||||||
variation?: string | null;
|
variation?: string | null;
|
||||||
|
isMainLight?: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 別のオブジェクトのID
|
* 別のオブジェクトのID
|
||||||
@@ -436,12 +437,14 @@ export class RoomEngine {
|
|||||||
startDistance: number;
|
startDistance: number;
|
||||||
ghost: BABYLON.AbstractMesh;
|
ghost: BABYLON.AbstractMesh;
|
||||||
descendantStickyObjectIds: string[];
|
descendantStickyObjectIds: string[];
|
||||||
|
isMainLight: boolean;
|
||||||
} | null = null;
|
} | null = null;
|
||||||
private highlightedObjectId: string | null = null;
|
private highlightedObjectId: string | null = null;
|
||||||
private time: 0 | 1 | 2 = 0; // 0: 昼, 1: 夕, 2: 夜
|
private time: 0 | 1 | 2 = 0; // 0: 昼, 1: 夕, 2: 夜
|
||||||
private roomCollisionMeshes: BABYLON.AbstractMesh[] = [];
|
private roomCollisionMeshes: BABYLON.AbstractMesh[] = [];
|
||||||
private def: RoomDef;
|
private def: RoomDef;
|
||||||
public enableGridSnapping = false;
|
public enableGridSnapping = false;
|
||||||
|
public gridSnappingScale = 10/*cm*/;
|
||||||
private putParticleSystem: BABYLON.ParticleSystem;
|
private putParticleSystem: BABYLON.ParticleSystem;
|
||||||
private envMapIndoor: BABYLON.CubeTexture;
|
private envMapIndoor: BABYLON.CubeTexture;
|
||||||
private envMapOutdoor: BABYLON.CubeTexture;
|
private envMapOutdoor: BABYLON.CubeTexture;
|
||||||
@@ -760,10 +763,9 @@ export class RoomEngine {
|
|||||||
grabbing.ghost.rotation = new BABYLON.Vector3(0, this.camera.rotation.y + grabbing.startRotationY, 0);
|
grabbing.ghost.rotation = new BABYLON.Vector3(0, this.camera.rotation.y + grabbing.startRotationY, 0);
|
||||||
|
|
||||||
if (this.enableGridSnapping) {
|
if (this.enableGridSnapping) {
|
||||||
const scale = 10/*cm*/;
|
grabbing.ghost.position.x = Math.round(grabbing.ghost.position.x / this.gridSnappingScale) * this.gridSnappingScale;
|
||||||
grabbing.ghost.position.x = Math.round(grabbing.ghost.position.x / scale) * scale;
|
grabbing.ghost.position.y = Math.round(grabbing.ghost.position.y / this.gridSnappingScale) * this.gridSnappingScale;
|
||||||
grabbing.ghost.position.y = Math.round(grabbing.ghost.position.y / scale) * scale;
|
grabbing.ghost.position.z = Math.round(grabbing.ghost.position.z / this.gridSnappingScale) * this.gridSnappingScale;
|
||||||
grabbing.ghost.position.z = Math.round(grabbing.ghost.position.z / scale) * scale;
|
|
||||||
grabbing.ghost.rotation.y = Math.round(grabbing.ghost.rotation.y / (Math.PI / 8)) * (Math.PI / 8);
|
grabbing.ghost.rotation.y = Math.round(grabbing.ghost.rotation.y / (Math.PI / 8)) * (Math.PI / 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -791,6 +793,15 @@ export class RoomEngine {
|
|||||||
newRotation.y = Math.atan2(normalLocal.z, normalLocal.x);
|
newRotation.y = Math.atan2(normalLocal.z, normalLocal.x);
|
||||||
sticky = hit.pickedMesh.metadata?.objectId ?? null;
|
sticky = hit.pickedMesh.metadata?.objectId ?? null;
|
||||||
}
|
}
|
||||||
|
} else if (placement === 'bottom') {
|
||||||
|
// 上に向かってレイを飛ばす
|
||||||
|
const ray = new BABYLON.Ray(grabbing.ghost.position, new BABYLON.Vector3(0, 1, 0), 1000/*cm*/);
|
||||||
|
const hit = this.scene.pickWithRay(ray, (m) => isCollisionTarget(m) && (m.name.startsWith('_COLLISION_CEILING_') || m.name.startsWith('_BOTTOM_')));
|
||||||
|
if (hit != null && hit.pickedPoint != null && hit.pickedMesh != null) {
|
||||||
|
newPos.y = hit.pickedPoint.y;
|
||||||
|
sticky = hit.pickedMesh.metadata?.objectId ?? null;
|
||||||
|
}
|
||||||
|
if (newPos.y > 250/*cm*/) newPos.y = 250/*cm*/;
|
||||||
} else {
|
} else {
|
||||||
// 下に向かってレイを飛ばす
|
// 下に向かってレイを飛ばす
|
||||||
const ray = new BABYLON.Ray(grabbing.ghost.position, new BABYLON.Vector3(0, -1, 0), 1000/*cm*/);
|
const ray = new BABYLON.Ray(grabbing.ghost.position, new BABYLON.Vector3(0, -1, 0), 1000/*cm*/);
|
||||||
@@ -835,6 +846,10 @@ export class RoomEngine {
|
|||||||
// //const offset = this.grabbing.mesh!.position.subtract(soMeshStartPosition);
|
// //const offset = this.grabbing.mesh!.position.subtract(soMeshStartPosition);
|
||||||
// //soMesh.position = this.grabbing.mesh!.position.subtract(offset);
|
// //soMesh.position = this.grabbing.mesh!.position.subtract(offset);
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
if (grabbing.isMainLight) {
|
||||||
|
this.roomLight.position = grabbing.mesh.position.add(new BABYLON.Vector3(0, -1/*cm*/, 0));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async loadEnvModel() {
|
private async loadEnvModel() {
|
||||||
@@ -918,8 +933,8 @@ export class RoomEngine {
|
|||||||
mesh.isVisible = false;
|
mesh.isVisible = false;
|
||||||
} else {
|
} else {
|
||||||
//if (mesh.name === '__root__') continue;
|
//if (mesh.name === '__root__') continue;
|
||||||
if (def.receiveShadows !== false) mesh.receiveShadows = true;
|
if (!o.isMainLight && def.receiveShadows !== false) mesh.receiveShadows = true;
|
||||||
if (def.castShadows !== false) {
|
if (!o.isMainLight && def.castShadows !== false) {
|
||||||
this.shadowGenerator1.addShadowCaster(mesh);
|
this.shadowGenerator1.addShadowCaster(mesh);
|
||||||
this.shadowGenerator2.addShadowCaster(mesh);
|
this.shadowGenerator2.addShadowCaster(mesh);
|
||||||
}
|
}
|
||||||
@@ -941,6 +956,10 @@ export class RoomEngine {
|
|||||||
if (objDef != null && objDef.onInit != null) {
|
if (objDef != null && objDef.onInit != null) {
|
||||||
objDef.onInit(this, o, obj);
|
objDef.onInit(this, o, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (o.isMainLight) {
|
||||||
|
this.roomLight.position = obj.meshes[0].position.add(new BABYLON.Vector3(0, -1/*cm*/, 0));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public toggleGrab() {
|
public toggleGrab() {
|
||||||
@@ -1022,6 +1041,7 @@ export class RoomEngine {
|
|||||||
startDistance: startDistance,
|
startDistance: startDistance,
|
||||||
ghost: ghost,
|
ghost: ghost,
|
||||||
descendantStickyObjectIds,
|
descendantStickyObjectIds,
|
||||||
|
isMainLight: this.def.objects.find(o => o.id === highlightedObject.metadata.objectId)?.isMainLight ?? false,
|
||||||
};
|
};
|
||||||
|
|
||||||
sound.playUrl('/client-assets/room/sfx/grab.mp3', {
|
sound.playUrl('/client-assets/room/sfx/grab.mp3', {
|
||||||
|
|||||||
Reference in New Issue
Block a user