diff --git a/nerfactory/viewer/app/src/modules/SidePanel/CameraPanel/CameraPanel.jsx b/nerfactory/viewer/app/src/modules/SidePanel/CameraPanel/CameraPanel.jsx index 6942a2082..c359c20c0 100644 --- a/nerfactory/viewer/app/src/modules/SidePanel/CameraPanel/CameraPanel.jsx +++ b/nerfactory/viewer/app/src/modules/SidePanel/CameraPanel/CameraPanel.jsx @@ -5,8 +5,10 @@ import { AllInclusiveOutlined, ChangeHistory, GestureOutlined, + LinearScaleOutlined, RadioButtonUnchecked, Replay, + Timeline, } from '@mui/icons-material'; import { Button, Slider } from '@mui/material'; import { MeshLine, MeshLineMaterial } from 'meshline'; @@ -136,18 +138,18 @@ function CameraList(props) { const cameraList = cameras.map((camera, index) => { return (
-
- -
@@ -189,6 +191,7 @@ export default function CameraPanel(props) { const [smoothness_value, set_smoothness_value] = React.useState(0.5); const [is_playing, setIsPlaying] = React.useState(false); const [is_cycle, setIsCycle] = React.useState(false); + const [is_linear, setIsLinear] = React.useState(false); const [seconds, setSeconds] = React.useState(4); const [fps, setFps] = React.useState(24); @@ -228,6 +231,8 @@ export default function CameraPanel(props) { const total_num_steps = seconds * fps; const step_size = (cameras.length - 1) / total_num_steps; + + // nonlinear render option const slider_min = 0; const slider_max = Math.max(0, cameras.length - 1); @@ -290,6 +295,7 @@ export default function CameraPanel(props) { labelDiv.className = 'label'; labelDiv.textContent = i; labelDiv.style.color = 'black'; + labelDiv.style.visibility = 'visible'; const camera_label = new CSS2DObject(labelDiv); camera_label.position.set(0, -0.1, -0.1); camera_helper.add(camera_label); @@ -326,15 +332,19 @@ export default function CameraPanel(props) { sceneTree.set_object_from_path(['Camera Path', 'Curve'], spline_mesh); // set the camera - const position = curve_object.curve_positions.getPoint( - slider_value / (cameras.length - 1.0), - ); - const lookat = curve_object.curve_lookats.getPoint( - slider_value / (cameras.length - 1.0), - ); - const up = curve_object.curve_ups.getPoint( - slider_value / (cameras.length - 1.0), - ); + const point = Math.min(slider_value / (cameras.length - 1.0), 1); + let position = null; + let lookat = null; + let up = null; + if (!is_linear) { + position = curve_object.curve_positions.getPoint(point); + lookat = curve_object.curve_lookats.getPoint(point); + up = curve_object.curve_ups.getPoint(point); + } else { + position = curve_object.curve_positions.getPointAt(point); + lookat = curve_object.curve_lookats.getPointAt(point); + up = curve_object.curve_ups.getPointAt(point); + } const mat = get_transform_matrix(position, lookat, up); set_camera_position(camera_render, mat); } else { @@ -349,16 +359,20 @@ export default function CameraPanel(props) { // when the slider changes, update the main camera position useEffect(() => { if (cameras.length > 1) { - // interpolate to get the points - const position = curve_object.curve_positions.getPoint( - slider_value / (cameras.length - 1.0), - ); - const lookat = curve_object.curve_lookats.getPoint( - slider_value / (cameras.length - 1.0), - ); - const up = curve_object.curve_ups.getPoint( - slider_value / (cameras.length - 1.0), - ); + const point = Math.min(slider_value / (cameras.length - 1.0), 1); + let position = null; + let lookat = null; + let up = null; + if (!is_linear) { + // interpolate to get the points + position = curve_object.curve_positions.getPoint(point); + lookat = curve_object.curve_lookats.getPoint(point); + up = curve_object.curve_ups.getPoint(point); + } else { + position = curve_object.curve_positions.getPointAt(point); + lookat = curve_object.curve_lookats.getPointAt(point); + up = curve_object.curve_ups.getPointAt(point); + } const mat = get_transform_matrix(position, lookat, up); set_camera_position(camera_render, mat); } @@ -386,6 +400,7 @@ export default function CameraPanel(props) { const get_camera_path = () => { // NOTE: currently assuming these are ints const num_points = fps * seconds; + const positions = curve_object.curve_positions.getPoints(num_points); const lookats = curve_object.curve_lookats.getPoints(num_points); const ups = curve_object.curve_ups.getPoints(num_points); @@ -482,51 +497,78 @@ export default function CameraPanel(props) { return (
-
- +
+
+ +
+
+ +
+
+ + + + + +
-
- +
+
+ + {!is_cycle ? ( + + ) : ( + + )} + +
+
+ + {!is_linear ? ( + + ) : ( + + )} + +
-
- - {!is_cycle ? ( - - ) : ( - - )} - -
-
- - - - - -
-
+

Smoothness

@@ -559,7 +601,7 @@ export default function CameraPanel(props) { />
- - {/* eslint-disable-next-line no-nested-ternary */} {!is_playing && slider_max === slider_value ? ( - ) : !is_playing ? ( - ) : ( - )} - -
diff --git a/nerfactory/viewer/app/src/modules/SidePanel/StatusPanel/StatusPanel.jsx b/nerfactory/viewer/app/src/modules/SidePanel/StatusPanel/StatusPanel.jsx index f721bf5be..0b8b516c8 100644 --- a/nerfactory/viewer/app/src/modules/SidePanel/StatusPanel/StatusPanel.jsx +++ b/nerfactory/viewer/app/src/modules/SidePanel/StatusPanel/StatusPanel.jsx @@ -3,6 +3,7 @@ import * as React from 'react'; import Button from '@mui/material/Button'; import { ButtonGroup } from '@mui/material'; import { useDispatch, useSelector } from 'react-redux'; +import { useEffect } from 'react'; import PauseIcon from '@mui/icons-material/Pause'; import PlayArrowIcon from '@mui/icons-material/PlayArrow'; import ViewInArIcon from '@mui/icons-material/ViewInAr'; @@ -40,6 +41,17 @@ export default function StatusPanel(props: StatusPanelProps) { setValue(!value); }; + useEffect(() => { + const labels = document.getElementsByClassName('label'); + for(let i =0; i < labels.length; i+=1) { + if(!value){ + labels[i].style.visibility = 'hidden'; + } else { + labels[i].style.visibility = 'visible'; + } + } + }, [value]) + const handlePlayChange = () => { dispatch({ type: 'write',