-
Notifications
You must be signed in to change notification settings - Fork 285
/
PlanarRotateTool.ts
79 lines (67 loc) · 2.58 KB
/
PlanarRotateTool.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import {
BaseVolumeViewport,
getEnabledElement,
Types,
} from '@cornerstonejs/core';
import { mat4, vec3 } from 'gl-matrix';
import { BaseTool } from './base';
import angleBetweenLines from '../utilities/math/angle/angleBetweenLines';
import { PublicToolProps, ToolProps, EventTypes } from '../types';
/**
* The PlanarRotateTool is a tool that allows the user to rotate
* the image by pressing the mouse click and dragging
*/
class PlanarRotateTool extends BaseTool {
static toolName;
touchDragCallback: (evt: EventTypes.MouseDragEventType) => void;
mouseDragCallback: (evt: EventTypes.MouseDragEventType) => void;
constructor(
toolProps: PublicToolProps = {},
defaultToolProps: ToolProps = {
supportedInteractionTypes: ['Mouse', 'Touch'],
}
) {
super(toolProps, defaultToolProps);
this.touchDragCallback = this._dragCallback.bind(this);
this.mouseDragCallback = this._dragCallback.bind(this);
}
_dragCallback(evt: EventTypes.MouseDragEventType) {
const { element, currentPoints, startPoints } = evt.detail;
const currentPointWorld = currentPoints.world;
const startPointWorld = startPoints.world;
const enabledElement = getEnabledElement(element);
const { viewport } = enabledElement;
const camera = viewport.getCamera();
const width = element.clientWidth;
const height = element.clientHeight;
const centerCanvas: Types.Point2 = [width * 0.5, height * 0.5];
const centerWorld = viewport.canvasToWorld(centerCanvas);
let angle = angleBetweenLines(
[startPointWorld, centerWorld],
[centerWorld, currentPointWorld]
);
const { viewPlaneNormal, viewUp } = camera;
const v1 = vec3.sub(vec3.create(), centerWorld, startPointWorld);
const v2 = vec3.sub(vec3.create(), centerWorld, currentPointWorld);
const cross = vec3.cross(vec3.create(), v1, v2);
if (vec3.dot(viewPlaneNormal, cross) > 0) {
angle = -angle;
}
if (Number.isNaN(angle)) {
return;
}
if (viewport instanceof BaseVolumeViewport) {
const rotAngle = (angle * Math.PI) / 180;
const rotMat = mat4.identity(new Float32Array(16));
mat4.rotate(rotMat, rotMat, rotAngle, viewPlaneNormal);
const rotatedViewUp = vec3.transformMat4(vec3.create(), viewUp, rotMat);
viewport.setCamera({ viewUp: rotatedViewUp as Types.Point3 });
} else {
const { rotation } = (viewport as Types.IStackViewport).getProperties();
viewport.setProperties({ rotation: rotation + angle });
}
viewport.render();
}
}
PlanarRotateTool.toolName = 'PlanarRotate';
export default PlanarRotateTool;