mirror of
https://github.com/misskey-dev/misskey.git
synced 2026-05-14 07:35:35 +02:00
wip
This commit is contained in:
@@ -37,6 +37,7 @@ onMounted(() => {
|
|||||||
type: 'cardboard-box2',
|
type: 'cardboard-box2',
|
||||||
position: [120, 31, 50],
|
position: [120, 31, 50],
|
||||||
rotation: [0, 0.1, 0],
|
rotation: [0, 0.1, 0],
|
||||||
|
sticky: 'a',
|
||||||
}, {
|
}, {
|
||||||
id: '1',
|
id: '1',
|
||||||
type: 'cardboard-box',
|
type: 'cardboard-box',
|
||||||
|
|||||||
@@ -240,7 +240,7 @@ export class RoomEngine {
|
|||||||
private camera: BABYLON.UniversalCamera;
|
private camera: BABYLON.UniversalCamera;
|
||||||
private camera2: BABYLON.ArcRotateCamera;
|
private camera2: BABYLON.ArcRotateCamera;
|
||||||
private intervalIds: number[] = [];
|
private intervalIds: number[] = [];
|
||||||
private objects: Map<string, BABYLON.AbstractMesh> = new Map();
|
private objectMeshs: Map<string, BABYLON.AbstractMesh> = new Map();
|
||||||
private grabbing: BABYLON.AbstractMesh | null = null;
|
private grabbing: BABYLON.AbstractMesh | null = null;
|
||||||
private grabbingStartDistance: number | null = null;
|
private grabbingStartDistance: number | null = null;
|
||||||
private grabbingGhost: BABYLON.AbstractMesh | null = null;
|
private grabbingGhost: BABYLON.AbstractMesh | null = null;
|
||||||
@@ -389,17 +389,24 @@ export class RoomEngine {
|
|||||||
const mesh = this.scene.pick(this.scene.pointerX, this.scene.pointerY)?.pickedMesh;
|
const mesh = this.scene.pick(this.scene.pointerX, this.scene.pointerY)?.pickedMesh;
|
||||||
if (mesh != null) {
|
if (mesh != null) {
|
||||||
const oid = mesh.metadata.objectId;
|
const oid = mesh.metadata.objectId;
|
||||||
if (oid != null && this.objects.has(oid)) {
|
if (oid != null && this.objectMeshs.has(oid)) {
|
||||||
const o = this.objects.get(oid)!;
|
const o = this.objectMeshs.get(oid)!;
|
||||||
// focus camera
|
// focus camera
|
||||||
this.camera.setTarget(o.position);
|
this.camera.setTarget(o.position);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.canvas.addEventListener('keypress', (ev) => {
|
||||||
|
if (ev.code === 'KeyE') {
|
||||||
|
ev.preventDefault();
|
||||||
|
ev.stopPropagation();
|
||||||
|
this.grab();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if (_DEV_) {
|
if (_DEV_) {
|
||||||
const axes = new AxesViewer(this.scene, 5);
|
const axes = new AxesViewer(this.scene, 30);
|
||||||
axes.scaleLines = 30;
|
|
||||||
axes.xAxis.position = new BABYLON.Vector3(0, 30, 0);
|
axes.xAxis.position = new BABYLON.Vector3(0, 30, 0);
|
||||||
axes.yAxis.position = new BABYLON.Vector3(0, 30, 0);
|
axes.yAxis.position = new BABYLON.Vector3(0, 30, 0);
|
||||||
axes.zAxis.position = new BABYLON.Vector3(0, 30, 0);
|
axes.zAxis.position = new BABYLON.Vector3(0, 30, 0);
|
||||||
@@ -432,17 +439,17 @@ export class RoomEngine {
|
|||||||
private handleSeeking() {
|
private handleSeeking() {
|
||||||
this.highlightedObjectId = null;
|
this.highlightedObjectId = null;
|
||||||
const ray = new BABYLON.Ray(this.camera.position, this.camera.getDirection(BABYLON.Axis.Z), 1000/*cm*/);
|
const ray = new BABYLON.Ray(this.camera.position, this.camera.getDirection(BABYLON.Axis.Z), 1000/*cm*/);
|
||||||
for (const [id, o] of this.objects.entries()) {
|
for (const [id, o] of this.objectMeshs.entries()) {
|
||||||
for (const om of o.getChildMeshes()) {
|
for (const om of o.getChildMeshes()) {
|
||||||
om.renderOutline = false;
|
om.renderOutline = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const hit = this.scene.pickWithRay(ray)!;
|
const hit = this.scene.pickWithRay(ray)!;
|
||||||
if (hit.pickedMesh != null) {
|
if (hit.pickedMesh != null) {
|
||||||
const oid = hit.pickedMesh.metadata.objectId;
|
const oid = hit.pickedMesh.metadata?.objectId;
|
||||||
if (oid != null && this.objects.has(oid)) {
|
if (oid != null && this.objectMeshs.has(oid)) {
|
||||||
this.highlightedObjectId = oid;
|
this.highlightedObjectId = oid;
|
||||||
const o = this.objects.get(oid)!;
|
const o = this.objectMeshs.get(oid)!;
|
||||||
for (const om of o.getChildMeshes()) {
|
for (const om of o.getChildMeshes()) {
|
||||||
om.renderOutline = true;
|
om.renderOutline = true;
|
||||||
}
|
}
|
||||||
@@ -454,7 +461,10 @@ export class RoomEngine {
|
|||||||
const dir = this.camera.getDirection(BABYLON.Axis.Z);
|
const dir = this.camera.getDirection(BABYLON.Axis.Z);
|
||||||
this.grabbingGhost.position = this.camera.position.add(dir.scale(this.grabbingStartDistance));
|
this.grabbingGhost.position = this.camera.position.add(dir.scale(this.grabbingStartDistance));
|
||||||
|
|
||||||
|
const stickyObjectIds = Array.from(this.def.objects.filter(o => o.sticky === this.grabbing!.metadata.objectId)).map(o => o.id);
|
||||||
|
|
||||||
let y = 0;
|
let y = 0;
|
||||||
|
let sticky = null;
|
||||||
|
|
||||||
for (const rcmb of this.roomCollisionMeshes.filter(m => m.name.startsWith('_COLLISION_FLOOR_'))) {
|
for (const rcmb of this.roomCollisionMeshes.filter(m => m.name.startsWith('_COLLISION_FLOOR_'))) {
|
||||||
const rcb = rcmb.getBoundingInfo().boundingBox;
|
const rcb = rcmb.getBoundingInfo().boundingBox;
|
||||||
@@ -469,7 +479,25 @@ export class RoomEngine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const [id, o] of this.objects.entries().filter(([_id, o]) => o !== this.grabbing)) {
|
const isStickyChild = (parent: BABYLON.AbstractMesh, target: BABYLON.AbstractMesh): boolean => {
|
||||||
|
const stickyObjectIds = Array.from(this.def.objects.filter(o => o.sticky === parent.metadata.objectId)).map(o => o.id);
|
||||||
|
for (const soid of stickyObjectIds) {
|
||||||
|
if (soid === target.metadata.objectId) return true;
|
||||||
|
const soMesh = this.objectMeshs.get(soid)!;
|
||||||
|
if (isStickyChild(soMesh, target)) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
const checkObjectEntries = this.objectMeshs.entries()
|
||||||
|
.filter(([_id, o]) => {
|
||||||
|
if (o === this.grabbing) return false;
|
||||||
|
if (stickyObjectIds.includes(_id)) return false;
|
||||||
|
if (isStickyChild(this.grabbing!, o)) return false;
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const [id, o] of checkObjectEntries) {
|
||||||
for (const om of o.getChildMeshes()) {
|
for (const om of o.getChildMeshes()) {
|
||||||
const omb = om.getBoundingInfo().boundingBox;
|
const omb = om.getBoundingInfo().boundingBox;
|
||||||
for (const tm of this.grabbing.getChildMeshes()) {
|
for (const tm of this.grabbing.getChildMeshes()) {
|
||||||
@@ -478,12 +506,19 @@ export class RoomEngine {
|
|||||||
const topY = omb.maximumWorld.y;
|
const topY = omb.maximumWorld.y;
|
||||||
if (y === 0 || topY > y) {
|
if (y === 0 || topY > y) {
|
||||||
y = topY;
|
y = topY;
|
||||||
|
sticky = id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sticky != null) {
|
||||||
|
this.def.objects.find(o => o.id === this.grabbing!.metadata.objectId)!.sticky = sticky;
|
||||||
|
} else {
|
||||||
|
this.def.objects.find(o => o.id === this.grabbing!.metadata.objectId)!.sticky = null;
|
||||||
|
}
|
||||||
|
|
||||||
this.grabbing.position = this.grabbingGhost.position.clone();
|
this.grabbing.position = this.grabbingGhost.position.clone();
|
||||||
//this.grabbing.position.x = Math.min(Math.max(this.grabbing.position.x, -(this.ROOM_SIZE / 2)), (this.ROOM_SIZE / 2));
|
//this.grabbing.position.x = Math.min(Math.max(this.grabbing.position.x, -(this.ROOM_SIZE / 2)), (this.ROOM_SIZE / 2));
|
||||||
//this.grabbing.position.z = Math.min(Math.max(this.grabbing.position.z, -(this.ROOM_SIZE / 2)), (this.ROOM_SIZE / 2));
|
//this.grabbing.position.z = Math.min(Math.max(this.grabbing.position.z, -(this.ROOM_SIZE / 2)), (this.ROOM_SIZE / 2));
|
||||||
@@ -507,6 +542,12 @@ export class RoomEngine {
|
|||||||
//);
|
//);
|
||||||
//this.grabbing.moveWithCollisions(displacementVector);
|
//this.grabbing.moveWithCollisions(displacementVector);
|
||||||
//this.grabbing.position.y = y;
|
//this.grabbing.position.y = y;
|
||||||
|
|
||||||
|
for (const soid of stickyObjectIds) {
|
||||||
|
//const soMesh = this.objectMeshs.get(soid)!;
|
||||||
|
//const offset = this.grabbing!.position.subtract(soMeshStartPosition);
|
||||||
|
//soMesh.position = this.grabbing!.position.subtract(offset);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async loadEnvModel() {
|
private async loadEnvModel() {
|
||||||
@@ -566,7 +607,7 @@ export class RoomEngine {
|
|||||||
mesh.outlineColor = new BABYLON.Color3(1, 0, 0);
|
mesh.outlineColor = new BABYLON.Color3(1, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.objects.set(id, obj.meshes[0]);
|
this.objectMeshs.set(id, obj.meshes[0]);
|
||||||
|
|
||||||
const objDef = OBJECTS[type];
|
const objDef = OBJECTS[type];
|
||||||
if (objDef != null && objDef.onInit != null) {
|
if (objDef != null && objDef.onInit != null) {
|
||||||
@@ -576,6 +617,17 @@ export class RoomEngine {
|
|||||||
|
|
||||||
public grab() {
|
public grab() {
|
||||||
if (this.grabbing != null) {
|
if (this.grabbing != null) {
|
||||||
|
// 親から先に外していく
|
||||||
|
const removeStickyParentRecursively = (mesh: BABYLON.AbstractMesh) => {
|
||||||
|
const stickyObjectIds = Array.from(this.def.objects.filter(o => o.sticky === mesh.metadata.objectId)).map(o => o.id);
|
||||||
|
for (const soid of stickyObjectIds) {
|
||||||
|
const soMesh = this.objectMeshs.get(soid)!;
|
||||||
|
soMesh.parent = null;
|
||||||
|
soMesh.position = soMesh.position.add(mesh.position);
|
||||||
|
removeStickyParentRecursively(soMesh);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
removeStickyParentRecursively(this.grabbing);
|
||||||
this.grabbing = null;
|
this.grabbing = null;
|
||||||
this.grabbingStartDistance = null;
|
this.grabbingStartDistance = null;
|
||||||
if (this.grabbingGhost != null) {
|
if (this.grabbingGhost != null) {
|
||||||
@@ -585,7 +637,7 @@ export class RoomEngine {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (this.highlightedObjectId == null) return;
|
if (this.highlightedObjectId == null) return;
|
||||||
const highlightedObject = this.objects.get(this.highlightedObjectId)!;
|
const highlightedObject = this.objectMeshs.get(this.highlightedObjectId)!;
|
||||||
this.grabbing = highlightedObject;
|
this.grabbing = highlightedObject;
|
||||||
this.grabbingStartDistance = BABYLON.Vector3.Distance(this.camera.position, highlightedObject.position);
|
this.grabbingStartDistance = BABYLON.Vector3.Distance(this.camera.position, highlightedObject.position);
|
||||||
this.grabbingGhost = highlightedObject.clone('ghost', null, false);
|
this.grabbingGhost = highlightedObject.clone('ghost', null, false);
|
||||||
@@ -598,6 +650,18 @@ export class RoomEngine {
|
|||||||
m.material = mat;
|
m.material = mat;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 子から先に適用していく
|
||||||
|
const setStickyParentRecursively = (mesh: BABYLON.AbstractMesh) => {
|
||||||
|
const stickyObjectIds = Array.from(this.def.objects.filter(o => o.sticky === mesh.metadata.objectId)).map(o => o.id);
|
||||||
|
for (const soid of stickyObjectIds) {
|
||||||
|
const soMesh = this.objectMeshs.get(soid)!;
|
||||||
|
setStickyParentRecursively(soMesh);
|
||||||
|
soMesh.parent = mesh;
|
||||||
|
soMesh.position = soMesh.position.subtract(mesh.position);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
setStickyParentRecursively(this.grabbing);
|
||||||
}
|
}
|
||||||
|
|
||||||
public destroy() {
|
public destroy() {
|
||||||
|
|||||||
Reference in New Issue
Block a user