@kitware/vtk.js 24.5.4 → 24.6.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.
Files changed (61) hide show
  1. package/Common/Core/CellArray.js +14 -3
  2. package/Common/Core/Math/index.js +1 -1
  3. package/Common/Core/Math.js +1 -1
  4. package/Common/DataModel/Triangle.js +1 -1
  5. package/Common/Transform/LandmarkTransform.js +1 -1
  6. package/Filters/Core/PolyDataNormals.js +1 -1
  7. package/Filters/General/OBBTree.js +1 -1
  8. package/Filters/General/WindowedSincPolyDataFilter.js +1 -1
  9. package/Filters/Sources/CircleSource.js +1 -1
  10. package/Filters/Sources/PointSource.js +1 -1
  11. package/Filters/Texture/TextureMapToPlane.js +1 -1
  12. package/Interaction/Manipulators/MouseCameraTrackballRollManipulator.js +1 -1
  13. package/Interaction/Manipulators/MouseCameraTrackballRotateManipulator.js +1 -1
  14. package/Interaction/Manipulators/MouseCameraUnicamManipulator.js +1 -1
  15. package/Interaction/Manipulators/MouseCameraUnicamRotateManipulator.js +1 -1
  16. package/Interaction/Style/InteractorStyleTrackballCamera.js +1 -1
  17. package/Interaction/Widgets/PiecewiseGaussianWidget.js +1 -1
  18. package/Proxy/Core/View2DProxy.js +1 -1
  19. package/Rendering/Core/ColorTransferFunction.js +1 -1
  20. package/Rendering/Core/Coordinate.js +1 -1
  21. package/Rendering/Core/CubeAxesActor.js +1 -1
  22. package/Rendering/Core/Glyph3DMapper.js +1 -1
  23. package/Rendering/Core/ImageMapper.js +1 -1
  24. package/Rendering/Core/Mapper.js +2 -2
  25. package/Rendering/Core/Prop3D.js +1 -1
  26. package/Rendering/Core/RenderWindowInteractor.js +1 -1
  27. package/Rendering/Core/Renderer.js +1 -1
  28. package/Rendering/Core/ScalarBarActor.js +1 -1
  29. package/Rendering/Core/VolumeMapper.js +1 -1
  30. package/Rendering/OpenGL/PolyDataMapper2D.js +5 -3
  31. package/Rendering/OpenGL/Texture.js +1 -1
  32. package/Rendering/WebGPU/BindGroup.js +1 -1
  33. package/Rendering/WebGPU/BufferManager/Constants.js +1 -1
  34. package/Rendering/WebGPU/BufferManager.js +149 -263
  35. package/Rendering/WebGPU/CellArrayMapper.js +46 -73
  36. package/Rendering/WebGPU/Device.js +97 -57
  37. package/Rendering/WebGPU/Glyph3DMapper.js +2 -0
  38. package/Rendering/WebGPU/ImageMapper.js +1 -5
  39. package/Rendering/WebGPU/IndexBuffer.js +397 -0
  40. package/Rendering/WebGPU/RenderEncoder.js +1 -1
  41. package/Rendering/WebGPU/SimpleMapper.js +7 -1
  42. package/Rendering/WebGPU/SphereMapper.js +29 -31
  43. package/Rendering/WebGPU/StickMapper.js +38 -42
  44. package/Rendering/WebGPU/StorageBuffer.js +0 -1
  45. package/Rendering/WebGPU/Texture.js +0 -2
  46. package/Rendering/WebGPU/TextureManager.js +37 -7
  47. package/Rendering/WebGPU/UniformBuffer.js +0 -1
  48. package/Rendering/WebGPU/VertexInput.js +7 -2
  49. package/Rendering/WebGPU/VolumePass.js +16 -8
  50. package/Rendering/WebGPU/VolumePassFSQ.js +1 -5
  51. package/Widgets/Manipulators/LineManipulator.js +1 -1
  52. package/Widgets/Representations/PolyLineRepresentation.js +1 -1
  53. package/Widgets/Representations/ResliceCursorContextRepresentation.js +1 -1
  54. package/Widgets/Widgets3D/AngleWidget.js +1 -1
  55. package/Widgets/Widgets3D/LineWidget/helpers.js +1 -1
  56. package/Widgets/Widgets3D/ResliceCursorWidget/behavior.js +1 -1
  57. package/Widgets/Widgets3D/ResliceCursorWidget/helpers.js +1 -1
  58. package/Widgets/Widgets3D/ResliceCursorWidget.js +1 -1
  59. package/Widgets/Widgets3D/ShapeWidget/behavior.js +1 -1
  60. package/index.d.ts +2 -2
  61. package/package.json +1 -1
