@kitware/vtk.js 29.11.2 → 30.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/BREAKING_CHANGES.md +5 -0
- package/Interaction/Manipulators/3DControllerModelSelectorManipulator/index.js +182 -0
- package/Interaction/Manipulators/3DControllerModelSelectorManipulator.d.ts +19 -0
- package/Interaction/Manipulators/CompositeVRManipulator.d.ts +9 -9
- package/Interaction/Manipulators/CompositeVRManipulator.js +2 -2
- package/Interaction/Manipulators/VRButtonPanManipulator.js +5 -5
- package/Interaction/Style/InteractorStyleHMDXR.d.ts +22 -0
- package/Interaction/Style/InteractorStyleHMDXR.js +50 -0
- package/Interaction/Style/InteractorStyleManipulator.js +20 -10
- package/Rendering/Core/CellPicker.d.ts +2 -20
- package/Rendering/Core/CellPicker.js +8 -8
- package/Rendering/Core/Picker.d.ts +12 -10
- package/Rendering/Core/Picker.js +143 -134
- package/Rendering/Core/PointPicker.d.ts +2 -18
- package/Rendering/Core/PointPicker.js +5 -5
- package/Rendering/Core/Prop3D.d.ts +16 -1
- package/Rendering/Core/Prop3D.js +14 -0
- package/Rendering/Core/RenderWindowInteractor.d.ts +21 -5
- package/Rendering/Core/RenderWindowInteractor.js +43 -37
- package/Rendering/Core/VolumeMapper.d.ts +3 -3
- package/Rendering/WebXR/RenderWindowHelper.js +66 -11
- package/Widgets/Widgets3D/ResliceCursorWidget/behavior.d.ts +0 -1
- package/Widgets/Widgets3D/ResliceCursorWidget/behavior.js +3 -12
- package/Widgets/Widgets3D/ResliceCursorWidget.d.ts +0 -1
- package/Widgets/Widgets3D/ResliceCursorWidget.js +2 -2
- package/index.d.ts +1 -0
- package/package.json +1 -1
package/BREAKING_CHANGES.md
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
## From 29.x to 30
|
|
2
|
+
|
|
3
|
+
- **ResliceCursorWidget.interactionEvent**: no longer pass an object of computeFocalPointOffset, canUpdateFocalPoint but simply the type of the handle that triggers the event. Those values can easily be recomputed by the consumers of the event. Regarding `computeFocalPointOffset`, it is no longer adviced to compute focal point offset for each interaction, instead observing `startInteraction()` should be considered (see ResliceCursorWidget example).
|
|
4
|
+
- **ResliceCursorWidget.invokeInternalInteractionEvent(methodName)**: has been removed and should be replaced by `ResliceCursorWidget.invokeInteractionEvent(methodName)`.
|
|
5
|
+
|
|
1
6
|
## From 28.x to 29
|
|
2
7
|
|
|
3
8
|
- **getOpenGLRenderWindow**: `getOpenGLRenderWindow` has been renamed to `getApiSpecificRenderWindow` in `vtkFullScreenRenderWindow`, `vtkGenericRenderWindow` and `vtkViewProxy` to support WebGL and WebGPU backend. ([#2816](https://github.com/Kitware/vtk-js/pull/2816))
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { vec3, vec4, quat, mat4 } from 'gl-matrix';
|
|
2
|
+
import vtkCompositeVRManipulator from '../CompositeVRManipulator.js';
|
|
3
|
+
import vtkPicker from '../../../Rendering/Core/Picker.js';
|
|
4
|
+
import { m as macro } from '../../../macros2.js';
|
|
5
|
+
import { States } from '../../../Rendering/Core/InteractorStyle/Constants.js';
|
|
6
|
+
|
|
7
|
+
// ----------------------------------------------------------------------------
|
|
8
|
+
// vtk3DControllerModelSelectorManipulator methods
|
|
9
|
+
// ----------------------------------------------------------------------------
|
|
10
|
+
|
|
11
|
+
function vtk3DControllerModelSelectorManipulator(publicAPI, model) {
|
|
12
|
+
model.classHierarchy.push('vtk3DControllerModelSelectorManipulator');
|
|
13
|
+
const picker = vtkPicker.newInstance();
|
|
14
|
+
|
|
15
|
+
// The current prop we are manipulating, if any.
|
|
16
|
+
let pickedProp;
|
|
17
|
+
|
|
18
|
+
// pre-allocate array buffers
|
|
19
|
+
const physicalToWorldMatrix = new Float64Array(16);
|
|
20
|
+
|
|
21
|
+
// arrays holding deltas from lastWorldPosition and lastOrientation
|
|
22
|
+
const translation = new Float64Array(3);
|
|
23
|
+
const rotation = new Float64Array(4);
|
|
24
|
+
const lastOrientationConjugate = new Float64Array(4);
|
|
25
|
+
const orientationAxis = new Float64Array(3);
|
|
26
|
+
|
|
27
|
+
// arrays holding the transform
|
|
28
|
+
const computedTransform = new Float64Array(16);
|
|
29
|
+
const computedTransformRotation = new Float64Array(4);
|
|
30
|
+
|
|
31
|
+
// arrays holding the current state of pickedProp.
|
|
32
|
+
const transposedPropMatrix = new Float64Array(16);
|
|
33
|
+
const propCurrentOrientation = new Float64Array(4);
|
|
34
|
+
const propCurrentOrientationConjugate = new Float64Array(4);
|
|
35
|
+
|
|
36
|
+
// arrays holding the new properties that must be assigned to pickedProp.
|
|
37
|
+
const propNewTranslation = new Float64Array(3);
|
|
38
|
+
const propNewScaling = new Float64Array(3);
|
|
39
|
+
const propNewOrientation = new Float64Array(4);
|
|
40
|
+
function applyPositionAndOrientationToProp(prop, worldPosition, orientation) {
|
|
41
|
+
vec3.subtract(translation, worldPosition, model.lastWorldPosition);
|
|
42
|
+
quat.conjugate(lastOrientationConjugate, model.lastOrientation);
|
|
43
|
+
quat.multiply(rotation, orientation, lastOrientationConjugate);
|
|
44
|
+
quat.normalize(rotation, rotation);
|
|
45
|
+
const rotationAngle = quat.getAxisAngle(orientationAxis, rotation);
|
|
46
|
+
|
|
47
|
+
// reset to identity
|
|
48
|
+
mat4.identity(computedTransform);
|
|
49
|
+
|
|
50
|
+
// compute transform
|
|
51
|
+
mat4.translate(computedTransform, computedTransform, worldPosition);
|
|
52
|
+
mat4.rotate(computedTransform, computedTransform, rotationAngle, orientationAxis);
|
|
53
|
+
mat4.translate(computedTransform, computedTransform, vec3.negate(new Float64Array(3), worldPosition));
|
|
54
|
+
mat4.translate(computedTransform, computedTransform, translation);
|
|
55
|
+
|
|
56
|
+
// lookup the prop internal matrix
|
|
57
|
+
mat4.transpose(transposedPropMatrix, prop.getMatrix());
|
|
58
|
+
// apply the new computedTransform to the prop internal matrix
|
|
59
|
+
mat4.multiply(computedTransform, computedTransform, transposedPropMatrix);
|
|
60
|
+
|
|
61
|
+
// Multiply the computedTransform with the current prop orientation to get the delta
|
|
62
|
+
// that must be applied to the prop
|
|
63
|
+
mat4.getRotation(computedTransformRotation, computedTransform);
|
|
64
|
+
prop.getOrientationQuaternion(propCurrentOrientation);
|
|
65
|
+
quat.conjugate(propCurrentOrientationConjugate, propCurrentOrientation);
|
|
66
|
+
quat.multiply(propNewOrientation, propCurrentOrientationConjugate, computedTransformRotation);
|
|
67
|
+
quat.normalize(propNewOrientation, propNewOrientation);
|
|
68
|
+
mat4.getTranslation(propNewTranslation, computedTransform);
|
|
69
|
+
mat4.getScaling(propNewScaling, computedTransform);
|
|
70
|
+
|
|
71
|
+
// Update the prop internal matrix
|
|
72
|
+
prop.setPosition(...propNewTranslation);
|
|
73
|
+
prop.setScale(...propNewScaling);
|
|
74
|
+
prop.rotateQuaternion(propNewOrientation);
|
|
75
|
+
}
|
|
76
|
+
function releasePickedProp() {
|
|
77
|
+
model.lastOrientation = null;
|
|
78
|
+
model.lastWorldPosition = null;
|
|
79
|
+
if (pickedProp) {
|
|
80
|
+
pickedProp.setDragable(true);
|
|
81
|
+
}
|
|
82
|
+
pickedProp = null;
|
|
83
|
+
}
|
|
84
|
+
publicAPI.onButton3D = (interactorStyle, renderer, state, eventData) => {
|
|
85
|
+
// If the button is not pressed, clear the state
|
|
86
|
+
if (!eventData.pressed) {
|
|
87
|
+
releasePickedProp();
|
|
88
|
+
return macro.VOID;
|
|
89
|
+
}
|
|
90
|
+
const camera = renderer.getActiveCamera();
|
|
91
|
+
camera.getPhysicalToWorldMatrix(physicalToWorldMatrix);
|
|
92
|
+
const {
|
|
93
|
+
targetPosition,
|
|
94
|
+
targetOrientation
|
|
95
|
+
} = eventData;
|
|
96
|
+
|
|
97
|
+
// Since targetPosition is in physical coordinates,
|
|
98
|
+
// transform it using the physicalToWorldMatrix to get it in world coordinates
|
|
99
|
+
const targetRayWorldPosition = vec3.transformMat4([], [targetPosition.x, targetPosition.y, targetPosition.z], physicalToWorldMatrix);
|
|
100
|
+
const targetRayWorldDirection = camera.physicalOrientationToWorldDirection([targetOrientation.x, targetOrientation.y, targetOrientation.z, targetOrientation.w]);
|
|
101
|
+
const dist = renderer.getActiveCamera().getClippingRange()[1];
|
|
102
|
+
const rayPoint1 = [...targetRayWorldPosition, 1.0];
|
|
103
|
+
const rayPoint2 = [rayPoint1[0] - targetRayWorldDirection[0] * dist, rayPoint1[1] - targetRayWorldDirection[1] * dist, rayPoint1[2] - targetRayWorldDirection[2] * dist, 1.0];
|
|
104
|
+
|
|
105
|
+
// Perform picking on the given renderer
|
|
106
|
+
picker.pick3DPoint(rayPoint1, rayPoint2, renderer);
|
|
107
|
+
const props = picker.getActors();
|
|
108
|
+
|
|
109
|
+
// If we have picked props, store the first one.
|
|
110
|
+
if (props.length > 0 && props[0].getNestedDragable()) {
|
|
111
|
+
pickedProp = props[0];
|
|
112
|
+
|
|
113
|
+
// prevent the prop from being dragged somewhere else
|
|
114
|
+
pickedProp.setDragable(false);
|
|
115
|
+
} else {
|
|
116
|
+
releasePickedProp();
|
|
117
|
+
}
|
|
118
|
+
return macro.EVENT_ABORT;
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
// pre-allocation to reduce gc in onMove3D
|
|
122
|
+
const currentTargetRayWorldPosition = new Float64Array(3);
|
|
123
|
+
const currentTargetRayOrientation = new Float64Array(4);
|
|
124
|
+
publicAPI.onMove3D = (interactorStyle, renderer, state, eventData) => {
|
|
125
|
+
// If we are not interacting with any prop, we have nothing to do.
|
|
126
|
+
// Also check for dragable
|
|
127
|
+
if (state !== States.IS_CAMERA_POSE || pickedProp == null) {
|
|
128
|
+
return macro.VOID;
|
|
129
|
+
}
|
|
130
|
+
const camera = renderer.getActiveCamera();
|
|
131
|
+
camera.getPhysicalToWorldMatrix(physicalToWorldMatrix);
|
|
132
|
+
const {
|
|
133
|
+
targetPosition
|
|
134
|
+
} = eventData;
|
|
135
|
+
vec3.transformMat4(currentTargetRayWorldPosition, [targetPosition.x, targetPosition.y, targetPosition.z], physicalToWorldMatrix);
|
|
136
|
+
|
|
137
|
+
// this is a unit quaternion
|
|
138
|
+
vec4.set(currentTargetRayOrientation, eventData.targetOrientation.x, eventData.targetOrientation.y, eventData.targetOrientation.z, eventData.targetOrientation.w);
|
|
139
|
+
if (model.lastWorldPosition && model.lastOrientation) {
|
|
140
|
+
applyPositionAndOrientationToProp(pickedProp, currentTargetRayWorldPosition, currentTargetRayOrientation);
|
|
141
|
+
} else {
|
|
142
|
+
// allocate
|
|
143
|
+
model.lastWorldPosition = new Float64Array(3);
|
|
144
|
+
model.lastOrientation = new Float64Array(4);
|
|
145
|
+
}
|
|
146
|
+
vec3.copy(model.lastWorldPosition, currentTargetRayWorldPosition);
|
|
147
|
+
vec4.copy(model.lastOrientation, currentTargetRayOrientation);
|
|
148
|
+
return macro.EVENT_ABORT;
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// ----------------------------------------------------------------------------
|
|
153
|
+
// Object factory
|
|
154
|
+
// ----------------------------------------------------------------------------
|
|
155
|
+
|
|
156
|
+
const DEFAULT_VALUES = {};
|
|
157
|
+
|
|
158
|
+
// ----------------------------------------------------------------------------
|
|
159
|
+
|
|
160
|
+
function extend(publicAPI, model) {
|
|
161
|
+
let initialValues = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
162
|
+
Object.assign(model, DEFAULT_VALUES, initialValues);
|
|
163
|
+
macro.get(publicAPI, model, ['lastWorldPosition', 'lastOrientation']);
|
|
164
|
+
macro.obj(publicAPI, model);
|
|
165
|
+
vtkCompositeVRManipulator.extend(publicAPI, model, initialValues);
|
|
166
|
+
|
|
167
|
+
// Object specific methods
|
|
168
|
+
vtk3DControllerModelSelectorManipulator(publicAPI, model);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// ----------------------------------------------------------------------------
|
|
172
|
+
|
|
173
|
+
const newInstance = macro.newInstance(extend, 'vtk3DControllerModelSelectorManipulator');
|
|
174
|
+
|
|
175
|
+
// ----------------------------------------------------------------------------
|
|
176
|
+
|
|
177
|
+
var vtk3DControllerModelSelectorManipulator$1 = {
|
|
178
|
+
newInstance,
|
|
179
|
+
extend
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
export { vtk3DControllerModelSelectorManipulator$1 as default, extend, newInstance };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import vtkCompositeVRManipulator from './CompositeVRManipulator';
|
|
2
|
+
|
|
3
|
+
export interface vtk3DControllerModelSelectorManipulator
|
|
4
|
+
extends vtkCompositeVRManipulator {}
|
|
5
|
+
|
|
6
|
+
export interface I3DControllerModelSelectorManipulatorInitialValues
|
|
7
|
+
extends vtkCompositeVRManipulator {}
|
|
8
|
+
|
|
9
|
+
export function extend(
|
|
10
|
+
publicAPI: object,
|
|
11
|
+
model: object,
|
|
12
|
+
initialValues?: I3DControllerModelSelectorManipulatorInitialValues
|
|
13
|
+
): void;
|
|
14
|
+
|
|
15
|
+
export const vtk3DControllerModelSelectorManipulator: {
|
|
16
|
+
extend: typeof extend;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export default vtk3DControllerModelSelectorManipulator;
|
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
import { States } from './../../Rendering/Core/InteractorStyle/Constants';
|
|
2
2
|
import vtkRenderer from './../../Rendering/Core/Renderer';
|
|
3
|
-
import
|
|
3
|
+
import vtkInteractorObserver from './../../Rendering/Core/InteractorObserver';
|
|
4
4
|
import {
|
|
5
5
|
Device,
|
|
6
6
|
Input,
|
|
7
7
|
} from './../../Rendering/Core/RenderWindowInteractor/Constants';
|
|
8
|
+
import {
|
|
9
|
+
I3DEvent,
|
|
10
|
+
IButton3DEvent,
|
|
11
|
+
} from './../../Rendering/Core/RenderWindowInteractor';
|
|
8
12
|
|
|
9
13
|
export interface vtkCompositeVRManipulator {
|
|
10
14
|
onButton3D(
|
|
11
|
-
|
|
15
|
+
interactorStyle: vtkInteractorObserver,
|
|
12
16
|
renderer: vtkRenderer,
|
|
13
17
|
state: States,
|
|
14
|
-
|
|
15
|
-
input: Input,
|
|
16
|
-
pressed: boolean
|
|
18
|
+
eventData: IButton3DEvent
|
|
17
19
|
): void;
|
|
18
20
|
|
|
19
21
|
onMove3D(
|
|
20
|
-
|
|
22
|
+
interactorStyle: vtkInteractorObserver,
|
|
21
23
|
renderer: vtkRenderer,
|
|
22
24
|
state: States,
|
|
23
|
-
|
|
24
|
-
input: Input,
|
|
25
|
-
pressed: boolean
|
|
25
|
+
eventData: I3DEvent
|
|
26
26
|
): void;
|
|
27
27
|
}
|
|
28
28
|
|
|
@@ -8,8 +8,8 @@ import { Device, Input } from '../../Rendering/Core/RenderWindowInteractor/Const
|
|
|
8
8
|
function vtkCompositeVRManipulator(publicAPI, model) {
|
|
9
9
|
// Set our className
|
|
10
10
|
model.classHierarchy.push('vtkCompositeVRManipulator');
|
|
11
|
-
publicAPI.onButton3D = (
|
|
12
|
-
publicAPI.onMove3D = (
|
|
11
|
+
publicAPI.onButton3D = (interactorStyle, renderer, state, eventData) => {};
|
|
12
|
+
publicAPI.onMove3D = (interactorStyle, renderer, state, eventData) => {};
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
// ----------------------------------------------------------------------------
|
|
@@ -10,14 +10,14 @@ import { States } from '../../Rendering/Core/InteractorStyle/Constants.js';
|
|
|
10
10
|
function vtkVRButtonPanManipulator(publicAPI, model) {
|
|
11
11
|
// Set our className
|
|
12
12
|
model.classHierarchy.push('vtkVRButtonPanManipulator');
|
|
13
|
-
publicAPI.onButton3D = (interactorStyle, renderer, state,
|
|
14
|
-
if (pressed) {
|
|
13
|
+
publicAPI.onButton3D = (interactorStyle, renderer, state, eventData) => {
|
|
14
|
+
if (eventData.pressed) {
|
|
15
15
|
interactorStyle.startCameraPose();
|
|
16
16
|
} else if (state === States.IS_CAMERA_POSE) {
|
|
17
17
|
interactorStyle.endCameraPose();
|
|
18
18
|
}
|
|
19
19
|
};
|
|
20
|
-
publicAPI.onMove3D = (interactorStyle, renderer, state,
|
|
20
|
+
publicAPI.onMove3D = (interactorStyle, renderer, state, eventData) => {
|
|
21
21
|
if (state !== States.IS_CAMERA_POSE) {
|
|
22
22
|
return;
|
|
23
23
|
}
|
|
@@ -28,13 +28,13 @@ function vtkVRButtonPanManipulator(publicAPI, model) {
|
|
|
28
28
|
const oldTrans = camera.getPhysicalTranslation();
|
|
29
29
|
|
|
30
30
|
// look at the y axis to determine how fast / what direction to move
|
|
31
|
-
const speed =
|
|
31
|
+
const speed = eventData.gamepad.axes[1];
|
|
32
32
|
|
|
33
33
|
// 0.05 meters / frame movement
|
|
34
34
|
const pscale = speed * 0.05 * camera.getPhysicalScale();
|
|
35
35
|
|
|
36
36
|
// convert orientation to world coordinate direction
|
|
37
|
-
const dir = camera.physicalOrientationToWorldDirection(
|
|
37
|
+
const dir = camera.physicalOrientationToWorldDirection(eventData.orientation);
|
|
38
38
|
camera.setPhysicalTranslation(oldTrans[0] + dir[0] * pscale, oldTrans[1] + dir[1] * pscale, oldTrans[2] + dir[2] * pscale);
|
|
39
39
|
};
|
|
40
40
|
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import vtkInteractorStyleManipulator, { IInteractorStyleManipulatorInitialValues } from './InteractorStyleManipulator';
|
|
2
|
+
|
|
3
|
+
export interface vtkInteractorStyleHMDXR extends vtkInteractorStyleManipulator {}
|
|
4
|
+
|
|
5
|
+
export interface IInteractorStyleHMDXRInitialValues extends IInteractorStyleManipulatorInitialValues {}
|
|
6
|
+
|
|
7
|
+
export function newInstance(
|
|
8
|
+
initialValues?: IInteractorStyleHMDXRInitialValues
|
|
9
|
+
): vtkInteractorStyleHMDXR;
|
|
10
|
+
|
|
11
|
+
export function extend(
|
|
12
|
+
publicAPI: object,
|
|
13
|
+
model: object,
|
|
14
|
+
initialValues?: IInteractorStyleHMDXRInitialValues
|
|
15
|
+
): void;
|
|
16
|
+
|
|
17
|
+
export const vtkInteractorStyleHMDXR: {
|
|
18
|
+
newInstance: typeof newInstance;
|
|
19
|
+
extend: typeof extend;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export default vtkInteractorStyleHMDXR;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { m as macro } from '../../macros2.js';
|
|
2
|
+
import vtkInteractorStyleManipulator from './InteractorStyleManipulator.js';
|
|
3
|
+
import vtk3DControllerModelSelectorManipulator from '../Manipulators/3DControllerModelSelectorManipulator/index.js';
|
|
4
|
+
import { Device, Input } from '../../Rendering/Core/RenderWindowInteractor/Constants.js';
|
|
5
|
+
|
|
6
|
+
function vtkInteractorStyleHMDXR(publicAPI, model) {
|
|
7
|
+
model.classHierarchy.push('vtkInteractorStyleHMDXR');
|
|
8
|
+
const leftHandManipulator = vtk3DControllerModelSelectorManipulator.newInstance({
|
|
9
|
+
device: Device.LeftController,
|
|
10
|
+
input: Input.A
|
|
11
|
+
});
|
|
12
|
+
const rightHandManipulator = vtk3DControllerModelSelectorManipulator.newInstance({
|
|
13
|
+
device: Device.RightController,
|
|
14
|
+
input: Input.A
|
|
15
|
+
});
|
|
16
|
+
publicAPI.addVRManipulator(leftHandManipulator);
|
|
17
|
+
publicAPI.addVRManipulator(rightHandManipulator);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// ----------------------------------------------------------------------------
|
|
21
|
+
// Object factory
|
|
22
|
+
// ----------------------------------------------------------------------------
|
|
23
|
+
|
|
24
|
+
const DEFAULT_VALUES = {};
|
|
25
|
+
|
|
26
|
+
// ----------------------------------------------------------------------------
|
|
27
|
+
|
|
28
|
+
function extend(publicAPI, model) {
|
|
29
|
+
let initialValues = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
30
|
+
Object.assign(model, DEFAULT_VALUES, initialValues);
|
|
31
|
+
|
|
32
|
+
// Inheritance
|
|
33
|
+
vtkInteractorStyleManipulator.extend(publicAPI, model, initialValues);
|
|
34
|
+
|
|
35
|
+
// Object specific methods
|
|
36
|
+
vtkInteractorStyleHMDXR(publicAPI, model);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// ----------------------------------------------------------------------------
|
|
40
|
+
|
|
41
|
+
const newInstance = macro.newInstance(extend, 'vtkInteractorStyleHMDXR');
|
|
42
|
+
|
|
43
|
+
// ----------------------------------------------------------------------------
|
|
44
|
+
|
|
45
|
+
var index = {
|
|
46
|
+
newInstance,
|
|
47
|
+
extend
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export { index as default, extend, newInstance };
|
|
@@ -118,6 +118,7 @@ const STATIC = {
|
|
|
118
118
|
function vtkInteractorStyleManipulator(publicAPI, model) {
|
|
119
119
|
// Set our className
|
|
120
120
|
model.classHierarchy.push('vtkInteractorStyleManipulator');
|
|
121
|
+
model.currentVRManipulators = new Map();
|
|
121
122
|
model.mouseManipulators = [];
|
|
122
123
|
model.keyboardManipulators = [];
|
|
123
124
|
model.vrManipulators = [];
|
|
@@ -246,13 +247,20 @@ function vtkInteractorStyleManipulator(publicAPI, model) {
|
|
|
246
247
|
}
|
|
247
248
|
|
|
248
249
|
// Look for a matching 3D camera interactor.
|
|
249
|
-
|
|
250
|
-
if (
|
|
251
|
-
|
|
250
|
+
const manipulator = publicAPI.findVRManipulator(ed.device, ed.input, ed.pressed);
|
|
251
|
+
if (manipulator) {
|
|
252
|
+
// register the manipulator for this device
|
|
253
|
+
model.currentVRManipulators.set(ed.device, manipulator);
|
|
254
|
+
manipulator.onButton3D(publicAPI, ed.pokedRenderer, model.state, ed);
|
|
252
255
|
if (ed.pressed) {
|
|
253
256
|
publicAPI.startCameraPose();
|
|
254
257
|
} else {
|
|
255
|
-
|
|
258
|
+
model.currentVRManipulators.delete(ed.device);
|
|
259
|
+
|
|
260
|
+
// make sure we don't end camera pose if other VR manipulators are currently interacting
|
|
261
|
+
if (model.currentVRManipulators.size === 0) {
|
|
262
|
+
publicAPI.endCameraPose();
|
|
263
|
+
}
|
|
256
264
|
}
|
|
257
265
|
} else {
|
|
258
266
|
vtkDebugMacro('No manipulator found');
|
|
@@ -261,8 +269,9 @@ function vtkInteractorStyleManipulator(publicAPI, model) {
|
|
|
261
269
|
|
|
262
270
|
//-------------------------------------------------------------------------
|
|
263
271
|
publicAPI.handleMove3D = ed => {
|
|
264
|
-
|
|
265
|
-
|
|
272
|
+
const manipulator = model.currentVRManipulators.get(ed.device);
|
|
273
|
+
if (manipulator && model.state === States.IS_CAMERA_POSE) {
|
|
274
|
+
manipulator.onMove3D(publicAPI, ed.pokedRenderer, model.state, ed);
|
|
266
275
|
}
|
|
267
276
|
};
|
|
268
277
|
|
|
@@ -576,7 +585,7 @@ function vtkInteractorStyleManipulator(publicAPI, model) {
|
|
|
576
585
|
// Object factory
|
|
577
586
|
// ----------------------------------------------------------------------------
|
|
578
587
|
|
|
579
|
-
const
|
|
588
|
+
const defaultValues = initialValues => ({
|
|
580
589
|
cachedMousePosition: null,
|
|
581
590
|
currentManipulator: null,
|
|
582
591
|
currentWheelManipulator: null,
|
|
@@ -585,14 +594,15 @@ const DEFAULT_VALUES = {
|
|
|
585
594
|
// vrManipulators: null,
|
|
586
595
|
// gestureManipulators: null,
|
|
587
596
|
centerOfRotation: [0, 0, 0],
|
|
588
|
-
rotationFactor: 1
|
|
589
|
-
|
|
597
|
+
rotationFactor: 1,
|
|
598
|
+
...initialValues
|
|
599
|
+
});
|
|
590
600
|
|
|
591
601
|
// ----------------------------------------------------------------------------
|
|
592
602
|
|
|
593
603
|
function extend(publicAPI, model) {
|
|
594
604
|
let initialValues = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
595
|
-
Object.assign(model,
|
|
605
|
+
Object.assign(model, defaultValues(initialValues));
|
|
596
606
|
|
|
597
607
|
// Inheritance
|
|
598
608
|
vtkInteractorStyle.extend(publicAPI, model, initialValues);
|
|
@@ -2,7 +2,9 @@ import vtkCell from './../../Common/DataModel/Cell';
|
|
|
2
2
|
import { Vector3 } from './../../types';
|
|
3
3
|
import vtkMapper from './Mapper';
|
|
4
4
|
import vtkPicker, { IPickerInitialValues } from './Picker';
|
|
5
|
+
import vtkProp3D from './Prop3D';
|
|
5
6
|
import vtkRenderer from './Renderer';
|
|
7
|
+
import { Nullable } from './../../types';
|
|
6
8
|
|
|
7
9
|
/**
|
|
8
10
|
*
|
|
@@ -83,26 +85,6 @@ export interface vtkCellPicker extends vtkPicker {
|
|
|
83
85
|
* @param {vtkRenderer} renderer The vtkRenderer instance.
|
|
84
86
|
*/
|
|
85
87
|
pick(selection: any, renderer: vtkRenderer): void;
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
*
|
|
89
|
-
* @param {Vector3} p1
|
|
90
|
-
* @param {Vector3} p2
|
|
91
|
-
* @param {Number} tol
|
|
92
|
-
* @param {vtkMapper} mapper The vtkMapper instance.
|
|
93
|
-
*/
|
|
94
|
-
intersectWithLine(p1: Vector3, p2: Vector3, tol: number, mapper: vtkMapper): number;
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
*
|
|
98
|
-
* @param {Vector3} p1
|
|
99
|
-
* @param {Vector3} p2
|
|
100
|
-
* @param {Number} t1
|
|
101
|
-
* @param {Number} t2
|
|
102
|
-
* @param {Number} tol
|
|
103
|
-
* @param {vtkMapper} mapper The vtkMapper instance.
|
|
104
|
-
*/
|
|
105
|
-
intersectActorWithLine(p1: Vector3, p2: Vector3, t1: number, t2: number, tol: number, mapper: vtkMapper): number;
|
|
106
88
|
}
|
|
107
89
|
|
|
108
90
|
/**
|
|
@@ -158,7 +158,7 @@ function vtkCellPicker(publicAPI, model) {
|
|
|
158
158
|
}
|
|
159
159
|
return pickResult;
|
|
160
160
|
};
|
|
161
|
-
|
|
161
|
+
model.intersectWithLine = (p1, p2, tolerance, prop, mapper) => {
|
|
162
162
|
let tMin = Number.MAX_VALUE;
|
|
163
163
|
let t1 = 0.0;
|
|
164
164
|
let t2 = 1.0;
|
|
@@ -177,13 +177,13 @@ function vtkCellPicker(publicAPI, model) {
|
|
|
177
177
|
} else if (mapper.isA('vtkVolumeMapper')) {
|
|
178
178
|
// we calculate here the parametric intercept points between the ray and the bounding box, so
|
|
179
179
|
// if the application defines for some reason a too large ray length (1e6), it restrict the calculation
|
|
180
|
-
// to the vtkVolume
|
|
180
|
+
// to the vtkVolume prop bounding box
|
|
181
181
|
const interceptionObject = vtkBox.intersectWithLine(mapper.getBounds(), p1, p2);
|
|
182
182
|
t1 = interceptionObject?.t1 > clipLine.t1 ? interceptionObject.t1 : clipLine.t1;
|
|
183
183
|
t2 = interceptionObject?.t2 < clipLine.t2 ? interceptionObject.t2 : clipLine.t2;
|
|
184
|
-
tMin =
|
|
184
|
+
tMin = model.intersectVolumeWithLine(p1, p2, t1, t2, tolerance, prop);
|
|
185
185
|
} else if (mapper.isA('vtkMapper')) {
|
|
186
|
-
tMin =
|
|
186
|
+
tMin = model.intersectActorWithLine(p1, p2, t1, t2, tolerance, mapper);
|
|
187
187
|
}
|
|
188
188
|
if (tMin < model.globalTMin) {
|
|
189
189
|
model.globalTMin = tMin;
|
|
@@ -208,7 +208,7 @@ function vtkCellPicker(publicAPI, model) {
|
|
|
208
208
|
}
|
|
209
209
|
return tMin;
|
|
210
210
|
};
|
|
211
|
-
|
|
211
|
+
model.intersectVolumeWithLine = (p1, p2, t1, t2, tolerance, volume) => {
|
|
212
212
|
let tMin = Number.MAX_VALUE;
|
|
213
213
|
const mapper = volume.getMapper();
|
|
214
214
|
const imageData = mapper.getInputData();
|
|
@@ -315,7 +315,7 @@ function vtkCellPicker(publicAPI, model) {
|
|
|
315
315
|
}
|
|
316
316
|
return tMin;
|
|
317
317
|
};
|
|
318
|
-
|
|
318
|
+
model.intersectActorWithLine = (p1, p2, t1, t2, tolerance, mapper) => {
|
|
319
319
|
let tMin = Number.MAX_VALUE;
|
|
320
320
|
const minXYZ = [0, 0, 0];
|
|
321
321
|
let pDistMin = Number.MAX_VALUE;
|
|
@@ -368,9 +368,9 @@ function vtkCellPicker(publicAPI, model) {
|
|
|
368
368
|
let cellPicked;
|
|
369
369
|
{
|
|
370
370
|
if (vtkCellTypes.hasSubCells(minCellType)) {
|
|
371
|
-
cellPicked = cell.intersectWithLine(t1, t2, p1, p2,
|
|
371
|
+
cellPicked = cell.intersectWithLine(t1, t2, p1, p2, tolerance, x, pCoords);
|
|
372
372
|
} else {
|
|
373
|
-
cellPicked = cell.intersectWithLine(p1, p2,
|
|
373
|
+
cellPicked = cell.intersectWithLine(p1, p2, tolerance, x, pCoords);
|
|
374
374
|
}
|
|
375
375
|
}
|
|
376
376
|
if (cellPicked.intersect === 1 && cellPicked.t <= tMin + model.tolerance && cellPicked.t >= t1 && cellPicked.t <= t2) {
|
|
@@ -2,6 +2,7 @@ import { Vector3, Nullable } from './../../types';
|
|
|
2
2
|
import vtkAbstractPicker, { IAbstractPickerInitialValues } from './AbstractPicker';
|
|
3
3
|
import vtkActor from './Actor';
|
|
4
4
|
import vtkMapper from './Mapper';
|
|
5
|
+
import vtkProp3D from './Prop3D';
|
|
5
6
|
import vtkRenderer from './Renderer';
|
|
6
7
|
import { vtkSubscription } from './../../interfaces';
|
|
7
8
|
|
|
@@ -67,16 +68,6 @@ export interface vtkPicker extends vtkAbstractPicker {
|
|
|
67
68
|
*/
|
|
68
69
|
onPickChange(callback: OnPickChangeCallback): vtkSubscription;
|
|
69
70
|
|
|
70
|
-
/**
|
|
71
|
-
* Intersect data with specified ray.
|
|
72
|
-
* Project the center point of the mapper onto the ray and determine its parametric value
|
|
73
|
-
* @param {Vector3} p1
|
|
74
|
-
* @param {Vector3} p2
|
|
75
|
-
* @param {Number} tol
|
|
76
|
-
* @param {vtkMapper} mapper
|
|
77
|
-
*/
|
|
78
|
-
intersectWithLine(p1: Vector3, p2: Vector3, tol: number, mapper: vtkMapper): number;
|
|
79
|
-
|
|
80
71
|
/**
|
|
81
72
|
* Perform pick operation with selection point provided.
|
|
82
73
|
* @param {Vector3} selection First two values should be x-y pixel coordinate, the third is usually zero.
|
|
@@ -84,6 +75,15 @@ export interface vtkPicker extends vtkAbstractPicker {
|
|
|
84
75
|
*/
|
|
85
76
|
pick(selection: Vector3, renderer: vtkRenderer): void;
|
|
86
77
|
|
|
78
|
+
/**
|
|
79
|
+
* Perform pick operation with the provided selection and focal points.
|
|
80
|
+
* Both point are in world coordinates.
|
|
81
|
+
* @param {Vector3} selectionPoint
|
|
82
|
+
* @param {Vector3} focalPoint
|
|
83
|
+
* @param {vtkRenderer} renderer
|
|
84
|
+
*/
|
|
85
|
+
pick3DPoint(selectionPoint: Vector3, focalPoint: Vector3, renderer: vtkRenderer): void;
|
|
86
|
+
|
|
87
87
|
/**
|
|
88
88
|
* Set position in mapper coordinates of pick point.
|
|
89
89
|
* @param {Number} x The x coordinate.
|
|
@@ -141,6 +141,8 @@ export function newInstance(initialValues?: IPickerInitialValues): vtkPicker;
|
|
|
141
141
|
* picking of points or cells based on the geometry of any vtkProp3D, use the
|
|
142
142
|
* subclasses vtkPointPicker or vtkCellPicker. For hardware-accelerated
|
|
143
143
|
* picking of any type of vtkProp, use vtkPropPicker or vtkWorldPointPicker.
|
|
144
|
+
*
|
|
145
|
+
* Note that only vtkProp3D's can be picked by vtkPicker.
|
|
144
146
|
*/
|
|
145
147
|
export declare const vtkPicker: {
|
|
146
148
|
newInstance: typeof newInstance,
|