@shapediver/viewer.rendering-engine.intersection-engine 3.1.2 → 3.2.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.
@@ -1,27 +1,34 @@
1
- import { ITreeNode } from "@shapediver/viewer.shared.node-tree";
2
- import { RENDERER_TYPE } from "@shapediver/viewer.rendering-engine.rendering-engine";
3
- import { IIntersectionFilter } from "../interfaces/IIntersectionFilter";
4
- import { IRay } from "../interfaces/IRay";
5
- import { IIntersection } from "../interfaces/IIntersection";
6
- import { IIntersectionEngine } from "../interfaces/IIntersectionEngine";
1
+ import { GeometryData } from '@shapediver/viewer.shared.types';
2
+ import { IIntersection } from '../interfaces/IIntersection';
3
+ import { IIntersectionEngine } from '../interfaces/IIntersectionEngine';
4
+ import { IIntersectionFilter } from '../interfaces/IIntersectionFilter';
5
+ import { IRay } from '../interfaces/IRay';
6
+ import { ITreeNode } from '@shapediver/viewer.shared.node-tree';
7
7
  export declare class IntersectionEngine implements IIntersectionEngine {
8
8
  private readonly _eventEngine;
9
+ private readonly _raycaster;
9
10
  private readonly _tree;
10
11
  private static _instance;
11
12
  private _intersectNodes;
12
13
  private constructor();
13
14
  static get instance(): IntersectionEngine;
14
- intersect(ray: IRay, filterCriteria?: IIntersectionFilter[], intersectionOptions?: {
15
- opacity: number;
16
- rendererType: RENDERER_TYPE;
17
- }, root?: ITreeNode, viewerID?: string): IIntersection[];
18
- intersectNode(node: ITreeNode, rayIn: IRay, intersectionOptions?: {
19
- opacity: number;
20
- rendererType: RENDERER_TYPE;
21
- }): IIntersection[] | undefined;
22
- private checkIntersection;
23
- private checkLineIntersection;
24
- private checkPointIntersection;
15
+ intersect(ray: IRay, viewportId: string, filterCriteria?: IIntersectionFilter[]): IIntersection[];
16
+ intersectNode(ray: IRay, node: ITreeNode, geometryData: {
17
+ [key: string]: GeometryData;
18
+ }, viewportId: string, filterCriteria?: IIntersectionFilter[]): IIntersection[] | undefined;
19
+ /**
20
+ * Gather all nodes that contain geometry data.
21
+ */
25
22
  private gatherNodes;
23
+ /**
24
+ * Do the intersection test with the ray and the node.
25
+ *
26
+ * @param ray the ray to test
27
+ * @param node the node to test
28
+ * @param geometryData the geometry data of the node
29
+ * @param viewportId the viewport id
30
+ * @returns
31
+ */
32
+ private intersectionTest;
26
33
  }
27
34
  //# sourceMappingURL=IntersectionEngine.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"IntersectionEngine.d.ts","sourceRoot":"","sources":["../../src/implementation/IntersectionEngine.ts"],"names":[],"mappings":"AAGA,OAAO,EAAS,SAAS,EAAkB,MAAM,qCAAqC,CAAC;AACvF,OAAO,EAAE,aAAa,EAAE,MAAM,sDAAsD,CAAC;AACrF,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAGxE,qBAAa,kBAAmB,YAAW,mBAAmB;IAG1D,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAqC;IAClE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAwB;IAE9C,OAAO,CAAC,MAAM,CAAC,SAAS,CAAqB;IAE7C,OAAO,CAAC,eAAe,CAKd;IAMT,OAAO;IAWP,WAAkB,QAAQ,uBAEzB;IAOM,SAAS,CACZ,GAAG,EAAE,IAAI,EACT,cAAc,CAAC,EAAE,mBAAmB,EAAE,EACtC,mBAAmB,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,aAAa,CAAA;KAAE,EACtE,IAAI,GAAE,SAA2B,EACjC,QAAQ,CAAC,EAAE,MAAM,GAClB,aAAa,EAAE;IAuCX,aAAa,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,mBAAmB,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,aAAa,CAAA;KAAE,GAAG,aAAa,EAAE,GAAG,SAAS;IA6LvJ,OAAO,CAAC,iBAAiB;IAqBzB,OAAO,CAAC,qBAAqB;IA2C7B,OAAO,CAAC,sBAAsB;IAuB9B,OAAO,CAAC,WAAW;CA8BtB"}