@@ -0,0 +1,397 @@
1
+ import _defineProperty from '@babel/runtime/helpers/defineProperty';
2
+ import _classCallCheck from '@babel/runtime/helpers/classCallCheck';
3
+ import _createClass from '@babel/runtime/helpers/createClass';
4
+ import macro from '../../macros.js';
5
+ import Constants from './BufferManager/Constants.js';
6
+ import vtkProperty from '../Core/Property.js';
7
+ import vtkWebGPUBuffer from './Buffer.js';
8
+
9
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
10
+
11
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
12
+ var Representation = vtkProperty.Representation;
13
+ var PrimitiveTypes = Constants.PrimitiveTypes; // Simulate a small map of pointId to flatId for a cell. The original code
14
+ // used a map and was 2.6x slower (4.7 to 1.9 seconds). Using two fixed
15
+ // length arrays with a count is so much faster even with the required for
16
+ // loops and if statements. This only works as we know the usage is
17
+ // restricted to clear(), set() get() and has() so the count is always
18
+ // incrmenting except for clear where it goes back to 0. Performance
19
+ // improvement is probably due to this appoach not hitting the heap but wow
20
+ // it is so much faster. Code that adds to these vectors checks against 9 to
21
+ // make sure there is room. Switching to test against vec.length -1 results
22
+ // in a small performance hit, so if you change 10, search for 9 in this
23
+ // small class and change those as well.
24
+
25
+ var _LimitedMap = /*#__PURE__*/function () {
26
+ function _LimitedMap() {
27
+ _classCallCheck(this, _LimitedMap);
28
+
29
+ this.keys = new Uint32Array(10);
30
+ this.values = new Uint32Array(10);
31
+ this.count = 0;
32
+ }
33
+
34
+ _createClass(_LimitedMap, [{
35
+ key: "clear",
36
+ value: function clear() {
37
+ this.count = 0;
38
+ }
39
+ }, {
40
+ key: "has",
41
+ value: function has(key) {
42
+ for (var i = 0; i < this.count; i++) {
43
+ if (this.keys[i] === key) {
44
+ return true;
45
+ }
46
+ }
47
+
48
+ return undefined;
49
+ }
50
+ }, {
51
+ key: "get",
52
+ value: function get(key) {
53
+ for (var i = 0; i < this.count; i++) {
54
+ if (this.keys[i] === key) {
55
+ return this.values[i];
56
+ }
57
+ }
58
+
59
+ return undefined;
60
+ }
61
+ }, {
62
+ key: "set",
63
+ value: function set(key, value) {
64
+ if (this.count < 9) {
65
+ this.keys[this.count] = key;
66
+ this.values[this.count++] = value;
67
+ }
68
+ }
69
+ }]);
70
+
71
+ return _LimitedMap;
72
+ }();
73
+
74
+ function getPrimitiveName(primType) {
75
+ switch (primType) {
76
+ case PrimitiveTypes.Points:
77
+ return 'points';
78
+
79
+ case PrimitiveTypes.Lines:
80
+ return 'lines';
81
+
82
+ case PrimitiveTypes.Triangles:
83
+ case PrimitiveTypes.TriangleEdges:
84
+ return 'polys';
85
+
86
+ case PrimitiveTypes.TriangleStripEdges:
87
+ case PrimitiveTypes.TriangleStrips:
88
+ return 'strips';
89
+
90
+ default:
91
+ return '';
92
+ }
93
+ }
94
+
95
+ function _getOrAddFlatId(state, ptId, cellId) {
96
+ var flatId = state.pointIdToFlatId[ptId];
97
+
98
+ if (flatId < 0) {
99
+ flatId = state.flatId;
100
+ state.pointIdToFlatId[ptId] = flatId;
101
+ state.flatIdToPointId[state.flatId] = ptId;
102
+ state.flatIdToCellId[state.flatId] = cellId;
103
+ state.flatId++;
104
+ }
105
+
106
+ return flatId;
107
+ }
108
+
109
+ function fillCell(ptIds, cellId, state) {
110
+ var numPtIds = ptIds.length; // are any points already marked for this cell? If so use that as the provoking point
111
+
112
+ for (var ptIdx = 0; ptIdx < numPtIds; ptIdx++) {
113
+ var _ptId = ptIds[ptIdx];
114
+
115
+ if (state.cellProvokedMap.has(_ptId)) {
116
+ state.ibo[state.iboId++] = state.cellProvokedMap.get(_ptId); // insert remaining ptIds (they do not need to provoke)
117
+
118
+ for (var ptIdx2 = ptIdx + 1; ptIdx2 < ptIdx + numPtIds; ptIdx2++) {
119
+ _ptId = ptIds[ptIdx2 % numPtIds];
120
+
121
+ var _flatId = _getOrAddFlatId(state, _ptId, cellId); // add to ibo
122
+
123
+
124
+ state.ibo[state.iboId++] = _flatId;
125
+ } // all done now
126
+
127
+
128
+ return;
129
+ }
130
+ } // else have any of the points not been used yet? (not in provokedPointIds)
131
+
132
+
133
+ for (var _ptIdx = 0; _ptIdx < numPtIds; _ptIdx++) {
134
+ var _ptId2 = ptIds[_ptIdx];
135
+
136
+ if (!state.provokedPointIds[_ptId2]) {
137
+ var _flatId2 = _getOrAddFlatId(state, _ptId2, cellId); // mark provoking and add to ibo
138
+
139
+
140
+ state.provokedPointIds[_ptId2] = 1;
141
+ state.cellProvokedMap.set(_ptId2, _flatId2); // when provoking always set the cellId as an original non-provoking value
142
+ // will have been stored and we need to overwrite that
143
+
144
+ state.flatIdToCellId[_flatId2] = cellId;
145
+ state.ibo[state.iboId++] = _flatId2; // insert remaining ptIds (they do not need to provoke)
146
+
147
+ for (var _ptIdx2 = _ptIdx + 1; _ptIdx2 < _ptIdx + numPtIds; _ptIdx2++) {
148
+ _ptId2 = ptIds[_ptIdx2 % numPtIds];
149
+ _flatId2 = _getOrAddFlatId(state, _ptId2, cellId); // add to ibo
150
+
151
+ state.ibo[state.iboId++] = _flatId2;
152
+ } // all done now
153
+
154
+
155
+ return;
156
+ }
157
+ } // if we got here then none of the ptIds could be used to provoke
158
+ // so just duplicate the first one
159
+
160
+
161
+ var ptId = ptIds[0];
162
+ var flatId = state.flatId;
163
+ state.cellProvokedMap.set(ptId, flatId);
164
+ state.flatIdToPointId[state.flatId] = ptId;
165
+ state.flatIdToCellId[state.flatId] = cellId;
166
+ state.flatId++; // add to ibo
167
+
168
+ state.ibo[state.iboId++] = flatId; // insert remaining ptIds (they do not need to provoke)
169
+
170
+ for (var _ptIdx3 = 1; _ptIdx3 < numPtIds; _ptIdx3++) {
171
+ ptId = ptIds[_ptIdx3];
172
+ flatId = _getOrAddFlatId(state, ptId, cellId); // add to ibo
173
+
174
+ state.ibo[state.iboId++] = flatId;
175
+ }
176
+ }
177
+
178
+ function countCell(ptIds, cellId, state) {
179
+ var numPtIds = ptIds.length;
180
+ state.iboSize += numPtIds; // are any points already marked for this cell? If so use that as the provoking point
181
+
182
+ for (var ptIdx = 0; ptIdx < numPtIds; ptIdx++) {
183
+ var ptId = ptIds[ptIdx];
184
+
185
+ if (state.cellProvokedMap.has(ptId)) {
186
+ return;
187
+ }
188
+ } // else have any of the points not been used yet? (not in provokedPointIds)
189
+
190
+
191
+ for (var _ptIdx4 = 0; _ptIdx4 < numPtIds; _ptIdx4++) {
192
+ var _ptId3 = ptIds[_ptIdx4];
193
+
194
+ if (!state.provokedPointIds[_ptId3]) {
195
+ state.provokedPointIds[_ptId3] = 1;
196
+ state.cellProvokedMap.set(_ptId3, 1);
197
+ return;
198
+ }
199
+ } // if we got here then none of the ptIds could be used to provoke
200
+
201
+
202
+ state.cellProvokedMap.set(ptIds[0], 1);
203
+ state.extraPoints++;
204
+ }
205
+
206
+ var processCell;
207
+
208
+ var _single = new Uint32Array(1);
209
+
210
+ var _double = new Uint32Array(2);
211
+
212
+ var _triple = new Uint32Array(3);
213
+
214
+ var _indexCellBuilders = {
215
+ // easy, every input point becomes an output point
216
+ anythingToPoints: function anythingToPoints(numPoints, cellPts, offset, cellId, state) {
217
+ for (var i = 0; i < numPoints; ++i) {
218
+ _single[0] = cellPts[offset + i];
219
+ processCell(_single, cellId, state);
220
+ }
221
+ },
222
+ linesToWireframe: function linesToWireframe(numPoints, cellPts, offset, cellId, state) {
223
+ // for lines we add a bunch of segments
224
+ for (var i = 0; i < numPoints - 1; ++i) {
225
+ _double[0] = cellPts[offset + i];
226
+ _double[1] = cellPts[offset + i + 1];
227
+ processCell(_double, cellId, state);
228
+ }
229
+ },
230
+ polysToWireframe: function polysToWireframe(numPoints, cellPts, offset, cellId, state) {
231
+ // for polys we add a bunch of segments and close it
232
+ if (numPoints > 2) {
233
+ for (var i = 0; i < numPoints; ++i) {
234
+ _double[0] = cellPts[offset + i];
235
+ _double[1] = cellPts[offset + (i + 1) % numPoints];
236
+ processCell(_double, cellId, state);
237
+ }
238
+ }
239
+ },
240
+ stripsToWireframe: function stripsToWireframe(numPoints, cellPts, offset, cellId, state) {
241
+ if (numPoints > 2) {
242
+ // for strips we add a bunch of segments and close it
243
+ for (var i = 0; i < numPoints - 1; ++i) {
244
+ _double[0] = cellPts[offset + i];
245
+ _double[1] = cellPts[offset + i + 1];
246
+ processCell(_double, cellId, state);
247
+ }
248
+
249
+ for (var _i = 0; _i < numPoints - 2; _i++) {
250
+ _double[0] = cellPts[offset + _i];
251
+ _double[1] = cellPts[offset + _i + 2];
252
+ processCell(_double, cellId, state);
253
+ }
254
+ }
255
+ },
256
+ polysToSurface: function polysToSurface(npts, cellPts, offset, cellId, state) {
257
+ for (var i = 0; i < npts - 2; i++) {
258
+ _triple[0] = cellPts[offset];
259
+ _triple[1] = cellPts[offset + i + 1];
260
+ _triple[2] = cellPts[offset + i + 2];
261
+ processCell(_triple, cellId, state);
262
+ }
263
+ },
264
+ stripsToSurface: function stripsToSurface(npts, cellPts, offset, cellId, state) {
265
+ for (var i = 0; i < npts - 2; i++) {
266
+ _triple[0] = cellPts[offset + i];
267
+ _triple[1] = cellPts[offset + i + 1 + i % 2];
268
+ _triple[2] = cellPts[offset + i + 1 + (i + 1) % 2];
269
+ processCell(_triple, cellId, state);
270
+ }
271
+ }
272
+ }; // ----------------------------------------------------------------------------
273
+ // vtkWebGPUIndexBufferManager methods
274
+ // ----------------------------------------------------------------------------
275
+
276
+ function vtkWebGPUIndexBuffer(publicAPI, model) {
277
+ // Set our className
278
+ model.classHierarchy.push('vtkWebGPUIndexBuffer');
279
+
280
+ publicAPI.buildIndexBuffer = function (req) {
281
+ var cellArray = req.cells;
282
+ var primitiveType = req.primitiveType;
283
+ var representation = req.representation;
284
+ var cellOffset = req.cellOffset;
285
+ var array = cellArray.getData();
286
+ var cellArraySize = array.length;
287
+ var inRepName = getPrimitiveName(primitiveType);
288
+ var numPts = req.numberOfPoints;
289
+ var state = {
290
+ provokedPointIds: new Uint8Array(numPts),
291
+ // size is good
292
+ extraPoints: 0,
293
+ iboSize: 0,
294
+ flatId: 0,
295
+ iboId: 0,
296
+ cellProvokedMap: new _LimitedMap()
297
+ };
298
+ var func = null;
299
+
300
+ if (representation === Representation.POINTS || primitiveType === PrimitiveTypes.Points) {
301
+ func = _indexCellBuilders.anythingToPoints;
302
+ } else if (representation === Representation.WIREFRAME || primitiveType === PrimitiveTypes.Lines) {
303
+ func = _indexCellBuilders["".concat(inRepName, "ToWireframe")];
304
+ } else {
305
+ func = _indexCellBuilders["".concat(inRepName, "ToSurface")];
306
+ } // first we count how many extra provoking points we need
307
+
308
+
309
+ processCell = countCell;
310
+ var cellId = cellOffset || 0;
311
+
312
+ for (var cellArrayIndex = 0; cellArrayIndex < cellArraySize;) {
313
+ state.cellProvokedMap.clear();
314
+ func(array[cellArrayIndex], array, cellArrayIndex + 1, cellId, state);
315
+ cellArrayIndex += array[cellArrayIndex] + 1;
316
+ cellId++;
317
+ } // then we allocate the remaining structures
318
+ // (we pick the best size to save space and transfer costs)
319
+
320
+
321
+ if (numPts <= 0xffff) {
322
+ state.flatIdToPointId = new Uint16Array(numPts + state.extraPoints);
323
+ } else {
324
+ state.flatIdToPointId = new Uint32Array(numPts + state.extraPoints);
325
+ }
326
+
327
+ if (numPts + state.extraPoints < 0x8fff) {
328
+ state.pointIdToFlatId = new Int16Array(numPts);
329
+ } else {
330
+ state.pointIdToFlatId = new Int32Array(numPts);
331
+ }
332
+
333
+ if (numPts + state.extraPoints <= 0xffff) {
334
+ state.ibo = new Uint16Array(state.iboSize);
335
+ req.format = 'uint16';
336
+ } else {
337
+ state.ibo = new Uint32Array(state.iboSize);
338
+ req.format = 'uint32';
339
+ }
340
+
341
+ if (cellId <= 0xffff) {
342
+ state.flatIdToCellId = new Uint16Array(numPts + state.extraPoints);
343
+ } else {
344
+ state.flatIdToCellId = new Uint32Array(numPts + state.extraPoints);
345
+ }
346
+
347
+ state.pointIdToFlatId.fill(-1);
348
+ state.provokedPointIds.fill(0); // and fill them in
349
+
350
+ processCell = fillCell;
351
+ cellId = cellOffset || 0;
352
+
353
+ for (var _cellArrayIndex = 0; _cellArrayIndex < cellArraySize;) {
354
+ state.cellProvokedMap.clear();
355
+ func(array[_cellArrayIndex], array, _cellArrayIndex + 1, cellId, state);
356
+ _cellArrayIndex += array[_cellArrayIndex] + 1;
357
+ cellId++;
358
+ }
359
+
360
+ delete state.provokedPointIds;
361
+ delete state.pointIdToFlatId; // store the results we need
362
+
363
+ req.nativeArray = state.ibo;
364
+ model.flatIdToPointId = state.flatIdToPointId;
365
+ model.flatIdToCellId = state.flatIdToCellId;
366
+ model.flatSize = state.flatId;
367
+ model.indexCount = state.iboId;
368
+ };
369
+ } // ----------------------------------------------------------------------------
370
+ // Object factory
371
+ // ----------------------------------------------------------------------------
372
+
373
+
374
+ var DEFAULT_VALUES = {
375
+ flatIdToPointId: null,
376
+ flatIdToCellId: null,
377
+ flatSize: 0,
378
+ indexCount: 0
379
+ }; // ----------------------------------------------------------------------------
380
+
381
+ function extend(publicAPI, model) {
382
+ var initialValues = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
383
+ Object.assign(model, DEFAULT_VALUES, initialValues); // Inheritance
384
+
385
+ vtkWebGPUBuffer.extend(publicAPI, model, initialValues);
386
+ macro.setGet(publicAPI, model, ['flatIdToPointId', 'flatIdToCellId', 'flatSize', 'indexCount']);
387
+ vtkWebGPUIndexBuffer(publicAPI, model);
388
+ } // ----------------------------------------------------------------------------
389
+
390
+ var newInstance = macro.newInstance(extend); // ----------------------------------------------------------------------------
391
+
392
+ var vtkWebGPUIndexBuffer$1 = _objectSpread({
393
+ newInstance: newInstance,
394
+ extend: extend
395
+ }, Constants);
396
+
397
+ export { vtkWebGPUIndexBuffer$1 as default, extend, newInstance };
@@ -1,7 +1,7 @@
1
1
  import { newInstance as newInstance$1, obj, get, setGet } from '../../macros.js';
