mirror of
https://github.com/misskey-dev/misskey.git
synced 2026-05-27 07:14:39 +02:00
Update engine.ts
This commit is contained in:
@@ -18,6 +18,7 @@
|
|||||||
import * as BABYLON from '@babylonjs/core';
|
import * as BABYLON from '@babylonjs/core';
|
||||||
import { AxesViewer } from '@babylonjs/core/Debug/axesViewer';
|
import { AxesViewer } from '@babylonjs/core/Debug/axesViewer';
|
||||||
import { registerBuiltInLoaders } from '@babylonjs/loaders/dynamic';
|
import { registerBuiltInLoaders } from '@babylonjs/loaders/dynamic';
|
||||||
|
import { BoundingBoxRenderer } from '@babylonjs/core/Rendering/boundingBoxRenderer';
|
||||||
import * as sound from '@/utility/sound.js';
|
import * as sound from '@/utility/sound.js';
|
||||||
|
|
||||||
type RoomDef = {
|
type RoomDef = {
|
||||||
@@ -439,7 +440,7 @@ export class RoomEngine {
|
|||||||
descendantStickyObjectIds: string[];
|
descendantStickyObjectIds: string[];
|
||||||
isMainLight: boolean;
|
isMainLight: boolean;
|
||||||
} | null = null;
|
} | null = null;
|
||||||
private highlightedObjectId: string | null = null;
|
private selectedObjectId: 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;
|
||||||
@@ -462,6 +463,11 @@ export class RoomEngine {
|
|||||||
|
|
||||||
this.engine = new BABYLON.Engine(options.canvas, false, { alpha: false });
|
this.engine = new BABYLON.Engine(options.canvas, false, { alpha: false });
|
||||||
this.scene = new BABYLON.Scene(this.engine);
|
this.scene = new BABYLON.Scene(this.engine);
|
||||||
|
|
||||||
|
if (_DEV_) {
|
||||||
|
new BoundingBoxRenderer(this.scene);
|
||||||
|
}
|
||||||
|
|
||||||
//this.scene.autoClear = true;
|
//this.scene.autoClear = true;
|
||||||
if (this.time === 0) {
|
if (this.time === 0) {
|
||||||
this.scene.clearColor = new BABYLON.Color4(0.7, 0.9, 1.0, 0);
|
this.scene.clearColor = new BABYLON.Color4(0.7, 0.9, 1.0, 0);
|
||||||
@@ -629,16 +635,24 @@ export class RoomEngine {
|
|||||||
}, 0);
|
}, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//this.canvas.addEventListener('mousemove', (ev) => {
|
||||||
|
//});
|
||||||
|
|
||||||
this.canvas.addEventListener('click', (ev) => {
|
this.canvas.addEventListener('click', (ev) => {
|
||||||
if (this.grabbing != null) return;
|
if (this.grabbing != null) return;
|
||||||
if (isDragging) return;
|
if (isDragging) return;
|
||||||
const mesh = this.scene.pick(this.scene.pointerX, this.scene.pointerY)?.pickedMesh;
|
|
||||||
if (mesh != null) {
|
this.selectObject(null);
|
||||||
const oid = mesh.metadata.objectId;
|
|
||||||
|
const pickingInfo = this.scene.pick(this.scene.pointerX, this.scene.pointerY,
|
||||||
|
(m) => m.metadata?.isCollision && m.metadata?.objectId != null && this.objectMeshs.has(m.metadata.objectId));
|
||||||
|
|
||||||
|
if (pickingInfo.pickedMesh != null) {
|
||||||
|
const oid = pickingInfo.pickedMesh.metadata.objectId;
|
||||||
if (oid != null && this.objectMeshs.has(oid)) {
|
if (oid != null && this.objectMeshs.has(oid)) {
|
||||||
const o = this.objectMeshs.get(oid)!;
|
const o = this.objectMeshs.get(oid)!;
|
||||||
// focus camera
|
this.camera.setTarget(o.getBoundingInfo().boundingBox.centerWorld);
|
||||||
this.camera.setTarget(o.position);
|
this.selectObject(oid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -669,8 +683,6 @@ export class RoomEngine {
|
|||||||
this.intervalIds.push(window.setInterval(() => {
|
this.intervalIds.push(window.setInterval(() => {
|
||||||
if (this.grabbing != null) {
|
if (this.grabbing != null) {
|
||||||
this.handleGrabbing();
|
this.handleGrabbing();
|
||||||
} else {
|
|
||||||
this.handleSeeking();
|
|
||||||
}
|
}
|
||||||
}, 10));
|
}, 10));
|
||||||
|
|
||||||
@@ -735,21 +747,24 @@ export class RoomEngine {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private handleSeeking() {
|
public selectObject(objectId: string | null) {
|
||||||
this.highlightedObjectId = null;
|
if (this.selectedObjectId != null) {
|
||||||
const ray = new BABYLON.Ray(this.camera.position, this.camera.getDirection(BABYLON.Axis.Z), 1000/*cm*/);
|
const prevMesh = this.objectMeshs.get(this.selectedObjectId);
|
||||||
for (const [id, o] of this.objectMeshs.entries()) {
|
if (prevMesh != null) {
|
||||||
for (const om of o.getChildMeshes()) {
|
for (const om of prevMesh.getChildMeshes()) {
|
||||||
om.renderOutline = false;
|
om.renderOutline = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
this.selectedObjectId = null;
|
||||||
}
|
}
|
||||||
const hit = this.scene.pickWithRay(ray, (m) => m.metadata?.isCollision && m.metadata?.objectId != null && this.objectMeshs.has(m.metadata.objectId));
|
|
||||||
if (hit != null && hit.pickedMesh != null) {
|
if (objectId != null) {
|
||||||
const oid = hit.pickedMesh.metadata?.objectId;
|
const mesh = this.objectMeshs.get(objectId);
|
||||||
this.highlightedObjectId = oid;
|
if (mesh != null) {
|
||||||
const o = this.objectMeshs.get(oid)!;
|
for (const om of mesh.getChildMeshes()) {
|
||||||
for (const om of o.getChildMeshes()) {
|
om.renderOutline = true;
|
||||||
om.renderOutline = true;
|
}
|
||||||
|
this.selectedObjectId = objectId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -902,8 +917,11 @@ export class RoomEngine {
|
|||||||
const obj = await BABYLON.ImportMeshAsync(`/client-assets/room/objects/${o.type}/${o.type}.glb`, this.scene);
|
const obj = await BABYLON.ImportMeshAsync(`/client-assets/room/objects/${o.type}/${o.type}.glb`, this.scene);
|
||||||
obj.meshes[0].scaling = new BABYLON.Vector3(-100, 100, 100);
|
obj.meshes[0].scaling = new BABYLON.Vector3(-100, 100, 100);
|
||||||
obj.meshes[0].bakeCurrentTransformIntoVertices();
|
obj.meshes[0].bakeCurrentTransformIntoVertices();
|
||||||
|
const rootBv = obj.meshes[0].getHierarchyBoundingVectors();
|
||||||
|
obj.meshes[0].setBoundingInfo(new BABYLON.BoundingInfo(rootBv.min, rootBv.max));
|
||||||
obj.meshes[0].position = new BABYLON.Vector3(...o.position);
|
obj.meshes[0].position = new BABYLON.Vector3(...o.position);
|
||||||
obj.meshes[0].rotation = new BABYLON.Vector3(...o.rotation);
|
obj.meshes[0].rotation = new BABYLON.Vector3(...o.rotation);
|
||||||
|
//obj.meshes[0].showBoundingBox = true;
|
||||||
|
|
||||||
let hasCollisionMesh = false;
|
let hasCollisionMesh = false;
|
||||||
for (const mesh of obj.meshes) {
|
for (const mesh of obj.meshes) {
|
||||||
@@ -915,8 +933,15 @@ export class RoomEngine {
|
|||||||
|
|
||||||
for (const m of obj.meshes) {
|
for (const m of obj.meshes) {
|
||||||
const mesh = m;
|
const mesh = m;
|
||||||
|
const isRoot = mesh.name === '__root__';
|
||||||
|
|
||||||
mesh.metadata = { isObject: true, objectId: o.id, objectType: o.type, isCollision: !hasCollisionMesh };
|
mesh.metadata = {
|
||||||
|
isObject: true,
|
||||||
|
isRoot: isRoot,
|
||||||
|
objectId: o.id,
|
||||||
|
objectType: o.type,
|
||||||
|
isCollision: !hasCollisionMesh,
|
||||||
|
};
|
||||||
mesh.checkCollisions = !hasCollisionMesh;
|
mesh.checkCollisions = !hasCollisionMesh;
|
||||||
|
|
||||||
if (mesh.name.startsWith('_TV_SCREEN_')) {
|
if (mesh.name.startsWith('_TV_SCREEN_')) {
|
||||||
@@ -932,7 +957,6 @@ export class RoomEngine {
|
|||||||
mesh.receiveShadows = false;
|
mesh.receiveShadows = false;
|
||||||
mesh.isVisible = false;
|
mesh.isVisible = false;
|
||||||
} else {
|
} else {
|
||||||
//if (mesh.name === '__root__') continue;
|
|
||||||
if (!o.isMainLight && def.receiveShadows !== false) mesh.receiveShadows = true;
|
if (!o.isMainLight && def.receiveShadows !== false) mesh.receiveShadows = true;
|
||||||
if (!o.isMainLight && def.castShadows !== false) {
|
if (!o.isMainLight && def.castShadows !== false) {
|
||||||
this.shadowGenerator1.addShadowCaster(mesh);
|
this.shadowGenerator1.addShadowCaster(mesh);
|
||||||
@@ -991,14 +1015,14 @@ export class RoomEngine {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.highlightedObjectId == null) return;
|
if (this.selectedObjectId == null) return;
|
||||||
|
|
||||||
const highlightedObject = this.objectMeshs.get(this.highlightedObjectId)!;
|
const selectedObject = this.objectMeshs.get(this.selectedObjectId)!;
|
||||||
for (const om of highlightedObject.getChildMeshes()) {
|
for (const om of selectedObject.getChildMeshes()) {
|
||||||
om.renderOutline = false;
|
om.renderOutline = false;
|
||||||
}
|
}
|
||||||
const startDistance = BABYLON.Vector3.Distance(this.camera.position, highlightedObject.position);
|
const startDistance = BABYLON.Vector3.Distance(this.camera.position, selectedObject.position);
|
||||||
const ghost = highlightedObject.clone('ghost', null, false)!;
|
const ghost = selectedObject.clone('ghost', null, false)!;
|
||||||
ghost.metadata = { isGhost: true };
|
ghost.metadata = { isGhost: true };
|
||||||
for (const m of ghost.getChildMeshes()) {
|
for (const m of ghost.getChildMeshes()) {
|
||||||
m.metadata = { isGhost: true };
|
m.metadata = { isGhost: true };
|
||||||
@@ -1021,7 +1045,7 @@ export class RoomEngine {
|
|||||||
soMesh.rotation = soMesh.rotation.subtract(mesh.rotation);
|
soMesh.rotation = soMesh.rotation.subtract(mesh.rotation);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
setStickyParentRecursively(highlightedObject);
|
setStickyParentRecursively(selectedObject);
|
||||||
|
|
||||||
const descendantStickyObjectIds: string[] = [];
|
const descendantStickyObjectIds: string[] = [];
|
||||||
const collectDescendantStickyObjectIds = (parentId: string) => {
|
const collectDescendantStickyObjectIds = (parentId: string) => {
|
||||||
@@ -1031,17 +1055,17 @@ export class RoomEngine {
|
|||||||
collectDescendantStickyObjectIds(cid);
|
collectDescendantStickyObjectIds(cid);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
collectDescendantStickyObjectIds(highlightedObject.metadata.objectId);
|
collectDescendantStickyObjectIds(selectedObject.metadata.objectId);
|
||||||
|
|
||||||
this.grabbing = {
|
this.grabbing = {
|
||||||
objectId: highlightedObject.metadata.objectId,
|
objectId: selectedObject.metadata.objectId,
|
||||||
mesh: highlightedObject,
|
mesh: selectedObject,
|
||||||
startOffset: highlightedObject.position.subtract(this.camera.position.add(this.camera.getDirection(BABYLON.Axis.Z).scale(startDistance))),
|
startOffset: selectedObject.position.subtract(this.camera.position.add(this.camera.getDirection(BABYLON.Axis.Z).scale(startDistance))),
|
||||||
startRotationY: highlightedObject.rotation.subtract(this.camera.rotation).y,
|
startRotationY: selectedObject.rotation.subtract(this.camera.rotation).y,
|
||||||
startDistance: startDistance,
|
startDistance: startDistance,
|
||||||
ghost: ghost,
|
ghost: ghost,
|
||||||
descendantStickyObjectIds,
|
descendantStickyObjectIds,
|
||||||
isMainLight: this.def.objects.find(o => o.id === highlightedObject.metadata.objectId)?.isMainLight ?? false,
|
isMainLight: this.def.objects.find(o => o.id === selectedObject.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