1
+ {"version":3,"file":"IntersectionEngine.d.ts","sourceRoot":"","sources":["../../src/implementation/IntersectionEngine.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC1C,OAAO,EAAS,SAAS,EAAQ,MAAM,qCAAqC,CAAC;AAE7E,qBAAa,kBAAmB,YAAW,mBAAmB;IAG1D,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAqC;IAClE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA0C;IACrE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAwB;IAE9C,OAAO,CAAC,MAAM,CAAC,SAAS,CAAqB;IAE7C,OAAO,CAAC,eAAe,CAMd;IAMT,OAAO;IAWP,WAAkB,QAAQ,uBAEzB;IAMM,SAAS,CACZ,GAAG,EAAE,IAAI,EACT,UAAU,EAAE,MAAM,EAClB,cAAc,CAAC,EAAE,mBAAmB,EAAE,GACvC,aAAa,EAAE;IAWX,aAAa,CAChB,GAAG,EAAE,IAAI,EACT,IAAI,EAAE,SAAS,EACf,YAAY,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,CAAA;KAAE,EAC7C,UAAU,EAAE,MAAM,EAClB,cAAc,CAAC,EAAE,mBAAmB,EAAE,GACvC,aAAa,EAAE,GAAG,SAAS;IAsB9B;;OAEG;IACH,OAAO,CAAC,WAAW;IA6BnB;;;;;;;;OAQG;IACH,OAAO,CAAC,gBAAgB;CA+B3B"}
@@ -1,18 +1,40 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
2
25
  Object.defineProperty(exports, "__esModule", { value: true });
3
26
  exports.IntersectionEngine = void 0;
27
+ const THREE = __importStar(require("three"));
28
+ const viewer_shared_services_1 = require("@shapediver/viewer.shared.services");
4
29
  const viewer_shared_types_1 = require("@shapediver/viewer.shared.types");
5
- const gl_matrix_1 = require("gl-matrix");
6
- const viewer_shared_math_1 = require("@shapediver/viewer.shared.math");
7
30
  const viewer_shared_node_tree_1 = require("@shapediver/viewer.shared.node-tree");
8
- const viewer_rendering_engine_rendering_engine_1 = require("@shapediver/viewer.rendering-engine.rendering-engine");
9
- const viewer_shared_services_1 = require("@shapediver/viewer.shared.services");
10
31
  class IntersectionEngine {
11
- // #endregion Properties (4)
32
+ // #endregion Properties (5)
12
33
  // #region Constructors (1)
13
34
  constructor() {
14
- // #region Properties (4)
35
+ // #region Properties (5)
15
36
  this._eventEngine = viewer_shared_services_1.EventEngine.instance;
37
+ this._raycaster = new THREE.Raycaster();
16
38
  this._tree = viewer_shared_node_tree_1.Tree.instance;
17
39
  this._intersectNodes = [];
18
40
  this.gatherNodes();
@@ -21,301 +43,46 @@ class IntersectionEngine {
21
43
  });
22
44
  }
23
45
  // #endregion Constructors (1)
24
- // #region Public Static Accessors (1)
46
+ // #region Public Static Getters And Setters (1)
25
47
  static get instance() {
26
48
  return this._instance || (this._instance = new this());
27
49
  }
28
- // #endregion Public Static Accessors (1)
50
+ // #endregion Public Static Getters And Setters (1)
29
51
  // #region Public Methods (2)
30
- intersect(ray, filterCriteria, intersectionOptions, root = this._tree.root, viewerID) {
52
+ intersect(ray, viewportId, filterCriteria) {
31
53
  let intersections = [];
32
- const intersectNode = (node, visible, excludeViewports, restrictViewports) => {
33
- if (visible === false)
34
- return;
35
- if (viewerID !== undefined) {
36
- if (excludeViewports.includes(viewerID))
37
- return;
38
- if (restrictViewports.length > 0 && !restrictViewports.includes(viewerID))
39
- return;
40
- }
41
- if (filterCriteria) {
42
- for (let i = 0; i < filterCriteria.length; i++) {
43
- if (filterCriteria[i](node)) {
44
- const intersection = this.intersectNode(node, ray, intersectionOptions);
45
- if (intersection) {
46
- intersection.forEach(i => i.node = node);
47
- intersections = intersections.concat(intersection);
48
- }
49
- break;
50
- }
51
- }
52
- }
53
- else {
54
- const intersection = this.intersectNode(node, ray);
55
- if (intersection) {
56
- intersection.forEach(i => i.node = node);
57
- intersections = intersections.concat(intersection);
58
- }
59
- }
60
- for (let i = 0; i < node.children.length; i++)
61
- intersectNode(node.children[i], visible && node.children[i].visible, excludeViewports.concat(node.children[i].excludeViewports), restrictViewports.concat(node.children[i].restrictViewports));
62
- };
63
- for (let i = 0; i < this._intersectNodes.length; i++)
64
- intersectNode(this._intersectNodes[i].node, this._intersectNodes[i].visible, this._intersectNodes[i].excludeViewports, this._intersectNodes[i].restrictViewports);
54
+ this._intersectNodes.forEach(i => {
55
+ const currentIntersections = this.intersectNode(ray, i.node, i.geometryData, viewportId, filterCriteria);
56
+ if (currentIntersections)
57
+ intersections = intersections.concat(currentIntersections);
58
+ });
65
59
  intersections.sort((a, b) => a.distance - b.distance);
66
60
  return intersections;
67
61
  }
68
- intersectNode(node, rayIn, intersectionOptions) {
62
+ intersectNode(ray, node, geometryData, viewportId, filterCriteria) {
69
63
  if (node.visible === false)
70
64
  return;
71
- const inverseMatrix = gl_matrix_1.mat4.invert(gl_matrix_1.mat4.create(), node.worldMatrix);
72
- const ray = {
73
- origin: gl_matrix_1.vec3.transformMat4(gl_matrix_1.vec3.create(), rayIn.origin, inverseMatrix),
74
- direction: gl_matrix_1.vec3.normalize(gl_matrix_1.vec3.create(), gl_matrix_1.vec3.fromValues(inverseMatrix[0] * rayIn.direction[0] + inverseMatrix[4] * rayIn.direction[1] + inverseMatrix[8] * rayIn.direction[2], inverseMatrix[1] * rayIn.direction[0] + inverseMatrix[5] * rayIn.direction[1] + inverseMatrix[9] * rayIn.direction[2], inverseMatrix[2] * rayIn.direction[0] + inverseMatrix[6] * rayIn.direction[1] + inverseMatrix[10] * rayIn.direction[2]))
75
- };
76
- let geometryData;
77
- for (let i = 0; i < node.data.length; i++) {
78
- if (node.data[i] instanceof viewer_shared_types_1.GeometryData) {
79
- geometryData = node.data[i];
80
- break;
81
- }
82
- }
83
- // quick out if the material does not fit the intersection options
84
- if (geometryData && intersectionOptions) {
85
- let materialData = null;
86
- if (geometryData.effectMaterials.length > 0) {
87
- materialData = geometryData.effectMaterials[geometryData.effectMaterials.length - 1].material;
88
- }
89
- else if (intersectionOptions.rendererType === viewer_rendering_engine_rendering_engine_1.RENDERER_TYPE.ATTRIBUTES) {
90
- materialData = geometryData.attributeMaterial;
91
- }
92
- else {
93
- materialData = geometryData.material;
94
- }
95
- // if opacity <= intersectionOptions.opacity
96
- if (materialData && materialData.opacity <= intersectionOptions.opacity)
97
- return;
98
- }
99
- if (!geometryData) {
100
- let intersections = [];
101
- for (let i = 0; i < node.children.length; i++) {
102
- let intersection = this.intersectNode(node.children[i], rayIn, intersectionOptions);
103
- if (intersection)
104
- intersections = intersections.concat(intersection);
105
- }
106
- if (intersections.length > 0) {
107
- intersections.sort((a, b) => a.distance - b.distance);
108
- return intersections;
109
- }
110
- return;
111
- }
112
- else if (geometryData.mode === viewer_shared_types_1.PRIMITIVE_MODE.LINES) {
113
- // if (node.boundingBox.boundingSphere.intersects(ray.origin, ray.direction) === false) return;
114
- if (node.boundingBox.intersects(rayIn.origin, rayIn.direction) === false)
65
+ if (viewportId !== undefined) {
66
+ if (node.excludeViewports.includes(viewportId))
115
67
  return;
116
- const index = geometryData.primitive.indices;
117
- const position = geometryData.primitive.attributes['POSITION'];
118
- const radius = 0.1;
119
- let intersections = [];
120
- if (index !== null) {
121
- // indexed buffer geometry
122
- for (let i = 0, il = +index.count; i < il; i += 2) {
123
- const a = index.array[(i) * index.itemSize];
124
- const b = index.array[(i + 1) * index.itemSize];
125
- let intersection = this.checkLineIntersection(node, ray, radius, gl_matrix_1.vec3.fromValues(position.array[a * position.itemSize], position.array[a * position.itemSize + 1], position.array[a * position.itemSize + 2]), gl_matrix_1.vec3.fromValues(position.array[b * position.itemSize], position.array[b * position.itemSize + 1], position.array[b * position.itemSize + 2]));
126
- if (intersection)
127
- intersections.push(Object.assign(intersection, { geometryData }));
128
- }
129
- }
130
- else if (position !== undefined) {
131
- // non-indexed buffer geometry
132
- for (let i = 0, il = +position.count; i < il; i += 2) {
133
- const a = i;
134
- const b = i + 1;
135
- let intersection = this.checkLineIntersection(node, ray, radius, gl_matrix_1.vec3.fromValues(position.array[a * position.itemSize], position.array[a * position.itemSize + 1], position.array[a * position.itemSize + 2]), gl_matrix_1.vec3.fromValues(position.array[b * position.itemSize], position.array[b * position.itemSize + 1], position.array[b * position.itemSize + 2]));
136
- if (intersection)
137
- intersections.push(Object.assign(intersection, { geometryData }));
138
- }
139
- }
140
- intersections.sort((a, b) => a.distance - b.distance);
141
- intersections.forEach(i => i.point = gl_matrix_1.vec3.transformMat4(i.point, i.point, node.worldMatrix));
142
- return intersections;
143
- }
144
- else if (geometryData.mode === viewer_shared_types_1.PRIMITIVE_MODE.LINE_LOOP || geometryData.mode === viewer_shared_types_1.PRIMITIVE_MODE.LINE_STRIP) {
145
- // if (node.boundingBox.boundingSphere.intersects(ray.origin, ray.direction) === false) return;
146
- if (node.boundingBox.intersects(rayIn.origin, rayIn.direction) === false)
68
+ if (node.restrictViewports.length > 0 && !node.restrictViewports.includes(viewportId))
147
69
  return;
148
- const index = geometryData.primitive.indices;
149
- const position = geometryData.primitive.attributes['POSITION'];
150
- const radius = 0.1;
151
- let intersections = [];
152
- if (index !== null) {
153
- // indexed buffer geometry
154
- for (let i = 0, il = +index.count - 1; i < il; i++) {
155
- const a = index.array[(i) * index.itemSize];
156
- const b = index.array[(i + 1) * index.itemSize];
157
- let intersection = this.checkLineIntersection(node, ray, radius, gl_matrix_1.vec3.fromValues(position.array[a * position.itemSize], position.array[a * position.itemSize + 1], position.array[a * position.itemSize + 2]), gl_matrix_1.vec3.fromValues(position.array[b * position.itemSize], position.array[b * position.itemSize + 1], position.array[b * position.itemSize + 2]));
158
- if (intersection)
159
- intersections.push(Object.assign(intersection, { geometryData }));
160
- }
161
- }
162
- else if (position !== undefined) {
163
- // non-indexed buffer geometry
164
- for (let i = 0, il = +position.count; i < il; i += 2) {
165
- const a = i;
166
- const b = i + 1;
167
- let intersection = this.checkLineIntersection(node, ray, radius, gl_matrix_1.vec3.fromValues(position.array[a * position.itemSize], position.array[a * position.itemSize + 1], position.array[a * position.itemSize + 2]), gl_matrix_1.vec3.fromValues(position.array[b * position.itemSize], position.array[b * position.itemSize + 1], position.array[b * position.itemSize + 2]));
168
- if (intersection)
169
- intersections.push(Object.assign(intersection, { geometryData }));
170
- }
171
- }
172
- intersections.sort((a, b) => a.distance - b.distance);
173
- intersections.forEach(i => i.point = gl_matrix_1.vec3.transformMat4(i.point, i.point, node.worldMatrix));
174
- return intersections;
175
70
  }
176
- else if (geometryData.mode === viewer_shared_types_1.PRIMITIVE_MODE.POINTS) {
177
- const position = geometryData.primitive.attributes['POSITION'];
178
- const radius = 0.1;
179
- let intersections = [];
180
- if (position !== undefined) {
181
- // non-indexed buffer geometry
182
- for (let i = 0, il = +position.count; i < il; i++) {
183
- let intersection = this.checkPointIntersection(node, ray, radius, gl_matrix_1.vec3.fromValues(position.array[i * position.itemSize], position.array[i * position.itemSize + 1], position.array[i * position.itemSize + 2]));
184
- if (intersection)
185
- intersections.push(Object.assign(intersection, { geometryData }));
186
- }
71
+ if (filterCriteria) {
72
+ for (let i = 0; i < filterCriteria.length; i++) {
73
+ if (filterCriteria[i](node))
74
+ return this.intersectionTest(ray, node, geometryData, viewportId);
187
75
  }
188
- intersections.sort((a, b) => a.distance - b.distance);
189
- intersections.forEach(i => i.point = gl_matrix_1.vec3.transformMat4(i.point, i.point, node.worldMatrix));
190
- return intersections;
191
76
  }
192
77
  else {
193
- // Here, Vector is a vector in Rn, not a dynamic array.
194
- let v = gl_matrix_1.vec3.sub(gl_matrix_1.vec3.create(), node.boundingBox.boundingSphere.center, rayIn.origin);
195
- let dotProd = gl_matrix_1.vec3.dot(v, rayIn.direction);
196
- dotProd = Math.max(dotProd, 0.0); // if dotProd is negative, the closest point is in the opposite direction to d.
197
- let e = gl_matrix_1.vec3.add(gl_matrix_1.vec3.create(), rayIn.origin, gl_matrix_1.vec3.scale(gl_matrix_1.vec3.create(), rayIn.direction, dotProd));
198
- let squaredDistance = gl_matrix_1.vec3.squaredDistance(e, node.boundingBox.boundingSphere.center);
199
- if (squaredDistance > node.boundingBox.boundingSphere.radius * node.boundingBox.boundingSphere.radius)
200
- return;
201
- // if (node.boundingBox.boundingSphere.intersects(ray.origin, ray.direction) === false) return;
202
- if (node.boundingBox.intersects(rayIn.origin, rayIn.direction) === false)
203
- return;
204
- const material = geometryData.material;
205
- const index = geometryData.primitive.indices;
206
- const position = geometryData.primitive.attributes['POSITION'];
207
- let intersections = [];
208
- if (index !== null) {
209
- // indexed buffer geometry
210
- for (let i = 0, il = +index.count; i < il; i += 3) {
211
- const a = index.array[(i) * index.itemSize];
212
- const b = index.array[(i + 1) * index.itemSize];
213
- const c = index.array[(i + 2) * index.itemSize];
214
- let intersection = this.checkIntersection(node, material, ray, gl_matrix_1.vec3.fromValues(position.array[a * position.itemSize], position.array[a * position.itemSize + 1], position.array[a * position.itemSize + 2]), gl_matrix_1.vec3.fromValues(position.array[b * position.itemSize], position.array[b * position.itemSize + 1], position.array[b * position.itemSize + 2]), gl_matrix_1.vec3.fromValues(position.array[c * position.itemSize], position.array[c * position.itemSize + 1], position.array[c * position.itemSize + 2]));
215
- if (intersection)
216
- intersections.push(Object.assign(intersection, { geometryData }));
217
- }
218
- }
219
- else if (position !== undefined) {
220
- // non-indexed buffer geometry
221
- for (let i = 0, il = +position.count; i < il; i += 3) {
222
- const a = i;
223
- const b = i + 1;
224
- const c = i + 2;
225
- let intersection = this.checkIntersection(node, material, ray, gl_matrix_1.vec3.fromValues(position.array[a * position.itemSize], position.array[a * position.itemSize + 1], position.array[a * position.itemSize + 2]), gl_matrix_1.vec3.fromValues(position.array[b * position.itemSize], position.array[b * position.itemSize + 1], position.array[b * position.itemSize + 2]), gl_matrix_1.vec3.fromValues(position.array[c * position.itemSize], position.array[c * position.itemSize + 1], position.array[c * position.itemSize + 2]));
226
- if (intersection)
227
- intersections.push(Object.assign(intersection, { geometryData }));
228
- }
229
- }
230
- intersections.sort((a, b) => a.distance - b.distance);
231
- intersections.forEach(i => i.point = gl_matrix_1.vec3.transformMat4(i.point, i.point, node.worldMatrix));
232
- return intersections;
78
+ return this.intersectionTest(ray, node, geometryData, viewportId);
233
79
  }
234
80
  }
235
81
  // #endregion Public Methods (2)
236
- // #region Private Methods (4)
237
- checkIntersection(node, material, ray, pA, pB, pC) {
238
- let point;
239
- if (material && material.side === viewer_shared_types_1.MATERIAL_SIDE.BACK) {
240
- const triangle = new viewer_shared_math_1.Triangle(pC, pB, pA);
241
- point = triangle.intersect(ray.origin, ray.direction);
242
- }
243
- else {
244
- const triangle = new viewer_shared_math_1.Triangle(pA, pB, pC);
245
- point = triangle.intersect(ray.origin, ray.direction);
246
- }
247
- if (point === null)
248
- return;
249
- const distance = gl_matrix_1.vec3.distance(ray.origin, point);
250
- return {
251
- distance: distance,
252
- point: gl_matrix_1.vec3.clone(point),
253
- node
254
- };
255
- }
256
- checkLineIntersection(node, ray, radius, pA, pB) {
257
- const direction = gl_matrix_1.vec3.sub(gl_matrix_1.vec3.create(), pB, pA);
258
- const lineLength = gl_matrix_1.vec3.length(direction);
259
- const lineRay = {
260
- origin: pA,
261
- direction: gl_matrix_1.vec3.divide(gl_matrix_1.vec3.create(), direction, gl_matrix_1.vec3.fromValues(lineLength, lineLength, lineLength))
262
- };
263
- const planeNormal = gl_matrix_1.vec3.cross(gl_matrix_1.vec3.create(), ray.direction, lineRay.direction);
264
- const Na = gl_matrix_1.vec3.normalize(gl_matrix_1.vec3.create(), gl_matrix_1.vec3.cross(gl_matrix_1.vec3.create(), ray.direction, planeNormal));
265
- const Nb = gl_matrix_1.vec3.normalize(gl_matrix_1.vec3.create(), gl_matrix_1.vec3.cross(gl_matrix_1.vec3.create(), lineRay.direction, planeNormal));
266
- const da = gl_matrix_1.vec3.dot(gl_matrix_1.vec3.sub(gl_matrix_1.vec3.create(), pA, ray.origin), Nb) / gl_matrix_1.vec3.dot(ray.direction, Nb);
267
- const db = gl_matrix_1.vec3.dot(gl_matrix_1.vec3.sub(gl_matrix_1.vec3.create(), ray.origin, pA), Na) / gl_matrix_1.vec3.dot(lineRay.direction, Na);
268
- let pointA = gl_matrix_1.vec3.create();
269
- if (da < 0) {
270
- gl_matrix_1.vec3.copy(pointA, ray.origin);
271
- }
272
- else {
273
- pointA = gl_matrix_1.vec3.add(gl_matrix_1.vec3.create(), ray.origin, gl_matrix_1.vec3.mul(gl_matrix_1.vec3.create(), ray.direction, gl_matrix_1.vec3.fromValues(da, da, da)));
274
- }
275
- let pointB = gl_matrix_1.vec3.create();
276
- if (db < 0) {
277
- gl_matrix_1.vec3.copy(pointB, pA);
278
- }
279
- else if (db < lineLength) {
280
- pointB = gl_matrix_1.vec3.add(gl_matrix_1.vec3.create(), pA, gl_matrix_1.vec3.mul(gl_matrix_1.vec3.create(), lineRay.direction, gl_matrix_1.vec3.fromValues(db, db, db)));
281
- }
282
- else {
283
- gl_matrix_1.vec3.copy(pointB, pB);
284
- }
285
- const distance = gl_matrix_1.vec3.distance(pointA, pointB);
286
- if (distance < radius) {
287
- return {
288
- distance: distance,
289
- point: gl_matrix_1.vec3.clone(pointB),
290
- node
291
- };
292
- }
293
- else {
294
- return;
295
- }
296
- }
297
- checkPointIntersection(node, ray, radius, p) {
298
- const closestPoint = gl_matrix_1.vec3.sub(gl_matrix_1.vec3.create(), p, ray.origin);
299
- const directionDistance = gl_matrix_1.vec3.dot(closestPoint, ray.direction);
300
- if (directionDistance < 0) {
301
- gl_matrix_1.vec3.copy(closestPoint, ray.origin);
302
- }
303
- else {
304
- gl_matrix_1.vec3.multiply(closestPoint, gl_matrix_1.vec3.copy(closestPoint, ray.direction), gl_matrix_1.vec3.fromValues(directionDistance, directionDistance, directionDistance));
305
- gl_matrix_1.vec3.add(closestPoint, closestPoint, ray.origin);
306
- }
307
- const distance = gl_matrix_1.vec3.distance(closestPoint, p);
308
- if (distance < radius) {
309
- return {
310
- distance: distance,
311
- point: gl_matrix_1.vec3.clone(closestPoint),
312
- node
313
- };
314
- }
315
- else {
316
- return;
317
- }
318
- }
82
+ // #region Private Methods (2)
83
+ /**
84
+ * Gather all nodes that contain geometry data.
85
+ */
319
86
  gatherNodes() {
320
87
  this._intersectNodes = [];
321
88
  this._tree.root.traverse(node => {
@@ -323,6 +90,7 @@ class IntersectionEngine {
323
90
  return;
324
91
  for (let i = 0; i < node.data.length; i++) {
325
92
  if (node.data[i] instanceof viewer_shared_types_1.GeometryData) {
93
+ const geometryData = node.data[i];
326
94
  let tempNode = node;
327
95
  let visible = true, restrictViewports = [], excludeViewports = [];
328
96
  while (tempNode.parent) {
@@ -333,6 +101,7 @@ class IntersectionEngine {
333
101
  }
334
102
  this._intersectNodes.push({
335
103
  node,
104
+ geometryData: { [`${geometryData.id}_${geometryData.version}`]: geometryData },
336
105
  visible,
337
106
  restrictViewports: [...new Set(restrictViewports)],
338
107
  excludeViewports: [...new Set(excludeViewports)]
@@ -341,6 +110,36 @@ class IntersectionEngine {
341
110
  }
342
111
  });
343
112
  }
113
+ /**
114
+ * Do the intersection test with the ray and the node.
115
+ *
116
+ * @param ray the ray to test
117
+ * @param node the node to test
118
+ * @param geometryData the geometry data of the node
119
+ * @param viewportId the viewport id
120
+ * @returns
121
+ */
122
+ intersectionTest(ray, node, geometryData, viewportId) {
123
+ this._raycaster.ray.direction.set(ray.direction[0], ray.direction[1], ray.direction[2]);
124
+ this._raycaster.ray.origin.set(ray.origin[0], ray.origin[1], ray.origin[2]);
125
+ let intersections = [];
126
+ const threeJsObject = node.convertedObject[viewportId];
127
+ if (threeJsObject) {
128
+ const intersectionThree = this._raycaster.intersectObject(threeJsObject);
129
+ const intersection = intersectionThree.map(i => {
130
+ const intersection = {
131
+ distance: i.distance,
132
+ point: [i.point.x, i.point.y, i.point.z],
133
+ node: node,
134
+ geometryData: geometryData[`${i.object.parent.SDid}_${i.object.parent.SDversion}`]
135
+ };
136
+ return intersection;
137
+ });
138
+ intersections = intersections.concat(intersection);
139
+ }
140
+ intersections.sort((a, b) => a.distance - b.distance);
141
+ return intersections;
142
+ }
344
143
  }
345
144
  exports.IntersectionEngine = IntersectionEngine;
346
145
  //# sourceMappingURL=IntersectionEngine.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"IntersectionEngine.js","sourceRoot":"","sources":["../../src/implementation/IntersectionEngine.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"IntersectionEngine.js","sourceRoot":"","sources":["../../src/implementation/IntersectionEngine.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,6CAA+B;AAC/B,+EAA4E;AAC5E,yEAA+D;AAK/D,iFAA6E;AAE7E,MAAa,kBAAkB;IAiB3B,4BAA4B;IAE5B,2BAA2B;IAE3B;QApBA,yBAAyB;QAER,iBAAY,GAAgB,oCAAW,CAAC,QAAQ,CAAC;QACjD,eAAU,GAAoB,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;QACpD,UAAK,GAAU,8BAAI,CAAC,QAAQ,CAAC;QAItC,oBAAe,GAMjB,EAAE,CAAC;QAOL,IAAI,CAAC,WAAW,EAAE,CAAC;QACnB,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,kCAAS,CAAC,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;YACpE,IAAI,CAAC,WAAW,EAAE,CAAC;QACvB,CAAC,CAAC,CAAC;IACP,CAAC;IAED,8BAA8B;IAE9B,gDAAgD;IAEzC,MAAM,KAAK,QAAQ;QACtB,OAAO,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,CAAC;IAC3D,CAAC;IAED,mDAAmD;IAEnD,6BAA6B;IAEtB,SAAS,CACZ,GAAS,EACT,UAAkB,EAClB,cAAsC;QAEtC,IAAI,aAAa,GAAoB,EAAE,CAAC;QACxC,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;YAC7B,MAAM,oBAAoB,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,YAAY,EAAE,UAAU,EAAE,cAAc,CAAC,CAAC;YACzG,IAAI,oBAAoB;gBACpB,aAAa,GAAG,aAAa,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;QACnE,CAAC,CAAC,CAAC;QACH,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC;QACtD,OAAO,aAAa,CAAC;IACzB,CAAC;IAEM,aAAa,CAChB,GAAS,EACT,IAAe,EACf,YAA6C,EAC7C,UAAkB,EAClB,cAAsC;QAEtC,IAAI,IAAI,CAAC,OAAO,KAAK,KAAK;YAAE,OAAO;QAEnC,IAAI,UAAU,KAAK,SAAS,EAAE;YAC1B,IAAI,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,UAAU,CAAC;gBAAE,OAAO;YACvD,IAAI,IAAI,CAAC,iBAAiB,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,UAAU,CAAC;gBAAE,OAAO;SACjG;QAED,IAAI,cAAc,EAAE;YAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,cAAc,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;gBAC5C,IAAI,cAAc,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;oBACvB,OAAO,IAAI,CAAC,gBAAgB,CAAC,GAAG,EAAE,IAAI,EAAE,YAAY,EAAE,UAAU,CAAC,CAAC;aACzE;SACJ;aAAM;YACH,OAAO,IAAI,CAAC,gBAAgB,CAAC,GAAG,EAAE,IAAI,EAAE,YAAY,EAAE,UAAU,CAAC,CAAC;SACrE;IACL,CAAC;IAED,gCAAgC;IAEhC,8BAA8B;IAE9B;;OAEG;IACK,WAAW;QACf,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;QAC1B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE;YAC5B,IAAI,IAAI,CAAC,OAAO,KAAK,KAAK;gBAAE,OAAO;YAEnC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;gBACvC,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,kCAAY,EAAE;oBACtC,MAAM,YAAY,GAAiB,IAAI,CAAC,IAAI,CAAC,CAAC,CAAiB,CAAC;oBAChE,IAAI,QAAQ,GAAG,IAAI,CAAC;oBACpB,IAAI,OAAO,GAAG,IAAI,EAAE,iBAAiB,GAAa,EAAE,EAAE,gBAAgB,GAAa,EAAE,CAAC;oBACtF,OAAO,QAAQ,CAAC,MAAM,EAAE;wBACpB,OAAO,GAAG,QAAQ,CAAC,OAAO,IAAI,OAAO,CAAC;wBACtC,iBAAiB,GAAG,iBAAiB,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC;wBACzE,gBAAgB,GAAG,gBAAgB,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC;wBACtE,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC;qBAC9B;oBAED,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC;wBACtB,IAAI;wBACJ,YAAY,EAAE,EAAE,CAAC,GAAG,YAAY,CAAC,EAAE,IAAI,YAAY,CAAC,OAAO,EAAE,CAAC,EAAE,YAAY,EAAE;wBAC9E,OAAO;wBACP,iBAAiB,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,iBAAiB,CAAC,CAAC;wBAClD,gBAAgB,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,gBAAgB,CAAC,CAAC;qBACnD,CAAC,CAAC;iBACN;aACJ;QACL,CAAC,CAAC,CAAC;IACP,CAAC;IAED;;;;;;;;OAQG;IACK,gBAAgB,CACpB,GAAS,EACT,IAAe,EACf,YAA6C,EAC7C,UAAkB;QAElB,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;QACxF,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAE5E,IAAI,aAAa,GAAoB,EAAE,CAAC;QAExC,MAAM,aAAa,GAAG,IAAI,CAAC,eAAe,CAAC,UAAW,CAAmB,CAAC;QAC1E,IAAI,aAAa,EAAE;YACf,MAAM,iBAAiB,GAAG,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC;YACzE,MAAM,YAAY,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;gBAC3C,MAAM,YAAY,GAAkB;oBAChC,QAAQ,EAAE,CAAC,CAAC,QAAQ;oBACpB,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;oBACxC,IAAI,EAAE,IAAI;oBACV,YAAY,EAAE,YAAY,CAAC,GAAI,CAAC,CAAC,MAAM,CAAC,MAAc,CAAC,IAAI,IAAK,CAAC,CAAC,MAAM,CAAC,MAAc,CAAC,SAAS,EAAE,CAAC;iBACvG,CAAC;gBACF,OAAO,YAAY,CAAC;YACxB,CAAC,CAAC,CAAC;YACH,aAAa,GAAG,aAAa,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;SACtD;QAED,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC;QACtD,OAAO,aAAa,CAAC;IACzB,CAAC;CAGJ;AA3JD,gDA2JC"}
@@ -1,12 +1,7 @@
1
- import { RENDERER_TYPE } from "@shapediver/viewer.rendering-engine.rendering-engine";
2
- import { ITreeNode } from "@shapediver/viewer.shared.node-tree";
3
- import { IIntersection } from "./IIntersection";
4
- import { IIntersectionFilter } from "./IIntersectionFilter";
5
- import { IRay } from "./IRay";
1
+ import { IIntersection } from './IIntersection';
2
+ import { IIntersectionFilter } from './IIntersectionFilter';
3
+ import { IRay } from './IRay';
6
4
  export interface IIntersectionEngine {
7
- intersect(ray: IRay, filterCriteria?: IIntersectionFilter[], intersectionOptions?: {
8
- opacity: number;
9
- rendererType: RENDERER_TYPE;
10
- }, root?: ITreeNode, viewerID?: string): IIntersection[];
5
+ intersect(ray: IRay, viewportId: string, filterCriteria?: IIntersectionFilter[]): IIntersection[];
11
6
  }
12
7
  //# sourceMappingURL=IIntersectionEngine.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"IIntersectionEngine.d.ts","sourceRoot":"","sources":["../../src/interfaces/IIntersectionEngine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,sDAAsD,CAAC;AACrF,OAAO,EAAE,SAAS,EAAY,MAAM,qCAAqC,CAAC;AAC1E,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAE9B,MAAM,WAAW,mBAAmB;IAChC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,cAAc,CAAC,EAAE,mBAAmB,EAAE,EAAE,mBAAmB,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,aAAa,CAAA;KAAE,EAAE,IAAI,CAAC,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,aAAa,EAAE,CAAC;CAC9L"}
1
+ {"version":3,"file":"IIntersectionEngine.d.ts","sourceRoot":"","sources":["../../src/interfaces/IIntersectionEngine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAE9B,MAAM,WAAW,mBAAmB;IAGhC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,mBAAmB,EAAE,GAAG,aAAa,EAAE,CAAC;CAGrG"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shapediver/viewer.rendering-engine.intersection-engine",
3
- "version": "3.1.2",
3
+ "version": "3.2.0",
4
4
  "description": "",
5
5
  "keywords": [],
6
6
  "author": "Michael Oppitz <michael@shapediver.com>",
@@ -39,13 +39,15 @@
39
39
  "testEnvironment": "node"
40
40
  },
41
41
  "dependencies": {
42
- "@shapediver/viewer.rendering-engine.rendering-engine": "3.1.2",
43
- "@shapediver/viewer.shared.math": "3.1.2",
44
- "@shapediver/viewer.shared.node-tree": "3.1.2",
45
- "@shapediver/viewer.shared.services": "3.1.2",
46
- "@shapediver/viewer.shared.types": "3.1.2",
42
+ "@shapediver/viewer.rendering-engine.rendering-engine": "3.2.0",
43
+ "@shapediver/viewer.shared.math": "3.2.0",
44
+ "@shapediver/viewer.shared.node-tree": "3.2.0",
45
+ "@shapediver/viewer.shared.services": "3.2.0",
46
+ "@shapediver/viewer.shared.types": "3.2.0",
47
+ "@types/three": "0.162.0",
47
48
  "detect-it": "4.0.1",
48
- "gl-matrix": "3.3.0"
49
+ "gl-matrix": "3.3.0",
50
+ "three": "0.162.0"
49
51
  },
50
- "gitHead": "b777b52622744784ca90b32c2008f24653e57c76"
52
+ "gitHead": "36007f976342f0390133d7e5cecf4ebf79905c8a"
51
53
  }
@@ -1,30 +1,30 @@
1
- import { GeometryData, IMaterialAbstractData, MATERIAL_SIDE, PRIMITIVE_MODE } from "@shapediver/viewer.shared.types";
2
- import { mat4, vec3 } from "gl-matrix";
3
- import { Triangle } from "@shapediver/viewer.shared.math";
4
- import { ITree, ITreeNode, Tree, TreeNode } from "@shapediver/viewer.shared.node-tree";
5
- import { RENDERER_TYPE } from "@shapediver/viewer.rendering-engine.rendering-engine";
6
- import { IIntersectionFilter } from "../interfaces/IIntersectionFilter";
7
- import { IRay } from "../interfaces/IRay";
8
- import { IIntersection } from "../interfaces/IIntersection";
9
- import { IIntersectionEngine } from "../interfaces/IIntersectionEngine";
10
- import { EventEngine, EVENTTYPE } from "@shapediver/viewer.shared.services";
1
+ import * as THREE from 'three';
2
+ import { EventEngine, EVENTTYPE } from '@shapediver/viewer.shared.services';
3
+ import { GeometryData } from '@shapediver/viewer.shared.types';
4
+ import { IIntersection } from '../interfaces/IIntersection';
5
+ import { IIntersectionEngine } from '../interfaces/IIntersectionEngine';
6
+ import { IIntersectionFilter } from '../interfaces/IIntersectionFilter';
7
+ import { IRay } from '../interfaces/IRay';
8
+ import { ITree, ITreeNode, Tree } from '@shapediver/viewer.shared.node-tree';
11
9
 
12
10
  export class IntersectionEngine implements IIntersectionEngine {
13
- // #region Properties (4)
11
+ // #region Properties (5)
14
12
 
15
13
  private readonly _eventEngine: EventEngine = EventEngine.instance;
14
+ private readonly _raycaster: THREE.Raycaster = new THREE.Raycaster();
16
15
  private readonly _tree: ITree = Tree.instance;
17
16
 
18
17
  private static _instance: IntersectionEngine;
19
18
 
20
19
  private _intersectNodes: {
21
20
  node: ITreeNode,
21
+ geometryData: { [key: string]: GeometryData },
22
22
  visible: boolean,
23
23
  excludeViewports: string[],
24
24
  restrictViewports: string[],
25
25
  }[] = [];
26
26
 
27
- // #endregion Properties (4)
27
+ // #endregion Properties (5)
28
28
 
29
29
  // #region Constructors (1)
30
30
 
@@ -32,371 +32,134 @@ export class IntersectionEngine implements IIntersectionEngine {
32
32
  this.gatherNodes();
33
33
  this._eventEngine.addListener(EVENTTYPE.VIEWPORT.VIEWPORT_UPDATED, () => {
34
34
  this.gatherNodes();
35
- })
35
+ });
36
36
  }
37
37
 
38
38
  // #endregion Constructors (1)
39
39
 
40
- // #region Public Static Accessors (1)
40
+ // #region Public Static Getters And Setters (1)
41
41
 
42
42
  public static get instance() {
43
43
  return this._instance || (this._instance = new this());
44
44
  }
45
45
 
46
- // #endregion Public Static Accessors (1)
46
+ // #endregion Public Static Getters And Setters (1)
47
47
 
48
48
  // #region Public Methods (2)
49
49
 
50
-
51
50
  public intersect(
52
- ray: IRay,
53
- filterCriteria?: IIntersectionFilter[],
54
- intersectionOptions?: { opacity: number, rendererType: RENDERER_TYPE },
55
- root: ITreeNode = this._tree.root,
56
- viewerID?: string
51
+ ray: IRay,
52
+ viewportId: string,
53
+ filterCriteria?: IIntersectionFilter[]
57
54
  ): IIntersection[] {
58
55
  let intersections: IIntersection[] = [];
59
- const intersectNode = (node: ITreeNode, visible: boolean, excludeViewports: string[], restrictViewports: string[]) => {
60
- if(visible === false) return;
61
-
62
- if(viewerID !== undefined) {
63
- if(excludeViewports.includes(viewerID)) return;
64
- if(restrictViewports.length > 0 && !restrictViewports.includes(viewerID)) return;
65
- }
66
-
67
- if(filterCriteria) {
68
- for (let i = 0; i < filterCriteria.length; i++) {
69
- if (filterCriteria[i](node)) {
70
- const intersection = this.intersectNode(node, ray, intersectionOptions)
71
- if (intersection) {
72
- intersection.forEach(i => i.node = node);
73
- intersections = intersections.concat(intersection);
74
- }
75
- break;
76
- }
77
- }
78
- } else {
79
- const intersection = this.intersectNode(node, ray)
80
- if (intersection) {
81
- intersection.forEach(i => i.node = node);
82
- intersections = intersections.concat(intersection);
83
- }
84
- }
85
-
86
- for (let i = 0; i < node.children.length; i++)
87
- intersectNode(node.children[i], visible && node.children[i].visible, excludeViewports.concat(node.children[i].excludeViewports), restrictViewports.concat(node.children[i].restrictViewports))
88
- }
89
- for (let i = 0; i < this._intersectNodes.length; i++)
90
- intersectNode(this._intersectNodes[i].node, this._intersectNodes[i].visible, this._intersectNodes[i].excludeViewports, this._intersectNodes[i].restrictViewports)
91
-
56
+ this._intersectNodes.forEach(i => {
57
+ const currentIntersections = this.intersectNode(ray, i.node, i.geometryData, viewportId, filterCriteria);
58
+ if (currentIntersections)
59
+ intersections = intersections.concat(currentIntersections);
60
+ });
92
61
  intersections.sort((a, b) => a.distance - b.distance);
93
62
  return intersections;
94
63
  }
95
64
 
96
- public intersectNode(node: ITreeNode, rayIn: IRay, intersectionOptions?: { opacity: number, rendererType: RENDERER_TYPE }): IIntersection[] | undefined {
65
+ public intersectNode(
66
+ ray: IRay,
67
+ node: ITreeNode,
68
+ geometryData: { [key: string]: GeometryData },
69
+ viewportId: string,
70
+ filterCriteria?: IIntersectionFilter[]
71
+ ): IIntersection[] | undefined {
97
72
  if (node.visible === false) return;
98
73
 
99
- const inverseMatrix = mat4.invert(mat4.create(), node.worldMatrix);
100
- const ray = {
101
- origin: vec3.transformMat4(vec3.create(), rayIn.origin, inverseMatrix),
102
- direction: vec3.normalize(vec3.create(), vec3.fromValues(
103
- inverseMatrix[0] * rayIn.direction[0] + inverseMatrix[4] * rayIn.direction[1] + inverseMatrix[8] * rayIn.direction[2],
104
- inverseMatrix[1] * rayIn.direction[0] + inverseMatrix[5] * rayIn.direction[1] + inverseMatrix[9] * rayIn.direction[2],
105
- inverseMatrix[2] * rayIn.direction[0] + inverseMatrix[6] * rayIn.direction[1] + inverseMatrix[10] * rayIn.direction[2]
106
- ))
107
- };
108
-
109
- let geometryData: GeometryData | undefined;
110
- for (let i = 0; i < node.data.length; i++) {
111
- if (node.data[i] instanceof GeometryData) {
112
- geometryData = <GeometryData>node.data[i];
113
- break;
114
- }
74
+ if (viewportId !== undefined) {
75
+ if (node.excludeViewports.includes(viewportId)) return;
76
+ if (node.restrictViewports.length > 0 && !node.restrictViewports.includes(viewportId)) return;
115
77
  }
116
78
 
117
- // quick out if the material does not fit the intersection options
118
- if (geometryData && intersectionOptions) {
119
- let materialData: IMaterialAbstractData | null = null;
120
- if (geometryData.effectMaterials.length > 0) {
121
- materialData = geometryData.effectMaterials[geometryData.effectMaterials.length - 1].material
122
- } else if (intersectionOptions.rendererType === RENDERER_TYPE.ATTRIBUTES) {
123
- materialData = geometryData.attributeMaterial;
124
- } else {
125
- materialData = geometryData.material;
79
+ if (filterCriteria) {
80
+ for (let i = 0; i < filterCriteria.length; i++) {
81
+ if (filterCriteria[i](node))
82
+ return this.intersectionTest(ray, node, geometryData, viewportId);
126
83
  }
127
-
128
- // if opacity <= intersectionOptions.opacity
129
- if (materialData && materialData.opacity <= intersectionOptions.opacity)
130
- return;
131
- }
132
-
133
- if (!geometryData) {
134
- let intersections: IIntersection[] = [];
135
- for (let i = 0; i < node.children.length; i++) {
136
- let intersection = this.intersectNode(node.children[i], rayIn, intersectionOptions);
137
- if (intersection)
138
- intersections = intersections.concat(intersection);
139
- }
140
- if (intersections.length > 0) {
141
- intersections.sort((a, b) => a.distance - b.distance);
142
- return intersections;
143
- }
144
- return;
145
- } else if (geometryData.mode === PRIMITIVE_MODE.LINES) {
146
- // if (node.boundingBox.boundingSphere.intersects(ray.origin, ray.direction) === false) return;
147
- if (node.boundingBox.intersects(rayIn.origin, rayIn.direction) === false) return;
148
-
149
- const index = geometryData.primitive.indices;
150
- const position = geometryData.primitive.attributes['POSITION'];
151
- const radius = 0.1;
152
- let intersections: IIntersection[] = [];
153
- if (index !== null) {
154
- // indexed buffer geometry
155
- for (let i = 0, il = +index.count; i < il; i += 2) {
156
- const a = index.array[(i) * index.itemSize];
157
- const b = index.array[(i + 1) * index.itemSize];
158
-
159
- let intersection = this.checkLineIntersection(node, ray, radius,
160
- vec3.fromValues(position.array[a * position.itemSize], position.array[a * position.itemSize + 1], position.array[a * position.itemSize + 2]),
161
- vec3.fromValues(position.array[b * position.itemSize], position.array[b * position.itemSize + 1], position.array[b * position.itemSize + 2]));
162
- if (intersection) intersections.push(Object.assign(intersection, { geometryData }))
163
- }
164
- } else if (position !== undefined) {
165
- // non-indexed buffer geometry
166
- for (let i = 0, il = +position.count; i < il; i += 2) {
167
- const a = i;
168
- const b = i + 1;
169
- let intersection = this.checkLineIntersection(node, ray, radius,
170
- vec3.fromValues(position.array[a * position.itemSize], position.array[a * position.itemSize + 1], position.array[a * position.itemSize + 2]),
171
- vec3.fromValues(position.array[b * position.itemSize], position.array[b * position.itemSize + 1], position.array[b * position.itemSize + 2]));
172
- if (intersection) intersections.push(Object.assign(intersection, { geometryData }))
173
- }
174
- }
175
-
176
- intersections.sort((a, b) => a.distance - b.distance);
177
- intersections.forEach(i => i.point = vec3.transformMat4(i.point, i.point, node.worldMatrix));
178
- return intersections;
179
- } else if (geometryData.mode === PRIMITIVE_MODE.LINE_LOOP || geometryData.mode === PRIMITIVE_MODE.LINE_STRIP) {
180
- // if (node.boundingBox.boundingSphere.intersects(ray.origin, ray.direction) === false) return;
181
- if (node.boundingBox.intersects(rayIn.origin, rayIn.direction) === false) return;
182
-
183
- const index = geometryData.primitive.indices;
184
- const position = geometryData.primitive.attributes['POSITION'];
185
- const radius = 0.1;
186
- let intersections: IIntersection[] = [];
187
- if (index !== null) {
188
- // indexed buffer geometry
189
- for (let i = 0, il = +index.count - 1; i < il; i++) {
190
- const a = index.array[(i) * index.itemSize];
191
- const b = index.array[(i + 1) * index.itemSize];
192
-
193
- let intersection = this.checkLineIntersection(node, ray, radius,
194
- vec3.fromValues(position.array[a * position.itemSize], position.array[a * position.itemSize + 1], position.array[a * position.itemSize + 2]),
195
- vec3.fromValues(position.array[b * position.itemSize], position.array[b * position.itemSize + 1], position.array[b * position.itemSize + 2]));
196
- if (intersection) intersections.push(Object.assign(intersection, { geometryData }))
197
- }
198
- } else if (position !== undefined) {
199
- // non-indexed buffer geometry
200
- for (let i = 0, il = +position.count; i < il; i += 2) {
201
- const a = i;
202
- const b = i + 1;
203
- let intersection = this.checkLineIntersection(node, ray, radius,
204
- vec3.fromValues(position.array[a * position.itemSize], position.array[a * position.itemSize + 1], position.array[a * position.itemSize + 2]),
205
- vec3.fromValues(position.array[b * position.itemSize], position.array[b * position.itemSize + 1], position.array[b * position.itemSize + 2]));
206
- if (intersection) intersections.push(Object.assign(intersection, { geometryData }))
207
- }
208
- }
209
-
210
- intersections.sort((a, b) => a.distance - b.distance);
211
- intersections.forEach(i => i.point = vec3.transformMat4(i.point, i.point, node.worldMatrix));
212
- return intersections;
213
- } else if (geometryData.mode === PRIMITIVE_MODE.POINTS) {
214
- const position = geometryData.primitive.attributes['POSITION'];
215
- const radius = 0.1;
216
- let intersections: IIntersection[] = [];
217
- if (position !== undefined) {
218
- // non-indexed buffer geometry
219
- for (let i = 0, il = +position.count; i < il; i++) {
220
- let intersection = this.checkPointIntersection(node, ray, radius,
221
- vec3.fromValues(position.array[i * position.itemSize], position.array[i * position.itemSize + 1], position.array[i * position.itemSize + 2]));
222
- if (intersection) intersections.push(Object.assign(intersection, { geometryData }))
223
- }
224
- }
225
-
226
- intersections.sort((a, b) => a.distance - b.distance);
227
- intersections.forEach(i => i.point = vec3.transformMat4(i.point, i.point, node.worldMatrix));
228
- return intersections;
229
84
  } else {
230
- // Here, Vector is a vector in Rn, not a dynamic array.
231
- let v = vec3.sub(vec3.create(), node.boundingBox.boundingSphere.center, rayIn.origin);
232
- let dotProd = vec3.dot(v, rayIn.direction);
233
- dotProd = Math.max(dotProd, 0.0); // if dotProd is negative, the closest point is in the opposite direction to d.
234
- let e = vec3.add(vec3.create(), rayIn.origin, vec3.scale(vec3.create(), rayIn.direction, dotProd));
235
-
236
- let squaredDistance = vec3.squaredDistance(e, node.boundingBox.boundingSphere.center);
237
- if (squaredDistance > node.boundingBox.boundingSphere.radius * node.boundingBox.boundingSphere.radius) return;
238
-
239
- // if (node.boundingBox.boundingSphere.intersects(ray.origin, ray.direction) === false) return;
240
- if (node.boundingBox.intersects(rayIn.origin, rayIn.direction) === false) return;
241
-
242
- const material = geometryData.material;
243
- const index = geometryData.primitive.indices;
244
- const position = geometryData.primitive.attributes['POSITION'];
245
-
246
- let intersections: IIntersection[] = [];
247
-
248
- if (index !== null) {
249
- // indexed buffer geometry
250
- for (let i = 0, il = +index.count; i < il; i += 3) {
251
- const a = index.array[(i) * index.itemSize];
252
- const b = index.array[(i + 1) * index.itemSize];
253
- const c = index.array[(i + 2) * index.itemSize];
254
-
255
- let intersection = this.checkIntersection(node, material, ray,
256
- vec3.fromValues(position.array[a * position.itemSize], position.array[a * position.itemSize + 1], position.array[a * position.itemSize + 2]),
257
- vec3.fromValues(position.array[b * position.itemSize], position.array[b * position.itemSize + 1], position.array[b * position.itemSize + 2]),
258
- vec3.fromValues(position.array[c * position.itemSize], position.array[c * position.itemSize + 1], position.array[c * position.itemSize + 2]));
259
- if (intersection) intersections.push(Object.assign(intersection, { geometryData }))
260
- }
261
- } else if (position !== undefined) {
262
- // non-indexed buffer geometry
263
- for (let i = 0, il = +position.count; i < il; i += 3) {
264
- const a = i;
265
- const b = i + 1;
266
- const c = i + 2;
267
- let intersection = this.checkIntersection(node, material, ray,
268
- vec3.fromValues(position.array[a * position.itemSize], position.array[a * position.itemSize + 1], position.array[a * position.itemSize + 2]),
269
- vec3.fromValues(position.array[b * position.itemSize], position.array[b * position.itemSize + 1], position.array[b * position.itemSize + 2]),
270
- vec3.fromValues(position.array[c * position.itemSize], position.array[c * position.itemSize + 1], position.array[c * position.itemSize + 2]));
271
- if (intersection) intersections.push(Object.assign(intersection, { geometryData }))
272
- }
273
- }
274
-
275
- intersections.sort((a, b) => a.distance - b.distance);
276
- intersections.forEach(i => i.point = vec3.transformMat4(i.point, i.point, node.worldMatrix));
277
- return intersections;
85
+ return this.intersectionTest(ray, node, geometryData, viewportId);
278
86
  }
279
87
  }
280
88
 
281
89
  // #endregion Public Methods (2)
282
90
 
283
- // #region Private Methods (4)
284
-
285
- private checkIntersection(node: ITreeNode, material: IMaterialAbstractData | null, ray: IRay, pA: vec3, pB: vec3, pC: vec3): { distance: number, point: vec3, node: ITreeNode } | undefined {
286
- let point: vec3 | null;
287
-
288
- if (material && material.side === MATERIAL_SIDE.BACK) {
289
- const triangle = new Triangle(pC, pB, pA);
290
- point = triangle.intersect(ray.origin, ray.direction);
291
- } else {
292
- const triangle = new Triangle(pA, pB, pC);
293
- point = triangle.intersect(ray.origin, ray.direction);
294
- }
295
-
296
- if (point === null) return;
297
-
298
- const distance = vec3.distance(ray.origin, point);
299
- return {
300
- distance: distance,
301
- point: vec3.clone(point),
302
- node
303
- };
304
- }
305
-
306
- private checkLineIntersection(node: ITreeNode, ray: IRay, radius: number, pA: vec3, pB: vec3): { distance: number, point: vec3, node: ITreeNode } | undefined {
307
- const direction = vec3.sub(vec3.create(), pB, pA);
308
- const lineLength = vec3.length(direction);
309
- const lineRay = {
310
- origin: pA,
311
- direction: vec3.divide(vec3.create(), direction, vec3.fromValues(lineLength, lineLength, lineLength))
312
- };
313
- const planeNormal = vec3.cross(vec3.create(), ray.direction, lineRay.direction);
314
-
315
- const Na = vec3.normalize(vec3.create(), vec3.cross(vec3.create(), ray.direction, planeNormal));
316
- const Nb = vec3.normalize(vec3.create(), vec3.cross(vec3.create(), lineRay.direction, planeNormal));
317
-
318
- const da = vec3.dot(vec3.sub(vec3.create(), pA, ray.origin), Nb) / vec3.dot(ray.direction, Nb);
319
- const db = vec3.dot(vec3.sub(vec3.create(), ray.origin, pA), Na) / vec3.dot(lineRay.direction, Na);
320
-
321
- let pointA: vec3 = vec3.create();
322
- if (da < 0) {
323
- vec3.copy(pointA, ray.origin);
324
- } else {
325
- pointA = vec3.add(vec3.create(), ray.origin, vec3.mul(vec3.create(), ray.direction, vec3.fromValues(da, da, da)));
326
- }
327
-
328
- let pointB: vec3 = vec3.create();
329
- if (db < 0) {
330
- vec3.copy(pointB, pA);
331
- } else if (db < lineLength) {
332
- pointB = vec3.add(vec3.create(), pA, vec3.mul(vec3.create(), lineRay.direction, vec3.fromValues(db, db, db)));
333
- } else {
334
- vec3.copy(pointB, pB);
335
- }
336
-
337
- const distance = vec3.distance(pointA, pointB);
338
- if (distance < radius) {
339
- return {
340
- distance: distance,
341
- point: vec3.clone(pointB),
342
- node
343
- }
344
- } else {
345
- return;
346
- }
347
- }
348
-
349
- private checkPointIntersection(node: ITreeNode, ray: IRay, radius: number, p: vec3): { distance: number, point: vec3, node: ITreeNode } | undefined {
350
- const closestPoint = vec3.sub(vec3.create(), p, ray.origin);
351
- const directionDistance = vec3.dot(closestPoint, ray.direction);
352
-
353
- if (directionDistance < 0) {
354
- vec3.copy(closestPoint, ray.origin);
355
- } else {
356
- vec3.multiply(closestPoint, vec3.copy(closestPoint, ray.direction), vec3.fromValues(directionDistance, directionDistance, directionDistance));
357
- vec3.add(closestPoint, closestPoint, ray.origin);
358
- }
359
-
360
- const distance = vec3.distance(closestPoint, p);
361
- if (distance < radius) {
362
- return {
363
- distance: distance,
364
- point: vec3.clone(closestPoint),
365
- node
366
- }
367
- } else {
368
- return;
369
- }
370
- }
91
+ // #region Private Methods (2)
371
92
 
93
+ /**
94
+ * Gather all nodes that contain geometry data.
95
+ */
372
96
  private gatherNodes() {
373
97
  this._intersectNodes = [];
374
98
  this._tree.root.traverse(node => {
375
99
  if (node.visible === false) return;
376
100
 
377
- for(let i = 0; i < node.data.length; i++) {
378
- if(node.data[i] instanceof GeometryData) {
379
-
101
+ for (let i = 0; i < node.data.length; i++) {
102
+ if (node.data[i] instanceof GeometryData) {
103
+ const geometryData: GeometryData = node.data[i] as GeometryData;
380
104
  let tempNode = node;
381
105
  let visible = true, restrictViewports: string[] = [], excludeViewports: string[] = [];
382
- while(tempNode.parent) {
106
+ while (tempNode.parent) {
383
107
  visible = tempNode.visible && visible;
384
- restrictViewports = restrictViewports.concat(tempNode.restrictViewports)
385
- excludeViewports = excludeViewports.concat(tempNode.excludeViewports)
108
+ restrictViewports = restrictViewports.concat(tempNode.restrictViewports);
109
+ excludeViewports = excludeViewports.concat(tempNode.excludeViewports);
386
110
  tempNode = tempNode.parent;
387
111
  }
388
112
 
389
113
  this._intersectNodes.push({
390
114
  node,
115
+ geometryData: { [`${geometryData.id}_${geometryData.version}`]: geometryData },
391
116
  visible,
392
117
  restrictViewports: [...new Set(restrictViewports)],
393
118
  excludeViewports: [...new Set(excludeViewports)]
394
- })
395
-
119
+ });
396
120
  }
397
121
  }
398
- })
122
+ });
123
+ }
124
+
125
+ /**
126
+ * Do the intersection test with the ray and the node.
127
+ *
128
+ * @param ray the ray to test
129
+ * @param node the node to test
130
+ * @param geometryData the geometry data of the node
131
+ * @param viewportId the viewport id
132
+ * @returns
133
+ */
134
+ private intersectionTest(
135
+ ray: IRay,
136
+ node: ITreeNode,
137
+ geometryData: { [key: string]: GeometryData },
138
+ viewportId: string
139
+ ): IIntersection[] | undefined {
140
+ this._raycaster.ray.direction.set(ray.direction[0], ray.direction[1], ray.direction[2]);
141
+ this._raycaster.ray.origin.set(ray.origin[0], ray.origin[1], ray.origin[2]);
142
+
143
+ let intersections: IIntersection[] = [];
144
+
145
+ const threeJsObject = node.convertedObject[viewportId!] as THREE.Object3D;
146
+ if (threeJsObject) {
147
+ const intersectionThree = this._raycaster.intersectObject(threeJsObject);
148
+ const intersection = intersectionThree.map(i => {
149
+ const intersection: IIntersection = {
150
+ distance: i.distance,
151
+ point: [i.point.x, i.point.y, i.point.z],
152
+ node: node,
153
+ geometryData: geometryData[`${(i.object.parent as any).SDid}_${(i.object.parent as any).SDversion}`]
154
+ };
155
+ return intersection;
156
+ });
157
+ intersections = intersections.concat(intersection);
158
+ }
159
+
160
+ intersections.sort((a, b) => a.distance - b.distance);
161
+ return intersections;
399
162
  }
400
163
 
401
- // #endregion Private Methods (4)
164
+ // #endregion Private Methods (2)
402
165
  }
@@ -1,9 +1,11 @@
1
- import { RENDERER_TYPE } from "@shapediver/viewer.rendering-engine.rendering-engine";
2
- import { ITreeNode, TreeNode } from "@shapediver/viewer.shared.node-tree";
3
- import { IIntersection } from "./IIntersection";
4
- import { IIntersectionFilter } from "./IIntersectionFilter";
5
- import { IRay } from "./IRay";
1
+ import { IIntersection } from './IIntersection';
2
+ import { IIntersectionFilter } from './IIntersectionFilter';
3
+ import { IRay } from './IRay';
6
4
 
7
5
  export interface IIntersectionEngine {
8
- intersect(ray: IRay, filterCriteria?: IIntersectionFilter[], intersectionOptions?: { opacity: number, rendererType: RENDERER_TYPE }, root?: ITreeNode, viewerID?: string): IIntersection[];
6
+ // #region Public Methods (1)
7
+
8
+ intersect(ray: IRay, viewportId: string, filterCriteria?: IIntersectionFilter[]): IIntersection[];
9
+
10
+ // #endregion Public Methods (1)
9
11
  }