1
0
mirror of https://github.com/misskey-dev/misskey.git synced 2026-05-25 12:04:04 +02:00
This commit is contained in:
syuilo
2026-04-20 12:17:57 +09:00
parent c3c36b06c2
commit 79a063f692
2 changed files with 59 additions and 47 deletions

View File

@@ -113,6 +113,5 @@ async function cancel() {
width: 100%; width: 100%;
height: 100%; height: 100%;
display: block; display: block;
background: #000;
} }
</style> </style>

View File

@@ -17,7 +17,7 @@ export async function createRoomObjectPreviewEngine(canvas: HTMLCanvasElement) {
//const babylonEngine = new BABYLON.WebGPUEngine(canvas); //const babylonEngine = new BABYLON.WebGPUEngine(canvas);
//babylonEngine.compatibilityMode = false; //babylonEngine.compatibilityMode = false;
//await babylonEngine.initAsync(); //await babylonEngine.initAsync();
const babylonEngine = new BABYLON.Engine(canvas, false, { alpha: false, antialias: false }); const babylonEngine = new BABYLON.Engine(canvas, false, { alpha: true, antialias: false });
return new RoomObjectPreviewEngine({ canvas, engine: babylonEngine }); return new RoomObjectPreviewEngine({ canvas, engine: babylonEngine });
} }
@@ -25,7 +25,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 shadowGenerator1: 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;
private objectInstance: RoomObjectInstance<any> | null = null; private objectInstance: RoomObjectInstance<any> | null = null;
@@ -33,7 +33,8 @@ export class RoomObjectPreviewEngine {
private roomLight: BABYLON.SpotLight; private roomLight: BABYLON.SpotLight;
private zGridPreviewPlane: BABYLON.Mesh; private zGridPreviewPlane: BABYLON.Mesh;
private timerForEachObject: Timer | null = null; private timerForEachObject: Timer | null = null;
private fps = 60; private fps: number | null = null;
private disposed = false;
constructor(options: { constructor(options: {
canvas: HTMLCanvasElement; canvas: HTMLCanvasElement;
@@ -45,41 +46,34 @@ 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 = true;
this.scene.skipPointerMovePicking = true;
this.scene.ambientColor = new BABYLON.Color3(1.0, 0.9, 0.8); 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);
this.envMapIndoor.boundingBoxSize = new BABYLON.Vector3(cm(500), cm(500), cm(500)); this.envMapIndoor.boundingBoxSize = new BABYLON.Vector3(cm(500), cm(500), cm(500));
this.envMapIndoor.level = 0.6;
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.attachControl(this.canvas);
this.camera.minZ = cm(1);
this.camera.maxZ = cm(100000);
this.camera.fov = 0.5;
this.camera.lowerRadiusLimit = cm(50);
this.camera.upperRadiusLimit = cm(1000);
this.camera.useAutoRotationBehavior = true;
this.camera.autoRotationBehavior!.idleRotationSpeed = 0.3;
this.camera.panningSensibility = 0;
//this.camera.mode = BABYLON.Camera.ORTHOGRAPHIC_CAMERA;
this.scene.activeCamera = this.camera;
const ambientLight = new BABYLON.HemisphericLight('ambientLight', new BABYLON.Vector3(0, 1, -0.5), this.scene); const ambientLight = new BABYLON.HemisphericLight('ambientLight', new BABYLON.Vector3(0, 1, -0.5), this.scene);
ambientLight.diffuse = new BABYLON.Color3(1.0, 1.0, 1.0); ambientLight.diffuse = new BABYLON.Color3(1.0, 1.0, 1.0);
ambientLight.intensity = 0.5; ambientLight.intensity = 0.3;
//ambientLight.intensity = 0; //ambientLight.intensity = 0;
this.roomLight = new BABYLON.SpotLight('roomLight', new BABYLON.Vector3(0, cm(249), 0), new BABYLON.Vector3(0, -1, 0), 16, 8, this.scene); this.roomLight = new BABYLON.SpotLight('roomLight', new BABYLON.Vector3(cm(50), cm(249), cm(50)), new BABYLON.Vector3(0, -1, 0), 16, 8, this.scene);
this.roomLight.diffuse = new BABYLON.Color3(1.0, 0.9, 0.8); this.roomLight.diffuse = new BABYLON.Color3(1.0, 0.9, 0.8);
this.roomLight.shadowMinZ = cm(10); this.roomLight.shadowMinZ = cm(10);
this.roomLight.shadowMaxZ = cm(300); this.roomLight.shadowMaxZ = cm(500);
this.roomLight.radius = cm(30);
this.roomLight.intensity = 10 * WORLD_SCALE * WORLD_SCALE;
this.shadowGenerator1 = new BABYLON.ShadowGenerator(4096, this.roomLight); this.shadowGenerator = new BABYLON.ShadowGenerator(1024, this.roomLight);
this.shadowGenerator1.forceBackFacesOnly = true; this.shadowGenerator.forceBackFacesOnly = true;
this.shadowGenerator1.bias = 0.0001; this.shadowGenerator.bias = 0.0001;
this.shadowGenerator1.usePercentageCloserFiltering = true; this.shadowGenerator.usePercentageCloserFiltering = true;
this.shadowGenerator1.filteringQuality = BABYLON.ShadowGenerator.QUALITY_HIGH; this.shadowGenerator.filteringQuality = BABYLON.ShadowGenerator.QUALITY_HIGH;
//this.shadowGenerator1.useContactHardeningShadow = true; this.shadowGenerator.getShadowMap().refreshRate = 60;
const gridMaterial = new GridMaterial('grid', this.scene); const gridMaterial = new GridMaterial('grid', this.scene);
gridMaterial.lineColor = new BABYLON.Color3(0.5, 0.5, 0.5); gridMaterial.lineColor = new BABYLON.Color3(0.5, 0.5, 0.5);
@@ -91,26 +85,33 @@ export class RoomObjectPreviewEngine {
//this.zGridPreviewPlane = BABYLON.MeshBuilder.CreatePlane('zGridPreviewPlane', { width: cm(1000), height: cm(1000) }, this.scene); //this.zGridPreviewPlane = BABYLON.MeshBuilder.CreatePlane('zGridPreviewPlane', { width: cm(1000), height: cm(1000) }, this.scene);
//this.zGridPreviewPlane.material = gridMaterial; //this.zGridPreviewPlane.material = gridMaterial;
//this.zGridPreviewPlane.rotation = new BABYLON.Vector3(Math.PI / 2, 0, 0); //this.zGridPreviewPlane.rotation = new BABYLON.Vector3(Math.PI / 2, 0, 0);
//this.scene.fogMode = BABYLON.Scene.FOGMODE_LINEAR;
//this.scene.fogStart = cm(100);
//this.scene.fogEnd = cm(110);
//this.scene.fogColor = new BABYLON.Color3(0.0, 0.0, 0.0);
} }
public async init() { public async init() {
const frameInterval = 1000 / this.fps; if (this.fps == null) {
let lastTime = performance.now(); this.engine.runRenderLoop(() => {
this.engine.runRenderLoop(() => {
const currentTime = performance.now();
const delta = currentTime - lastTime;
if (delta >= frameInterval) {
this.scene.render(); this.scene.render();
lastTime = currentTime - (delta % frameInterval); });
} } else {
}); let then = 0;
const interval = 1000 / this.fps;
const renderLoop = (timeStamp: number) => {
if (this.disposed) return;
window.requestAnimationFrame(renderLoop);
const delta = timeStamp - then;
if (delta <= interval) return;
then = timeStamp - (delta % interval);
this.engine.beginFrame();
this.scene.render();
this.engine.endFrame();
};
window.requestAnimationFrame(renderLoop);
}
} }
public async load(type: string) { public async load(type: string) {
@@ -120,9 +121,6 @@ export class RoomObjectPreviewEngine {
this.objectMesh!.dispose(); this.objectMesh!.dispose();
} }
// reset camera rotation
this.camera.setPosition(new BABYLON.Vector3(0, cm(90), cm(300)));
const def = getObjectDef(type); const def = getObjectDef(type);
const options = deepClone(def.options.default); const options = deepClone(def.options.default);
@@ -138,6 +136,20 @@ export class RoomObjectPreviewEngine {
// なぜかちょっと待たないとbounding boxのサイズが正しくない // なぜかちょっと待たないとbounding boxのサイズが正しくない
window.setTimeout(() => { window.setTimeout(() => {
const boundingInfo = getMeshesBoundingBox(this.objectMesh!.getChildMeshes().filter(m => m.isEnabled() && m.isVisible)); const boundingInfo = getMeshesBoundingBox(this.objectMesh!.getChildMeshes().filter(m => m.isEnabled() && m.isVisible));
this.camera.dispose();
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.attachControl(this.canvas);
this.camera.minZ = cm(1);
this.camera.maxZ = cm(100000);
this.camera.fov = 0.5;
this.camera.lowerRadiusLimit = cm(50);
this.camera.upperRadiusLimit = cm(1000);
this.camera.useAutoRotationBehavior = true;
this.camera.autoRotationBehavior!.idleRotationSpeed = 0.3;
this.camera.panningSensibility = 0;
//this.camera.mode = BABYLON.Camera.ORTHOGRAPHIC_CAMERA;
this.camera.setTarget(new BABYLON.Vector3(0, boundingInfo.center.y, 0)); this.camera.setTarget(new BABYLON.Vector3(0, boundingInfo.center.y, 0));
if (def.placement === 'wall' || def.placement === 'side') { if (def.placement === 'wall' || def.placement === 'side') {
@@ -210,7 +222,7 @@ export class RoomObjectPreviewEngine {
} else { } else {
if (def.receiveShadows !== false) mesh.receiveShadows = true; if (def.receiveShadows !== false) mesh.receiveShadows = true;
if (def.castShadows !== false) { if (def.castShadows !== false) {
this.shadowGenerator1.addShadowCaster(mesh); this.shadowGenerator.addShadowCaster(mesh);
} }
if (mesh.material) { if (mesh.material) {
@@ -266,5 +278,6 @@ export class RoomObjectPreviewEngine {
this.timerForEachObject.dispose(); this.timerForEachObject.dispose();
} }
this.engine.dispose(); this.engine.dispose();
this.disposed = true;
} }
} }