UNPKG

mylingo3d

Version:

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

134 lines 6.04 kB
import { Object3D, PerspectiveCamera } from "three"; import scene from "../../../engine/scene"; import { onBeforeRender } from "../../../events/onBeforeRender"; import { characterCameraDefaults, characterCameraSchema } from "../../../interface/ICharacterCamera"; import { getSelectionTarget } from "../../../states/useSelectionTarget"; import { getTransformControlsDragging } from "../../../states/useTransformControlsDragging"; import OrbitCameraBase from "../OrbitCameraBase"; import { euler, quaternion } from "../../utils/reusables"; import { getLoadedObject } from "../Loaded"; import getWorldQuaternion from "../../utils/getWorldQuaternion"; import { getEditorModeComputed } from "../../../states/useEditorModeComputed"; import characterCameraPlaced from "./characterCameraPlaced"; import { FAR, NEAR } from "../../../globals"; import { getCentripetal } from "../../../states/useCentripetal"; import applyCentripetalQuaternion from "../../utils/applyCentripetalQuaternion"; import fpsAlpha from "../../utils/fpsAlpha"; export default class CharacterCamera extends OrbitCameraBase { static defaults = characterCameraDefaults; static schema = characterCameraSchema; constructor() { super(new PerspectiveCamera(75, 1, NEAR, FAR)); const midObject3d = (this.midObject3d = new Object3D()); this.outerObject3d.add(midObject3d); midObject3d.add(this.object3d); const cam = this.camera; scene.attach(cam); this.then(() => scene.remove(cam)); this.createEffect(() => { const target = this.targetState.get(); if (!target) return; if ("frustumCulled" in target) target.frustumCulled = false; }, [this.targetState.get]); const followTargetRotation = (target, slerp) => { euler.setFromQuaternion(target.outerObject3d.quaternion); euler.y += Math.PI; if (slerp) { quaternion.setFromEuler(euler); midObject3d.quaternion.slerp(quaternion, fpsAlpha(0.1)); } else midObject3d.setRotationFromEuler(euler); this.updateAngle(); }; const lockTargetRotation = (target, slerp, quat) => { euler.setFromQuaternion(this.midObject3d.quaternion); euler.x = 0; euler.z = 0; euler.y += Math.PI; if (quat) { const innerObject = getLoadedObject(target); quaternion.copy(target.outerObject3d.quaternion); const innerRotationY = innerObject.rotation.y; target.outerObject3d.quaternion.copy(quat); innerObject.rotation.y = euler.y; euler.setFromQuaternion(getWorldQuaternion(innerObject)); innerObject.rotation.y = innerRotationY; target.outerObject3d.quaternion.copy(quaternion); } const placed = characterCameraPlaced.has(target); if (slerp && !placed) { quaternion.setFromEuler(euler); target.outerObject3d.quaternion.slerp(quaternion, fpsAlpha(0.1)); return; } target.outerObject3d.setRotationFromEuler(euler); quat && placed && characterCameraPlaced.delete(target); }; let transformControlRotating = false; this.createEffect(() => { const target = this.targetState.get(); if (!target) return; followTargetRotation(target, false); let [xOld, yOld, zOld] = [0, 0, 0]; const targetMoved = () => { const { x, y, z } = target.outerObject3d.position; const result = x !== xOld || y !== yOld || z !== zOld; [xOld, yOld, zOld] = [x, y, z]; return result; }; const centripetal = getCentripetal(); const handle = onBeforeRender(() => { this.outerObject3d.position.copy(target.outerObject3d.position); const quat = centripetal ? applyCentripetalQuaternion(this) : undefined; if (!this.lockTargetRotation) return; if (this.lockTargetRotation === "follow" || transformControlRotating) { followTargetRotation(target, false); return; } if (this.lockTargetRotation === "dynamic-lock") { targetMoved() && lockTargetRotation(target, true, quat); return; } if (this.lockTargetRotation === "dynamic-follow") { targetMoved() && followTargetRotation(target, true); return; } lockTargetRotation(target, false, quat); }); return () => { handle.cancel(); }; }, [this.targetState.get, getCentripetal]); this.createEffect(() => { const target = this.targetState.get(); const selectionTarget = getSelectionTarget(); const dragging = getTransformControlsDragging(); const mode = getEditorModeComputed(); const rotating = target && target === selectionTarget && dragging && mode === "rotate"; if (!rotating) return; transformControlRotating = true; return () => { transformControlRotating = false; }; }, [ this.targetState.get, getSelectionTarget, getTransformControlsDragging, getEditorModeComputed ]); } lockTargetRotation = true; } //# sourceMappingURL=index.js.map