@kitware/vtk.js 21.3.1 → 21.5.1
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/Common/Core/Math.d.ts +233 -218
- package/Common/DataModel/ITKHelper.js +34 -8
- package/Interaction/Style/InteractorStyleTrackballCamera.js +5 -4
- package/Rendering/Core/ColorTransferFunction.js +11 -2
- package/Rendering/Core/RenderWindowInteractor/Constants.js +15 -3
- package/Rendering/Core/RenderWindowInteractor.js +27 -21
- package/Rendering/Misc/SynchronizableRenderWindow/vtkObjectManager.js +56 -8
- package/Rendering/OpenGL/RenderWindow.js +40 -18
- package/Rendering/WebGPU/RenderWindow.js +3 -2
- package/macros.js +1 -1
- package/package.json +1 -1
- package/types.d.ts +5 -0
|
@@ -2,9 +2,9 @@ import macro from '../../macros.js';
|
|
|
2
2
|
import vtkImageData from './ImageData.js';
|
|
3
3
|
import vtkDataArray from '../Core/DataArray.js';
|
|
4
4
|
|
|
5
|
-
var vtkErrorMacro = macro.vtkErrorMacro; // see itk.js
|
|
5
|
+
var vtkErrorMacro = macro.vtkErrorMacro; // see itk.js PixelTypes.js
|
|
6
6
|
|
|
7
|
-
var
|
|
7
|
+
var ITKJSPixelTypes = {
|
|
8
8
|
Unknown: 0,
|
|
9
9
|
Scalar: 1,
|
|
10
10
|
RGB: 2,
|
|
@@ -21,6 +21,25 @@ var ITKPixelTypes = {
|
|
|
21
21
|
Matrix: 13,
|
|
22
22
|
VariableLengthVector: 14,
|
|
23
23
|
VariableSizeMatrix: 15
|
|
24
|
+
}; // itk-wasm pixel types from https://github.com/InsightSoftwareConsortium/itk-wasm/blob/master/src/core/PixelTypes.ts
|
|
25
|
+
|
|
26
|
+
var ITKWASMPixelTypes = {
|
|
27
|
+
Unknown: 'Unknown',
|
|
28
|
+
Scalar: 'Scalar',
|
|
29
|
+
RGB: 'RGB',
|
|
30
|
+
RGBA: 'RGBA',
|
|
31
|
+
Offset: 'Offset',
|
|
32
|
+
Vector: 'Vector',
|
|
33
|
+
Point: 'Point',
|
|
34
|
+
CovariantVector: 'CovariantVector',
|
|
35
|
+
SymmetricSecondRankTensor: 'SymmetricSecondRankTensor',
|
|
36
|
+
DiffusionTensor3D: 'DiffusionTensor3D',
|
|
37
|
+
Complex: 'Complex',
|
|
38
|
+
FixedArray: 'FixedArray',
|
|
39
|
+
Array: 'Array',
|
|
40
|
+
Matrix: 'Matrix',
|
|
41
|
+
VariableLengthVector: 'VariableLengthVector',
|
|
42
|
+
VariableSizeMatrix: 'VariableSizeMatrix'
|
|
24
43
|
};
|
|
25
44
|
/**
|
|
26
45
|
* Converts an itk.js image to a vtk.js image.
|
|
@@ -35,7 +54,10 @@ function convertItkToVtkImage(itkImage) {
|
|
|
35
54
|
spacing: [1, 1, 1]
|
|
36
55
|
};
|
|
37
56
|
var dimensions = [1, 1, 1];
|
|
38
|
-
var direction = [1, 0, 0, 0, 1, 0, 0, 0, 1];
|
|
57
|
+
var direction = [1, 0, 0, 0, 1, 0, 0, 0, 1]; // Check whether itkImage is an itk.js Image or an itk-wasm Image?
|
|
58
|
+
|
|
59
|
+
var isITKWasm = itkImage.direction.data === undefined;
|
|
60
|
+
var ITKPixelTypes = isITKWasm ? ITKWASMPixelTypes : ITKJSPixelTypes;
|
|
39
61
|
|
|
40
62
|
for (var idx = 0; idx < itkImage.imageType.dimension; ++idx) {
|
|
41
63
|
vtkImage.origin[idx] = itkImage.origin[idx];
|
|
@@ -47,7 +69,11 @@ function convertItkToVtkImage(itkImage) {
|
|
|
47
69
|
// matrix on the vtkImageData is a webGL matrix, which uses a
|
|
48
70
|
// column-major data layout. Transpose the direction matrix from
|
|
49
71
|
// itkImage when instantiating that vtkImageData direction matrix.
|
|
50
|
-
|
|
72
|
+
if (isITKWasm) {
|
|
73
|
+
direction[col + idx * 3] = itkImage.direction[idx + col * itkImage.imageType.dimension];
|
|
74
|
+
} else {
|
|
75
|
+
direction[col + idx * 3] = itkImage.direction.data[idx + col * itkImage.imageType.dimension];
|
|
76
|
+
}
|
|
51
77
|
}
|
|
52
78
|
} // Create VTK Image Data
|
|
53
79
|
|
|
@@ -66,7 +92,7 @@ function convertItkToVtkImage(itkImage) {
|
|
|
66
92
|
imageData.getPointData().setScalars(pointData); // Associate the point data that are 3D vectors / tensors
|
|
67
93
|
// Refer to itk-js/src/PixelTypes.js for numerical values
|
|
68
94
|
|
|
69
|
-
switch (itkImage.imageType.pixelType) {
|
|
95
|
+
switch (ITKPixelTypes[itkImage.imageType.pixelType]) {
|
|
70
96
|
case ITKPixelTypes.Scalar:
|
|
71
97
|
break;
|
|
72
98
|
|
|
@@ -148,7 +174,7 @@ function convertVtkToItkImage(vtkImage) {
|
|
|
148
174
|
var itkImage = {
|
|
149
175
|
imageType: {
|
|
150
176
|
dimension: 3,
|
|
151
|
-
pixelType:
|
|
177
|
+
pixelType: ITKJSPixelTypes.Scalar,
|
|
152
178
|
componentType: '',
|
|
153
179
|
components: 1
|
|
154
180
|
},
|
|
@@ -176,10 +202,10 @@ function convertVtkToItkImage(vtkImage) {
|
|
|
176
202
|
var vtkArray;
|
|
177
203
|
|
|
178
204
|
if (pointData.getTensors() !== null) {
|
|
179
|
-
itkImage.imageType.pixelType =
|
|
205
|
+
itkImage.imageType.pixelType = ITKJSPixelTypes.DiffusionTensor3D;
|
|
180
206
|
vtkArray = pointData.getTensors();
|
|
181
207
|
} else if (pointData.getVectors() != null) {
|
|
182
|
-
itkImage.imageType.pixelType =
|
|
208
|
+
itkImage.imageType.pixelType = ITKJSPixelTypes.Vector;
|
|
183
209
|
vtkArray = pointData.getVectors();
|
|
184
210
|
} else {
|
|
185
211
|
vtkArray = pointData.getScalars();
|
|
@@ -53,12 +53,12 @@ function vtkInteractorStyleTrackballCamera(publicAPI, model) {
|
|
|
53
53
|
|
|
54
54
|
|
|
55
55
|
publicAPI.handleButton3D = function (ed) {
|
|
56
|
-
if (ed && ed.pressed && ed.device === Device.RightController && ed.input === Input.TrackPad) {
|
|
56
|
+
if (ed && ed.pressed && ed.device === Device.RightController && (ed.input === Input.Trigger || ed.input === Input.TrackPad)) {
|
|
57
57
|
publicAPI.startCameraPose();
|
|
58
58
|
return;
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
if (ed && !ed.pressed && ed.device === Device.RightController && ed.input === Input.TrackPad && model.state === States.IS_CAMERA_POSE) {
|
|
61
|
+
if (ed && !ed.pressed && ed.device === Device.RightController && (ed.input === Input.Trigger || ed.input === Input.TrackPad) && model.state === States.IS_CAMERA_POSE) {
|
|
62
62
|
publicAPI.endCameraPose(); // return;
|
|
63
63
|
}
|
|
64
64
|
};
|
|
@@ -77,11 +77,12 @@ function vtkInteractorStyleTrackballCamera(publicAPI, model) {
|
|
|
77
77
|
var camera = ed.pokedRenderer.getActiveCamera();
|
|
78
78
|
var oldTrans = camera.getPhysicalTranslation(); // look at the y axis to determine how fast / what direction to move
|
|
79
79
|
|
|
80
|
-
var speed = ed.gamepad.axes[1];
|
|
80
|
+
var speed = 0.5; // ed.gamepad.axes[1];
|
|
81
|
+
// 0.05 meters / frame movement
|
|
81
82
|
|
|
82
83
|
var pscale = speed * 0.05 * camera.getPhysicalScale(); // convert orientation to world coordinate direction
|
|
83
84
|
|
|
84
|
-
var dir = camera.physicalOrientationToWorldDirection(ed.orientation);
|
|
85
|
+
var dir = camera.physicalOrientationToWorldDirection([ed.orientation.x, ed.orientation.y, ed.orientation.z, ed.orientation.w]);
|
|
85
86
|
camera.setPhysicalTranslation(oldTrans[0] + dir[0] * pscale, oldTrans[1] + dir[1] * pscale, oldTrans[2] + dir[2] * pscale);
|
|
86
87
|
}; //----------------------------------------------------------------------------
|
|
87
88
|
|
|
@@ -221,23 +221,32 @@ function vtkColorTransferFunction(publicAPI, model) {
|
|
|
221
221
|
|
|
222
222
|
publicAPI.setNodes = function (nodes) {
|
|
223
223
|
if (model.nodes !== nodes) {
|
|
224
|
+
var before = JSON.stringify(model.nodes);
|
|
224
225
|
model.nodes = nodes;
|
|
225
|
-
|
|
226
|
+
var after = JSON.stringify(model.nodes);
|
|
227
|
+
return publicAPI.sortAndUpdateRange() || before !== after;
|
|
226
228
|
}
|
|
229
|
+
|
|
230
|
+
return false;
|
|
227
231
|
}; //----------------------------------------------------------------------------
|
|
228
232
|
// Sort the vector in increasing order, then fill in
|
|
229
233
|
// the Range
|
|
230
234
|
|
|
231
235
|
|
|
232
236
|
publicAPI.sortAndUpdateRange = function () {
|
|
237
|
+
var before = JSON.stringify(model.nodes);
|
|
233
238
|
model.nodes.sort(function (a, b) {
|
|
234
239
|
return a.x - b.x;
|
|
235
240
|
});
|
|
241
|
+
var after = JSON.stringify(model.nodes);
|
|
236
242
|
var modifiedInvoked = publicAPI.updateRange(); // If range is updated, Modified() has been called, don't call it again.
|
|
237
243
|
|
|
238
|
-
if (!modifiedInvoked) {
|
|
244
|
+
if (!modifiedInvoked && before !== after) {
|
|
239
245
|
publicAPI.modified();
|
|
246
|
+
return true;
|
|
240
247
|
}
|
|
248
|
+
|
|
249
|
+
return modifiedInvoked;
|
|
241
250
|
}; //----------------------------------------------------------------------------
|
|
242
251
|
|
|
243
252
|
|
|
@@ -8,11 +8,23 @@ var Input = {
|
|
|
8
8
|
Trigger: 1,
|
|
9
9
|
TrackPad: 2,
|
|
10
10
|
Grip: 3,
|
|
11
|
-
|
|
11
|
+
Thumbstick: 4,
|
|
12
|
+
A: 5,
|
|
13
|
+
B: 6,
|
|
14
|
+
ApplicationMenu: 7 // Not exposed in WebXR API
|
|
15
|
+
|
|
16
|
+
};
|
|
17
|
+
var Axis = {
|
|
18
|
+
Unknown: 0,
|
|
19
|
+
TouchpadX: 1,
|
|
20
|
+
TouchpadY: 2,
|
|
21
|
+
ThumbstickX: 3,
|
|
22
|
+
ThumbstickY: 4
|
|
12
23
|
};
|
|
13
24
|
var Constants = {
|
|
14
25
|
Device: Device,
|
|
15
|
-
Input: Input
|
|
26
|
+
Input: Input,
|
|
27
|
+
Axis: Axis
|
|
16
28
|
};
|
|
17
29
|
|
|
18
|
-
export { Device, Input, Constants as default };
|
|
30
|
+
export { Axis, Device, Input, Constants as default };
|
|
@@ -16,7 +16,7 @@ var vtkWarningMacro = macro.vtkWarningMacro,
|
|
|
16
16
|
// ----------------------------------------------------------------------------
|
|
17
17
|
|
|
18
18
|
var deviceInputMap = {
|
|
19
|
-
'
|
|
19
|
+
'xr-standard': [Input.Trigger, Input.Grip, Input.TrackPad, Input.Thumbstick, Input.A, Input.B]
|
|
20
20
|
};
|
|
21
21
|
var handledEvents = ['StartAnimation', 'Animation', 'EndAnimation', 'MouseEnter', 'MouseLeave', 'StartMouseMove', 'MouseMove', 'EndMouseMove', 'LeftButtonPress', 'LeftButtonRelease', 'MiddleButtonPress', 'MiddleButtonRelease', 'RightButtonPress', 'RightButtonRelease', 'KeyPress', 'KeyDown', 'KeyUp', 'StartMouseWheel', 'MouseWheel', 'EndMouseWheel', 'StartPinch', 'Pinch', 'EndPinch', 'StartPan', 'Pan', 'EndPan', 'StartRotate', 'Rotate', 'EndRotate', 'Button3D', 'Move3D', 'StartPointerLock', 'EndPointerLock', 'StartInteraction', 'Interaction', 'EndInteraction'];
|
|
22
22
|
|
|
@@ -378,47 +378,53 @@ function vtkRenderWindowInteractor(publicAPI, model) {
|
|
|
378
378
|
}
|
|
379
379
|
};
|
|
380
380
|
|
|
381
|
-
publicAPI.
|
|
382
|
-
|
|
381
|
+
publicAPI.updateXRGamepads = function (xrSession, xrFrame, xrRefSpace) {
|
|
382
|
+
// watch for when buttons change state and fire events
|
|
383
|
+
xrSession.inputSources.forEach(function (inputSource) {
|
|
384
|
+
var pose = xrFrame.getPose(inputSource.gripSpace, xrRefSpace);
|
|
385
|
+
var gp = inputSource.gamepad;
|
|
386
|
+
var hand = inputSource.handedness;
|
|
383
387
|
|
|
384
|
-
|
|
385
|
-
var gp = gamepads[i];
|
|
386
|
-
|
|
387
|
-
if (gp && gp.displayId === displayId) {
|
|
388
|
+
if (gp) {
|
|
388
389
|
if (!(gp.index in model.lastGamepadValues)) {
|
|
389
390
|
model.lastGamepadValues[gp.index] = {
|
|
390
|
-
|
|
391
|
+
left: {
|
|
392
|
+
buttons: {}
|
|
393
|
+
},
|
|
394
|
+
right: {
|
|
395
|
+
buttons: {}
|
|
396
|
+
}
|
|
391
397
|
};
|
|
392
398
|
}
|
|
393
399
|
|
|
394
400
|
for (var b = 0; b < gp.buttons.length; ++b) {
|
|
395
|
-
if (!(b in model.lastGamepadValues[gp.index].buttons)) {
|
|
396
|
-
model.lastGamepadValues[gp.index].buttons[b] = false;
|
|
401
|
+
if (!(b in model.lastGamepadValues[gp.index][hand].buttons)) {
|
|
402
|
+
model.lastGamepadValues[gp.index][hand].buttons[b] = false;
|
|
397
403
|
}
|
|
398
404
|
|
|
399
|
-
if (model.lastGamepadValues[gp.index].buttons[b] !== gp.buttons[b].pressed) {
|
|
405
|
+
if (model.lastGamepadValues[gp.index][hand].buttons[b] !== gp.buttons[b].pressed) {
|
|
400
406
|
publicAPI.button3DEvent({
|
|
401
407
|
gamepad: gp,
|
|
402
|
-
position:
|
|
403
|
-
orientation:
|
|
408
|
+
position: pose.transform.position,
|
|
409
|
+
orientation: pose.transform.orientation,
|
|
404
410
|
pressed: gp.buttons[b].pressed,
|
|
405
|
-
device:
|
|
406
|
-
input: deviceInputMap[gp.
|
|
411
|
+
device: inputSource.handedness === 'left' ? Device.LeftController : Device.RightController,
|
|
412
|
+
input: deviceInputMap[gp.mapping] && deviceInputMap[gp.mapping][b] ? deviceInputMap[gp.mapping][b] : Input.Trigger
|
|
407
413
|
});
|
|
408
|
-
model.lastGamepadValues[gp.index].buttons[b] = gp.buttons[b].pressed;
|
|
414
|
+
model.lastGamepadValues[gp.index][hand].buttons[b] = gp.buttons[b].pressed;
|
|
409
415
|
}
|
|
410
416
|
|
|
411
|
-
if (model.lastGamepadValues[gp.index].buttons[b]) {
|
|
417
|
+
if (model.lastGamepadValues[gp.index][hand].buttons[b]) {
|
|
412
418
|
publicAPI.move3DEvent({
|
|
413
419
|
gamepad: gp,
|
|
414
|
-
position:
|
|
415
|
-
orientation:
|
|
416
|
-
device:
|
|
420
|
+
position: pose.transform.position,
|
|
421
|
+
orientation: pose.transform.orientation,
|
|
422
|
+
device: inputSource.handedness === 'left' ? Device.LeftController : Device.RightController
|
|
417
423
|
});
|
|
418
424
|
}
|
|
419
425
|
}
|
|
420
426
|
}
|
|
421
|
-
}
|
|
427
|
+
});
|
|
422
428
|
};
|
|
423
429
|
|
|
424
430
|
publicAPI.handleMouseMove = function (event) {
|
|
@@ -102,12 +102,29 @@ function bindArrays(arraysToBind) {
|
|
|
102
102
|
|
|
103
103
|
function createNewArrayHandler(instance, arrayMetadata, arraysToBind) {
|
|
104
104
|
return function (values) {
|
|
105
|
+
var regMethod = arrayMetadata.registration ? arrayMetadata.registration : 'addArray';
|
|
106
|
+
var location = arrayMetadata.location ? instance.getReferenceByName(arrayMetadata.location) : instance; // Try to prevent unncessary modified
|
|
107
|
+
|
|
108
|
+
var previousArray = null;
|
|
109
|
+
|
|
110
|
+
if (arrayMetadata.location) {
|
|
111
|
+
previousArray = instance.getReferenceByName(arrayMetadata.location).getArray(arrayMetadata.name);
|
|
112
|
+
} else {
|
|
113
|
+
previousArray = instance["get".concat(regMethod.substring(3))]();
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (previousArray) {
|
|
117
|
+
if (previousArray.getData() !== values) {
|
|
118
|
+
arraysToBind.push([previousArray.setData, [values, arrayMetadata.numberOfComponents]]);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return previousArray;
|
|
122
|
+
}
|
|
123
|
+
|
|
105
124
|
var vtkClass = arrayMetadata.vtkClass ? arrayMetadata.vtkClass : 'vtkDataArray';
|
|
106
125
|
var array = DATA_ARRAY_MAPPER[vtkClass].newInstance(_objectSpread(_objectSpread({}, arrayMetadata), {}, {
|
|
107
126
|
values: values
|
|
108
127
|
}));
|
|
109
|
-
var regMethod = arrayMetadata.registration ? arrayMetadata.registration : 'addArray';
|
|
110
|
-
var location = arrayMetadata.location ? instance.getReferenceByName(arrayMetadata.location) : instance;
|
|
111
128
|
arraysToBind.push([location[regMethod], [array]]);
|
|
112
129
|
return array;
|
|
113
130
|
};
|
|
@@ -273,6 +290,11 @@ function genericUpdater(instance, state, context) {
|
|
|
273
290
|
context.start(); // -> start(arraysToBind)
|
|
274
291
|
|
|
275
292
|
dependencies.push(Promise.all(promises).then(function () {
|
|
293
|
+
// Since some arrays are getting updated, we should modify our dataset
|
|
294
|
+
if (arraysToBind.length) {
|
|
295
|
+
instance.modified();
|
|
296
|
+
}
|
|
297
|
+
|
|
276
298
|
bindArrays(arraysToBind);
|
|
277
299
|
return true;
|
|
278
300
|
}).catch(function (error) {
|
|
@@ -429,8 +451,6 @@ function colorTransferFunctionUpdater(instance, state, context) {
|
|
|
429
451
|
instance.set(_objectSpread(_objectSpread({}, state.properties), {}, {
|
|
430
452
|
nodes: nodes
|
|
431
453
|
}), true);
|
|
432
|
-
instance.sortAndUpdateRange();
|
|
433
|
-
instance.modified();
|
|
434
454
|
context.end(); // -> end(colorTransferFunctionUpdater)
|
|
435
455
|
}
|
|
436
456
|
|
|
@@ -454,12 +474,30 @@ function piecewiseFunctionUpdater(instance, state, context) {
|
|
|
454
474
|
instance.set(_objectSpread(_objectSpread({}, state.properties), {}, {
|
|
455
475
|
nodes: nodes
|
|
456
476
|
}), true);
|
|
457
|
-
instance.sortAndUpdateRange();
|
|
458
|
-
|
|
477
|
+
instance.sortAndUpdateRange(); // instance.modified();
|
|
478
|
+
|
|
459
479
|
context.end(); // -> end(piecewiseFunctionUpdater)
|
|
460
480
|
} // ----------------------------------------------------------------------------
|
|
461
481
|
|
|
462
482
|
|
|
483
|
+
function removeUnavailableArrays(fields, availableNames) {
|
|
484
|
+
var namesToDelete = [];
|
|
485
|
+
var size = fields.getNumberOfArrays();
|
|
486
|
+
|
|
487
|
+
for (var i = 0; i < size; i++) {
|
|
488
|
+
var array = fields.getArray(i);
|
|
489
|
+
var name = array.getName();
|
|
490
|
+
|
|
491
|
+
if (!availableNames.has(name)) {
|
|
492
|
+
namesToDelete.push(name);
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
for (var _i = 0; _i < namesToDelete.length; _i++) {
|
|
497
|
+
fields.removeArray(namesToDelete[_i]);
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
|
|
463
501
|
function createDataSetUpdate() {
|
|
464
502
|
var piecesToFetch = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
|
|
465
503
|
return function (instance, state, context) {
|
|
@@ -489,8 +527,18 @@ function createDataSetUpdate() {
|
|
|
489
527
|
|
|
490
528
|
delete state.properties.fields; // Reset any pre-existing fields array
|
|
491
529
|
|
|
492
|
-
|
|
493
|
-
|
|
530
|
+
var arrayToKeep = {
|
|
531
|
+
pointData: new Set(),
|
|
532
|
+
cellData: new Set(),
|
|
533
|
+
fieldData: new Set()
|
|
534
|
+
};
|
|
535
|
+
fieldsArrays.forEach(function (_ref5) {
|
|
536
|
+
var location = _ref5.location,
|
|
537
|
+
name = _ref5.name;
|
|
538
|
+
arrayToKeep[location].add(name);
|
|
539
|
+
});
|
|
540
|
+
removeUnavailableArrays(instance.getPointData(), arrayToKeep.pointData);
|
|
541
|
+
removeUnavailableArrays(instance.getCellData(), arrayToKeep.cellData); // Generic handling
|
|
494
542
|
|
|
495
543
|
var res = genericUpdater(instance, state, context); // Finish what we started
|
|
496
544
|
|
|
@@ -245,21 +245,28 @@ function vtkOpenGLRenderWindow(publicAPI, model) {
|
|
|
245
245
|
// typically in response to a user request such as a button press
|
|
246
246
|
|
|
247
247
|
|
|
248
|
-
publicAPI.startXR = function () {
|
|
248
|
+
publicAPI.startXR = function (isAR) {
|
|
249
249
|
if (navigator.xr === undefined) {
|
|
250
250
|
throw new Error('WebXR is not available');
|
|
251
251
|
}
|
|
252
252
|
|
|
253
|
-
|
|
254
|
-
|
|
253
|
+
model.xrSessionIsAR = isAR;
|
|
254
|
+
var sessionType = isAR ? 'immersive-ar' : 'immersive-vr';
|
|
255
|
+
|
|
256
|
+
if (!navigator.xr.isSessionSupported(sessionType)) {
|
|
257
|
+
if (isAR) {
|
|
258
|
+
throw new Error('Device does not support AR session');
|
|
259
|
+
} else {
|
|
260
|
+
throw new Error('VR display is not available');
|
|
261
|
+
}
|
|
255
262
|
}
|
|
256
263
|
|
|
257
264
|
if (model.xrSession === null) {
|
|
258
|
-
navigator.xr.requestSession(
|
|
259
|
-
throw new Error('Failed to create
|
|
265
|
+
navigator.xr.requestSession(sessionType).then(publicAPI.enterXR, function () {
|
|
266
|
+
throw new Error('Failed to create XR session!');
|
|
260
267
|
});
|
|
261
268
|
} else {
|
|
262
|
-
throw new Error('
|
|
269
|
+
throw new Error('XR Session already exists!');
|
|
263
270
|
}
|
|
264
271
|
}; // When an XR session is available, set up the XRWebGLLayer
|
|
265
272
|
// and request the first animation frame for the device
|
|
@@ -348,7 +355,10 @@ function vtkOpenGLRenderWindow(publicAPI, model) {
|
|
|
348
355
|
model.xrSession = null;
|
|
349
356
|
|
|
350
357
|
case 10:
|
|
351
|
-
|
|
358
|
+
if (model.oldCanvasSize !== undefined) {
|
|
359
|
+
publicAPI.setSize.apply(publicAPI, _toConsumableArray(model.oldCanvasSize));
|
|
360
|
+
} // Reset to default canvas
|
|
361
|
+
|
|
352
362
|
|
|
353
363
|
ren = model.renderable.getRenderers()[0];
|
|
354
364
|
ren.getActiveCamera().setProjectionMatrix(null);
|
|
@@ -372,11 +382,18 @@ function vtkOpenGLRenderWindow(publicAPI, model) {
|
|
|
372
382
|
switch (_context3.prev = _context3.next) {
|
|
373
383
|
case 0:
|
|
374
384
|
xrSession = frame.session;
|
|
385
|
+
model.renderable.getInteractor().updateXRGamepads(xrSession, frame, model.xrReferenceSpace);
|
|
375
386
|
model.xrSceneFrame = model.xrSession.requestAnimationFrame(publicAPI.xrRender);
|
|
376
387
|
xrPose = frame.getViewerPose(model.xrReferenceSpace);
|
|
377
388
|
|
|
378
389
|
if (xrPose) {
|
|
379
390
|
gl = publicAPI.get3DContext();
|
|
391
|
+
|
|
392
|
+
if (model.xrSessionIsAR && model.oldCanvasSize !== undefined) {
|
|
393
|
+
gl.canvas.width = model.oldCanvasSize[0];
|
|
394
|
+
gl.canvas.height = model.oldCanvasSize[1];
|
|
395
|
+
}
|
|
396
|
+
|
|
380
397
|
glLayer = xrSession.renderState.baseLayer;
|
|
381
398
|
gl.bindFramebuffer(gl.FRAMEBUFFER, glLayer.framebuffer);
|
|
382
399
|
gl.clear(gl.COLOR_BUFFER_BIT);
|
|
@@ -386,15 +403,18 @@ function vtkOpenGLRenderWindow(publicAPI, model) {
|
|
|
386
403
|
|
|
387
404
|
xrPose.views.forEach(function (view) {
|
|
388
405
|
var viewport = glLayer.getViewport(view);
|
|
389
|
-
gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
406
|
+
gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height); // TODO: Appropriate handling for AR passthrough on HMDs
|
|
407
|
+
// with two eyes will require further investigation.
|
|
408
|
+
|
|
409
|
+
if (!model.xrSessionIsAR) {
|
|
410
|
+
if (view.eye === 'left') {
|
|
411
|
+
ren.setViewport(0, 0, 0.5, 1.0);
|
|
412
|
+
} else if (view.eye === 'right') {
|
|
413
|
+
ren.setViewport(0.5, 0, 1.0, 1.0);
|
|
414
|
+
} else {
|
|
415
|
+
// No handling for non-eye viewport
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
398
418
|
}
|
|
399
419
|
|
|
400
420
|
ren.getActiveCamera().computeViewParametersFromPhysicalMatrix(view.transform.inverse.matrix);
|
|
@@ -403,7 +423,7 @@ function vtkOpenGLRenderWindow(publicAPI, model) {
|
|
|
403
423
|
});
|
|
404
424
|
}
|
|
405
425
|
|
|
406
|
-
case
|
|
426
|
+
case 5:
|
|
407
427
|
case "end":
|
|
408
428
|
return _context3.stop();
|
|
409
429
|
}
|
|
@@ -776,7 +796,9 @@ var DEFAULT_VALUES = {
|
|
|
776
796
|
// attempt webgl2 on by default
|
|
777
797
|
activeFramebuffer: null,
|
|
778
798
|
xrSession: null,
|
|
799
|
+
xrSessionIsAR: false,
|
|
779
800
|
xrReferenceSpace: null,
|
|
801
|
+
xrSupported: true,
|
|
780
802
|
imageFormat: 'image/png',
|
|
781
803
|
useOffScreen: false,
|
|
782
804
|
useBackgroundImage: false
|
|
@@ -819,7 +841,7 @@ function extend(publicAPI, model) {
|
|
|
819
841
|
macro.event(publicAPI, model, 'imageReady');
|
|
820
842
|
macro.event(publicAPI, model, 'haveVRDisplay'); // Build VTK API
|
|
821
843
|
|
|
822
|
-
macro.get(publicAPI, model, ['shaderCache', 'textureUnitManager', 'webgl2', 'vrDisplay', 'useBackgroundImage']);
|
|
844
|
+
macro.get(publicAPI, model, ['shaderCache', 'textureUnitManager', 'webgl2', 'vrDisplay', 'useBackgroundImage', 'xrSupported']);
|
|
823
845
|
macro.setGet(publicAPI, model, ['initialized', 'context', 'canvas', 'renderPasses', 'notifyStartCaptureImage', 'defaultToWebgl2', 'cursor', 'useOffScreen', // might want to make this not call modified as
|
|
824
846
|
// we change the active framebuffer a lot. Or maybe
|
|
825
847
|
// only mark modified if the size or depth
|
|
@@ -616,7 +616,8 @@ var DEFAULT_VALUES = {
|
|
|
616
616
|
imageFormat: 'image/png',
|
|
617
617
|
useOffScreen: false,
|
|
618
618
|
useBackgroundImage: false,
|
|
619
|
-
nextPropID: 1
|
|
619
|
+
nextPropID: 1,
|
|
620
|
+
xrSupported: false
|
|
620
621
|
}; // ----------------------------------------------------------------------------
|
|
621
622
|
|
|
622
623
|
function extend(publicAPI, model) {
|
|
@@ -652,7 +653,7 @@ function extend(publicAPI, model) {
|
|
|
652
653
|
macro.event(publicAPI, model, 'imageReady');
|
|
653
654
|
macro.event(publicAPI, model, 'initialized'); // Build VTK API
|
|
654
655
|
|
|
655
|
-
macro.get(publicAPI, model, ['commandEncoder', 'device', 'useBackgroundImage']);
|
|
656
|
+
macro.get(publicAPI, model, ['commandEncoder', 'device', 'useBackgroundImage', 'xrSupported']);
|
|
656
657
|
macro.setGet(publicAPI, model, ['initialized', 'context', 'canvas', 'device', 'renderPasses', 'notifyStartCaptureImage', 'cursor', 'useOffScreen']);
|
|
657
658
|
macro.setGetArray(publicAPI, model, ['size'], 2); // Object methods
|
|
658
659
|
|
package/macros.js
CHANGED
package/package.json
CHANGED
package/types.d.ts
CHANGED
|
@@ -19,6 +19,11 @@ declare type Size = [number, number];
|
|
|
19
19
|
declare type Range = [number, number];
|
|
20
20
|
declare type Vector2 = [number, number];
|
|
21
21
|
declare type Vector3 = [number, number, number];
|
|
22
|
+
declare type Vector4 = [number, number, number, number];
|
|
23
|
+
|
|
24
|
+
declare type Matrix = number[][];
|
|
25
|
+
declare type Matrix2x2 = [Vector2, Vector2];
|
|
26
|
+
declare type Matrix3x3 = [Vector3, Vector3, Vector3];
|
|
22
27
|
/**
|
|
23
28
|
* @deprecated The `Point` type is depracted, please use `Vector3` instead.
|
|
24
29
|
*/
|