mirror of
https://github.com/misskey-dev/misskey.git
synced 2026-05-26 23:04:16 +02:00
wip: sr in edit mode
This commit is contained in:
@@ -264,7 +264,7 @@ const roomControllerOptions = computed<RoomControllerOptions>(() => ({
|
|||||||
resolution: resolution.value,
|
resolution: resolution.value,
|
||||||
antialias: antialias.value,
|
antialias: antialias.value,
|
||||||
useVirtualJoystick,
|
useVirtualJoystick,
|
||||||
workerMode: true,
|
workerMode: false,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const controller = markRaw(new RoomController(data, roomControllerOptions.value));
|
const controller = markRaw(new RoomController(data, roomControllerOptions.value));
|
||||||
|
|||||||
@@ -198,6 +198,7 @@ export class RoomEngine extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public isSitting = false;
|
public isSitting = false;
|
||||||
|
private inited = false;
|
||||||
private fps: number | null = null;
|
private fps: number | null = null;
|
||||||
private disposed = false;
|
private disposed = false;
|
||||||
|
|
||||||
@@ -477,6 +478,8 @@ export class RoomEngine extends EventEmitter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.inited = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private currentRafId: number | null = null;
|
private currentRafId: number | null = null;
|
||||||
@@ -878,7 +881,18 @@ export class RoomEngine extends EventEmitter {
|
|||||||
|
|
||||||
const objectInstance = await def.createInstance({
|
const objectInstance = await def.createInstance({
|
||||||
scene: this.scene,
|
scene: this.scene,
|
||||||
sr: this.sr,
|
sr: {
|
||||||
|
updateMesh: (mesh) => {
|
||||||
|
if (!this.inited) return;
|
||||||
|
this.sr.updateMesh(mesh);
|
||||||
|
},
|
||||||
|
reset: () => {
|
||||||
|
if (!this.inited) return;
|
||||||
|
this.sr.disableSnapshotRendering();
|
||||||
|
this.sr.enableSnapshotRendering();
|
||||||
|
},
|
||||||
|
fixParticleSystem: (ps) => this.sr.fixParticleSystem(ps),
|
||||||
|
},
|
||||||
lc: this.lightContainer,
|
lc: this.lightContainer,
|
||||||
root,
|
root,
|
||||||
options: args.options,
|
options: args.options,
|
||||||
@@ -981,6 +995,7 @@ export class RoomEngine extends EventEmitter {
|
|||||||
} else if (placement === 'top' || placement === 'floor') {
|
} else if (placement === 'top' || placement === 'floor') {
|
||||||
arrowMesh.scaling = new BABYLON.Vector3(1, -1, 1);
|
arrowMesh.scaling = new BABYLON.Vector3(1, -1, 1);
|
||||||
}
|
}
|
||||||
|
this.sr.updateMesh(arrowMesh);
|
||||||
|
|
||||||
let stickyOtherObject: string | null = null;
|
let stickyOtherObject: string | null = null;
|
||||||
let sticky = false;
|
let sticky = false;
|
||||||
@@ -1031,7 +1046,8 @@ export class RoomEngine extends EventEmitter {
|
|||||||
this.gridPlane.position.y = 0;
|
this.gridPlane.position.y = 0;
|
||||||
this.gridPlane.position.x = 0;
|
this.gridPlane.position.x = 0;
|
||||||
}
|
}
|
||||||
this.gridPlane.isVisible = true;
|
//this.gridPlane.isVisible = true;
|
||||||
|
this.gridPlane.scaling = new BABYLON.Vector3(1, 1, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (placement === 'bottom' || placement === 'ceiling') {
|
} else if (placement === 'bottom' || placement === 'ceiling') {
|
||||||
@@ -1053,7 +1069,8 @@ export class RoomEngine extends EventEmitter {
|
|||||||
this.gridPlane.position = new BABYLON.Vector3(grabbing.mesh.position.x, grabbing.mesh.position.y - cm(0.1), grabbing.mesh.position.z);
|
this.gridPlane.position = new BABYLON.Vector3(grabbing.mesh.position.x, grabbing.mesh.position.y - cm(0.1), grabbing.mesh.position.z);
|
||||||
this.gridPlane.position.x = 0;
|
this.gridPlane.position.x = 0;
|
||||||
this.gridPlane.position.z = 0;
|
this.gridPlane.position.z = 0;
|
||||||
this.gridPlane.isVisible = true;
|
//this.gridPlane.isVisible = true;
|
||||||
|
this.gridPlane.scaling = new BABYLON.Vector3(1, 1, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else { // top or floor
|
} else { // top or floor
|
||||||
@@ -1075,7 +1092,8 @@ export class RoomEngine extends EventEmitter {
|
|||||||
this.gridPlane.position = new BABYLON.Vector3(grabbing.mesh.position.x, grabbing.mesh.position.y + cm(0.1), grabbing.mesh.position.z);
|
this.gridPlane.position = new BABYLON.Vector3(grabbing.mesh.position.x, grabbing.mesh.position.y + cm(0.1), grabbing.mesh.position.z);
|
||||||
this.gridPlane.position.x = 0;
|
this.gridPlane.position.x = 0;
|
||||||
this.gridPlane.position.z = 0;
|
this.gridPlane.position.z = 0;
|
||||||
this.gridPlane.isVisible = true;
|
//this.gridPlane.isVisible = true;
|
||||||
|
this.gridPlane.scaling = new BABYLON.Vector3(1, 1, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1093,10 +1111,14 @@ export class RoomEngine extends EventEmitter {
|
|||||||
|
|
||||||
grabbing.mesh.position = newPos;
|
grabbing.mesh.position = newPos;
|
||||||
grabbing.mesh.rotation = newRotation;
|
grabbing.mesh.rotation = newRotation;
|
||||||
|
|
||||||
|
this.sr.updateMesh(grabbing.mesh.getChildMeshes());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sticky) {
|
if (!sticky) {
|
||||||
this.gridPlane.isVisible = false;
|
//this.gridPlane.isVisible = false;
|
||||||
|
this.gridPlane.scaling = new BABYLON.Vector3(0, 0, 0);
|
||||||
|
|
||||||
//for (const mesh of grabbing.ghost.getChildMeshes()) {
|
//for (const mesh of grabbing.ghost.getChildMeshes()) {
|
||||||
//if (mesh.material instanceof BABYLON.MultiMaterial) {
|
//if (mesh.material instanceof BABYLON.MultiMaterial) {
|
||||||
// for (const subMat of mesh.material.subMaterials) {
|
// for (const subMat of mesh.material.subMaterials) {
|
||||||
@@ -1110,6 +1132,8 @@ export class RoomEngine extends EventEmitter {
|
|||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.sr.updateMesh(this.gridPlane);
|
||||||
|
|
||||||
//const pos = new BABYLON.Vector3(this.camera.position.x, this.camera.position.y, this.camera.position.z);
|
//const pos = new BABYLON.Vector3(this.camera.position.x, this.camera.position.y, this.camera.position.z);
|
||||||
//const _dir = newPos.subtract(pos).normalize();
|
//const _dir = newPos.subtract(pos).normalize();
|
||||||
//for (let i = 0; i < grabbing.distance; i++) {
|
//for (let i = 0; i < grabbing.distance; i++) {
|
||||||
@@ -1241,6 +1265,7 @@ export class RoomEngine extends EventEmitter {
|
|||||||
sticky = info.sticky;
|
sticky = info.sticky;
|
||||||
},
|
},
|
||||||
onCancel: () => {
|
onCancel: () => {
|
||||||
|
this.sr.disableSnapshotRendering();
|
||||||
selectedObject.position = initialPosition.clone();
|
selectedObject.position = initialPosition.clone();
|
||||||
selectedObject.rotation = initialRotation.clone();
|
selectedObject.rotation = initialRotation.clone();
|
||||||
|
|
||||||
@@ -1255,6 +1280,7 @@ export class RoomEngine extends EventEmitter {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
removeStickyParentRecursively(selectedObject);
|
removeStickyParentRecursively(selectedObject);
|
||||||
|
this.sr.enableSnapshotRendering();
|
||||||
},
|
},
|
||||||
onDone: () => { // todo: sticky状態などを引数でもらうようにしたい
|
onDone: () => { // todo: sticky状態などを引数でもらうようにしたい
|
||||||
this.putParticleSystem.emitter = selectedObject.position.clone();
|
this.putParticleSystem.emitter = selectedObject.position.clone();
|
||||||
@@ -1265,6 +1291,8 @@ export class RoomEngine extends EventEmitter {
|
|||||||
playbackRate: 1,
|
playbackRate: 1,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.sr.disableSnapshotRendering();
|
||||||
|
|
||||||
// put animation
|
// put animation
|
||||||
const animTarget = new BABYLON.Animation(
|
const animTarget = new BABYLON.Animation(
|
||||||
'',
|
'',
|
||||||
@@ -1284,9 +1312,11 @@ export class RoomEngine extends EventEmitter {
|
|||||||
selectedObject.animations.push(animTarget);
|
selectedObject.animations.push(animTarget);
|
||||||
const animating = Promise.withResolvers<void>();
|
const animating = Promise.withResolvers<void>();
|
||||||
this.scene.beginAnimation(selectedObject, 0, 60, false, 3, () => { animating.resolve(); });
|
this.scene.beginAnimation(selectedObject, 0, 60, false, 3, () => { animating.resolve(); });
|
||||||
|
this.sr.enableSnapshotRendering();
|
||||||
|
|
||||||
// TODO: アニメーションの完了まで親子関係の解除を遅延するため、一瞬「grabbingが終わっているのに親子関係が解除されていない」状態が発生する。その間に新たにgrabbingを開始するなどの別の操作が発生すると不具合のもとになるのでそれを防止する仕組みを作る
|
// TODO: アニメーションの完了まで親子関係の解除を遅延するため、一瞬「grabbingが終わっているのに親子関係が解除されていない」状態が発生する。その間に新たにgrabbingを開始するなどの別の操作が発生すると不具合のもとになるのでそれを防止する仕組みを作る
|
||||||
animating.promise.then(() => {
|
animating.promise.then(() => {
|
||||||
|
this.sr.disableSnapshotRendering();
|
||||||
// 親から先に外していく
|
// 親から先に外していく
|
||||||
const removeStickyParentRecursively = (mesh: BABYLON.Mesh) => {
|
const removeStickyParentRecursively = (mesh: BABYLON.Mesh) => {
|
||||||
const stickyObjectIds = Array.from(this.roomState.installedObjects.filter(o => o.sticky === mesh.metadata.objectId)).map(o => o.id);
|
const stickyObjectIds = Array.from(this.roomState.installedObjects.filter(o => o.sticky === mesh.metadata.objectId)).map(o => o.id);
|
||||||
@@ -1303,6 +1333,7 @@ export class RoomEngine extends EventEmitter {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
removeStickyParentRecursively(selectedObject);
|
removeStickyParentRecursively(selectedObject);
|
||||||
|
this.sr.enableSnapshotRendering();
|
||||||
|
|
||||||
const pos = selectedObject.position.clone();
|
const pos = selectedObject.position.clone();
|
||||||
const rotation = selectedObject.rotation.clone();
|
const rotation = selectedObject.rotation.clone();
|
||||||
@@ -1315,6 +1346,8 @@ export class RoomEngine extends EventEmitter {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.gridPlane.isVisible = true;
|
||||||
|
|
||||||
this.timer.setInterval(() => {
|
this.timer.setInterval(() => {
|
||||||
this.handleGrabbing();
|
this.handleGrabbing();
|
||||||
}, 10);
|
}, 10);
|
||||||
@@ -1481,6 +1514,8 @@ export class RoomEngine extends EventEmitter {
|
|||||||
playbackRate: 1,
|
playbackRate: 1,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.sr.disableSnapshotRendering();
|
||||||
|
|
||||||
// put animation
|
// put animation
|
||||||
const animTarget = new BABYLON.Animation(
|
const animTarget = new BABYLON.Animation(
|
||||||
'',
|
'',
|
||||||
@@ -1500,6 +1535,8 @@ export class RoomEngine extends EventEmitter {
|
|||||||
root.animations.push(animTarget);
|
root.animations.push(animTarget);
|
||||||
this.scene.beginAnimation(root, 0, 60, false, 3);
|
this.scene.beginAnimation(root, 0, 60, false, 3);
|
||||||
|
|
||||||
|
this.sr.enableSnapshotRendering();
|
||||||
|
|
||||||
this.roomState.installedObjects.push({
|
this.roomState.installedObjects.push({
|
||||||
id,
|
id,
|
||||||
type,
|
type,
|
||||||
@@ -1513,6 +1550,8 @@ export class RoomEngine extends EventEmitter {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.gridPlane.isVisible = true;
|
||||||
|
|
||||||
this.timer.setInterval(() => {
|
this.timer.setInterval(() => {
|
||||||
this.handleGrabbing();
|
this.handleGrabbing();
|
||||||
}, 10);
|
}, 10);
|
||||||
@@ -1530,13 +1569,14 @@ export class RoomEngine extends EventEmitter {
|
|||||||
entity.instance.resetTemporaryState?.();
|
entity.instance.resetTemporaryState?.();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.sr.disableSnapshotRendering();
|
|
||||||
//if (this.gl != null) {
|
//if (this.gl != null) {
|
||||||
// this.gl.isEnabled = false; // 重いので切る
|
// this.gl.isEnabled = false; // 重いので切る
|
||||||
//}
|
//}
|
||||||
|
|
||||||
if (this.gridPlane.material == null) {
|
if (this.gridPlane.material == null) {
|
||||||
import('@babylonjs/materials').then(m => {
|
import('@babylonjs/materials').then(m => {
|
||||||
|
this.sr.disableSnapshotRendering();
|
||||||
|
|
||||||
this.gridMaterial = new m.GridMaterial('grid', this.scene);
|
this.gridMaterial = new m.GridMaterial('grid', this.scene);
|
||||||
this.gridMaterial.lineColor = new BABYLON.Color3(0.5, 0.5, 0.5);
|
this.gridMaterial.lineColor = new BABYLON.Color3(0.5, 0.5, 0.5);
|
||||||
this.gridMaterial.mainColor = new BABYLON.Color3(0, 0, 0);
|
this.gridMaterial.mainColor = new BABYLON.Color3(0, 0, 0);
|
||||||
@@ -1548,6 +1588,8 @@ export class RoomEngine extends EventEmitter {
|
|||||||
|
|
||||||
this.gridPlane.material = this.gridMaterial;
|
this.gridPlane.material = this.gridMaterial;
|
||||||
this.gridPlane.setEnabled(true);
|
this.gridPlane.setEnabled(true);
|
||||||
|
|
||||||
|
this.sr.enableSnapshotRendering();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1558,7 +1600,6 @@ export class RoomEngine extends EventEmitter {
|
|||||||
|
|
||||||
await this.bake();
|
await this.bake();
|
||||||
|
|
||||||
this.sr.enableSnapshotRendering();
|
|
||||||
//if (this.gl != null) {
|
//if (this.gl != null) {
|
||||||
// this.gl.isEnabled = true;
|
// this.gl.isEnabled = true;
|
||||||
//}
|
//}
|
||||||
|
|||||||
@@ -113,7 +113,13 @@ export type ObjectDef<OpSc extends OptionsSchema = OptionsSchema> = {
|
|||||||
treatLoaderResult?: (loaderResult: BABYLON.AssetContainer) => void;
|
treatLoaderResult?: (loaderResult: BABYLON.AssetContainer) => void;
|
||||||
createInstance: (args: {
|
createInstance: (args: {
|
||||||
scene: BABYLON.Scene;
|
scene: BABYLON.Scene;
|
||||||
sr: BABYLON.SnapshotRenderingHelper;
|
// TODO: snapshot renderingの関心を隠蔽した方が綺麗かもしれない
|
||||||
|
// 例えばmaterialUpdatedというメソッドを用意して内部的にresetを呼ぶなど
|
||||||
|
sr: {
|
||||||
|
updateMesh: (meshes: BABYLON.Mesh[]) => void;
|
||||||
|
reset: () => void;
|
||||||
|
fixParticleSystem: (ps: BABYLON.ParticleSystem) => void;
|
||||||
|
};
|
||||||
lc: BABYLON.ClusteredLightContainer | null;
|
lc: BABYLON.ClusteredLightContainer | null;
|
||||||
root: BABYLON.Mesh;
|
root: BABYLON.Mesh;
|
||||||
options: Readonly<GetOptionsSchemaValues<OpSc>>;
|
options: Readonly<GetOptionsSchemaValues<OpSc>>;
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ export const laptopPc = defineObject({
|
|||||||
placement: 'top',
|
placement: 'top',
|
||||||
hasCollisions: false,
|
hasCollisions: false,
|
||||||
hasTexture: true,
|
hasTexture: true,
|
||||||
createInstance: async ({ lc, scene, options, model, graphicsQuality }) => {
|
createInstance: async ({ lc, sr, scene, options, model, graphicsQuality }) => {
|
||||||
const matrix = model.root.getWorldMatrix(true);
|
const matrix = model.root.getWorldMatrix(true);
|
||||||
const scale = new BABYLON.Vector3();
|
const scale = new BABYLON.Vector3();
|
||||||
matrix.decompose(scale);
|
matrix.decompose(scale);
|
||||||
@@ -131,11 +131,13 @@ export const laptopPc = defineObject({
|
|||||||
const applyBodyColor = () => {
|
const applyBodyColor = () => {
|
||||||
const [r, g, b] = options.bodyColor;
|
const [r, g, b] = options.bodyColor;
|
||||||
bodyMaterial.albedoColor = new BABYLON.Color3(r, g, b);
|
bodyMaterial.albedoColor = new BABYLON.Color3(r, g, b);
|
||||||
|
sr.reset();
|
||||||
};
|
};
|
||||||
|
|
||||||
const applyBezelColor = () => {
|
const applyBezelColor = () => {
|
||||||
const [r, g, b] = options.bezelColor;
|
const [r, g, b] = options.bezelColor;
|
||||||
bezelMaterial.albedoColor = new BABYLON.Color3(r, g, b);
|
bezelMaterial.albedoColor = new BABYLON.Color3(r, g, b);
|
||||||
|
sr.reset();
|
||||||
};
|
};
|
||||||
|
|
||||||
applyBodyColor();
|
applyBodyColor();
|
||||||
@@ -151,6 +153,7 @@ export const laptopPc = defineObject({
|
|||||||
light.intensity = (2 * options.screenBrightness) * WORLD_SCALE * WORLD_SCALE;
|
light.intensity = (2 * options.screenBrightness) * WORLD_SCALE * WORLD_SCALE;
|
||||||
}
|
}
|
||||||
model.updated();
|
model.updated();
|
||||||
|
sr.updateMesh(hutaNode.getChildMeshes());
|
||||||
};
|
};
|
||||||
|
|
||||||
applyOpenAngle();
|
applyOpenAngle();
|
||||||
|
|||||||
@@ -332,7 +332,16 @@ export class RoomObjectPreviewEngine {
|
|||||||
|
|
||||||
const objectInstance = await def.createInstance({
|
const objectInstance = await def.createInstance({
|
||||||
scene: this.scene,
|
scene: this.scene,
|
||||||
sr: this.sr,
|
sr: {
|
||||||
|
updateMesh: (mesh) => {
|
||||||
|
this.sr.updateMesh(mesh);
|
||||||
|
},
|
||||||
|
reset: () => {
|
||||||
|
this.sr.disableSnapshotRendering();
|
||||||
|
this.sr.enableSnapshotRendering();
|
||||||
|
},
|
||||||
|
fixParticleSystem: (ps) => this.sr.fixParticleSystem(ps),
|
||||||
|
},
|
||||||
root,
|
root,
|
||||||
options: args.options,
|
options: args.options,
|
||||||
model,
|
model,
|
||||||
|
|||||||
Reference in New Issue
Block a user