Update render ui to use leva (#1133)

This commit is contained in:
Matthew Tancik authored and GitHub committed 2022-12-15 14:18:23 -08:00
1 parent bc690632bb
commit 3da0ca727d
3 files changed
+124 -122

No files matched your search

+24 -5
View File
@@ -242,18 +242,37 @@ $sidebar-width: 100% !default;
// ------------------------------------
// Camera Pane
.CameraPanel {
.CameraPanel-props {
margin-top: 10px;
margin-bottom: 10px;
margin-left: 20px;
margin-right: 20px;
}
.CameraPanel-path-row {
display: inline-block;
width: 45%;
margin-top: 8px;
margin-bottom: 8px;
margin-left: 4px;
margin-right: 4px;
}
.CameraPanel-row {
display: inline-block;
margin-top: 8px;
margin-bottom: 8px;
margin-left: 4px;
margin-right: 4px;
}
.CameraPanel-top-button {
display: inline-block;
margin: 4px;
margin-top: 8px;
width: 100%;
}
.CameraPanel-render-button {
display: inline-block;
width: 70%;
width: 92%;
margin: 4px;
margin-top: 8px;
}
@@ -37,6 +37,7 @@ import { useDispatch, useSelector } from 'react-redux';
import { CSS2DObject } from 'three/examples/jsm/renderers/CSS2DRenderer';
import AddAPhotoIcon from '@mui/icons-material/AddAPhoto';
import FileDownloadOutlinedIcon from '@mui/icons-material/FileDownloadOutlined';
import { LevaPanel, LevaStoreProvider, useCreateStore } from 'leva';
import FileUploadOutlinedIcon from '@mui/icons-material/FileUploadOutlined';
import { Stack } from '@mui/system';
import TextField from '@mui/material/TextField';
@@ -46,6 +47,8 @@ import { CameraHelper } from './CameraHelper';
import { get_curve_object_from_cameras, get_transform_matrix } from './curve';
import { WebSocketContext } from '../../WebSocket/WebSocket';
import RenderModal from '../../RenderModal';
import CameraPropPanel from './CameraPropPanel';
import LevaTheme from '../../../themes/leva_theme.json';
const msgpack = require('msgpack-lite');
@@ -460,6 +463,9 @@ export default function CameraPanel(props) {
const [animate, setAnimate] = React.useState(new Set());
const [globalFov, setGlobalFov] = React.useState(DEFAULT_FOV);
// leva store
const cameraPropsStore = useCreateStore();
const scene_state = sceneTree.get_scene_state();
// Template for sharing state between Vanilla JS Three.js and React components
@@ -496,10 +502,6 @@ export default function CameraPanel(props) {
};
// ui state
const [ui_render_height, setUIRenderHeight] = React.useState(render_height);
const [ui_render_width, setUIRenderWidth] = React.useState(render_width);
const [ui_seconds, setUISeconds] = React.useState(seconds);
const [ui_fps, setUIfps] = React.useState(fps);
const [fovLabel, setFovLabel] = React.useState(FOV_LABELS.FOV);
// nonlinear render option
@@ -868,15 +870,10 @@ export default function CameraPanel(props) {
const new_properties = new Map(cameraProperties);
setRenderHeight(camera_path_object.render_height);
setUIRenderHeight(camera_path_object.render_height);
setRenderWidth(camera_path_object.render_width);
setUIRenderWidth(camera_path_object.render_width);
setFps(camera_path_object.fps);
setUIfps(camera_path_object.fps);
setSeconds(camera_path_object.seconds);
setUISeconds(camera_path_object.seconds);
set_smoothness_value(camera_path_object.smoothness_value);
setIsCycle(camera_path_object.is_cycle);
@@ -968,7 +965,7 @@ export default function CameraPanel(props) {
return (
<div className="CameraPanel">
<div>
<div className="CameraPanel-top-button">
<div className="CameraPanel-path-row">
<Button
size="small"
className="CameraPanel-top-button"
@@ -986,7 +983,7 @@ export default function CameraPanel(props) {
/>
</Button>
</div>
<div className="CameraPanel-top-button">
<div className="CameraPanel-path-row">
<Button
size="small"
className="CameraPanel-top-button"
@@ -1009,110 +1006,23 @@ export default function CameraPanel(props) {
Render
</Button>
</div>
<div className="CameraList-row-time-interval">
<TextField
label="Height"
inputProps={{
inputMode: 'numeric',
pattern: '[+-]?([0-9]*[.])?[0-9]+',
}}
size="small"
onChange={(e) => {
if (e.target.validity.valid) {
setUIRenderHeight(e.target.value);
}
}}
onBlur={(e) => {
if (e.target.validity.valid) {
if (e.target.value !== '') {
setRenderHeight(parseInt(e.target.value, 10));
} else {
setUIRenderHeight(render_height);
}
}
}}
value={ui_render_height}
error={ui_render_height <= 0}
helperText={ui_render_height <= 0 ? 'Required' : ''}
variant="standard"
/>
<TextField
label="Width"
inputProps={{
inputMode: 'numeric',
pattern: '[+-]?([0-9]*[.])?[0-9]+',
}}
size="small"
onChange={(e) => {
if (e.target.validity.valid) {
setUIRenderWidth(e.target.value);
}
}}
onBlur={(e) => {
if (e.target.validity.valid) {
if (e.target.value !== '') {
setRenderWidth(parseInt(e.target.value, 10));
} else {
setUIRenderWidth(render_width);
}
}
}}
value={ui_render_width}
error={ui_render_width <= 0}
helperText={ui_render_width <= 0 ? 'Required' : ''}
variant="standard"
/>
</div>
<div className="CameraList-row-time-interval">
<TextField
label="Seconds"
inputProps={{
inputMode: 'numeric',
pattern: '[+-]?([0-9]*[.])?[0-9]+',
}}
size="small"
onChange={(e) => {
if (e.target.validity.valid) {
setUISeconds(e.target.value);
}
}}
onBlur={(e) => {
if (e.target.validity.valid) {
if (e.target.value !== '') {
setSeconds(parseInt(e.target.value, 10));
} else {
setUISeconds(seconds);
}
}
}}
value={ui_seconds}
error={ui_seconds <= 0}
helperText={ui_seconds <= 0 ? 'Required' : ''}
variant="standard"
/>
<TextField
label="FPS"
inputProps={{ inputMode: 'numeric', pattern: '[0-9]*' }}
size="small"
onChange={(e) => {
if (e.target.validity.valid) {
setUIfps(e.target.value);
}
}}
onBlur={(e) => {
if (e.target.validity.valid) {
if (e.target.value !== '') {
setFps(parseInt(e.target.value, 10));
} else {
setUIfps(fps);
}
}
}}
value={ui_fps}
error={ui_fps <= 0}
helperText={ui_fps <= 0 ? 'Required' : ''}
variant="standard"
<div className="CameraPanel-props">
<LevaPanel
store={cameraPropsStore}
className="Leva-panel"
theme={LevaTheme}
titleBar={false}
fill
flat
/>
<LevaStoreProvider store={cameraPropsStore}>
<CameraPropPanel
seconds={seconds}
set_seconds={setSeconds}
fps={fps}
set_fps={setFps}
/>
</LevaStoreProvider>
</div>
<div className="CameraList-row-animation-properties">
<Tooltip title="Animate FOV for Each Camera">
@@ -1161,7 +1071,7 @@ export default function CameraPanel(props) {
/>
</div>
<div>
<div className="CameraPanel-top-button">
<div className="CameraPanel-row">
<Button
size="small"
variant="outlined"
@@ -1171,7 +1081,7 @@ export default function CameraPanel(props) {
Add Camera
</Button>
</div>
<div className="CameraPanel-top-button">
<div className="CameraPanel-row">
<Tooltip
className="curve-button"
title="Toggle looping camera spline"
@@ -1199,7 +1109,7 @@ export default function CameraPanel(props) {
)}
</Tooltip>
</div>
<div className="CameraPanel-top-button">
<div className="CameraPanel-row">
<Tooltip title="Reset Keyframe Timing">
<Button
size="small"
@@ -0,0 +1,73 @@
import { useControls, useStoreContext } from 'leva';
import { useDispatch, useSelector } from 'react-redux';
export default function CameraPropPanel(props) {
const seconds = props.seconds;
const set_seconds = props.set_seconds;
const fps = props.fps;
const set_fps = props.set_fps;
const store = useStoreContext();
const dispatch = useDispatch();
// redux store state
const render_height = useSelector(
(state) => state.renderingState.render_height,
);
const render_width = useSelector(
(state) => state.renderingState.render_width,
);
const setResolution = (value) => {
dispatch({
type: 'write',
path: 'renderingState/render_width',
data: value.width,
});
dispatch({
type: 'write',
path: 'renderingState/render_height',
data: value.height,
});
};
const [, setControls] = useControls(
() => ({
camera_resolution: {
label: 'Resolution',
value: { width: render_width, height: render_height },
joystick: false,
onChange: (v) => {
setResolution(v);
},
},
video_duration: {
label: 'Duration (Sec)',
value: seconds,
min: 0.1,
step: 0.1,
onChange: (v) => {
set_seconds(v);
},
},
video_fps: {
label: 'Framerate (FPS)',
value: fps,
min: 0.1,
onChange: (v) => {
set_fps(v);
},
},
}),
{ store },
);
setControls({ video_fps: fps });
setControls({ video_duration: seconds });
setControls({
camera_resolution: { width: render_width, height: render_height },
});
return null;
}