mylingo3d
Version:
Lingo3D is a React/Vue 3d game development framework that ships with a complete visual editor
97 lines (86 loc) • 3.38 kB
text/typescript
import { Cancellable } from "@lincode/promiselikes"
import { createNestedEffect } from "@lincode/reactivity"
import { Object3D } from "three"
import { mouseEvents } from "../../../../api/mouse"
import { onSceneGraphChange } from "../../../../events/onSceneGraphChange"
import { onSelectionRecompute } from "../../../../events/onSelectionRecompute"
import {
emitSelectionTarget,
onSelectionTarget
} from "../../../../events/onSelectionTarget"
import { getEditing } from "../../../../states/useEditing"
import { getEditorMode } from "../../../../states/useEditorMode"
import { resetMultipleSelectionTargets } from "../../../../states/useMultipleSelectionTargets"
import {
getSelectionTarget,
setSelectionTarget
} from "../../../../states/useSelectionTarget"
import { getTransformControlsDragging } from "../../../../states/useTransformControlsDragging"
import Sphere from "../../../primitives/Sphere"
import { vec2Point } from "../../../utils/vec2Point"
import pickable from "./pickable"
import selectionCandidates, {
getSelectionCandidates
} from "./selectionCandidates"
let pathObjects: Array<Sphere> = []
export default () => {
createNestedEffect(() => {
if (
!getEditing() ||
getTransformControlsDragging() ||
getEditorMode() !== "path"
)
return
getSelectionCandidates(pathObjects)
const handle0 = onSceneGraphChange(() =>
getSelectionCandidates(pathObjects)
)
const handle1 = onSelectionRecompute(() => {
getSelectionCandidates(pathObjects)
emitSelectionTarget()
})
const handle2 = new Cancellable()
Promise.all([
import("../../../primitives/Sphere"),
import("../../../Curve")
]).then(([{ default: Sphere }, { default: Curve }]) => {
if (handle2.done) return
const curve = new Curve()
handle2.then(() => curve.dispose())
handle2.watch(
mouseEvents.on("click", (e) => {
setTimeout(() => {
if (handle2.done || getSelectionTarget()) return
const target = new Sphere()
target.scale = 0.1
target.placeAt(e.point)
target.name = "point" + pathObjects.length
pathObjects.push(target)
emitSelectionTarget(target)
curve.addPoint(vec2Point(target.outerObject3d.position))
})
})
)
})
const handle3 = mouseEvents.on("click", () => emitSelectionTarget())
const handle4 = pickable("click", selectionCandidates, (target) =>
emitSelectionTarget(target)
)
const handle5 = onSelectionTarget(({ target }) => {
resetMultipleSelectionTargets()
setSelectionTarget(target)
})
return () => {
handle2.cancel()
handle0.cancel()
handle1.cancel()
handle2.cancel()
handle3.cancel()
handle4.cancel()
handle5.cancel()
if (getEditorMode() !== "path") {
pathObjects = []
}
}
}, [getEditing, getTransformControlsDragging, getEditorMode])
}