UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

101 lines (77 loc) 3.08 kB
import { AmbientLight as ThreeAmbientLight, Box3, DirectionalLight as ThreeDirectionalLight, PerspectiveCamera as ThreePerspectiveCamera, Scene as ThreeScene, Vector3 as ThreeVector3 } from "three"; import Vector3 from "../../../core/geom/Vector3.js"; import { rootObject3DFastMatrixUpdate } from "../ecs/mesh/rootObject3DFastMatrixUpdate.js"; import { camera_compute_distance_to_fit_length } from "../camera/camera_compute_distance_to_fit_length.js"; import { scaleObject3ToBox } from "./ScaleObject3ToBox.js"; import { DEG_TO_RAD } from "../../../core/math/DEG_TO_RAD.js"; import AABB2 from "../../../core/geom/2d/aabb/AABB2.js"; /** * * @param {THREE.OrthographicCamera} camera */ function setShadowCamera(camera) { const sqrt2 = Math.sqrt(2); let sqrt2_2 = sqrt2 / 2; camera.left = -sqrt2_2; camera.right = sqrt2_2; camera.bottom = -sqrt2_2; camera.top = sqrt2_2; } /** * * @param {THREE.Scene} scene */ function setupLights(scene) { const lightKey = new ThreeDirectionalLight(0xffffff, 1); lightKey.position.set(-1, 1, 1); lightKey.castShadow = true; lightKey.shadow.mapSize.set(1024, 1024); setShadowCamera(lightKey.shadow.camera); scene.add(lightKey); const lightHighlight = new ThreeDirectionalLight(0xffffff, 0.50); lightHighlight.position.set(0, 0, 1); scene.add(lightHighlight); const lightFill = new ThreeAmbientLight(0xFFFFFF, 0.5); scene.add(lightFill); } /** * * @param {Mesh} mesh trhee.js mesh * @param {Vector2} size * @param {AABB2} focus * @returns {{scene: Scene, camera: THREE.PerspectiveCamera}} */ export function makeMeshPreviewScene(mesh, size, focus = new AABB2(0, 0, size.x, size.y)) { const scene = new ThreeScene(); setupLights(scene); scaleObject3ToBox(mesh, new Vector3(1, 1, 1), mesh.scale); scene.add(mesh); const camera = new ThreePerspectiveCamera(45, size.x / size.y, 0.1, 10); const bBox = new Box3(); bBox.expandByObject(mesh); const bBoxCenterScaled = new Vector3(); bBoxCenterScaled.copy(bBox.min).add(bBox.max).multiplyScalar(0.5); //center model at 0,0,0 mesh.position.set(0, 0, 0).sub(bBoxCenterScaled); //update transformation matrix rootObject3DFastMatrixUpdate(mesh); //move model to align front of BB with z=0 const focusHeight = (focus.y1 - focus.y0); const fov = camera.fov * DEG_TO_RAD; const distance = bBox.max.z + camera_compute_distance_to_fit_length(focusHeight, fov); const cameraPositionX = focus.x0 + (focus.x1 - focus.x0) / 2 - 0.5; const cameraPositionY = 0.5 - (focus.y0 + (focus.y1 - focus.y0) / 2); camera.position.set(cameraPositionX, cameraPositionY, distance); camera.lookAt(new ThreeVector3(cameraPositionX, cameraPositionY, 0)); //set near and far for camera to capture // camera.near = 0.1; // camera.far = bBox.size.z * mesh.scale.z+distance; return { scene: scene, camera: camera }; }