Implement dynamic scene trees in r3f
This makes it possible to add/remove objects on the fly, do hot-module reloading, change object configs on the fly, and more.
This commit is contained in:
parent
151fcce298
commit
a9c3c00153
4 changed files with 95 additions and 41 deletions
|
@ -43,21 +43,21 @@ const EditableProxy: VFC<EditableProxyProps> = ({storeKey, object}) => {
|
|||
useLayoutEffect(() => {
|
||||
const originalVisibility = object.visible
|
||||
|
||||
if (editable.visibleOnlyInEditor) {
|
||||
if (editable?.visibleOnlyInEditor) {
|
||||
object.visible = true
|
||||
}
|
||||
|
||||
return () => {
|
||||
object.visible = originalVisibility
|
||||
}
|
||||
}, [editable.visibleOnlyInEditor, object.visible])
|
||||
}, [editable?.visibleOnlyInEditor, object.visible])
|
||||
|
||||
const [hovered, setHovered] = useState(false)
|
||||
|
||||
// Helpers
|
||||
const scene = useThree((state) => state.scene)
|
||||
const helper = useMemo<Helper | undefined>(
|
||||
() => editable.objectConfig.createHelper?.(object),
|
||||
() => editable?.objectConfig.createHelper?.(object),
|
||||
[object],
|
||||
)
|
||||
useEffect(() => {
|
||||
|
@ -92,6 +92,7 @@ const EditableProxy: VFC<EditableProxyProps> = ({storeKey, object}) => {
|
|||
|
||||
// subscribe to external changes
|
||||
useEffect(() => {
|
||||
if (!editable) return
|
||||
const sheetObject = editable.sheetObject
|
||||
const objectConfig = editable.objectConfig
|
||||
|
||||
|
@ -114,6 +115,8 @@ const EditableProxy: VFC<EditableProxyProps> = ({storeKey, object}) => {
|
|||
}
|
||||
}, [editable])
|
||||
|
||||
if (!editable) return null
|
||||
|
||||
return (
|
||||
<>
|
||||
<group
|
||||
|
|
|
@ -58,18 +58,19 @@ const ProxyManager: VFC<ProxyManagerProps> = ({orbitControlsRef}) => {
|
|||
|
||||
sceneProxy.traverse((object) => {
|
||||
if (object.userData.__editable) {
|
||||
// there are duplicate theatreKeys in the scene, only display one instance in the editor
|
||||
if (editableProxies[object.userData.__storeKey]) {
|
||||
const theatreKey = object.userData.__storeKey
|
||||
|
||||
if (
|
||||
// there are duplicate theatreKeys in the scene, only display one instance in the editor
|
||||
editableProxies[theatreKey] ||
|
||||
// this object has been unmounted
|
||||
!editables[theatreKey]
|
||||
) {
|
||||
object.parent!.remove(object)
|
||||
} else {
|
||||
const theatreKey = object.userData.__storeKey
|
||||
|
||||
editableProxies[theatreKey] = {
|
||||
portal: createPortal(
|
||||
<EditableProxy
|
||||
storeKey={object.userData.__storeKey}
|
||||
object={object}
|
||||
/>,
|
||||
<EditableProxy storeKey={theatreKey} object={object} />,
|
||||
object.parent!,
|
||||
),
|
||||
object: object,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue