mylingo3d
Version:
Lingo3D is a React/Vue 3d game development framework that ships with a complete visual editor
74 lines (59 loc) • 2.47 kB
text/typescript
import { createEffect } from "@lincode/reactivity"
import { Group as ThreeGroup, Object3D } from "three"
import scene from "../engine/scene"
import { onEditorGroupItems } from "../events/onEditorGroupItems"
import { emitSelectionTarget } from "../events/onSelectionTarget"
import IGroup, { groupDefaults, groupSchema } from "../interface/IGroup"
import {
getMultipleSelectionTargets,
multipleSelectionGroupManagers
} from "../states/useMultipleSelectionTargets"
import { setSelectionTarget } from "../states/useSelectionTarget"
import ObjectManager from "./core/ObjectManager"
import SimpleObjectManager from "./core/SimpleObjectManager"
import { box3, vector3 } from "./utils/reusables"
export default class Group extends ObjectManager<ThreeGroup> implements IGroup {
public static componentName = "group"
public static defaults = groupDefaults
public static schema = groupSchema
public constructor() {
super(new ThreeGroup())
}
}
createEffect(() => {
const targets = getMultipleSelectionTargets()
if (!targets.length) return
const group = new ThreeGroup()
scene.add(group)
const groupManager = new SimpleObjectManager(group)
multipleSelectionGroupManagers.add(groupManager)
setSelectionTarget(groupManager)
const parentEntries: Array<[Object3D, Object3D]> = []
for (const { outerObject3d: target } of targets) {
if (!target.parent) continue
parentEntries.push([target, target.parent])
group.attach(target)
}
box3.setFromObject(group)
for (const [object, parent] of parentEntries) parent.attach(object)
group.position.copy(box3.getCenter(vector3))
for (const [object] of parentEntries) group.attach(object)
let consolidated = false
const handle = onEditorGroupItems(() => {
if (!targets.length || consolidated) return
consolidated = true
const consolidatedGroup = new Group()
consolidatedGroup.outerObject3d.position.copy(group.position)
for (const target of targets) consolidatedGroup.attach(target)
emitSelectionTarget(consolidatedGroup)
})
return () => {
emitSelectionTarget()
if (!groupManager.done && !consolidated)
for (const [object, parent] of parentEntries) parent.attach(object)
setSelectionTarget(undefined)
groupManager.dispose()
scene.remove(group)
handle.cancel()
}
}, [getMultipleSelectionTargets])