File tree Expand file tree Collapse file tree 3 files changed +48
-1
lines changed
packages/blocks/src/splat-viewer Expand file tree Collapse file tree 3 files changed +48
-1
lines changed Original file line number Diff line number Diff line change 1+ import { useApp , useFrame } from "@playcanvas/react/hooks" ;
2+ import { Entity } from "playcanvas" ;
3+ import { useRef } from "react" ;
4+
5+ const nearlyEquals = ( a : Float32Array , b : Float32Array , epsilon = 1e-4 ) : boolean => {
6+ for ( let i = 0 ; i < a . length ; i ++ ) {
7+ if ( Math . abs ( a [ i ] - b [ i ] ) >= epsilon ) return false ;
8+ }
9+ return true ;
10+ } ;
11+
12+ export const useRenderOnCameraChange = ( entity : Entity | null ) => {
13+ const app = useApp ( ) ;
14+ const prevWorld = useRef < Float32Array > ( new Float32Array ( 16 ) ) ;
15+ const prevProj = useRef < Float32Array > ( new Float32Array ( 16 ) ) ;
16+
17+ useFrame ( ( ) => {
18+ if ( ! entity ) return ;
19+ const world = entity . getWorldTransform ( ) . data ;
20+ const proj = entity . camera ?. projectionMatrix ?. data ;
21+
22+ if ( ! proj ) return ;
23+
24+ let changed = false ;
25+
26+ if ( ! app . autoRender && ! app . renderNextFrame ) {
27+ changed = ! nearlyEquals ( world , prevWorld . current ) || ! nearlyEquals ( proj , prevProj . current ) ;
28+
29+ if ( changed ) {
30+ console . log ( "changed" ) ;
31+ app . renderNextFrame = true ;
32+ }
33+ }
34+
35+ if ( app . renderNextFrame ) {
36+ if ( changed || app . autoRender ) {
37+ prevWorld . current . set ( world ) ;
38+ prevProj . current . set ( proj ) ;
39+ }
40+ }
41+ } ) ;
42+ } ;
Original file line number Diff line number Diff line change @@ -14,6 +14,7 @@ import style from "./utils/style";
1414
1515// @ts -expect-error There is no type definition for the camera-controls script
1616import { CameraControls } from "playcanvas/scripts/esm/camera-controls.mjs" ;
17+ import { useRenderOnCameraChange } from "./hooks/use-render-on-camera-change" ;
1718
1819type CameraControlsProps = {
1920 /* The focus point of the camera */
@@ -53,11 +54,14 @@ export function SmartCamera({
5354 fov ?: number ;
5455 animationTrack ?: AnimationTrack ;
5556} ) {
57+
5658 const entityRef = useRef < pc . Entity > ( null ) ;
59+ useRenderOnCameraChange ( entityRef . current ) ;
5760 const { subscribe, isPlaying } = useTimeline ( ) ;
5861 const { mode } = useAssetViewer ( ) ;
5962// const [mode] = useState<"interactive" | "transition" | "animation">(isPlaying ? "animation" : "interactive");
6063 const app = useApp ( ) ;
64+ app . renderNextFrame = true ;
6165
6266 const [ pose , setPose ] = useState < PoseType > ( {
6367 position : [ 2 , 1 , 2 ] ,
Original file line number Diff line number Diff line change @@ -83,6 +83,7 @@ function SplatComponent({
8383 const { isInteracting } = useAssetViewer ( ) ;
8484 const { isPlaying } = useTimeline ( ) ;
8585 const app = useApp ( ) ;
86+ app . renderNextFrame = true ;
8687
8788 // unload the asset when the component is unmounted
8889 useEffect ( ( ) => {
@@ -160,7 +161,7 @@ export function SplatViewer( {
160161 setMode = { setCameraMode }
161162 >
162163 < Suspense fallback = { < PosterComponent poster = { poster } /> } >
163- < Application fillMode = { FILLMODE_NONE } resolutionMode = { RESOLUTION_AUTO } autoRender = { true } >
164+ < Application fillMode = { FILLMODE_NONE } resolutionMode = { RESOLUTION_AUTO } autoRender = { false } >
164165 < SplatComponent src = { src } { ...props } />
165166 </ Application >
166167 < TooltipProvider >
You can’t perform that action at this time.
0 commit comments