@@ -4,6 +4,7 @@ import Constants from 'vtk.js/Sources/Rendering/Core/InteractorStyle/Constants';
4
4
import vtkCoordinate from 'vtk.js/Sources/Rendering/Core/Coordinate' ;
5
5
import vtkMatrixBuilder from 'vtk.js/Sources/Common/Core/MatrixBuilder' ;
6
6
import { vec2 , vec3 , quat } from 'gl-matrix' ;
7
+ import vtkMath from 'vtk.js/Sources/Common/Core/Math' ;
7
8
8
9
const { States } = Constants ;
9
10
@@ -250,28 +251,92 @@ function vtkInteractorStyleRotatableMPRCrosshairs(publicAPI, model) {
250
251
const sliceNormal = thisApi . getSliceNormal ( ) ;
251
252
const axis = [ - sliceNormal [ 0 ] , - sliceNormal [ 1 ] , - sliceNormal [ 2 ] ] ;
252
253
253
- const { matrix } = vtkMatrixBuilder . buildFromRadian ( ) . rotate ( angle , axis ) ;
254
-
255
254
// Rotate other apis
256
255
apis . forEach ( ( api , index ) => {
257
256
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 ) ;
259
284
260
285
const sliceNormalForApi = api . getSliceNormal ( ) ;
261
286
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 ) ;
270
288
}
271
289
} ) ;
272
290
273
291
updateCrosshairs ( callData ) ;
274
292
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
+
275
340
operation . prevPosition = newPosition ;
276
341
}
277
342
0 commit comments