UNPKG

lingo3d

Version:

Lingo3D is a React/Vue 3d game development framework that ships with a complete visual editor

88 lines 3.67 kB
import { mapRange } from "@lincode/math"; import { Reactive } from "@lincode/reactivity"; import { WebGLRenderTarget, PerspectiveCamera, SpriteMaterial, Sprite } from "three"; import scene from "../engine/scene"; import { onBeforeRender } from "../events/onBeforeRender"; import { NEAR, FAR } from "../globals"; import { getCameraRendered } from "../states/useCameraRendered"; import VisibleObjectManager from "./core/VisibleObjectManager"; import getWorldPosition from "../memo/getWorldPosition"; import getWorldQuaternion from "../memo/getWorldQuaternion"; import { complementQuaternion, diffQuaternions } from "./utils/quaternions"; import { cameraRenderedPtr } from "../pointers/cameraRenderedPtr"; import { rendererPtr } from "../pointers/rendererPtr"; export default class Portal extends VisibleObjectManager { constructor() { const renderTarget = new WebGLRenderTarget(100, 100); const material = new SpriteMaterial({ map: renderTarget.texture }); const mesh = new Sprite(material); super(mesh); const camera = new PerspectiveCamera(75, 1, NEAR, FAR); this.createEffect(() => { const { width, height } = this; renderTarget.setSize(width * 2, height * 2); camera.aspect = width / height; camera.updateProjectionMatrix(); }, [this.refreshState.get]); this.createEffect(() => { const target = this.targetState.get(); if (!target) return; const [cameraRendererd] = cameraRenderedPtr; camera.position.copy(getWorldPosition(target.outerObject3d)); camera.quaternion.copy(getWorldQuaternion(target.outerObject3d)); const handle = onBeforeRender(() => { camera.quaternion.copy(getWorldQuaternion(target.outerObject3d)); camera.position.copy(getWorldPosition(target.outerObject3d)); complementQuaternion(camera.quaternion, diffQuaternions(getWorldQuaternion(cameraRendererd), getWorldQuaternion(this.outerObject3d))); camera.zoom = mapRange(getWorldPosition(cameraRendererd).distanceTo(getWorldPosition(this.outerObject3d)), 0, 1, 0.25, 0.5); camera.updateProjectionMatrix(); // const posDiff = getWorldPosition(cameraRendererd).sub( // getWorldPosition(this.outerObject3d) // ) // camera.translateX(-posDiff.x) // camera.translateY(-posDiff.y) mesh.visible = false; target.outerObject3d.visible = false; rendererPtr[0].setRenderTarget(renderTarget); rendererPtr[0].render(scene, camera); rendererPtr[0].setRenderTarget(null); mesh.visible = true; target.outerObject3d.visible = true; }); return () => { handle.cancel(); }; }, [this.targetState.get, getCameraRendered]); this.then(() => { renderTarget.dispose(); material.dispose(); }); } refreshState = new Reactive({}); get width() { return super.width; } set width(val) { super.width = val; this.refreshState.set({}); } get height() { return super.height; } set height(val) { super.height = val; this.refreshState.set({}); } get depth() { return 0; } set depth(_) { } targetState = new Reactive(undefined); set target(val) { this.targetState.set(val); } } //# sourceMappingURL=Portal.js.map