mirror of
https://github.com/misskey-dev/misskey.git
synced 2026-05-13 16:25:44 +02:00
wip
This commit is contained in:
@@ -10,7 +10,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
<template v-if="!isZenMode">
|
||||
<div v-if="engine != null" class="_buttonsCenter" :class="$style.overlayControls">
|
||||
<template v-if="engine.isEditMode.value">
|
||||
<template v-if="isEditMode">
|
||||
<MkButton v-if="engine.ui.isGrabbing" @click="endGrabbing"><i class="ti ti-check"></i> (E)</MkButton>
|
||||
<MkButton v-else-if="engine.ui.isGrabbingForInstall" @click="endGrabbing"><i class="ti ti-check"></i> (E)</MkButton>
|
||||
<MkButton v-else-if="engine.selected.value != null" @click="beginSelectedInstalledObjectGrabbing"><i class="ti ti-hand-grab"></i> (E)</MkButton>
|
||||
@@ -27,7 +27,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<div v-if="engine != null && engine.isEditMode.value && engine.selected.value != null" :key="engine.selected.value.objectId" class="_panel" :class="$style.overlayObjectInfoPanel">
|
||||
<div v-if="engine != null && isEditMode && engine.selected.value != null" :key="engine.selected.value.objectId" class="_panel" :class="$style.overlayObjectInfoPanel">
|
||||
{{ engine.selected.value.objectDef.name }}
|
||||
|
||||
<div class="_gaps">
|
||||
@@ -58,10 +58,10 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
<div v-if="engine != null" class="_buttons" :class="$style.controls">
|
||||
<!--<MkButton v-for="action in actions" :key="action.key" @click="action.fn">{{ action.label }}{{ hotkeyToLabel(action.hotkey) }}</MkButton>-->
|
||||
<MkButton @click="toggleLight">Toggle Light</MkButton>
|
||||
<MkButton :primary="engine.isEditMode.value" @click="toggleEditMode">Edit mode: {{ engine.isEditMode.value ? 'on' : 'off' }}</MkButton>
|
||||
<MkButton @click="addObject">addObject</MkButton>
|
||||
<MkButton primary @click="save">save</MkButton>
|
||||
<MkButton @click="showBoundingBox">showBoundingBox</MkButton>
|
||||
<MkButton v-if="isEditMode" primary @click="save">Save</MkButton>
|
||||
<MkButton v-if="isEditMode" @click="exitEditMode">Exit edit mode</MkButton>
|
||||
<MkButton v-if="!isEditMode" @click="enterEditMode">Edit mode</MkButton>
|
||||
<MkButton v-if="isEditMode" @click="addObject">addObject</MkButton>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
@@ -85,6 +85,8 @@ const canvas = useTemplateRef('canvas');
|
||||
|
||||
const engine = shallowRef<RoomEngine | null>(null);
|
||||
|
||||
const isEditMode = ref(false);
|
||||
|
||||
const interacions = shallowRef<{
|
||||
id: string;
|
||||
label: string;
|
||||
@@ -118,7 +120,7 @@ const actions = computed<Action[]>(() => {
|
||||
|
||||
const actions: Action[] = [];
|
||||
|
||||
if (engine.value.isEditMode.value) {
|
||||
if (isEditMode.value) {
|
||||
actions.push({
|
||||
key: 'grab',
|
||||
label: 'Grab',
|
||||
@@ -152,7 +154,7 @@ function onKeydown(ev: KeyboardEvent) {
|
||||
if (ev.code === 'KeyE') {
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
if (engine.value.isEditMode.value) {
|
||||
if (isEditMode.value) {
|
||||
if (engine.value.ui.isGrabbing || engine.value.ui.isGrabbingForInstall) {
|
||||
endGrabbing();
|
||||
} else {
|
||||
@@ -349,11 +351,6 @@ function rotate() {
|
||||
canvas.value!.focus();
|
||||
}
|
||||
|
||||
function toggleEditMode() {
|
||||
engine.value.isEditMode.value = !engine.value.isEditMode.value;
|
||||
canvas.value!.focus();
|
||||
}
|
||||
|
||||
async function addObject(ev: PointerEvent) {
|
||||
if (engine.value == null) return;
|
||||
const { dispose } = await os.popupAsyncWithDialog(import('./room.add-object-dialog.vue').then(x => x.default), {
|
||||
@@ -376,6 +373,16 @@ function showBoundingBox() {
|
||||
canvas.value!.focus();
|
||||
}
|
||||
|
||||
function enterEditMode() {
|
||||
engine.value?.enterEditMode();
|
||||
isEditMode.value = true;
|
||||
}
|
||||
|
||||
function exitEditMode() {
|
||||
engine.value?.exitEditMode();
|
||||
isEditMode.value = false;
|
||||
}
|
||||
|
||||
function getHex(c: [number, number, number]) {
|
||||
return `#${c.map(x => Math.round(x * 255).toString(16).padStart(2, '0')).join('')}`;
|
||||
}
|
||||
|
||||
@@ -452,15 +452,13 @@ export class RoomEngine {
|
||||
private putParticleSystem: BABYLON.ParticleSystem;
|
||||
private envMapIndoor: BABYLON.CubeTexture;
|
||||
private envMapOutdoor: BABYLON.CubeTexture;
|
||||
private reflectionProbe: BABYLON.ReflectionProbe;
|
||||
private roomLight: BABYLON.SpotLight;
|
||||
public lightContainer: BABYLON.ClusteredLightContainer;
|
||||
private enableReflectionProbe = false; // NOTE: babylonのバグが仕様かは不明だが、WebGPUモードでは自分自身をrenderListに含むReflectionProbeを自分自身のreflectionTextureに設定するとエラーになる(WebGLモードでは問題なく動く) https://forum.babylonjs.com/t/in-webgpu-cannot-use-a-reflectionprobe-that-includes-itself-in-the-renderlist-as-a-reflectiontexture/63065
|
||||
private xGridPreviewPlane: BABYLON.Mesh;
|
||||
private yGridPreviewPlane: BABYLON.Mesh;
|
||||
private zGridPreviewPlane: BABYLON.Mesh;
|
||||
private selectionOutlineLayer: BABYLON.SelectionOutlineLayer | null = null;
|
||||
public isEditMode = ref(false);
|
||||
public isEditMode = false;
|
||||
public isSitting = ref(false);
|
||||
public ui = reactive({
|
||||
isGrabbing: false,
|
||||
@@ -512,21 +510,6 @@ export class RoomEngine {
|
||||
this.envMapOutdoor = BABYLON.CubeTexture.CreateFromPrefilteredData(this.time === 2 ? '/client-assets/room/outdoor-night.env' : '/client-assets/room/outdoor-day.env', this.scene);
|
||||
this.envMapOutdoor.level = this.time === 0 ? 0.5 : this.time === 1 ? 0.3 : 0.1;
|
||||
|
||||
if (this.enableReflectionProbe) {
|
||||
this.reflectionProbe = new BABYLON.ReflectionProbe('reflectionProbe', 128, this.scene, true, true, true);
|
||||
this.reflectionProbe.position = new BABYLON.Vector3(0, 150/*cm*/, 0);
|
||||
this.reflectionProbe.refreshRate = 200;
|
||||
}
|
||||
|
||||
//const sphere = BABYLON.MeshBuilder.CreateSphere('', { diameter: 50/*cm*/ }, this.scene);
|
||||
//sphere.position = new BABYLON.Vector3(0, 100/*cm*/, 0);
|
||||
//const mat = new BABYLON.PBRMaterial('', this.scene);
|
||||
//mat.metallic = 1;
|
||||
//mat.roughness = 0;
|
||||
//mat.reflectionTexture = this.envMapIndoor;
|
||||
//mat.reflectionTexture = this.reflectionProbe.cubeTexture;
|
||||
//sphere.material = mat;
|
||||
|
||||
this.scene.collisionsEnabled = true;
|
||||
|
||||
this.camera = new BABYLON.UniversalCamera('camera', new BABYLON.Vector3(0, 130/*cm*/, 0/*cm*/), this.scene);
|
||||
@@ -689,14 +672,6 @@ export class RoomEngine {
|
||||
this.zGridPreviewPlane.isPickable = false;
|
||||
this.zGridPreviewPlane.isVisible = false;
|
||||
|
||||
watch(this.isEditMode, (v) => {
|
||||
if (v) {
|
||||
for (const entity of this.objectEntities.values()) {
|
||||
entity.instance.resetTemporaryState?.();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let isDragging = false;
|
||||
|
||||
this.canvas.addEventListener('pointerdown', (ev) => {
|
||||
@@ -1034,10 +1009,9 @@ export class RoomEngine {
|
||||
this.shadowGeneratorForSunLight.addShadowCaster(m);
|
||||
//if (m.material) (m.material as BABYLON.PBRMaterial).ambientColor = new BABYLON.Color3(1, 1, 1);
|
||||
if (m.material) {
|
||||
(m.material as BABYLON.PBRMaterial).reflectionTexture = this.enableReflectionProbe ? this.reflectionProbe.cubeTexture : this.envMapIndoor;
|
||||
(m.material as BABYLON.PBRMaterial).reflectionTexture = this.envMapIndoor;
|
||||
(m.material as BABYLON.PBRMaterial).useGLTFLightFalloff = true; // Clustered Lightingではphysical falloffを持つマテリアルはアーチファクトが発生する https://doc.babylonjs.com/features/featuresDeepDive/lights/clusteredLighting/#materials-with-a-physical-falloff-may-cause-artefacts
|
||||
}
|
||||
if (this.enableReflectionProbe) this.reflectionProbe.renderList!.push(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1230,11 +1204,11 @@ export class RoomEngine {
|
||||
if (mesh.material) {
|
||||
if (mesh.material instanceof BABYLON.MultiMaterial) {
|
||||
for (const subMat of mesh.material.subMaterials) {
|
||||
(subMat as BABYLON.PBRMaterial).reflectionTexture = this.enableReflectionProbe ? this.reflectionProbe.cubeTexture : this.envMapIndoor;
|
||||
(subMat as BABYLON.PBRMaterial).reflectionTexture = this.envMapIndoor;
|
||||
(subMat as BABYLON.PBRMaterial).useGLTFLightFalloff = true; // Clustered Lightingではphysical falloffを持つマテリアルはアーチファクトが発生する https://doc.babylonjs.com/features/featuresDeepDive/lights/clusteredLighting/#materials-with-a-physical-falloff-may-cause-artefacts
|
||||
}
|
||||
} else {
|
||||
(mesh.material as BABYLON.PBRMaterial).reflectionTexture = this.enableReflectionProbe ? this.reflectionProbe.cubeTexture : this.envMapIndoor;
|
||||
(mesh.material as BABYLON.PBRMaterial).reflectionTexture = this.envMapIndoor;
|
||||
(mesh.material as BABYLON.PBRMaterial).useGLTFLightFalloff = true; // Clustered Lightingではphysical falloffを持つマテリアルはアーチファクトが発生する https://doc.babylonjs.com/features/featuresDeepDive/lights/clusteredLighting/#materials-with-a-physical-falloff-may-cause-artefacts
|
||||
}
|
||||
}
|
||||
@@ -1503,10 +1477,9 @@ export class RoomEngine {
|
||||
}
|
||||
|
||||
public async addObject(type: string) {
|
||||
if (!this.isEditMode) return;
|
||||
if (this.grabbingCtx != null) return;
|
||||
|
||||
this.isEditMode.value = true;
|
||||
|
||||
const dir = this.camera.getDirection(BABYLON.Axis.Z).scale(this.scene.useRightHandedSystem ? -1 : 1);
|
||||
const distance = 30/*cm*/;
|
||||
|
||||
@@ -1593,6 +1566,61 @@ export class RoomEngine {
|
||||
});
|
||||
}
|
||||
|
||||
public enterEditMode() {
|
||||
this.isEditMode = true;
|
||||
|
||||
for (const entity of this.objectEntities.values()) {
|
||||
entity.instance.resetTemporaryState?.();
|
||||
}
|
||||
}
|
||||
|
||||
public async exitEditMode() {
|
||||
this.isEditMode = false;
|
||||
|
||||
await this.bake();
|
||||
}
|
||||
|
||||
public async bake() {
|
||||
/*
|
||||
const reflectionProbe = new BABYLON.ReflectionProbe('', 256, this.scene, true, true, true);
|
||||
reflectionProbe.position = new BABYLON.Vector3(0, 150, 0);
|
||||
reflectionProbe.refreshRate = BABYLON.RenderTargetTexture.REFRESHRATE_RENDER_ONCE;
|
||||
reflectionProbe.renderList = this.scene.meshes.filter(m => (m instanceof BABYLON.Mesh || m instanceof BABYLON.InstancedMesh) && m.isEnabled() && m.isVisible && m.material);
|
||||
|
||||
await new Promise(res => window.setTimeout(res, 1000));
|
||||
|
||||
const tex = reflectionProbe.cubeTexture;
|
||||
|
||||
const sphere = BABYLON.MeshBuilder.CreateSphere('', { diameter: 50 }, this.scene);
|
||||
sphere.position = new BABYLON.Vector3(0, 100, 0);
|
||||
const mat = new BABYLON.PBRMaterial('', this.scene);
|
||||
mat.metallic = 1;
|
||||
mat.roughness = 0;
|
||||
mat.reflectionTexture = tex;
|
||||
sphere.material = mat;
|
||||
|
||||
await new Promise(res => window.setTimeout(res, 3000));
|
||||
|
||||
reflectionProbe.renderList = [];
|
||||
|
||||
for (const mesh of this.scene.meshes.filter(m => (m instanceof BABYLON.Mesh || m instanceof BABYLON.InstancedMesh) && m.isEnabled() && m.isVisible && m.material && m.metadata?.isObject)) {
|
||||
if (mesh.material) {
|
||||
mesh.material.unfreeze();
|
||||
if (mesh.material instanceof BABYLON.MultiMaterial) {
|
||||
for (const subMat of mesh.material.subMaterials) {
|
||||
subMat.unfreeze();
|
||||
(subMat as BABYLON.PBRMaterial).reflectionTexture = tex;
|
||||
(subMat as BABYLON.PBRMaterial).realTimeFiltering = true;
|
||||
}
|
||||
} else {
|
||||
(mesh.material as BABYLON.PBRMaterial).reflectionTexture = tex;
|
||||
(mesh.material as BABYLON.PBRMaterial).realTimeFiltering = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
public removeSelectedObject() {
|
||||
if (this.selected.value == null) return;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user