R3F now uses a single sheet in studio

This commit is contained in:
Aria Minaei 2021-08-08 22:25:48 +02:00
parent b08588e9d6
commit d1fb0300e0
8 changed files with 101 additions and 90 deletions

View file

@ -1 +1 @@
import './r3f' import './space-exploration'

View file

@ -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}</>

View file

@ -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,
) )

View file

@ -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 =

View file

@ -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,
) )

View file

@ -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'

View 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
}

View file

@ -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)
}
} }