@@ -4,6 +4,7 @@ import Constants from 'vtk.js/Sources/Rendering/Core/InteractorStyle/Constants';
44import vtkCoordinate from 'vtk.js/Sources/Rendering/Core/Coordinate' ;
55import vtkMatrixBuilder from 'vtk.js/Sources/Common/Core/MatrixBuilder' ;
66import { vec2 , vec3 , quat } from 'gl-matrix' ;
7+ import vtkMath from 'vtk.js/Sources/Common/Core/Math' ;
78
89const { States } = Constants ;
910
@@ -250,28 +251,92 @@ function vtkInteractorStyleRotatableMPRCrosshairs(publicAPI, model) {
250251 const sliceNormal = thisApi . getSliceNormal ( ) ;
251252 const axis = [ - sliceNormal [ 0 ] , - sliceNormal [ 1 ] , - sliceNormal [ 2 ] ] ;
252253
253- const { matrix } = vtkMatrixBuilder . buildFromRadian ( ) . rotate ( angle , axis ) ;
254-
255254 // Rotate other apis
256255 apis . forEach ( ( api , index ) => {
257256 if ( index !== apiIndex ) {
258- // get normal and viewUp.
257+ const cameraForApi = api . genericRenderWindow
258+ . getRenderWindow ( )
259+ . getInteractor ( )
260+ . getCurrentRenderer ( )
261+ . getActiveCamera ( ) ;
262+
263+ const crosshairPointForApi = api . get ( 'cachedCrosshairWorldPosition' ) ;
264+ const initialCrosshairPointForApi = api . get (
265+ 'initialCachedCrosshairWorldPosition'
266+ ) ;
267+
268+ const center = [ ] ;
269+ vtkMath . subtract (
270+ crosshairPointForApi ,
271+ initialCrosshairPointForApi ,
272+ center
273+ ) ;
274+ const translate = [ ] ;
275+ vtkMath . add ( crosshairPointForApi , center , translate ) ;
276+
277+ const { matrix } = vtkMatrixBuilder
278+ . buildFromRadian ( )
279+ . translate ( translate [ 0 ] , translate [ 1 ] , translate [ 2 ] )
280+ . rotate ( angle , axis )
281+ . translate ( - translate [ 0 ] , - translate [ 1 ] , - translate [ 2 ] ) ;
282+
283+ cameraForApi . applyTransform ( matrix ) ;
259284
260285 const sliceNormalForApi = api . getSliceNormal ( ) ;
261286 const viewUpForApi = api . getViewUp ( ) ;
262-
263- const newSliceNormalForApi = [ ] ;
264- const newViewUpForApi = [ ] ;
265-
266- vec3 . transformMat4 ( newSliceNormalForApi , sliceNormalForApi , matrix ) ;
267- vec3 . transformMat4 ( newViewUpForApi , viewUpForApi , matrix ) ;
268-
269- api . setOrientation ( newSliceNormalForApi , newViewUpForApi ) ;
287+ api . setOrientation ( sliceNormalForApi , viewUpForApi ) ;
270288 }
271289 } ) ;
272290
273291 updateCrosshairs ( callData ) ;
274292
293+ /*
294+ After the rotations and update of the crosshairs, the focal point of the
295+ camera has a shift along the line of sight coordinate respect to the
296+ crosshair (i.e., the focal point is not on the same slice of the crosshair).
297+ We calculate the new focal point coordinates as the nearest point between
298+ the line of sight of the camera and the crosshair coordinates:
299+
300+ p1 = cameraPositionForApi
301+ p2 = cameraFocalPointForApi
302+ q = crosshairPointForApi
303+
304+ Vector3 u = p2 - p1;
305+ Vector3 pq = q - p1;
306+ Vector3 w2 = pq - vtkMath.multiplyScalar(u, vtkMath.dot(pq, u) / u2);
307+
308+ Vector3 newFocalPoint = q - w2;
309+ */
310+
311+ apis . forEach ( api => {
312+ const cameraForApi = api . genericRenderWindow
313+ . getRenderWindow ( )
314+ . getInteractor ( )
315+ . getCurrentRenderer ( )
316+ . getActiveCamera ( ) ;
317+
318+ const crosshairPointForApi = api . get ( 'cachedCrosshairWorldPosition' ) ;
319+ const cameraFocalPointForApi = cameraForApi . getFocalPoint ( ) ;
320+ const cameraPositionForApi = cameraForApi . getPosition ( ) ;
321+
322+ const u = [ ] ;
323+ vtkMath . subtract ( cameraFocalPointForApi , cameraPositionForApi , u ) ;
324+ const pq = [ ] ;
325+ vtkMath . subtract ( crosshairPointForApi , cameraPositionForApi , pq ) ;
326+ const uLength2 = u [ 0 ] * u [ 0 ] + u [ 1 ] * u [ 1 ] + u [ 2 ] * u [ 2 ] ;
327+ vtkMath . multiplyScalar ( u , vtkMath . dot ( pq , u ) / uLength2 ) ;
328+ const w2 = [ ] ;
329+ vtkMath . subtract ( pq , u , w2 ) ;
330+ const newFocalPointForApi = [ ] ;
331+ vtkMath . subtract ( crosshairPointForApi , w2 , newFocalPointForApi ) ;
332+
333+ cameraForApi . setFocalPoint (
334+ newFocalPointForApi [ 0 ] ,
335+ newFocalPointForApi [ 1 ] ,
336+ newFocalPointForApi [ 2 ]
337+ ) ;
338+ } ) ;
339+
275340 operation . prevPosition = newPosition ;
276341 }
277342
0 commit comments