mirror of
https://github.com/misskey-dev/misskey.git
synced 2026-05-18 16:35:30 +02:00
wip
This commit is contained in:
@@ -883,6 +883,7 @@ export class RoomEngine extends EventEmitter {
|
|||||||
const objectInstance = await def.createInstance({
|
const objectInstance = await def.createInstance({
|
||||||
room: this,
|
room: this,
|
||||||
scene: this.scene,
|
scene: this.scene,
|
||||||
|
sr: this.sr,
|
||||||
root,
|
root,
|
||||||
options: args.options,
|
options: args.options,
|
||||||
model,
|
model,
|
||||||
|
|||||||
@@ -114,6 +114,7 @@ export type ObjectDef<OpSc extends OptionsSchema = OptionsSchema> = {
|
|||||||
createInstance: (args: {
|
createInstance: (args: {
|
||||||
room?: RoomEngine | null;
|
room?: RoomEngine | null;
|
||||||
scene: BABYLON.Scene;
|
scene: BABYLON.Scene;
|
||||||
|
sr: BABYLON.SnapshotRenderingHelper;
|
||||||
root: BABYLON.Mesh;
|
root: BABYLON.Mesh;
|
||||||
options: Readonly<GetOptionsSchemaValues<OpSc>>;
|
options: Readonly<GetOptionsSchemaValues<OpSc>>;
|
||||||
model: ModelManager;
|
model: ModelManager;
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ export const ceilingFanLight = defineObject({
|
|||||||
hasCollisions: false,
|
hasCollisions: false,
|
||||||
receiveShadows: false,
|
receiveShadows: false,
|
||||||
castShadows: false,
|
castShadows: false,
|
||||||
createInstance: ({ options, room, scene, model }) => {
|
createInstance: ({ options, sr, scene, model }) => {
|
||||||
const shadeMaterial = model.findMaterial('__X_SHADE__');
|
const shadeMaterial = model.findMaterial('__X_SHADE__');
|
||||||
|
|
||||||
const applyShadeColor = () => {
|
const applyShadeColor = () => {
|
||||||
@@ -49,7 +49,7 @@ export const ceilingFanLight = defineObject({
|
|||||||
]);
|
]);
|
||||||
rotor.animations = [anim];
|
rotor.animations = [anim];
|
||||||
animationObserver = scene.onAfterAnimationsObservable.add(() => {
|
animationObserver = scene.onAfterAnimationsObservable.add(() => {
|
||||||
room?.sr.updateMesh([rotor, ...rotor.getChildMeshes()], false);
|
sr.updateMesh([rotor, ...rotor.getChildMeshes()], false);
|
||||||
});
|
});
|
||||||
scene.beginAnimation(rotor, 0, 100, true);
|
scene.beginAnimation(rotor, 0, 100, true);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ export const lavaLamp = defineObject({
|
|||||||
placement: 'top',
|
placement: 'top',
|
||||||
hasCollisions: false,
|
hasCollisions: false,
|
||||||
canPreMeshesMerging: true,
|
canPreMeshesMerging: true,
|
||||||
createInstance: ({ options, room, scene, root, model, graphicsQuality }) => {
|
createInstance: ({ options, room, scene, sr, root, model, graphicsQuality }) => {
|
||||||
const bodyMaterial = model.findMaterial('__X_BODY__');
|
const bodyMaterial = model.findMaterial('__X_BODY__');
|
||||||
const glassMaterial = model.findMaterial('__X_GLASS__');
|
const glassMaterial = model.findMaterial('__X_GLASS__');
|
||||||
const lightMaterial = model.findMaterial('__X_LIGHT__');
|
const lightMaterial = model.findMaterial('__X_LIGHT__');
|
||||||
@@ -111,7 +111,7 @@ export const lavaLamp = defineObject({
|
|||||||
scene.beginAnimation(sphere3, 0, 800, true, 0.6);
|
scene.beginAnimation(sphere3, 0, 800, true, 0.6);
|
||||||
|
|
||||||
animationObserver = scene.onAfterAnimationsObservable.add(() => {
|
animationObserver = scene.onAfterAnimationsObservable.add(() => {
|
||||||
room?.sr.updateMesh([sphere, sphere2, sphere3], false);
|
sr.updateMesh([sphere, sphere2, sphere3], false);
|
||||||
});
|
});
|
||||||
|
|
||||||
const emitter = new BABYLON.TransformNode('emitter', scene);
|
const emitter = new BABYLON.TransformNode('emitter', scene);
|
||||||
@@ -139,7 +139,7 @@ export const lavaLamp = defineObject({
|
|||||||
ps.preWarmCycles = 100;
|
ps.preWarmCycles = 100;
|
||||||
ps.start();
|
ps.start();
|
||||||
|
|
||||||
room?.sr.fixParticleSystem(ps);
|
sr.fixParticleSystem(ps);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
onInited: () => {
|
onInited: () => {
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export const radiometer = defineObject({
|
|||||||
},
|
},
|
||||||
placement: 'top',
|
placement: 'top',
|
||||||
hasCollisions: false,
|
hasCollisions: false,
|
||||||
createInstance: ({ room, scene, model }) => {
|
createInstance: ({ sr, scene, model }) => {
|
||||||
const vanes = model.findTransformNode('__X_VANES__');
|
const vanes = model.findTransformNode('__X_VANES__');
|
||||||
model.bakeExcludeMeshes = [...vanes.getChildMeshes()];
|
model.bakeExcludeMeshes = [...vanes.getChildMeshes()];
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@ export const radiometer = defineObject({
|
|||||||
]);
|
]);
|
||||||
vanes.animations = [anim];
|
vanes.animations = [anim];
|
||||||
animationObserver = scene.onAfterAnimationsObservable.add(() => {
|
animationObserver = scene.onAfterAnimationsObservable.add(() => {
|
||||||
room?.sr.updateMesh([...vanes.getChildMeshes()], true);
|
sr.updateMesh([...vanes.getChildMeshes()], true);
|
||||||
});
|
});
|
||||||
scene.beginAnimation(vanes, 0, 240, true);
|
scene.beginAnimation(vanes, 0, 240, true);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ export const tabletopDigitalClock = defineObject({
|
|||||||
placement: 'top',
|
placement: 'top',
|
||||||
hasCollisions: false,
|
hasCollisions: false,
|
||||||
canPreMeshesMerging: false,
|
canPreMeshesMerging: false,
|
||||||
createInstance: ({ root, room, options, model, scene, timer }) => {
|
createInstance: ({ sr, options, model, timer }) => {
|
||||||
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);
|
||||||
@@ -123,7 +123,7 @@ export const tabletopDigitalClock = defineObject({
|
|||||||
mesh.position.y = isVisible ? defaultSegMeshDepth : defaultSegMeshDepth - (cm(2) / Math.abs(scale.y));
|
mesh.position.y = isVisible ? defaultSegMeshDepth : defaultSegMeshDepth - (cm(2) / Math.abs(scale.y));
|
||||||
}
|
}
|
||||||
|
|
||||||
room?.sr.updateMesh([...Object.values(segmentMeshes), ...colonMeshes]);
|
sr.updateMesh([...Object.values(segmentMeshes), ...colonMeshes]);
|
||||||
}, 1000);
|
}, 1000);
|
||||||
},
|
},
|
||||||
onOptionsUpdated: ([k, v]) => {
|
onOptionsUpdated: ([k, v]) => {
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ export const wallClock = defineObject({
|
|||||||
},
|
},
|
||||||
placement: 'side',
|
placement: 'side',
|
||||||
hasCollisions: false,
|
hasCollisions: false,
|
||||||
createInstance: ({ room, timer, options, model }) => {
|
createInstance: ({ sr, timer, options, model }) => {
|
||||||
const hourHand = model.findMesh('HandH');
|
const hourHand = model.findMesh('HandH');
|
||||||
const minuteHand = model.findMesh('HandM');
|
const minuteHand = model.findMesh('HandM');
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ export const wallClock = defineObject({
|
|||||||
const mAngle = -(minutes / 60) * Math.PI * 2;
|
const mAngle = -(minutes / 60) * Math.PI * 2;
|
||||||
hourHand.rotation = new BABYLON.Vector3(0, 0, hAngle);
|
hourHand.rotation = new BABYLON.Vector3(0, 0, hAngle);
|
||||||
minuteHand.rotation = new BABYLON.Vector3(0, 0, mAngle);
|
minuteHand.rotation = new BABYLON.Vector3(0, 0, mAngle);
|
||||||
room?.sr.updateMesh([hourHand, minuteHand], false);
|
sr.updateMesh([hourHand, minuteHand], false);
|
||||||
}, 1000);
|
}, 1000);
|
||||||
},
|
},
|
||||||
onOptionsUpdated: ([k, v]) => {
|
onOptionsUpdated: ([k, v]) => {
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ export class RoomObjectPreviewEngine {
|
|||||||
private canvas: HTMLCanvasElement;
|
private canvas: HTMLCanvasElement;
|
||||||
private engine: BABYLON.WebGPUEngine;
|
private engine: BABYLON.WebGPUEngine;
|
||||||
private scene: BABYLON.Scene;
|
private scene: BABYLON.Scene;
|
||||||
|
private sr: BABYLON.SnapshotRenderingHelper;
|
||||||
private shadowGenerator: BABYLON.ShadowGenerator;
|
private shadowGenerator: BABYLON.ShadowGenerator;
|
||||||
private camera: BABYLON.ArcRotateCamera;
|
private camera: BABYLON.ArcRotateCamera;
|
||||||
private objectMesh: BABYLON.Mesh | null = null;
|
private objectMesh: BABYLON.Mesh | null = null;
|
||||||
@@ -50,10 +51,11 @@ export class RoomObjectPreviewEngine {
|
|||||||
|
|
||||||
this.engine = options.engine;
|
this.engine = options.engine;
|
||||||
this.scene = new BABYLON.Scene(this.engine);
|
this.scene = new BABYLON.Scene(this.engine);
|
||||||
this.scene.clearColor = new BABYLON.Color4(0, 0, 0, 0);
|
this.scene.autoClear = false;
|
||||||
this.scene.autoClear = true;
|
|
||||||
this.scene.skipPointerMovePicking = true;
|
this.scene.skipPointerMovePicking = true;
|
||||||
|
|
||||||
|
this.sr = new BABYLON.SnapshotRenderingHelper(this.scene);
|
||||||
|
|
||||||
this.camera = new BABYLON.ArcRotateCamera('camera', -Math.PI / 2, Math.PI / 2.5, cm(300), new BABYLON.Vector3(0, cm(90), 0), this.scene);
|
this.camera = new BABYLON.ArcRotateCamera('camera', -Math.PI / 2, Math.PI / 2.5, cm(300), new BABYLON.Vector3(0, cm(90), 0), this.scene);
|
||||||
|
|
||||||
this.envMapIndoor = BABYLON.CubeTexture.CreateFromPrefilteredData('/client-assets/room/indoor.env', this.scene);
|
this.envMapIndoor = BABYLON.CubeTexture.CreateFromPrefilteredData('/client-assets/room/indoor.env', this.scene);
|
||||||
@@ -95,6 +97,7 @@ export class RoomObjectPreviewEngine {
|
|||||||
});
|
});
|
||||||
gl.intensity = 0.5;
|
gl.intensity = 0.5;
|
||||||
this.scene.setRenderingAutoClearDepthStencil(gl.renderingGroupId, false);
|
this.scene.setRenderingAutoClearDepthStencil(gl.renderingGroupId, false);
|
||||||
|
this.sr.updateMeshesForEffectLayer(gl);
|
||||||
|
|
||||||
this.pipeline = new BABYLON.DefaultRenderingPipeline('default', true, this.scene);
|
this.pipeline = new BABYLON.DefaultRenderingPipeline('default', true, this.scene);
|
||||||
this.pipeline.samples = 4;
|
this.pipeline.samples = 4;
|
||||||
@@ -188,10 +191,12 @@ export class RoomObjectPreviewEngine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async init() {
|
public async init() {
|
||||||
// 特になし
|
await this.scene.whenReadyAsync();
|
||||||
|
this.sr.enableSnapshotRendering();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async load(type: string) {
|
public async load(type: string) {
|
||||||
|
this.sr.disableSnapshotRendering();
|
||||||
this.clear();
|
this.clear();
|
||||||
|
|
||||||
const id = genId();
|
const id = genId();
|
||||||
@@ -254,6 +259,8 @@ export class RoomObjectPreviewEngine {
|
|||||||
|
|
||||||
this.pipeline.addCamera(this.camera);
|
this.pipeline.addCamera(this.camera);
|
||||||
|
|
||||||
|
this.sr.enableSnapshotRendering();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id,
|
id,
|
||||||
objectInstance: this.objectInstance,
|
objectInstance: this.objectInstance,
|
||||||
@@ -317,6 +324,10 @@ export class RoomObjectPreviewEngine {
|
|||||||
const model = new ModelManager(subRoot, loaderResult.meshes.filter(m => !m.isDisposed() && m !== subRoot), def.hasTexture, (meshes) => {
|
const model = new ModelManager(subRoot, loaderResult.meshes.filter(m => !m.isDisposed() && m !== subRoot), def.hasTexture, (meshes) => {
|
||||||
updateMeshes(meshes);
|
updateMeshes(meshes);
|
||||||
});
|
});
|
||||||
|
//model.updatedCallback = () => {
|
||||||
|
// this.sr.disableSnapshotRendering();
|
||||||
|
// this.sr.enableSnapshotRendering();
|
||||||
|
//};
|
||||||
|
|
||||||
updateMeshes(subRoot.getChildMeshes());
|
updateMeshes(subRoot.getChildMeshes());
|
||||||
|
|
||||||
@@ -325,6 +336,7 @@ export class RoomObjectPreviewEngine {
|
|||||||
const objectInstance = await def.createInstance({
|
const objectInstance = await def.createInstance({
|
||||||
room: null,
|
room: null,
|
||||||
scene: this.scene,
|
scene: this.scene,
|
||||||
|
sr: this.sr,
|
||||||
root,
|
root,
|
||||||
options: args.options,
|
options: args.options,
|
||||||
model,
|
model,
|
||||||
@@ -341,12 +353,15 @@ export class RoomObjectPreviewEngine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public updateObjectOption(key: string, value: any) {
|
public updateObjectOption(key: string, value: any) {
|
||||||
|
this.sr.disableSnapshotRendering();
|
||||||
this.objectOptions[key] = value;
|
this.objectOptions[key] = value;
|
||||||
this.objectInstance?.onOptionsUpdated?.([key, value]);
|
this.objectInstance?.onOptionsUpdated?.([key, value]);
|
||||||
|
this.sr.enableSnapshotRendering();
|
||||||
return this.objectOptions;
|
return this.objectOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
public clear() {
|
public clear() {
|
||||||
|
this.sr.disableSnapshotRendering();
|
||||||
if (this.timerForEachObject != null) {
|
if (this.timerForEachObject != null) {
|
||||||
this.timerForEachObject.dispose();
|
this.timerForEachObject.dispose();
|
||||||
this.timerForEachObject = null;
|
this.timerForEachObject = null;
|
||||||
@@ -359,10 +374,20 @@ export class RoomObjectPreviewEngine {
|
|||||||
this.objectMesh = null;
|
this.objectMesh = null;
|
||||||
this.objectType = null;
|
this.objectType = null;
|
||||||
}
|
}
|
||||||
|
this.sr.enableSnapshotRendering();
|
||||||
}
|
}
|
||||||
|
|
||||||
public resize() {
|
public resize() {
|
||||||
|
// 一旦snapshot renderingを無効にしておかないとエラーが出る(babylonのバグ?)
|
||||||
|
// ~~...が、一旦無効にしたらしたで複数のマテリアルがそれぞれ入れ替わる(?)という謎の現象が発生するためコメントアウトしとく(エラー出てもレンダリングが止まったりするわけでもないし)~~
|
||||||
|
// ↑追記: engine.resizeした後に一瞬待つことで回避できることが判明
|
||||||
|
this.sr.disableSnapshotRendering();
|
||||||
this.engine.resize();
|
this.engine.resize();
|
||||||
|
// workerで実行される可能性がある
|
||||||
|
// eslint-disable-next-line no-restricted-globals
|
||||||
|
setTimeout(() => {
|
||||||
|
this.sr.enableSnapshotRendering();
|
||||||
|
}, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public destroy() {
|
public destroy() {
|
||||||
|
|||||||
@@ -203,6 +203,7 @@ export function findMaterial(rootMesh: BABYLON.AbstractMesh, keyword: string, al
|
|||||||
export class ModelManager {
|
export class ModelManager {
|
||||||
public root: BABYLON.Mesh;
|
public root: BABYLON.Mesh;
|
||||||
public bakedCallback: (() => void) | null = null;
|
public bakedCallback: (() => void) | null = null;
|
||||||
|
public updatedCallback: (() => void) | null = null;
|
||||||
public bakeExcludeMeshes: BABYLON.Mesh[] = [];
|
public bakeExcludeMeshes: BABYLON.Mesh[] = [];
|
||||||
private originalMeshes: BABYLON.Mesh[] = [];
|
private originalMeshes: BABYLON.Mesh[] = [];
|
||||||
private bakedMeshes: BABYLON.Mesh[] = [];
|
private bakedMeshes: BABYLON.Mesh[] = [];
|
||||||
@@ -241,6 +242,7 @@ export class ModelManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public updated() {
|
public updated() {
|
||||||
|
this.updatedCallback?.();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bakeMesh() {
|
public bakeMesh() {
|
||||||
|
|||||||
Reference in New Issue
Block a user