R3F now uses a single sheet in studio
This commit is contained in:
parent
b08588e9d6
commit
d1fb0300e0
8 changed files with 101 additions and 90 deletions
|
@ -1 +1 @@
|
||||||
import './r3f'
|
import './space-exploration'
|
||||||
|
|
|
@ -15,7 +15,7 @@ const Wrapper: React.FC<{
|
||||||
`getSheet() in <Wrapper getSheet={getSheet}> has returned an invalid value`,
|
`getSheet() in <Wrapper getSheet={getSheet}> has returned an invalid value`,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
bindToCanvas({sheet})({gl, scene})
|
bindToCanvas({sheet, gl, scene})
|
||||||
}, [scene, gl])
|
}, [scene, gl])
|
||||||
|
|
||||||
return <>{props.children}</>
|
return <>{props.children}</>
|
||||||
|
|
|
@ -24,6 +24,7 @@ import type {IconType} from 'react-icons'
|
||||||
import studio from '@theatre/studio'
|
import studio from '@theatre/studio'
|
||||||
import {useSelected} from './useSelected'
|
import {useSelected} from './useSelected'
|
||||||
import {useVal} from '@theatre/dataverse-react'
|
import {useVal} from '@theatre/dataverse-react'
|
||||||
|
import {getEditorSheetObject} from './editorStuff'
|
||||||
|
|
||||||
export interface EditableProxyProps {
|
export interface EditableProxyProps {
|
||||||
editableName: string
|
editableName: string
|
||||||
|
@ -37,8 +38,9 @@ const EditableProxy: VFC<EditableProxyProps> = ({
|
||||||
editableType,
|
editableType,
|
||||||
object,
|
object,
|
||||||
}) => {
|
}) => {
|
||||||
const [editorObject, setSnapshotProxyObject] = useEditorStore(
|
const editorObject = getEditorSheetObject()
|
||||||
(state) => [state.editorObject, state.setSnapshotProxyObject],
|
const setSnapshotProxyObject = useEditorStore(
|
||||||
|
(state) => state.setSnapshotProxyObject,
|
||||||
shallow,
|
shallow,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ import type {$FixMe} from '../types'
|
||||||
import {useSelected} from './useSelected'
|
import {useSelected} from './useSelected'
|
||||||
import {useVal} from '@theatre/dataverse-react'
|
import {useVal} from '@theatre/dataverse-react'
|
||||||
import useInvalidate from './useInvalidate'
|
import useInvalidate from './useInvalidate'
|
||||||
|
import {getEditorSheetObject} from './editorStuff'
|
||||||
|
|
||||||
export interface ProxyManagerProps {
|
export interface ProxyManagerProps {
|
||||||
orbitControlsRef: React.MutableRefObject<OrbitControls | null>
|
orbitControlsRef: React.MutableRefObject<OrbitControls | null>
|
||||||
|
@ -33,8 +34,9 @@ type IEditableProxy = {
|
||||||
|
|
||||||
const ProxyManager: VFC<ProxyManagerProps> = ({orbitControlsRef}) => {
|
const ProxyManager: VFC<ProxyManagerProps> = ({orbitControlsRef}) => {
|
||||||
const isBeingEdited = useRef(false)
|
const isBeingEdited = useRef(false)
|
||||||
const [editorObject, sceneSnapshot, sheetObjects] = useEditorStore(
|
const editorObject = getEditorSheetObject()
|
||||||
(state) => [state.editorObject, state.sceneSnapshot, state.sheetObjects],
|
const [sceneSnapshot, sheetObjects] = useEditorStore(
|
||||||
|
(state) => [state.sceneSnapshot, state.sheetObjects],
|
||||||
shallow,
|
shallow,
|
||||||
)
|
)
|
||||||
const transformControlsMode =
|
const transformControlsMode =
|
||||||
|
|
|
@ -11,6 +11,7 @@ import styled, {createGlobalStyle, StyleSheetManager} from 'styled-components'
|
||||||
import {IoCameraReverseOutline} from 'react-icons/all'
|
import {IoCameraReverseOutline} from 'react-icons/all'
|
||||||
import type {ISheet} from '@theatre/core'
|
import type {ISheet} from '@theatre/core'
|
||||||
import useSnapshotEditorCamera from './useSnapshotEditorCamera'
|
import useSnapshotEditorCamera from './useSnapshotEditorCamera'
|
||||||
|
import {getEditorSheet, getEditorSheetObject} from './editorStuff'
|
||||||
|
|
||||||
const GlobalStyle = createGlobalStyle`
|
const GlobalStyle = createGlobalStyle`
|
||||||
:host {
|
:host {
|
||||||
|
@ -40,10 +41,9 @@ const EditorScene: React.FC<{snapshotEditorSheet: ISheet; paneId: string}> = ({
|
||||||
paneId,
|
paneId,
|
||||||
)
|
)
|
||||||
|
|
||||||
const [editorObject, helpersRoot] = useEditorStore(
|
const editorObject = getEditorSheetObject()
|
||||||
(state) => [state.editorObject, state.helpersRoot],
|
|
||||||
shallow,
|
const helpersRoot = useEditorStore((state) => state.helpersRoot, shallow)
|
||||||
)
|
|
||||||
|
|
||||||
const showGrid = useVal(editorObject?.props.viewport.showGrid) ?? true
|
const showGrid = useVal(editorObject?.props.viewport.showGrid) ?? true
|
||||||
const showAxes = useVal(editorObject?.props.viewport.showAxes) ?? true
|
const showAxes = useVal(editorObject?.props.viewport.showAxes) ?? true
|
||||||
|
@ -95,16 +95,12 @@ const Tools = styled.div`
|
||||||
`
|
`
|
||||||
|
|
||||||
const SnapshotEditor: React.FC<{paneId: string}> = (props) => {
|
const SnapshotEditor: React.FC<{paneId: string}> = (props) => {
|
||||||
const snapshotEditorSheet = studio.getStudioProject().sheet('Plugin-R3F')
|
const snapshotEditorSheet = getEditorSheet()
|
||||||
const paneId = props.paneId
|
const paneId = props.paneId
|
||||||
|
const editorObject = getEditorSheetObject()
|
||||||
|
|
||||||
const [editorObject, sceneSnapshot, createSnapshot, sheet] = useEditorStore(
|
const [sceneSnapshot, createSnapshot, sheet] = useEditorStore(
|
||||||
(state) => [
|
(state) => [state.sceneSnapshot, state.createSnapshot, state.sheet],
|
||||||
state.editorObject,
|
|
||||||
state.sceneSnapshot,
|
|
||||||
state.createSnapshot,
|
|
||||||
state.sheet,
|
|
||||||
],
|
|
||||||
shallow,
|
shallow,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,19 +1,15 @@
|
||||||
import type {VFC} from 'react'
|
import type {VFC} from 'react'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {useEditorStore} from '../../store'
|
|
||||||
import shallow from 'zustand/shallow'
|
|
||||||
import {IoCameraOutline} from 'react-icons/all'
|
import {IoCameraOutline} from 'react-icons/all'
|
||||||
import studio, {ToolbarIconButton} from '@theatre/studio'
|
import studio, {ToolbarIconButton} from '@theatre/studio'
|
||||||
import {useVal} from '@theatre/dataverse-react'
|
import {useVal} from '@theatre/dataverse-react'
|
||||||
import TransformControlsModeSelect from './TransformControlsModeSelect'
|
import TransformControlsModeSelect from './TransformControlsModeSelect'
|
||||||
import ViewportShadingSelect from './ViewportShadingSelect'
|
import ViewportShadingSelect from './ViewportShadingSelect'
|
||||||
import TransformControlsSpaceSelect from './TransformControlsSpaceSelect'
|
import TransformControlsSpaceSelect from './TransformControlsSpaceSelect'
|
||||||
|
import {getEditorSheetObject} from '../editorStuff'
|
||||||
|
|
||||||
const Toolbar: VFC = () => {
|
const Toolbar: VFC = () => {
|
||||||
const [editorObject] = useEditorStore(
|
const editorObject = getEditorSheetObject()
|
||||||
(state) => [state.editorObject],
|
|
||||||
shallow,
|
|
||||||
)
|
|
||||||
|
|
||||||
const transformControlsMode =
|
const transformControlsMode =
|
||||||
useVal(editorObject?.props.transformControls.mode) ?? 'translate'
|
useVal(editorObject?.props.transformControls.mode) ?? 'translate'
|
||||||
|
|
72
packages/plugin-r3f/src/components/editorStuff.ts
Normal file
72
packages/plugin-r3f/src/components/editorStuff.ts
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
import type {ISheet, ISheetObject} from '@theatre/core'
|
||||||
|
import {types} from '@theatre/core'
|
||||||
|
import studio from '@theatre/studio'
|
||||||
|
|
||||||
|
let sheet: ISheet | undefined = undefined
|
||||||
|
let sheetObject: ISheetObject<typeof editorSheetObjectConfig> | undefined =
|
||||||
|
undefined
|
||||||
|
|
||||||
|
const editorSheetObjectConfig = types.compound({
|
||||||
|
isOpen: types.boolean(false, {label: 'Editor Open'}),
|
||||||
|
viewport: types.compound(
|
||||||
|
{
|
||||||
|
showAxes: types.boolean(true, {label: 'Axes'}),
|
||||||
|
showGrid: types.boolean(true, {label: 'Grid'}),
|
||||||
|
showOverlayIcons: types.boolean(false, {label: 'Overlay Icons'}),
|
||||||
|
resolution: types.number(1440, {
|
||||||
|
label: 'Resolution',
|
||||||
|
range: [0, 1000],
|
||||||
|
}),
|
||||||
|
shading: types.stringLiteral(
|
||||||
|
'rendered',
|
||||||
|
{
|
||||||
|
flat: 'Flat',
|
||||||
|
rendered: 'Rendered',
|
||||||
|
solid: 'Solid',
|
||||||
|
wireframe: 'Wireframe',
|
||||||
|
},
|
||||||
|
{as: 'menu', label: 'Shading'},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{label: 'Viewport Config'},
|
||||||
|
),
|
||||||
|
transformControls: types.compound(
|
||||||
|
{
|
||||||
|
mode: types.stringLiteral(
|
||||||
|
'translate',
|
||||||
|
{
|
||||||
|
translate: 'Translate',
|
||||||
|
rotate: 'Rotate',
|
||||||
|
scale: 'Scale',
|
||||||
|
},
|
||||||
|
{as: 'switch', label: 'Mode'},
|
||||||
|
),
|
||||||
|
space: types.stringLiteral(
|
||||||
|
'world',
|
||||||
|
{
|
||||||
|
local: 'Local',
|
||||||
|
world: 'World',
|
||||||
|
},
|
||||||
|
{as: 'switch', label: 'Space'},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{label: 'Transform Controls'},
|
||||||
|
),
|
||||||
|
})
|
||||||
|
|
||||||
|
export function getEditorSheet(): ISheet {
|
||||||
|
if (!sheet) {
|
||||||
|
sheet = studio.getStudioProject().sheet('R3F UI')
|
||||||
|
}
|
||||||
|
return sheet
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getEditorSheetObject(): ISheetObject<
|
||||||
|
typeof editorSheetObjectConfig
|
||||||
|
> | null {
|
||||||
|
if (!sheetObject) {
|
||||||
|
sheetObject =
|
||||||
|
getEditorSheet().object('Editor', null, editorSheetObjectConfig) || null
|
||||||
|
}
|
||||||
|
return sheetObject
|
||||||
|
}
|
|
@ -3,7 +3,7 @@ import create from 'zustand'
|
||||||
import type {Object3D, Scene, WebGLRenderer} from 'three'
|
import type {Object3D, Scene, WebGLRenderer} from 'three'
|
||||||
import {Group} from 'three'
|
import {Group} from 'three'
|
||||||
import type {ISheet, ISheetObject} from '@theatre/core'
|
import type {ISheet, ISheetObject} from '@theatre/core'
|
||||||
import {types, getProject} from '@theatre/core'
|
import {types} from '@theatre/core'
|
||||||
|
|
||||||
export type EditableType =
|
export type EditableType =
|
||||||
| 'group'
|
| 'group'
|
||||||
|
@ -129,7 +129,6 @@ export interface EditableState {
|
||||||
|
|
||||||
export type EditorStore = {
|
export type EditorStore = {
|
||||||
sheet: ISheet | null
|
sheet: ISheet | null
|
||||||
editorObject: ISheetObject<typeof editorSheetObjectConfig> | null
|
|
||||||
sheetObjects: {[uniqueName in string]?: BaseSheetObjectType}
|
sheetObjects: {[uniqueName in string]?: BaseSheetObjectType}
|
||||||
scene: Scene | null
|
scene: Scene | null
|
||||||
gl: WebGLRenderer | null
|
gl: WebGLRenderer | null
|
||||||
|
@ -146,7 +145,6 @@ export type EditorStore = {
|
||||||
gl: WebGLRenderer,
|
gl: WebGLRenderer,
|
||||||
allowImplicitInstancing: boolean,
|
allowImplicitInstancing: boolean,
|
||||||
sheet: ISheet,
|
sheet: ISheet,
|
||||||
editorObject: null | ISheetObject<typeof editorSheetObjectConfig>,
|
|
||||||
) => void
|
) => void
|
||||||
|
|
||||||
addEditable: <T extends EditableType>(type: T, uniqueName: string) => void
|
addEditable: <T extends EditableType>(type: T, uniqueName: string) => void
|
||||||
|
@ -174,13 +172,12 @@ const config: StateCreator<EditorStore> = (set, get) => {
|
||||||
editablesSnapshot: null,
|
editablesSnapshot: null,
|
||||||
initialEditorCamera: {},
|
initialEditorCamera: {},
|
||||||
|
|
||||||
init: (scene, gl, allowImplicitInstancing, sheet, editorObject) => {
|
init: (scene, gl, allowImplicitInstancing, sheet) => {
|
||||||
set({
|
set({
|
||||||
scene,
|
scene,
|
||||||
gl,
|
gl,
|
||||||
allowImplicitInstancing,
|
allowImplicitInstancing,
|
||||||
sheet,
|
sheet,
|
||||||
editorObject,
|
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -264,70 +261,16 @@ export const useEditorStore = create<EditorStore>(config)
|
||||||
export type BindFunction = (options: {
|
export type BindFunction = (options: {
|
||||||
allowImplicitInstancing?: boolean
|
allowImplicitInstancing?: boolean
|
||||||
sheet: ISheet
|
sheet: ISheet
|
||||||
}) => (options: {gl: WebGLRenderer; scene: Scene}) => void
|
gl: WebGLRenderer
|
||||||
|
scene: Scene
|
||||||
const editorSheetObjectConfig = types.compound({
|
}) => void
|
||||||
isOpen: types.boolean(false, {label: 'Editor Open'}),
|
|
||||||
viewport: types.compound(
|
|
||||||
{
|
|
||||||
showAxes: types.boolean(true, {label: 'Axes'}),
|
|
||||||
showGrid: types.boolean(true, {label: 'Grid'}),
|
|
||||||
showOverlayIcons: types.boolean(false, {label: 'Overlay Icons'}),
|
|
||||||
resolution: types.number(1440, {
|
|
||||||
label: 'Resolution',
|
|
||||||
range: [0, 1000],
|
|
||||||
}),
|
|
||||||
shading: types.stringLiteral(
|
|
||||||
'rendered',
|
|
||||||
{
|
|
||||||
flat: 'Flat',
|
|
||||||
rendered: 'Rendered',
|
|
||||||
solid: 'Solid',
|
|
||||||
wireframe: 'Wireframe',
|
|
||||||
},
|
|
||||||
{as: 'menu', label: 'Shading'},
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{label: 'Viewport Config'},
|
|
||||||
),
|
|
||||||
transformControls: types.compound(
|
|
||||||
{
|
|
||||||
mode: types.stringLiteral(
|
|
||||||
'translate',
|
|
||||||
{
|
|
||||||
translate: 'Translate',
|
|
||||||
rotate: 'Rotate',
|
|
||||||
scale: 'Scale',
|
|
||||||
},
|
|
||||||
{as: 'switch', label: 'Mode'},
|
|
||||||
),
|
|
||||||
space: types.stringLiteral(
|
|
||||||
'world',
|
|
||||||
{
|
|
||||||
local: 'Local',
|
|
||||||
world: 'World',
|
|
||||||
},
|
|
||||||
{as: 'switch', label: 'Space'},
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{label: 'Transform Controls'},
|
|
||||||
),
|
|
||||||
})
|
|
||||||
|
|
||||||
export const bindToCanvas: BindFunction = ({
|
export const bindToCanvas: BindFunction = ({
|
||||||
allowImplicitInstancing = false,
|
allowImplicitInstancing = false,
|
||||||
sheet,
|
sheet,
|
||||||
|
gl,
|
||||||
|
scene,
|
||||||
}) => {
|
}) => {
|
||||||
const uiSheet: null | ISheet =
|
|
||||||
process.env.NODE_ENV === 'development'
|
|
||||||
? getProject('R3F Plugin').sheet('UI')
|
|
||||||
: null
|
|
||||||
|
|
||||||
const editorSheetObject =
|
|
||||||
uiSheet?.object('Editor', null, editorSheetObjectConfig) || null
|
|
||||||
|
|
||||||
return ({gl, scene}) => {
|
|
||||||
const init = useEditorStore.getState().init
|
const init = useEditorStore.getState().init
|
||||||
init(scene, gl, allowImplicitInstancing, sheet, editorSheetObject)
|
init(scene, gl, allowImplicitInstancing, sheet)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue