UNPKG

@needle-tools/engine

Version:

Needle Engine is a web-based runtime for 3D apps. It runs on your machine for development with great integrations into editors like Unity or Blender - and can be deployed onto any device! It is flexible, extensible and networking and XR are built-in.

103 lines 4.21 kB
import { Mathf } from "./engine_math.js"; import { getParam } from "./engine_utils.js"; const $cameraController = "needle:cameraController"; /** Get the camera controller for the given camera (if any) */ export function getCameraController(cam) { return cam[$cameraController]; } /** Set the camera controller for the given camera */ export function setCameraController(cam, cameraController, active) { if (active) cam[$cameraController] = cameraController; else { if (cam[$cameraController] === cameraController) cam[$cameraController] = null; } } const autofit = "needle:autofit"; /** * Used by e.g. getBoundingBox via ContactShadows or OrbitControls when fitting the camera or shadow planes. Objects can be marked to be excluded from bounding box calculations via `setAutoFitEnabled(obj, <bool>)` * @see setAutoFitEnabled * @internal */ export function useForAutoFit(obj) { // if autofit is not defined we assume it may be included if (obj[autofit] === undefined) return true; // otherwise if anything is set except false we assume it should be included return obj[autofit] !== false; } /** * Enable or disable autofitting for the given object. Objects that are 'disabled' will be excluded in getBoundingBox calculations. * This is used by ContactShadows or OrbitControls when fitting the shadow plane or camera to the given objects or scene. * @see useForAutoFit */ export function setAutoFitEnabled(obj, enabled) { obj[autofit] = enabled; } let rendererRect = undefined; const overlapRect = { x: 0, y: 0, width: 0, height: 0 }; const _testTime = 1; const debug = getParam("debugfocusrect"); /** Used internally by the Needle Engine context via 'setFocusRect(<rect>)' */ export function updateCameraFocusRect(focusRect, settings, dt, camera, renderer) { if (focusRect instanceof Element) { if (debug && focusRect instanceof HTMLElement) { focusRect.style.outline = "2px dashed rgba(255, 150, 0, .8)"; } focusRect = focusRect.getBoundingClientRect(); } rendererRect = renderer.domElement.getBoundingClientRect(); const rect = overlapRect; rect.x = focusRect.x; rect.y = focusRect.y; rect.width = focusRect.width; rect.height = focusRect.height; rect.x -= rendererRect.x; rect.y -= rendererRect.y; const sourceWidth = rendererRect.width; const sourceHeight = rendererRect.height; const view = camera.view; // Apply zoom const zoom = settings.zoom; let offsetX = view?.offsetX || 0; let offsetY = view?.offsetY || 0; let width = rendererRect.width; let height = rendererRect.height; width /= zoom; height /= zoom; offsetX = width * (zoom - 1) * .5; offsetY = height * (zoom - 1) * .5; const focusRectCenterX = rect.x + rect.width * .5; const focusRectCenterY = rect.y + rect.height * .5; const rendererCenterX = rendererRect.width * .5; const rendererCenterY = rendererRect.height * .5; const diffx = focusRectCenterX - rendererCenterX; const diffy = focusRectCenterY - rendererCenterY; offsetX -= diffx / zoom; offsetY -= diffy / zoom; if (settings.offsetX !== undefined) { offsetX += settings.offsetX * (rendererRect.width * .5); } if (settings.offsetY !== undefined) { offsetY -= settings.offsetY * (rendererRect.height * .5); } const currentOffsetX = view?.offsetX || offsetX; const currentOffsetY = view?.offsetY || offsetY; offsetX = Mathf.lerp(currentOffsetX, offsetX, dt); offsetY = Mathf.lerp(currentOffsetY, offsetY, dt); const currentWidth = view?.width || sourceWidth; const currentHeight = view?.height || sourceHeight; width = Mathf.lerp(currentWidth, width, dt); height = Mathf.lerp(currentHeight, height, dt); camera.setViewOffset(sourceWidth, sourceHeight, offsetX, offsetY, width, height); camera.updateProjectionMatrix(); if (settings.damping > 0) { settings.damping *= (1.0 - dt); if (settings.damping < 0.01) settings.damping = 0; settings.damping = Math.max(0, settings.damping); } } //# sourceMappingURL=engine_camera.js.map