Support fog editing in r3f second try (#163)
* Add support for editable fog * Oops
This commit is contained in:
parent
ef96fa1974
commit
10b4954ee2
5 changed files with 61 additions and 8 deletions
|
@ -1,10 +1,11 @@
|
|||
import {editable as e, RefreshSnapshot, SheetProvider} from '@theatre/r3f'
|
||||
import { Stars} from '@react-three/drei'
|
||||
import {Stars} from '@react-three/drei'
|
||||
import {getProject} from '@theatre/core'
|
||||
import React, {Suspense, useState} from 'react'
|
||||
import React, {Suspense, useMemo, useState} from 'react'
|
||||
import {Canvas} from '@react-three/fiber'
|
||||
import {useGLTF, PerspectiveCamera} from '@react-three/drei'
|
||||
import sceneGLB from './scene.glb'
|
||||
import {Color} from 'three'
|
||||
|
||||
document.body.style.backgroundColor = '#171717'
|
||||
|
||||
|
@ -55,7 +56,13 @@ function App() {
|
|||
>
|
||||
<Canvas dpr={[1.5, 2]} linear shadows frameloop="demand">
|
||||
<SheetProvider getSheet={() => getProject('Space').sheet('Scene')}>
|
||||
<fog attach="fog" args={[bg, 16, 30]} />
|
||||
<e.fog
|
||||
attach="fog"
|
||||
color={useMemo(() => new Color(bg), [bg])}
|
||||
near={16}
|
||||
far={30}
|
||||
uniqueName="Fog"
|
||||
/>
|
||||
<color attach="background" args={[bg]} />
|
||||
<ambientLight intensity={0.75} />
|
||||
<EditableCamera
|
||||
|
|
|
@ -59,11 +59,15 @@ const EditableProxy: VFC<EditableProxyProps> = ({
|
|||
|
||||
// Helpers
|
||||
const scene = useThree((state) => state.scene)
|
||||
const helper = useMemo<Helper>(
|
||||
() => editable.objectConfig.createHelper(object),
|
||||
const helper = useMemo<Helper | undefined>(
|
||||
() => editable.objectConfig.createHelper?.(object),
|
||||
[object],
|
||||
)
|
||||
useEffect(() => {
|
||||
if (helper == undefined) {
|
||||
return
|
||||
}
|
||||
|
||||
if (selected === uniqueName || hovered) {
|
||||
scene.add(helper)
|
||||
invalidate()
|
||||
|
@ -75,6 +79,10 @@ const EditableProxy: VFC<EditableProxyProps> = ({
|
|||
}
|
||||
}, [selected, hovered, helper, scene])
|
||||
useFrame(() => {
|
||||
if (helper == undefined) {
|
||||
return
|
||||
}
|
||||
|
||||
if (helper.update) {
|
||||
helper.update()
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import type {EditableFactoryConfig} from './editableFactoryConfigUtils'
|
||||
import {
|
||||
createColorPropConfig,
|
||||
createNumberPropConfig,
|
||||
createVector,
|
||||
createVectorPropConfig,
|
||||
|
@ -100,6 +101,15 @@ const defaultEditableFactoryConfig = {
|
|||
line: baseObjectConfig,
|
||||
lineLoop: baseObjectConfig,
|
||||
lineSegments: baseObjectConfig,
|
||||
fog: {
|
||||
props: {
|
||||
color: createColorPropConfig('color'),
|
||||
near: createNumberPropConfig('near', 1, {nudgeMultiplier: 0.1}),
|
||||
far: createNumberPropConfig('far', 1000, {nudgeMultiplier: 0.1}),
|
||||
},
|
||||
useTransformControls: false,
|
||||
icon: 'cloud' as const,
|
||||
},
|
||||
}
|
||||
|
||||
// Assert that the config is indeed of EditableFactoryConfig without actually
|
||||
|
|
|
@ -2,6 +2,7 @@ import type {UnknownShorthandCompoundProps} from '@theatre/core'
|
|||
import {types} from '@theatre/core'
|
||||
import type {Object3D} from 'three'
|
||||
import type {IconID} from './icons'
|
||||
import {Color} from 'three'
|
||||
|
||||
export type Helper = Object3D & {
|
||||
update?: () => void
|
||||
|
@ -17,7 +18,7 @@ type Meta<T> = {
|
|||
updateObject?: (object: T) => void
|
||||
icon: IconID
|
||||
dimensionless?: boolean
|
||||
createHelper: (object: T) => Helper
|
||||
createHelper?: (object: T) => Helper
|
||||
}
|
||||
export type ObjectConfig<T> = {props: Props} & Meta<T>
|
||||
export type EditableFactoryConfig = Partial<
|
||||
|
@ -79,7 +80,7 @@ export const createNumberPropConfig = (
|
|||
{nudgeMultiplier = 0.01} = {},
|
||||
): PropConfig<number> => ({
|
||||
parse: (props) => {
|
||||
return props[key] ?? defaultValue ?? 0
|
||||
return props[key] ?? defaultValue
|
||||
},
|
||||
apply: (value, object) => {
|
||||
object[key] = value
|
||||
|
@ -89,6 +90,28 @@ export const createNumberPropConfig = (
|
|||
},
|
||||
})
|
||||
|
||||
export type Rgba = {
|
||||
r: number
|
||||
g: number
|
||||
b: number
|
||||
a: number
|
||||
}
|
||||
|
||||
export const createColorPropConfig = (
|
||||
key: string,
|
||||
defaultValue = new Color(0, 0, 0),
|
||||
): PropConfig<Rgba> => ({
|
||||
parse: (props) => {
|
||||
return {...(props[key] ?? defaultValue), a: 1}
|
||||
},
|
||||
apply: (value, object) => {
|
||||
object[key].setRGB(value.r, value.g, value.b)
|
||||
},
|
||||
type: {
|
||||
[key]: types.rgba({...defaultValue, a: 1}),
|
||||
},
|
||||
})
|
||||
|
||||
export const extendObjectProps = <T extends {props: {}}>(
|
||||
objectConfig: T,
|
||||
extension: Props,
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
import {BsCameraVideoFill, BsFillCollectionFill} from 'react-icons/bs'
|
||||
import {
|
||||
BsCameraVideoFill,
|
||||
BsFillCollectionFill,
|
||||
BsCloudFill,
|
||||
} from 'react-icons/bs'
|
||||
import {GiCube, GiLightBulb, GiLightProjector} from 'react-icons/gi'
|
||||
import {BiSun} from 'react-icons/bi'
|
||||
import React from 'react'
|
||||
|
@ -10,6 +14,7 @@ const icons = {
|
|||
spotLight: <GiLightProjector />,
|
||||
sun: <BiSun />,
|
||||
camera: <BsCameraVideoFill />,
|
||||
cloud: <BsCloudFill />,
|
||||
}
|
||||
|
||||
export type IconID = keyof typeof icons
|
||||
|
|
Loading…
Reference in a new issue