theatre/packages/r3f/src/store.ts

117 lines
2.8 KiB
TypeScript
Raw Normal View History

2021-06-18 13:05:06 +02:00
import type {StateCreator} from 'zustand'
import create from 'zustand'
2021-06-29 15:08:02 +02:00
import type {Object3D, Scene, WebGLRenderer} from 'three'
2021-07-03 15:16:18 +02:00
import {Group} from 'three'
import type {ISheetObject} from '@theatre/core'
import type {ObjectConfig} from './editableFactoryConfigUtils'
2021-06-18 13:05:06 +02:00
export type TransformControlsMode = 'translate' | 'rotate' | 'scale'
export type TransformControlsSpace = 'world' | 'local'
export type ViewportShading = 'wireframe' | 'flat' | 'solid' | 'rendered'
export type BaseSheetObjectType = ISheetObject<any>
2021-06-18 13:05:06 +02:00
export const allRegisteredObjects = new WeakSet<BaseSheetObjectType>()
export interface Editable<T> {
type: string
sheetObject: ISheetObject<any>
objectConfig: ObjectConfig<T>
visibleOnlyInEditor: boolean
2021-06-18 13:05:06 +02:00
}
export type EditableSnapshot<T extends Editable<any> = Editable<any>> = {
2021-06-18 13:05:06 +02:00
proxyObject?: Object3D | null
} & T
export interface SerializedEditable {
type: string
2021-06-18 13:05:06 +02:00
}
export interface EditableState {
editables: Record<string, SerializedEditable>
}
export type EditorStore = {
scene: Scene | null
gl: WebGLRenderer | null
helpersRoot: Group
editables: Record<string, Editable<any>>
2021-06-18 13:05:06 +02:00
// this will come in handy when we start supporting multiple canvases
canvasName: string
sceneSnapshot: Scene | null
editablesSnapshot: Record<string, EditableSnapshot> | null
init: (scene: Scene, gl: WebGLRenderer) => void
2021-06-18 13:05:06 +02:00
addEditable: (uniqueName: string, editable: Editable<any>) => void
2021-06-18 13:05:06 +02:00
createSnapshot: () => void
setSnapshotProxyObject: (
proxyObject: Object3D | null,
uniqueName: string,
) => void
}
const config: StateCreator<EditorStore> = (set) => {
2021-06-18 13:05:06 +02:00
return {
sheet: null,
editorObject: null,
2021-06-18 13:05:06 +02:00
scene: null,
gl: null,
helpersRoot: new Group(),
editables: {},
canvasName: 'default',
sceneSnapshot: null,
editablesSnapshot: null,
initialEditorCamera: {},
init: (scene, gl) => {
2021-06-18 13:05:06 +02:00
set({
scene,
gl,
})
},
addEditable: (uniqueName, editable) => {
2021-06-18 13:05:06 +02:00
set((state) => ({
editables: {
...state.editables,
[uniqueName]: editable,
2021-06-18 13:05:06 +02:00
},
}))
},
2021-07-03 13:20:40 +02:00
2021-06-18 13:05:06 +02:00
createSnapshot: () => {
set((state) => ({
sceneSnapshot: state.scene?.clone() ?? null,
editablesSnapshot: state.editables,
}))
},
2021-06-18 13:05:06 +02:00
setSnapshotProxyObject: (proxyObject, uniqueName) => {
set((state) => ({
editablesSnapshot: {
...state.editablesSnapshot,
[uniqueName]: {
...state.editablesSnapshot![uniqueName],
proxyObject,
},
},
}))
},
}
}
export const useEditorStore = create<EditorStore>(config)
export type BindFunction = (options: {
allowImplicitInstancing?: boolean
2021-08-08 22:25:48 +02:00
gl: WebGLRenderer
scene: Scene
}) => void
export const bindToCanvas: BindFunction = ({gl, scene}) => {
2021-08-08 22:25:48 +02:00
const init = useEditorStore.getState().init
init(scene, gl)
2021-06-18 13:05:06 +02:00
}