@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
101 lines (77 loc) • 3.08 kB
JavaScript
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 };
}