UNPKG

mylingo3d

Version:

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

321 lines 13.3 kB
import { jsx as _jsx } from "preact/jsx-runtime"; import { last, omit } from "@lincode/utils"; import { Pane } from "tweakpane"; import settings from "../../api/settings"; import mainCamera from "../../engine/mainCamera"; import { setOrbitControls } from "../../states/useOrbitControls"; import { useEffect, useLayoutEffect, useState } from "preact/hooks"; import register from "preact-custom-element"; import { useSelectionTarget, useCameraList, useMultipleSelectionTargets, useCameraStack, useNodeEditor } from "../states"; import { Cancellable } from "@lincode/promiselikes"; import { getSecondaryCamera, setSecondaryCamera } from "../../states/useSecondaryCamera"; import { nonEditorSettings } from "../../api/serializer/types"; import { setupDefaults, setupSchema } from "../../interface/ISetup"; import mainOrbitCamera from "../../engine/mainOrbitCamera"; import getComponentName from "../utils/getComponentName"; import addInputs, { setProgrammatic } from "./addInputs"; import getParams from "./getParams"; import splitObject from "./splitObject"; import { onTransformControls } from "../../events/onTransformControls"; import assignIn from "./assignIn"; import { emitSceneGraphNameChange } from "../../events/onSceneGraphNameChange"; import { dummyDefaults } from "../../interface/IDummy"; import useInit from "../utils/useInit"; import { decreaseEditorMounted, increaseEditorMounted } from "../../states/useEditorMounted"; import useHotkeys from "./useHotkeys"; Object.assign(dummyDefaults, { stride: { x: 0, y: 0 } }); const Editor = () => { const elRef = useInit(); useHotkeys(); useLayoutEffect(() => { window.onbeforeunload = confirmExit; function confirmExit() { return "Are you sure you want to close the current page?"; } mainOrbitCamera.active = true; setOrbitControls(true); settings.gridHelper = true; increaseEditorMounted(); return () => { setOrbitControls(false); settings.gridHelper = false; decreaseEditorMounted(); }; }, []); const [cameraStack] = useCameraStack(); const camera = last(cameraStack); const [selectionTarget] = useSelectionTarget(); const [multipleSelectionTargets] = useMultipleSelectionTargets(); const [cameraList] = useCameraList(); const [pane, setPane] = useState(); const [cameraFolder, setCameraFolder] = useState(); useLayoutEffect(() => { if (!pane || !cameraFolder) return; const mainCameraName = "editor camera"; const options = cameraList.reduce((acc, cam, i) => { acc[i === 0 ? mainCameraName : getComponentName(cam.userData.manager)] = i; return acc; }, {}); const cameraInput = pane.addInput({ camera: cameraList.indexOf(camera) }, "camera", { options }); cameraFolder.add(cameraInput); cameraInput.on("change", ({ value }) => { cameraList[value].userData.manager.active = true; }); const secondaryOptions = { none: 0, ...omit(options, mainCameraName) }; const secondaryCameraInput = pane.addInput({ "secondary camera": cameraList.indexOf(getSecondaryCamera() ?? mainCamera) }, "secondary camera", { options: secondaryOptions }); cameraFolder.add(secondaryCameraInput); secondaryCameraInput.on("change", ({ value }) => setSecondaryCamera(value === 0 ? undefined : cameraList[value])); return () => { cameraInput.dispose(); secondaryCameraInput.dispose(); }; }, [pane, cameraFolder, cameraList, camera]); useEffect(() => { const el = elRef.current; if (!el) return; const pane = new Pane({ container: el }); setPane(pane); setCameraFolder(pane.addFolder({ title: "camera" })); if (!selectionTarget) { const [editorParams, editorRest] = splitObject(omit(getParams(setupSchema, setupDefaults, settings), nonEditorSettings), ["gridHelper", "gridHelperSize"]); addInputs(pane, "editor", settings, setupDefaults, editorParams); const [rendererParams, rendererRest] = splitObject(editorRest, [ "antiAlias", "pixelRatio", "fps", "logarithmicDepth", "pbr" ]); addInputs(pane, "renderer", settings, setupDefaults, rendererParams); const [sceneParams, sceneRest] = splitObject(rendererRest, [ "exposure", "defaultLight", "shadowDistance", "shadowResolution", "shadowBias", "skybox", "texture", "color" ]); addInputs(pane, "lighting & environment", settings, setupDefaults, sceneParams); const [effectsParams, effectsRest] = splitObject(sceneRest, [ "ambientOcclusion", "bloom", "bloomStrength", "bloomRadius", "bloomThreshold", "bokeh", "bokehAperture", "bokehFocus", "bokehMaxBlur", "lensDistortion", "lensIor", "lensBand", "motionBlur", "motionBlurStrength" ]); addInputs(pane, "effects", settings, setupDefaults, effectsParams); const [outlineParams, outlineRest] = splitObject(effectsRest, [ "outlineColor", "outlineHiddenColor", "outlinePattern", "outlinePulse", "outlineStrength", "outlineThickness" ]); addInputs(pane, "outline effect", settings, setupDefaults, outlineParams); const [physicsParams, physicsRest] = splitObject(outlineRest, [ "gravity", "repulsion", "centripetal" ]); addInputs(pane, "physics", settings, setupDefaults, physicsParams); Object.keys(physicsRest).length && addInputs(pane, "settings", settings, setupDefaults, physicsRest); return () => { pane.dispose(); }; } const target = selectionTarget; const handle = new Cancellable(); if (!multipleSelectionTargets.length) { const { schema, defaults, componentName } = target.constructor; const [generalParams, generalRest] = splitObject(omit(getParams(schema, defaults, target), [ "rotation", "innerRotation", "frustumCulled", "minAzimuthAngle", "maxAzimuthAngle" ]), ["name", "id", "physics", "gravity"]); if (generalParams) { const { name: nameInput } = addInputs(pane, "general", target, defaults, generalParams); nameInput?.on("change", () => emitSceneGraphNameChange()); } const [transformParams0, transformRest] = splitObject(generalRest, [ "x", "y", "z", "rotationX", "rotationY", "rotationZ", "scale", "scaleX", "scaleY", "scaleZ", "innerX", "innerY", "innerZ", "innerRotationX", "innerRotationY", "innerRotationZ", "width", "height", "depth" ]); if (transformParams0) { const [innerTransformParams, transformParams] = splitObject(transformParams0, [ "innerX", "innerY", "innerZ", "innerRotationX", "innerRotationY", "innerRotationZ", "width", "height", "depth" ]); addInputs(pane, "transform", target, defaults, transformParams); innerTransformParams && addInputs(pane, "inner transform", target, defaults, innerTransformParams); handle.watch(onTransformControls(() => { setProgrammatic(); assignIn(transformParams, target, [ "x", "y", "z", "rotationX", "rotationY", "rotationZ", "scaleX", "scaleY", "scaleZ" ]); pane.refresh(); })); } const [displayParams, displayRest] = splitObject(transformRest, [ "visible", "innerVisible", "castShadow", "receiveShadow" ]); displayParams && addInputs(pane, "display", target, defaults, displayParams); const [effectsParams, effectsRest] = splitObject(displayRest, [ "bloom", "outline" ]); effectsParams && addInputs(pane, "effects", target, defaults, effectsParams); const [animationParams, animationRest] = splitObject(effectsRest, [ "animation", "animationPaused", "animationRepeat" ]); animationParams && addInputs(pane, "animation", target, defaults, animationParams); const [adjustMaterialParams, adjustMaterialRest] = splitObject(animationRest, [ "metalnessFactor", "roughnessFactor", "opacityFactor", "envFactor", "adjustColor", "reflection", "illumination", "toon" ]); adjustMaterialParams && addInputs(pane, "adjust material", target, defaults, adjustMaterialParams); const [materialParams, materialRest] = splitObject(adjustMaterialRest, [ "fog", "opacity", "color", "texture", "textureRepeat", "textureFlipY", "textureRotation", "videoTexture", "wireframe" ]); materialParams && addInputs(pane, "material", target, defaults, materialParams); const [pbrMaterialParams, pbrMaterialRest] = splitObject(materialRest, [ "metalnessMap", "metalness", "roughnessMap", "roughness", "normalMap", "normalScale", "normalMapType", "bumpMap", "bumpScale", "displacementMap", "displacementScale", "displacementBias", "aoMap", "aoMapIntensity", "lightMap", "lightMapIntensity", "emissiveMap", "emissiveIntensity", "emissiveColor", "emissive", "envMap", "alphaMap" ]); pbrMaterialParams && addInputs(pane, "pbr material", target, defaults, pbrMaterialParams); if (componentName === "dummy") { pbrMaterialRest.stride = { x: target.strideRight, y: -target.strideForward }; const { stride: strideInput } = addInputs(pane, componentName, target, defaults, pbrMaterialRest); strideInput.on("change", ({ value }) => { Object.assign(pbrMaterialRest, { strideForward: -value.y, strideRight: value.x }); pane.refresh(); }); } else if (Object.keys(pbrMaterialRest).length) addInputs(pane, componentName, target, defaults, pbrMaterialRest); } return () => { handle.cancel(); pane.dispose(); }; }, [selectionTarget, multipleSelectionTargets]); return (_jsx("div", { ref: elRef, className: "lingo3d-ui lingo3d-bg", style: { width: 300, height: "100%", overflowY: "scroll" } })); }; const EditorParent = () => { const [nodeEditor] = useNodeEditor(); if (nodeEditor) return null; return _jsx(Editor, {}); }; export default EditorParent; register(EditorParent, "lingo3d-editor"); //# sourceMappingURL=index.js.map