@@ -8,7 +8,8 @@ type Pose = {
88 name : string ,
99 frame : number ,
1010 position : Vec3 ,
11- target : Vec3
11+ target : Vec3 ,
12+ fov ?: number
1213} ;
1314
1415/**
@@ -60,12 +61,12 @@ class CameraAnimTrack implements AnimTrack {
6061
6162 const existingIndex = this . poses . findIndex ( p => p . frame === frame ) ;
6263
63- // camera.getPose returns plain {x,y,z} objects, convert to Vec3
6464 const newPose : Pose = {
6565 name : `camera_${ this . poses . length } ` ,
6666 frame,
6767 position : new Vec3 ( pose . position . x , pose . position . y , pose . position . z ) ,
68- target : new Vec3 ( pose . target . x , pose . target . y , pose . target . z )
68+ target : new Vec3 ( pose . target . x , pose . target . y , pose . target . z ) ,
69+ fov : pose . fov
6970 } ;
7071
7172 if ( existingIndex === - 1 ) {
@@ -121,12 +122,12 @@ class CameraAnimTrack implements AnimTrack {
121122 this . poses . splice ( toIndex , 1 ) ;
122123 }
123124
124- // Clone the pose data to the new frame
125125 this . poses . push ( {
126126 name : `camera_${ this . poses . length } ` ,
127127 frame : toFrame ,
128128 position : source . position . clone ( ) ,
129- target : source . target . clone ( )
129+ target : source . target . clone ( ) ,
130+ fov : source . fov
130131 } ) ;
131132
132133 this . rebuildSpline ( ) ;
@@ -149,7 +150,8 @@ class CameraAnimTrack implements AnimTrack {
149150 name : p . name ,
150151 frame : p . frame ,
151152 position : p . position . clone ( ) ,
152- target : p . target . clone ( )
153+ target : p . target . clone ( ) ,
154+ fov : p . fov
153155 } ) ) ;
154156 }
155157
@@ -158,7 +160,8 @@ class CameraAnimTrack implements AnimTrack {
158160 name : p . name ,
159161 frame : p . frame ,
160162 position : p . position . clone ( ) ,
161- target : p . target . clone ( )
163+ target : p . target . clone ( ) ,
164+ fov : p . fov
162165 } ) ) ;
163166 this . rebuildSpline ( ) ;
164167 this . events . fire ( 'track.keysLoaded' ) ;
@@ -172,7 +175,8 @@ class CameraAnimTrack implements AnimTrack {
172175 return ;
173176 }
174177
175- // If a pose already exists at this frame, update it
178+ pose . fov ??= this . events . invoke ( 'camera.fov' ) ?? 60 ;
179+
176180 const idx = this . poses . findIndex ( p => p . frame === pose . frame ) ;
177181 if ( idx !== - 1 ) {
178182 this . poses [ idx ] = pose ;
@@ -212,24 +216,25 @@ class CameraAnimTrack implements AnimTrack {
212216 . filter ( a => a . frame < duration )
213217 . sort ( ( a , b ) => a . frame - b . frame ) ;
214218
215- // construct the spline points to be interpolated
216219 const times = orderedPoses . map ( p => p . frame ) ;
217220 const points : number [ ] = [ ] ;
218221 for ( let i = 0 ; i < orderedPoses . length ; ++ i ) {
219222 const p = orderedPoses [ i ] ;
220223 points . push ( p . position . x , p . position . y , p . position . z ) ;
221224 points . push ( p . target . x , p . target . y , p . target . z ) ;
225+ points . push ( p . fov ) ;
222226 }
223227
224228 if ( orderedPoses . length > 1 ) {
225229 const spline = CubicSpline . fromPointsLooping ( duration , times , points , smoothness ) ;
226230 const result : number [ ] = [ ] ;
227- const pose = { position : new Vec3 ( ) , target : new Vec3 ( ) } ;
231+ const pose = { position : new Vec3 ( ) , target : new Vec3 ( ) , fov : 0 } ;
228232
229233 this . onTimelineChange = ( frame : number ) => {
230234 spline . evaluate ( frame , result ) ;
231235 pose . position . set ( result [ 0 ] , result [ 1 ] , result [ 2 ] ) ;
232236 pose . target . set ( result [ 3 ] , result [ 4 ] , result [ 5 ] ) ;
237+ pose . fov = result [ 6 ] ;
233238 this . events . fire ( 'camera.setPose' , pose , 0 ) ;
234239 } ;
235240 } else {
@@ -281,25 +286,29 @@ const registerCameraPosesEvents = (events: Events) => {
281286 name : pose . name ,
282287 frame : pose . frame ,
283288 position : pack3 ( pose . position ) ,
284- target : pack3 ( pose . target )
289+ target : pack3 ( pose . target ) ,
290+ fov : pose . fov
285291 } ;
286292 } )
287293 } ] ;
288294 } ) ;
289295
290- events . function ( 'docDeserialize.poseSets' , ( poseSets : any [ ] ) => {
296+ events . function ( 'docDeserialize.poseSets' , ( poseSets : any [ ] , documentCameraFov ?: number ) => {
291297 if ( ! poseSets || poseSets . length === 0 ) {
292298 return ;
293299 }
294300
295301 const fps = events . invoke ( 'timeline.frameRate' ) ;
296302
303+ const defaultFov = documentCameraFov ?? events . invoke ( 'camera.fov' ) ?? 60 ;
304+
297305 const loadedPoses : Pose [ ] = poseSets [ 0 ] . poses . map ( ( docPose : any , index : number ) => {
298306 return {
299307 name : docPose . name ,
300308 frame : docPose . frame ?? ( index * fps ) ,
301309 position : new Vec3 ( docPose . position ) ,
302- target : new Vec3 ( docPose . target )
310+ target : new Vec3 ( docPose . target ) ,
311+ fov : docPose . fov ?? defaultFov
303312 } ;
304313 } ) ;
305314
0 commit comments