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'
|
2021-09-05 23:21:18 +02:00
|
|
|
import type {ISheetObject} from '@theatre/core'
|
2022-05-04 16:43:44 +02:00
|
|
|
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'
|
|
|
|
|
2022-05-04 16:43:44 +02:00
|
|
|
export type BaseSheetObjectType = ISheetObject<any>
|
2021-06-18 13:05:06 +02:00
|
|
|
|
2021-09-05 23:03:34 +02:00
|
|
|
export const allRegisteredObjects = new WeakSet<BaseSheetObjectType>()
|
|
|
|
|
2022-05-04 16:43:44 +02:00
|
|
|
export interface Editable<T> {
|
|
|
|
type: string
|
|
|
|
sheetObject: ISheetObject<any>
|
|
|
|
objectConfig: ObjectConfig<T>
|
|
|
|
visibleOnlyInEditor: boolean
|
2021-06-18 13:05:06 +02:00
|
|
|
}
|
|
|
|
|
2022-05-04 16:43:44 +02:00
|
|
|
export type EditableSnapshot<T extends Editable<any> = Editable<any>> = {
|
2021-06-18 13:05:06 +02:00
|
|
|
proxyObject?: Object3D | null
|
|
|
|
} & T
|
|
|
|
|
2022-05-04 16:43:44 +02:00
|
|
|
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
|
2022-05-04 16:43:44 +02:00
|
|
|
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
|
|
|
|
|
2022-05-04 16:43:44 +02:00
|
|
|
init: (scene: Scene, gl: WebGLRenderer) => void
|
2021-06-18 13:05:06 +02:00
|
|
|
|
2022-05-04 16:43:44 +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
|
|
|
|
}
|
|
|
|
|
2022-05-04 16:43:44 +02:00
|
|
|
const config: StateCreator<EditorStore> = (set) => {
|
2021-06-18 13:05:06 +02:00
|
|
|
return {
|
|
|
|
sheet: null,
|
2021-07-02 20:43:25 +02:00
|
|
|
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: {},
|
|
|
|
|
2022-05-04 16:43:44 +02:00
|
|
|
init: (scene, gl) => {
|
2021-06-18 13:05:06 +02:00
|
|
|
set({
|
|
|
|
scene,
|
|
|
|
gl,
|
|
|
|
})
|
|
|
|
},
|
|
|
|
|
2022-05-04 16:43:44 +02:00
|
|
|
addEditable: (uniqueName, editable) => {
|
2021-06-18 13:05:06 +02:00
|
|
|
set((state) => ({
|
2022-05-04 16:43:44 +02:00
|
|
|
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,
|
|
|
|
}))
|
|
|
|
},
|
2022-05-04 16:43:44 +02:00
|
|
|
|
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
|
2021-07-02 20:43:25 +02:00
|
|
|
|
2022-05-04 16:43:44 +02:00
|
|
|
export const bindToCanvas: BindFunction = ({gl, scene}) => {
|
2021-08-08 22:25:48 +02:00
|
|
|
const init = useEditorStore.getState().init
|
2022-05-04 16:43:44 +02:00
|
|
|
init(scene, gl)
|
2021-06-18 13:05:06 +02:00
|
|
|
}
|