2
2
  import vtkWebGPUShaderCache from './ShaderCache.js';
3
3
 
4
- var forwarded = ['setBindGroup', 'setVertexBuffer', 'draw']; // ----------------------------------------------------------------------------
4
+ var forwarded = ['setBindGroup', 'setIndexBuffer', 'setVertexBuffer', 'draw', 'drawIndexed']; // ----------------------------------------------------------------------------
5
5
  // vtkWebGPURenderEncoder methods
6
6
  // ----------------------------------------------------------------------------
7
7
 
@@ -179,7 +179,13 @@ function vtkWebGPUSimpleMapper(publicAPI, model) {
179
179
  renderEncoder.activateBindGroup(model.bindGroup); // bind the vertex input
180
180
 
181
181
  pipeline.bindVertexInput(renderEncoder, model.vertexInput);
182
- renderEncoder.draw(model.numberOfVertices, model.numberOfInstances, 0, 0);
182
+ var indexBuffer = model.vertexInput.getIndexBuffer();
183
+
184
+ if (indexBuffer) {
185
+ renderEncoder.drawIndexed(indexBuffer.getIndexCount(), model.numberOfInstances, 0, 0, 0);
186
+ } else {
187
+ renderEncoder.draw(model.numberOfVertices, model.numberOfInstances, 0, 0);
188
+ }
183
189
  };
184
190
 
185
191
  publicAPI.getBindables = function () {
@@ -74,16 +74,15 @@ function vtkWebGPUSphereMapper(publicAPI, model) {
74
74
  publicAPI.setNumberOfInstances(1);
75
75
  publicAPI.setNumberOfVertices(3 * numPoints);
76
76
  var vertexInput = model.vertexInput;
77
- var buffRequest = {
78
- owner: points,
79
- hash: 'spm',
80
- time: points.getMTime(),
81
- usage: BufferUsage.RawVertex,
82
- format: 'float32x3'
83
- };
84
-
85
- if (!model.device.getBufferManager().hasBuffer(buffRequest)) {
86
- // xyz v1 v2 v3
77
+ var hash = "spm".concat(points.getMTime(), "float32x3");
78
+
79
+ if (!model.device.getBufferManager().hasBuffer(hash)) {
80
+ var buffRequest = {
81
+ hash: hash,
82
+ usage: BufferUsage.RawVertex,
83
+ format: 'float32x3'
84
+ }; // xyz v1 v2 v3
85
+
87
86
  var tmpVBO = new Float32Array(3 * numPoints * 3);
88
87
  var pointIdx = 0;
89
88
  var vboIdx = 0;
@@ -117,15 +116,15 @@ function vtkWebGPUSphereMapper(publicAPI, model) {
117
116
  var defaultRadius = model.renderable.getRadius();
118
117
 
119
118
  if (scales || defaultRadius !== model._lastRadius) {
120
- buffRequest = {
121
- owner: scales,
122
- hash: 'spm',
123
- time: scales ? pointData.getArray(model.renderable.getScaleArray()).getMTime() : 0,
124
- usage: BufferUsage.RawVertex,
125
- format: 'float32x2'
126
- };
119
+ hash = "spm".concat(scales ? pointData.getArray(model.renderable.getScaleArray()).getMTime() : defaultRadius, "float32x2");
120
+
121
+ if (!model.device.getBufferManager().hasBuffer(hash)) {
122
+ var _buffRequest = {
123
+ hash: hash,
124
+ usage: BufferUsage.RawVertex,
125
+ format: 'float32x2'
126
+ };
127
127
 
128
- if (!model.device.getBufferManager().hasBuffer(buffRequest)) {
129
128
  var _tmpVBO = new Float32Array(3 * numPoints * 2);
130
129
 
131
130
  var cos30 = Math.cos(radiansFromDegrees(30.0));
@@ -146,9 +145,9 @@ function vtkWebGPUSphereMapper(publicAPI, model) {
146
145
  _tmpVBO[_vboIdx++] = 2.0 * radius;
147
146
  }
148
147
 
149
- buffRequest.nativeArray = _tmpVBO;
148
+ _buffRequest.nativeArray = _tmpVBO;
150
149
 
151
- var _buff = model.device.getBufferManager().getBuffer(buffRequest);
150
+ var _buff = model.device.getBufferManager().getBuffer(_buffRequest);
152
151
 
153
152
  vertexInput.addBuffer(_buff, ['offsetMC']);
154
153
  }
@@ -163,15 +162,14 @@ function vtkWebGPUSphereMapper(publicAPI, model) {
163
162
  var c = model.renderable.getColorMapColors();
164
163
 
165
164
  if (c) {
166
- buffRequest = {
167
- owner: c,
168
- hash: 'spm',
169
- time: c.getMTime(),
170
- usage: BufferUsage.RawVertex,
171
- format: 'unorm8x4'
172
- };
173
-
174
- if (!model.device.getBufferManager().hasBuffer(buffRequest)) {
165
+ hash = "spm".concat(c.getMTime(), "unorm8x4");
166
+
167
+ if (!model.device.getBufferManager().hasBuffer(hash)) {
168
+ var _buffRequest2 = {
169
+ hash: hash,
170
+ usage: BufferUsage.RawVertex,
171
+ format: 'unorm8x4'
172
+ };
175
173
  var colorComponents = c.getNumberOfComponents();
176
174
 
177
175
  if (colorComponents !== 4) {
@@ -194,9 +192,9 @@ function vtkWebGPUSphereMapper(publicAPI, model) {
194
192
  }
195
193
  }
196
194
 
197
- buffRequest.nativeArray = _tmpVBO2;
195
+ _buffRequest2.nativeArray = _tmpVBO2;
198
196
 
199
- var _buff2 = model.device.getBufferManager().getBuffer(buffRequest);
197
+ var _buff2 = model.device.getBufferManager().getBuffer(_buffRequest2);
200
198
 
201
199
  vertexInput.addBuffer(_buff2, ['colorVI']);
202
200
  }
@@ -59,7 +59,7 @@ function vtkWebGPUStickMapper(publicAPI, model) {
59
59
  vDesc.addBuiltinInput('u32', '@builtin(vertex_index) vertexIndex');
60
60
  var fDesc = pipeline.getShaderDescription('fragment');
61
61
  fDesc.addBuiltinOutput('f32', '@builtin(frag_depth) fragDepth');
62
- var stickFrag = "\n // compute the eye position and unit direction\n var vertexVC: vec4<f32>;\n var EyePos: vec3<f32>;\n var EyeDir: vec3<f32>;\n\n if (rendererUBO.cameraParallel != 0u)\n {\n EyePos = vec3<f32>(input.vertexVC.x, input.vertexVC.y, input.vertexVC.z + 3.0*input.radiusVC);\n EyeDir = vec3<f32>(0.0, 0.0, -1.0);\n }\n else\n {\n EyeDir = input.vertexVC.xyz;\n EyePos = vec3<f32>(0.0,0.0,0.0);\n var lengthED: f32 = length(EyeDir);\n EyeDir = normalize(EyeDir);\n // we adjust the EyePos to be closer if it is too far away\n // to prevent floating point precision noise\n if (lengthED > input.radiusVC*3.0)\n {\n EyePos = input.vertexVC.xyz - EyeDir*3.0*input.radiusVC;\n }\n }\n // translate to Sphere center\n EyePos = EyePos - input.centerVC;\n\n // rotate to new basis\n // base1, base2, orientVC\n var base1: vec3<f32>;\n if (abs(input.orientVC.z) < 0.99)\n {\n base1 = normalize(cross(input.orientVC,vec3<f32>(0.0,0.0,1.0)));\n }\n else\n {\n base1 = normalize(cross(input.orientVC,vec3<f32>(0.0,1.0,0.0)));\n }\n var base2: vec3<f32> = cross(input.orientVC,base1);\n EyePos = vec3<f32>(dot(EyePos,base1),dot(EyePos,base2),dot(EyePos,input.orientVC));\n EyeDir = vec3<f32>(dot(EyeDir,base1),dot(EyeDir,base2),dot(EyeDir,input.orientVC));\n\n // scale to radius 1.0\n EyePos = EyePos * (1.0 / input.radiusVC);\n\n // find the intersection\n var a: f32 = EyeDir.x*EyeDir.x + EyeDir.y*EyeDir.y;\n var b: f32 = 2.0*(EyePos.x*EyeDir.x + EyePos.y*EyeDir.y);\n var c: f32 = EyePos.x*EyePos.x + EyePos.y*EyePos.y - 1.0;\n var d: f32 = b*b - 4.0*a*c;\n var normal: vec3<f32> = vec3<f32>(0.0,0.0,1.0);\n if (d < 0.0) { discard; }\n else\n {\n var t: f32 = (-b - sqrt(d))*(0.5 / a);\n var tz: f32 = EyePos.z + t*EyeDir.z;\n var iPoint: vec3<f32> = EyePos + t*EyeDir;\n if (abs(iPoint.z)*input.radiusVC > input.lengthVC*0.5)\n {\n // test for end cap\n var t2: f32 = (-b + sqrt(d))*(0.5 / a);\n var tz2: f32 = EyePos.z + t2*EyeDir.z;\n if (tz2*input.radiusVC > input.lengthVC*0.5 || tz*input.radiusVC < -0.5*input.lengthVC) { discard; }\n else\n {\n normal = input.orientVC;\n var t3: f32 = (input.lengthVC*0.5/input.radiusVC - EyePos.z)/EyeDir.z;\n iPoint = EyePos + t3*EyeDir;\n vertexVC = vec4<f32>(input.radiusVC*(iPoint.x*base1 + iPoint.y*base2 + iPoint.z*input.orientVC) + input.centerVC, 1.0);\n }\n }\n else\n {\n // The normal is the iPoint.xy rotated back into VC\n normal = iPoint.x*base1 + iPoint.y*base2;\n // rescale rerotate and translate\n vertexVC = vec4<f32>(input.radiusVC*(normal + iPoint.z*input.orientVC) + input.centerVC, 1.0);\n }\n // compute the pixel's depth\n var pos: vec4<f32> = rendererUBO.VCPCMatrix * vertexVC;\n output.fragDepth = pos.z / pos.w;\n }\n ";
62
+ var stickFrag = "\n // compute the eye position and unit direction\n var vertexVC: vec4<f32>;\n var EyePos: vec3<f32>;\n var EyeDir: vec3<f32>;\n\n if (rendererUBO.cameraParallel != 0u)\n {\n EyePos = vec3<f32>(input.vertexVC.x, input.vertexVC.y, input.vertexVC.z + 3.0*input.radiusVC);\n EyeDir = vec3<f32>(0.0, 0.0, -1.0);\n }\n else\n {\n EyeDir = input.vertexVC.xyz;\n EyePos = vec3<f32>(0.0,0.0,0.0);\n var lengthED: f32 = length(EyeDir);\n EyeDir = normalize(EyeDir);\n // we adjust the EyePos to be closer if it is too far away\n // to prevent floating point precision noise\n if (lengthED > input.radiusVC*3.0)\n {\n EyePos = input.vertexVC.xyz - EyeDir*3.0*input.radiusVC;\n }\n }\n // translate to Sphere center\n EyePos = EyePos - input.centerVC;\n\n // rotate to new basis\n // base1, base2, orientVC\n var base1: vec3<f32>;\n if (abs(input.orientVC.z) < 0.99)\n {\n base1 = normalize(cross(input.orientVC,vec3<f32>(0.0,0.0,1.0)));\n }\n else\n {\n base1 = normalize(cross(input.orientVC,vec3<f32>(0.0,1.0,0.0)));\n }\n var base2: vec3<f32> = cross(input.orientVC,base1);\n EyePos = vec3<f32>(dot(EyePos,base1),dot(EyePos,base2),dot(EyePos,input.orientVC));\n EyeDir = vec3<f32>(dot(EyeDir,base1),dot(EyeDir,base2),dot(EyeDir,input.orientVC));\n\n // scale to radius 1.0\n EyePos = EyePos * (1.0 / input.radiusVC);\n\n // find the intersection\n var a: f32 = EyeDir.x*EyeDir.x + EyeDir.y*EyeDir.y;\n var b: f32 = 2.0*(EyePos.x*EyeDir.x + EyePos.y*EyeDir.y);\n var c: f32 = EyePos.x*EyePos.x + EyePos.y*EyePos.y - 1.0;\n var d: f32 = b*b - 4.0*a*c;\n var normal: vec3<f32> = vec3<f32>(0.0,0.0,1.0);\n if (d < 0.0) { discard; }\n else\n {\n var t: f32 = (-b - sqrt(d))*(0.5 / a);\n var tz: f32 = EyePos.z + t*EyeDir.z;\n var iPoint: vec3<f32> = EyePos + t*EyeDir;\n if (abs(iPoint.z)*input.radiusVC > input.lengthVC*0.5)\n {\n // test for end cap\n var t2: f32 = (-b + sqrt(d))*(0.5 / a);\n var tz2: f32 = EyePos.z + t2*EyeDir.z;\n if (tz2*input.radiusVC > input.lengthVC*0.5 || tz*input.radiusVC < -0.5*input.lengthVC) { discard; }\n else\n {\n normal = input.orientVC;\n var t3: f32 = (input.lengthVC*0.5/input.radiusVC - EyePos.z)/EyeDir.z;\n iPoint = EyePos + t3*EyeDir;\n vertexVC = vec4<f32>(input.radiusVC*(iPoint.x*base1 + iPoint.y*base2 + iPoint.z*input.orientVC) + input.centerVC, 1.0);\n }\n }\n else\n {\n // The normal is the iPoint.xy rotated back into VC\n normal = iPoint.x*base1 + iPoint.y*base2;\n // rescale rerotate and translate\n vertexVC = vec4<f32>(input.radiusVC*(normal + iPoint.z*input.orientVC) + input.centerVC, 1.0);\n }\n }\n // compute the pixel's depth\n var pos: vec4<f32> = rendererUBO.VCPCMatrix * vertexVC;\n output.fragDepth = pos.z / pos.w;\n ";
63
63
  var code = fDesc.getCode();
64
64
  code = vtkWebGPUShaderCache.substitute(code, '//VTK::Normal::Impl', [stickFrag]).result;
65
65
  fDesc.setCode(code);
@@ -97,16 +97,15 @@ function vtkWebGPUStickMapper(publicAPI, model) {
97
97
  publicAPI.setNumberOfInstances(numPoints);
98
98
  publicAPI.setNumberOfVertices(12);
99
99
  var vertexInput = model.vertexInput;
100
- var buffRequest = {
101
- owner: points,
102
- hash: 'stm',
103
- time: points.getMTime(),
104
- usage: BufferUsage.RawVertex,
105
- format: 'float32x3'
106
- };
107
-
108
- if (!device.getBufferManager().hasBuffer(buffRequest)) {
109
- // xyz v1 v2 v3
100
+ var hash = "stm".concat(points.getMTime(), "float32x3");
101
+
102
+ if (!device.getBufferManager().hasBuffer(hash)) {
103
+ var buffRequest = {
104
+ hash: hash,
105
+ usage: BufferUsage.RawVertex,
106
+ format: 'float32x3'
107
+ }; // xyz v1 v2 v3
108
+
110
109
  var tmpVBO = new Float32Array(numPoints * 3);
111
110
  var pointIdx = 0;
112
111
  var vboIdx = 0;
@@ -133,15 +132,15 @@ function vtkWebGPUStickMapper(publicAPI, model) {
133
132
  var defaultRadius = model.renderable.getRadius();
134
133
 
135
134
  if (scales || defaultRadius !== model._lastRadius) {
136
- buffRequest = {
137
- owner: scales,
138
- hash: 'stm',
139
- time: scales ? pointData.getArray(model.renderable.getScaleArray()).getMTime() : 0,
140
- usage: BufferUsage.RawVertex,
141
- format: 'float32'
142
- };
135
+ hash = "stm".concat(scales ? pointData.getArray(model.renderable.getScaleArray()).getMTime() : defaultRadius, "float32");
136
+
137
+ if (!device.getBufferManager().hasBuffer(hash)) {
138
+ var _buffRequest = {
139
+ hash: hash,
140
+ usage: BufferUsage.RawVertex,
141
+ format: 'float32'
142
+ };
143
143
 
144
- if (!device.getBufferManager().hasBuffer(buffRequest)) {
145
144
  var _tmpVBO = new Float32Array(numPoints);
146
145
 
147
146
  var _vboIdx = 0;
@@ -156,9 +155,9 @@ function vtkWebGPUStickMapper(publicAPI, model) {
156
155
  _tmpVBO[_vboIdx++] = radius;
157
156
  }
158
157
 
159
- buffRequest.nativeArray = _tmpVBO;
158
+ _buffRequest.nativeArray = _tmpVBO;
160
159
 
161
- var _buff = device.getBufferManager().getBuffer(buffRequest);
160
+ var _buff = device.getBufferManager().getBuffer(_buffRequest);
162
161
 
163
162
  vertexInput.addBuffer(_buff, ['radiusMC'], 'instance');
164
163
  }
@@ -174,16 +173,15 @@ function vtkWebGPUStickMapper(publicAPI, model) {
174
173
  vtkErrorMacro(['Error setting orientationArray.\n', 'You have to specify the stick orientation']);
175
174
  }
176
175
 
177
- buffRequest = {
178
- owner: orientationArray,
179
- hash: 'stm',
180
- time: pointData.getArray(model.renderable.getOrientationArray()).getMTime(),
181
- usage: BufferUsage.RawVertex,
182
- format: 'float32x3'
183
- };
176
+ hash = "stm".concat(pointData.getArray(model.renderable.getOrientationArray()).getMTime(), "float32x3");
177
+
178
+ if (!device.getBufferManager().hasBuffer(hash)) {
179
+ var _buffRequest2 = {
180
+ hash: hash,
181
+ usage: BufferUsage.RawVertex,
182
+ format: 'float32x3'
183
+ }; // xyz v1 v2 v3
184
184
 
185
- if (!device.getBufferManager().hasBuffer(buffRequest)) {
186
- // xyz v1 v2 v3
187
185
  var _tmpVBO2 = new Float32Array(numPoints * 3);
188
186
 
189
187
  var _pointIdx = 0;
@@ -202,9 +200,9 @@ function vtkWebGPUStickMapper(publicAPI, model) {
202
200
  _tmpVBO2[_vboIdx2++] = orientationArray[_pointIdx + 2] * length;
203
201
  }
204
202
 
205
- buffRequest.nativeArray = _tmpVBO2;
203
+ _buffRequest2.nativeArray = _tmpVBO2;
206
204
 
207
- var _buff2 = device.getBufferManager().getBuffer(buffRequest);
205
+ var _buff2 = device.getBufferManager().getBuffer(_buffRequest2);
208
206
 
209
207
  vertexInput.addBuffer(_buff2, ['orientMC'], 'instance');
210
208
  } // deal with colors but only if modified
@@ -216,15 +214,13 @@ function vtkWebGPUStickMapper(publicAPI, model) {
216
214
  var c = model.renderable.getColorMapColors();
217
215
 
218
216
  if (c) {
219
- buffRequest = {
220
- owner: c,
221
- hash: 'stm',
222
- time: c.getMTime(),
223
- usage: BufferUsage.RawVertex,
224
- format: 'unorm8x4'
225
- };
217
+ hash = "stm".concat(c.getMTime(), "unorm8x4");
226
218
 
227
- if (!device.getBufferManager().hasBuffer(buffRequest)) {
219
+ if (!device.getBufferManager().hasBuffer(hash)) {
220
+ var _buffRequest3 = {
221
+ usage: BufferUsage.RawVertex,
222
+ format: 'unorm8x4'
223
+ };
228
224
  var colorComponents = c.getNumberOfComponents();
229
225
 
230
226
  if (colorComponents !== 4) {
@@ -244,9 +240,9 @@ function vtkWebGPUStickMapper(publicAPI, model) {
244
240
  _tmpVBO3[_vboIdx3++] = colorData[colorIdx + 3];
245
241
  }
246
242
 
247
- buffRequest.nativeArray = _tmpVBO3;
243
+ _buffRequest3.nativeArray = _tmpVBO3;
248
244
 
249
- var _buff3 = device.getBufferManager().getBuffer(buffRequest);
245
+ var _buff3 = device.getBufferManager().getBuffer(_buffRequest3);
250
246
 
251
247
  vertexInput.addBuffer(_buff3, ['colorVI'], 'instance');
252
248
  }
@@ -40,7 +40,6 @@ function vtkWebGPUStorageBuffer(publicAPI, model) {
40
40
  if (!model._buffer) {
41
41
  var req = {
42
42
  nativeArray: model.Float32Array,
43
- time: 0,
44
43
  usage: BufferUsage.Storage,
45
44
  label: model.label
46
45
  };