@thatopen/components 2.4.8 → 2.4.9

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/dist/index.cjs CHANGED
@@ -4021,6 +4021,9 @@ const _plane = new THREE$1.Plane();
4021
4021
  const _closestPoint = new THREE$1.Vector3();
4022
4022
  const _triangle = new THREE$1.Triangle();
4023
4023
  class ConvexHull {
4024
+ /**
4025
+ * Constructs a new convex hull.
4026
+ */
4024
4027
  constructor() {
4025
4028
  this.tolerance = -1;
4026
4029
  this.faces = [];
@@ -4029,16 +4032,29 @@ class ConvexHull {
4029
4032
  this.unassigned = new VertexList();
4030
4033
  this.vertices = [];
4031
4034
  }
4035
+ /**
4036
+ * Computes to convex hull for the given array of points.
4037
+ *
4038
+ * @param {Array<Vector3>} points - The array of points in 3D space.
4039
+ * @return {ConvexHull} A reference to this convex hull.
4040
+ */
4032
4041
  setFromPoints(points) {
4033
4042
  if (points.length >= 4) {
4034
4043
  this.makeEmpty();
4035
4044
  for (let i = 0, l = points.length; i < l; i++) {
4036
4045
  this.vertices.push(new VertexNode(points[i]));
4037
4046
  }
4038
- this.compute();
4047
+ this._compute();
4039
4048
  }
4040
4049
  return this;
4041
4050
  }
4051
+ /**
4052
+ * Computes the convex hull of the given 3D object (including its descendants),
4053
+ * accounting for the world transforms of both the 3D object and its descendants.
4054
+ *
4055
+ * @param {Object3D} object - The 3D object to compute the convex hull for.
4056
+ * @return {ConvexHull} A reference to this convex hull.
4057
+ */
4042
4058
  setFromObject(object) {
4043
4059
  const points = [];
4044
4060
  object.updateMatrixWorld(true);
@@ -4057,6 +4073,12 @@ class ConvexHull {
4057
4073
  });
4058
4074
  return this.setFromPoints(points);
4059
4075
  }
4076
+ /**
4077
+ * Returns `true` if the given point lies in the convex hull.
4078
+ *
4079
+ * @param {Vector3} point - The point to test.
4080
+ * @return {boolean} Whether the given point lies in the convex hull or not.
4081
+ */
4060
4082
  containsPoint(point) {
4061
4083
  const faces = this.faces;
4062
4084
  for (let i = 0, l = faces.length; i < l; i++) {
@@ -4066,6 +4088,13 @@ class ConvexHull {
4066
4088
  }
4067
4089
  return true;
4068
4090
  }
4091
+ /**
4092
+ * Computes the intersections point of the given ray and this convex hull.
4093
+ *
4094
+ * @param {Ray} ray - The ray to test.
4095
+ * @param {Vector3} target - The target vector that is used to store the method's result.
4096
+ * @return {Vector3|null} The intersection point. Returns `null` if not intersection was detected.
4097
+ */
4069
4098
  intersectRay(ray2, target) {
4070
4099
  const faces = this.faces;
4071
4100
  let tNear = -Infinity;
@@ -4095,16 +4124,35 @@ class ConvexHull {
4095
4124
  }
4096
4125
  return target;
4097
4126
  }
4127
+ /**
4128
+ * Returns `true` if the given ray intersects with this convex hull.
4129
+ *
4130
+ * @param {Ray} ray - The ray to test.
4131
+ * @return {boolean} Whether the given ray intersects with this convex hull or not.
4132
+ */
4098
4133
  intersectsRay(ray2) {
4099
4134
  return this.intersectRay(ray2, _v1$1) !== null;
4100
4135
  }
4136
+ /**
4137
+ * Makes the convex hull empty.
4138
+ *
4139
+ * @return {ConvexHull} A reference to this convex hull.
4140
+ */
4101
4141
  makeEmpty() {
4102
4142
  this.faces = [];
4103
4143
  this.vertices = [];
4104
4144
  return this;
4105
4145
  }
4106
- // Adds a vertex to the 'assigned' list of vertices and assigns it to the given face
4107
- addVertexToFace(vertex, face) {
4146
+ // private
4147
+ /**
4148
+ * Adds a vertex to the 'assigned' list of vertices and assigns it to the given face.
4149
+ *
4150
+ * @private
4151
+ * @param {VertexNode} vertex - The vertex to add.
4152
+ * @param {Face} face - The target face.
4153
+ * @return {ConvexHull} A reference to this convex hull.
4154
+ */
4155
+ _addVertexToFace(vertex, face) {
4108
4156
  vertex.face = face;
4109
4157
  if (face.outside === null) {
4110
4158
  this.assigned.append(vertex);
@@ -4114,8 +4162,17 @@ class ConvexHull {
4114
4162
  face.outside = vertex;
4115
4163
  return this;
4116
4164
  }
4117
- // Removes a vertex from the 'assigned' list of vertices and from the given face
4118
- removeVertexFromFace(vertex, face) {
4165
+ /**
4166
+ * Removes a vertex from the 'assigned' list of vertices and from the given face.
4167
+ * It also makes sure that the link from 'face' to the first vertex it sees in 'assigned'
4168
+ * is linked correctly after the removal.
4169
+ *
4170
+ * @private
4171
+ * @param {VertexNode} vertex - The vertex to remove.
4172
+ * @param {Face} face - The target face.
4173
+ * @return {ConvexHull} A reference to this convex hull.
4174
+ */
4175
+ _removeVertexFromFace(vertex, face) {
4119
4176
  if (vertex === face.outside) {
4120
4177
  if (vertex.next !== null && vertex.next.face === face) {
4121
4178
  face.outside = vertex.next;
@@ -4126,8 +4183,15 @@ class ConvexHull {
4126
4183
  this.assigned.remove(vertex);
4127
4184
  return this;
4128
4185
  }
4129
- // Removes all the visible vertices that a given face is able to see which are stored in the 'assigned' vertex list
4130
- removeAllVerticesFromFace(face) {
4186
+ /**
4187
+ * Removes all the visible vertices that a given face is able to see which are stored in
4188
+ * the 'assigned' vertex list.
4189
+ *
4190
+ * @private
4191
+ * @param {Face} face - The target face.
4192
+ * @return {VertexNode|undefined} A reference to this convex hull.
4193
+ */
4194
+ _removeAllVerticesFromFace(face) {
4131
4195
  if (face.outside !== null) {
4132
4196
  const start = face.outside;
4133
4197
  let end = face.outside;
@@ -4140,9 +4204,20 @@ class ConvexHull {
4140
4204
  return start;
4141
4205
  }
4142
4206
  }
4143
- // Removes all the visible vertices that 'face' is able to see
4144
- deleteFaceVertices(face, absorbingFace) {
4145
- const faceVertices = this.removeAllVerticesFromFace(face);
4207
+ /**
4208
+ * Removes all the visible vertices that `face` is able to see.
4209
+ *
4210
+ * - If `absorbingFace` doesn't exist, then all the removed vertices will be added to the 'unassigned' vertex list.
4211
+ * - If `absorbingFace` exists, then this method will assign all the vertices of 'face' that can see 'absorbingFace'.
4212
+ * - If a vertex cannot see `absorbingFace`, it's added to the 'unassigned' vertex list.
4213
+ *
4214
+ * @private
4215
+ * @param {Face} face - The given face.
4216
+ * @param {Face} [absorbingFace] - An optional face that tries to absorb the vertices of the first face.
4217
+ * @return {ConvexHull} A reference to this convex hull.
4218
+ */
4219
+ _deleteFaceVertices(face, absorbingFace) {
4220
+ const faceVertices = this._removeAllVerticesFromFace(face);
4146
4221
  if (faceVertices !== void 0) {
4147
4222
  if (absorbingFace === void 0) {
4148
4223
  this.unassigned.appendChain(faceVertices);
@@ -4152,7 +4227,7 @@ class ConvexHull {
4152
4227
  const nextVertex = vertex.next;
4153
4228
  const distance = absorbingFace.distanceToPoint(vertex.point);
4154
4229
  if (distance > this.tolerance) {
4155
- this.addVertexToFace(vertex, absorbingFace);
4230
+ this._addVertexToFace(vertex, absorbingFace);
4156
4231
  } else {
4157
4232
  this.unassigned.append(vertex);
4158
4233
  }
@@ -4162,8 +4237,14 @@ class ConvexHull {
4162
4237
  }
4163
4238
  return this;
4164
4239
  }
4165
- // Reassigns as many vertices as possible from the unassigned list to the new faces
4166
- resolveUnassignedPoints(newFaces) {
4240
+ /**
4241
+ * Reassigns as many vertices as possible from the unassigned list to the new faces.
4242
+ *
4243
+ * @private
4244
+ * @param {Array<Face>} newFaces - The new faces.
4245
+ * @return {ConvexHull} A reference to this convex hull.
4246
+ */
4247
+ _resolveUnassignedPoints(newFaces) {
4167
4248
  if (this.unassigned.isEmpty() === false) {
4168
4249
  let vertex = this.unassigned.first();
4169
4250
  do {
@@ -4183,15 +4264,21 @@ class ConvexHull {
4183
4264
  }
4184
4265
  }
4185
4266
  if (maxFace !== null) {
4186
- this.addVertexToFace(vertex, maxFace);
4267
+ this._addVertexToFace(vertex, maxFace);
4187
4268
  }
4188
4269
  vertex = nextVertex;
4189
4270
  } while (vertex !== null);
4190
4271
  }
4191
4272
  return this;
4192
4273
  }
4193
- // Computes the extremes of a simplex which will be the initial hull
4194
- computeExtremes() {
4274
+ /**
4275
+ * Computes the extremes values (min/max vectors) which will be used to
4276
+ * compute the initial hull.
4277
+ *
4278
+ * @private
4279
+ * @return {Object} The extremes.
4280
+ */
4281
+ _computeExtremes() {
4195
4282
  const min = new THREE$1.Vector3();
4196
4283
  const max = new THREE$1.Vector3();
4197
4284
  const minVertices = [];
@@ -4220,11 +4307,16 @@ class ConvexHull {
4220
4307
  this.tolerance = 3 * Number.EPSILON * (Math.max(Math.abs(min.x), Math.abs(max.x)) + Math.max(Math.abs(min.y), Math.abs(max.y)) + Math.max(Math.abs(min.z), Math.abs(max.z)));
4221
4308
  return { min: minVertices, max: maxVertices };
4222
4309
  }
4223
- // Computes the initial simplex assigning to its faces all the points
4224
- // that are candidates to form part of the hull
4225
- computeInitialHull() {
4310
+ /**
4311
+ * Computes the initial simplex assigning to its faces all the points that are
4312
+ * candidates to form part of the hull.
4313
+ *
4314
+ * @private
4315
+ * @return {ConvexHull} A reference to this convex hull.
4316
+ */
4317
+ _computeInitialHull() {
4226
4318
  const vertices = this.vertices;
4227
- const extremes = this.computeExtremes();
4319
+ const extremes = this._computeExtremes();
4228
4320
  const min = extremes.min;
4229
4321
  const max = extremes.max;
4230
4322
  let maxDistance = 0;
@@ -4307,14 +4399,19 @@ class ConvexHull {
4307
4399
  }
4308
4400
  }
4309
4401
  if (maxFace !== null) {
4310
- this.addVertexToFace(vertex, maxFace);
4402
+ this._addVertexToFace(vertex, maxFace);
4311
4403
  }
4312
4404
  }
4313
4405
  }
4314
4406
  return this;
4315
4407
  }
4316
- // Removes inactive faces
4317
- reindexFaces() {
4408
+ /**
4409
+ * Removes inactive (e.g. deleted) faces from the internal face list.
4410
+ *
4411
+ * @private
4412
+ * @return {ConvexHull} A reference to this convex hull.
4413
+ */
4414
+ _reindexFaces() {
4318
4415
  const activeFaces = [];
4319
4416
  for (let i = 0; i < this.faces.length; i++) {
4320
4417
  const face = this.faces[i];
@@ -4325,8 +4422,17 @@ class ConvexHull {
4325
4422
  this.faces = activeFaces;
4326
4423
  return this;
4327
4424
  }
4328
- // Finds the next vertex to create faces with the current hull
4329
- nextVertexToAdd() {
4425
+ /**
4426
+ * Finds the next vertex to create faces with the current hull.
4427
+ *
4428
+ * - Let the initial face be the first face existing in the 'assigned' vertex list.
4429
+ * - If a face doesn't exist then return since there're no vertices left.
4430
+ * - Otherwise for each vertex that face sees find the one furthest away from it.
4431
+ *
4432
+ * @private
4433
+ * @return {?VertexNode} The next vertex to add.
4434
+ */
4435
+ _nextVertexToAdd() {
4330
4436
  if (this.assigned.isEmpty() === false) {
4331
4437
  let eyeVertex, maxDistance = 0;
4332
4438
  const eyeFace = this.assigned.first().face;
@@ -4342,11 +4448,20 @@ class ConvexHull {
4342
4448
  return eyeVertex;
4343
4449
  }
4344
4450
  }
4345
- // Computes a chain of half edges in CCW order called the 'horizon'.
4346
- // For an edge to be part of the horizon it must join a face that can see
4347
- // 'eyePoint' and a face that cannot see 'eyePoint'.
4348
- computeHorizon(eyePoint, crossEdge, face, horizon) {
4349
- this.deleteFaceVertices(face);
4451
+ /**
4452
+ * Computes a chain of half edges in CCW order called the 'horizon'. For an edge
4453
+ * to be part of the horizon it must join a face that can see 'eyePoint' and a face
4454
+ * that cannot see 'eyePoint'.
4455
+ *
4456
+ * @private
4457
+ * @param {Vector3} eyePoint - The 3D-coordinates of a point.
4458
+ * @param {HalfEdge} crossEdge - The edge used to jump to the current face.
4459
+ * @param {Face} face - The current face being tested.
4460
+ * @param {Array<HalfEdge>} horizon - The edges that form part of the horizon in CCW order.
4461
+ * @return {ConvexHull} A reference to this convex hull.
4462
+ */
4463
+ _computeHorizon(eyePoint, crossEdge, face, horizon) {
4464
+ this._deleteFaceVertices(face);
4350
4465
  face.mark = Deleted;
4351
4466
  let edge;
4352
4467
  if (crossEdge === null) {
@@ -4359,7 +4474,7 @@ class ConvexHull {
4359
4474
  const oppositeFace = twinEdge.face;
4360
4475
  if (oppositeFace.mark === Visible) {
4361
4476
  if (oppositeFace.distanceToPoint(eyePoint) > this.tolerance) {
4362
- this.computeHorizon(eyePoint, twinEdge, oppositeFace, horizon);
4477
+ this._computeHorizon(eyePoint, twinEdge, oppositeFace, horizon);
4363
4478
  } else {
4364
4479
  horizon.push(edge);
4365
4480
  }
@@ -4368,22 +4483,38 @@ class ConvexHull {
4368
4483
  } while (edge !== crossEdge);
4369
4484
  return this;
4370
4485
  }
4371
- // Creates a face with the vertices 'eyeVertex.point', 'horizonEdge.tail' and 'horizonEdge.head' in CCW order
4372
- addAdjoiningFace(eyeVertex, horizonEdge) {
4486
+ /**
4487
+ * Creates a face with the vertices 'eyeVertex.point', 'horizonEdge.tail' and 'horizonEdge.head'
4488
+ * in CCW order. All the half edges are created in CCW order thus the face is always pointing
4489
+ * outside the hull.
4490
+ *
4491
+ * @private
4492
+ * @param {VertexNode} eyeVertex - The vertex that is added to the hull.
4493
+ * @param {HalfEdge} horizonEdge - A single edge of the horizon.
4494
+ * @return {HalfEdge} The half edge whose vertex is the eyeVertex.
4495
+ */
4496
+ _addAdjoiningFace(eyeVertex, horizonEdge) {
4373
4497
  const face = Face.create(eyeVertex, horizonEdge.tail(), horizonEdge.head());
4374
4498
  this.faces.push(face);
4375
4499
  face.getEdge(-1).setTwin(horizonEdge.twin);
4376
4500
  return face.getEdge(0);
4377
4501
  }
4378
- // Adds 'horizon.length' faces to the hull, each face will be linked with the
4379
- // horizon opposite face and the face on the left/right
4380
- addNewFaces(eyeVertex, horizon) {
4502
+ /**
4503
+ * Adds 'horizon.length' faces to the hull, each face will be linked with the horizon
4504
+ * opposite face and the face on the left/right.
4505
+ *
4506
+ * @private
4507
+ * @param {VertexNode} eyeVertex - The vertex that is added to the hull.
4508
+ * @param {Array<HalfEdge>} horizon - The horizon.
4509
+ * @return {ConvexHull} A reference to this convex hull.
4510
+ */
4511
+ _addNewFaces(eyeVertex, horizon) {
4381
4512
  this.newFaces = [];
4382
4513
  let firstSideEdge = null;
4383
4514
  let previousSideEdge = null;
4384
4515
  for (let i = 0; i < horizon.length; i++) {
4385
4516
  const horizonEdge = horizon[i];
4386
- const sideEdge = this.addAdjoiningFace(eyeVertex, horizonEdge);
4517
+ const sideEdge = this._addAdjoiningFace(eyeVertex, horizonEdge);
4387
4518
  if (firstSideEdge === null) {
4388
4519
  firstSideEdge = sideEdge;
4389
4520
  } else {
@@ -4395,34 +4526,62 @@ class ConvexHull {
4395
4526
  firstSideEdge.next.setTwin(previousSideEdge);
4396
4527
  return this;
4397
4528
  }
4398
- // Adds a vertex to the hull
4399
- addVertexToHull(eyeVertex) {
4529
+ /**
4530
+ * Adds a vertex to the hull with the following algorithm:
4531
+ *
4532
+ * - Compute the 'horizon' which is a chain of half edges. For an edge to belong to this group
4533
+ * it must be the edge connecting a face that can see 'eyeVertex' and a face which cannot see 'eyeVertex'.
4534
+ * - All the faces that can see 'eyeVertex' have its visible vertices removed from the assigned vertex list.
4535
+ * - A new set of faces is created with each edge of the 'horizon' and 'eyeVertex'. Each face is connected
4536
+ * with the opposite horizon face and the face on the left/right.
4537
+ * - The vertices removed from all the visible faces are assigned to the new faces if possible.
4538
+ *
4539
+ * @private
4540
+ * @param {VertexNode} eyeVertex - The vertex to add.
4541
+ * @return {ConvexHull} A reference to this convex hull.
4542
+ */
4543
+ _addVertexToHull(eyeVertex) {
4400
4544
  const horizon = [];
4401
4545
  this.unassigned.clear();
4402
- this.removeVertexFromFace(eyeVertex, eyeVertex.face);
4403
- this.computeHorizon(eyeVertex.point, null, eyeVertex.face, horizon);
4404
- this.addNewFaces(eyeVertex, horizon);
4405
- this.resolveUnassignedPoints(this.newFaces);
4546
+ this._removeVertexFromFace(eyeVertex, eyeVertex.face);
4547
+ this._computeHorizon(eyeVertex.point, null, eyeVertex.face, horizon);
4548
+ this._addNewFaces(eyeVertex, horizon);
4549
+ this._resolveUnassignedPoints(this.newFaces);
4406
4550
  return this;
4407
4551
  }
4408
- cleanup() {
4552
+ /**
4553
+ * Cleans up internal properties after computing the convex hull.
4554
+ *
4555
+ * @private
4556
+ * @return {ConvexHull} A reference to this convex hull.
4557
+ */
4558
+ _cleanup() {
4409
4559
  this.assigned.clear();
4410
4560
  this.unassigned.clear();
4411
4561
  this.newFaces = [];
4412
4562
  return this;
4413
4563
  }
4414
- compute() {
4564
+ /**
4565
+ * Starts the execution of the quick hull algorithm.
4566
+ *
4567
+ * @private
4568
+ * @return {ConvexHull} A reference to this convex hull.
4569
+ */
4570
+ _compute() {
4415
4571
  let vertex;
4416
- this.computeInitialHull();
4417
- while ((vertex = this.nextVertexToAdd()) !== void 0) {
4418
- this.addVertexToHull(vertex);
4572
+ this._computeInitialHull();
4573
+ while ((vertex = this._nextVertexToAdd()) !== void 0) {
4574
+ this._addVertexToHull(vertex);
4419
4575
  }
4420
- this.reindexFaces();
4421
- this.cleanup();
4576
+ this._reindexFaces();
4577
+ this._cleanup();
4422
4578
  return this;
4423
4579
  }
4424
4580
  }
4425
4581
  class Face {
4582
+ /**
4583
+ * Constructs a new face.
4584
+ */
4426
4585
  constructor() {
4427
4586
  this.normal = new THREE$1.Vector3();
4428
4587
  this.midpoint = new THREE$1.Vector3();
@@ -4432,6 +4591,15 @@ class Face {
4432
4591
  this.mark = Visible;
4433
4592
  this.edge = null;
4434
4593
  }
4594
+ /**
4595
+ * Creates a face from the given vertex nodes.
4596
+ *
4597
+ * @private
4598
+ * @param {VertexNode} a - The first vertex node.
4599
+ * @param {VertexNode} b - The second vertex node.
4600
+ * @param {VertexNode} c - The third vertex node.
4601
+ * @return {Face} The created face.
4602
+ */
4435
4603
  static create(a, b, c) {
4436
4604
  const face = new Face();
4437
4605
  const e0 = new HalfEdge(a, face);
@@ -4443,6 +4611,13 @@ class Face {
4443
4611
  face.edge = e0;
4444
4612
  return face.compute();
4445
4613
  }
4614
+ /**
4615
+ * Returns an edge by the given index.
4616
+ *
4617
+ * @private
4618
+ * @param {number} i - The edge index.
4619
+ * @return {HalfEdge} The edge.
4620
+ */
4446
4621
  getEdge(i) {
4447
4622
  let edge = this.edge;
4448
4623
  while (i > 0) {
@@ -4455,6 +4630,12 @@ class Face {
4455
4630
  }
4456
4631
  return edge;
4457
4632
  }
4633
+ /**
4634
+ * Computes all properties of the face.
4635
+ *
4636
+ * @private
4637
+ * @return {Face} A reference to this face.
4638
+ */
4458
4639
  compute() {
4459
4640
  const a = this.edge.tail();
4460
4641
  const b = this.edge.head();
@@ -4466,11 +4647,24 @@ class Face {
4466
4647
  this.constant = this.normal.dot(this.midpoint);
4467
4648
  return this;
4468
4649
  }
4650
+ /**
4651
+ * Returns the signed distance from a given point to the plane representation of this face.
4652
+ *
4653
+ * @private
4654
+ * @param {Vector3} point - The point to compute the distance to.
4655
+ * @return {number} The distance.
4656
+ */
4469
4657
  distanceToPoint(point) {
4470
4658
  return this.normal.dot(point) - this.constant;
4471
4659
  }
4472
4660
  }
4473
4661
  class HalfEdge {
4662
+ /**
4663
+ * Constructs a new half edge.
4664
+ *
4665
+ * @param {VertexNode} vertex - A reference to its destination vertex.
4666
+ * @param {Face} face - A reference to its face.
4667
+ */
4474
4668
  constructor(vertex, face) {
4475
4669
  this.vertex = vertex;
4476
4670
  this.prev = null;
@@ -4478,12 +4672,30 @@ class HalfEdge {
4478
4672
  this.twin = null;
4479
4673
  this.face = face;
4480
4674
  }
4675
+ /**
4676
+ * Returns the destination vertex.
4677
+ *
4678
+ * @private
4679
+ * @return {VertexNode} The destination vertex.
4680
+ */
4481
4681
  head() {
4482
4682
  return this.vertex;
4483
4683
  }
4684
+ /**
4685
+ * Returns the origin vertex.
4686
+ *
4687
+ * @private
4688
+ * @return {VertexNode} The destination vertex.
4689
+ */
4484
4690
  tail() {
4485
4691
  return this.prev ? this.prev.vertex : null;
4486
4692
  }
4693
+ /**
4694
+ * Returns the Euclidean length (straight-line length) of the edge.
4695
+ *
4696
+ * @private
4697
+ * @return {number} The edge's length.
4698
+ */
4487
4699
  length() {
4488
4700
  const head = this.head();
4489
4701
  const tail = this.tail();
@@ -4492,6 +4704,12 @@ class HalfEdge {
4492
4704
  }
4493
4705
  return -1;
4494
4706
  }
4707
+ /**
4708
+ * Returns the square of the Euclidean length (straight-line length) of the edge.
4709
+ *
4710
+ * @private
4711
+ * @return {number} The square of the edge's length.
4712
+ */
4495
4713
  lengthSquared() {
4496
4714
  const head = this.head();
4497
4715
  const tail = this.tail();
@@ -4500,6 +4718,14 @@ class HalfEdge {
4500
4718
  }
4501
4719
  return -1;
4502
4720
  }
4721
+ /**
4722
+ * Sets the twin edge of this half-edge. It also ensures that the twin reference
4723
+ * of the given half-edge is correctly set.
4724
+ *
4725
+ * @private
4726
+ * @param {HalfEdge} edge - The twin edge to set.
4727
+ * @return {HalfEdge} A reference to this edge.
4728
+ */
4503
4729
  setTwin(edge) {
4504
4730
  this.twin = edge;
4505
4731
  edge.twin = this;
@@ -4507,6 +4733,11 @@ class HalfEdge {
4507
4733
  }
4508
4734
  }
4509
4735
  class VertexNode {
4736
+ /**
4737
+ * Constructs a new vertex node.
4738
+ *
4739
+ * @param {Vector3} point - A point in 3D space.
4740
+ */
4510
4741
  constructor(point) {
4511
4742
  this.point = point;
4512
4743
  this.prev = null;
@@ -4515,21 +4746,49 @@ class VertexNode {
4515
4746
  }
4516
4747
  }
4517
4748
  class VertexList {
4749
+ /**
4750
+ * Constructs a new vertex list.
4751
+ */
4518
4752
  constructor() {
4519
4753
  this.head = null;
4520
4754
  this.tail = null;
4521
4755
  }
4756
+ /**
4757
+ * Returns the head reference.
4758
+ *
4759
+ * @private
4760
+ * @return {VertexNode} The head reference.
4761
+ */
4522
4762
  first() {
4523
4763
  return this.head;
4524
4764
  }
4765
+ /**
4766
+ * Returns the tail reference.
4767
+ *
4768
+ * @private
4769
+ * @return {VertexNode} The tail reference.
4770
+ */
4525
4771
  last() {
4526
4772
  return this.tail;
4527
4773
  }
4774
+ /**
4775
+ * Clears the linked list.
4776
+ *
4777
+ * @private
4778
+ * @return {VertexList} A reference to this vertex list.
4779
+ */
4528
4780
  clear() {
4529
4781
  this.head = this.tail = null;
4530
4782
  return this;
4531
4783
  }
4532
- // Inserts a vertex before the target vertex
4784
+ /**
4785
+ * Inserts a vertex before a target vertex.
4786
+ *
4787
+ * @private
4788
+ * @param {VertexNode} target - The target.
4789
+ * @param {VertexNode} vertex - The vertex to insert.
4790
+ * @return {VertexList} A reference to this vertex list.
4791
+ */
4533
4792
  insertBefore(target, vertex) {
4534
4793
  vertex.prev = target.prev;
4535
4794
  vertex.next = target;
@@ -4541,7 +4800,14 @@ class VertexList {
4541
4800
  target.prev = vertex;
4542
4801
  return this;
4543
4802
  }
4544
- // Inserts a vertex after the target vertex
4803
+ /**
4804
+ * Inserts a vertex after a target vertex.
4805
+ *
4806
+ * @private
4807
+ * @param {VertexNode} target - The target.
4808
+ * @param {VertexNode} vertex - The vertex to insert.
4809
+ * @return {VertexList} A reference to this vertex list.
4810
+ */
4545
4811
  insertAfter(target, vertex) {
4546
4812
  vertex.prev = target;
4547
4813
  vertex.next = target.next;
@@ -4553,7 +4819,13 @@ class VertexList {
4553
4819
  target.next = vertex;
4554
4820
  return this;
4555
4821
  }
4556
- // Appends a vertex to the end of the linked list
4822
+ /**
4823
+ * Appends a vertex to this vertex list.
4824
+ *
4825
+ * @private
4826
+ * @param {VertexNode} vertex - The vertex to append.
4827
+ * @return {VertexList} A reference to this vertex list.
4828
+ */
4557
4829
  append(vertex) {
4558
4830
  if (this.head === null) {
4559
4831
  this.head = vertex;
@@ -4565,7 +4837,13 @@ class VertexList {
4565
4837
  this.tail = vertex;
4566
4838
  return this;
4567
4839
  }
4568
- // Appends a chain of vertices where 'vertex' is the head.
4840
+ /**
4841
+ * Appends a chain of vertices where the given vertex is the head.
4842
+ *
4843
+ * @private
4844
+ * @param {VertexNode} vertex - The head vertex of a chain of vertices.
4845
+ * @return {VertexList} A reference to this vertex list.
4846
+ */
4569
4847
  appendChain(vertex) {
4570
4848
  if (this.head === null) {
4571
4849
  this.head = vertex;
@@ -4579,7 +4857,13 @@ class VertexList {
4579
4857
  this.tail = vertex;
4580
4858
  return this;
4581
4859
  }
4582
- // Removes a vertex from the linked list
4860
+ /**
4861
+ * Removes a vertex from the linked list.
4862
+ *
4863
+ * @private
4864
+ * @param {VertexNode} vertex - The vertex to remove.
4865
+ * @return {VertexList} A reference to this vertex list.
4866
+ */
4583
4867
  remove(vertex) {
4584
4868
  if (vertex.prev === null) {
4585
4869
  this.head = vertex.next;
@@ -4593,7 +4877,14 @@ class VertexList {
4593
4877
  }
4594
4878
  return this;
4595
4879
  }
4596
- // Removes a list of vertices whose 'head' is 'a' and whose 'tail' is b
4880
+ /**
4881
+ * Removes a sublist of vertices from the linked list.
4882
+ *
4883
+ * @private
4884
+ * @param {VertexNode} a - The head of the sublist.
4885
+ * @param {VertexNode} b - The tail of the sublist.
4886
+ * @return {VertexList} A reference to this vertex list.
4887
+ */
4597
4888
  removeSubList(a, b) {
4598
4889
  if (a.prev === null) {
4599
4890
  this.head = b.next;
@@ -4607,6 +4898,12 @@ class VertexList {
4607
4898
  }
4608
4899
  return this;
4609
4900
  }
4901
+ /**
4902
+ * Returns `true` if the linked list is empty.
4903
+ *
4904
+ * @private
4905
+ * @return {boolean} Whether the linked list is empty or not.
4906
+ */
4610
4907
  isEmpty() {
4611
4908
  return this.head === null;
4612
4909
  }
@@ -6312,7 +6609,7 @@ const _Components = class _Components {
6312
6609
  /**
6313
6610
  * The version of the @thatopen/components library.
6314
6611
  */
6315
- __publicField(_Components, "release", "2.4.8");
6612
+ __publicField(_Components, "release", "2.4.9");
6316
6613
  let Components = _Components;
6317
6614
  class SimpleWorld extends Base {
6318
6615
  constructor() {
@@ -10808,7 +11105,7 @@ class SimpleGrid {
10808
11105
 
10809
11106
  `,
10810
11107
  extensions: {
10811
- derivatives: true
11108
+ // derivatives: true,
10812
11109
  }
10813
11110
  });
10814
11111
  this.three = new THREE__namespace.Mesh(geometry, material);
@@ -10962,26 +11259,26 @@ const _unit = {
10962
11259
  Z: new THREE$1.Vector3(0, 0, 1)
10963
11260
  };
10964
11261
  const _changeEvent = { type: "change" };
10965
- const _mouseDownEvent = { type: "mouseDown" };
11262
+ const _mouseDownEvent = { type: "mouseDown", mode: null };
10966
11263
  const _mouseUpEvent = { type: "mouseUp", mode: null };
10967
11264
  const _objectChangeEvent = { type: "objectChange" };
10968
- class TransformControls extends THREE$1.Object3D {
10969
- constructor(camera, domElement) {
10970
- super();
10971
- if (domElement === void 0) {
10972
- console.warn('THREE.TransformControls: The second parameter "domElement" is now mandatory.');
10973
- domElement = document;
10974
- }
10975
- this.isTransformControls = true;
10976
- this.visible = false;
10977
- this.domElement = domElement;
10978
- this.domElement.style.touchAction = "none";
10979
- const _gizmo = new TransformControlsGizmo();
10980
- this._gizmo = _gizmo;
10981
- this.add(_gizmo);
10982
- const _plane2 = new TransformControlsPlane();
10983
- this._plane = _plane2;
10984
- this.add(_plane2);
11265
+ class TransformControls extends THREE$1.Controls {
11266
+ /**
11267
+ * Constructs a new controls instance.
11268
+ *
11269
+ * @param {Camera} camera - The camera of the rendered scene.
11270
+ * @param {?HTMLDOMElement} domElement - The HTML element used for event listeners.
11271
+ */
11272
+ constructor(camera, domElement = null) {
11273
+ super(void 0, domElement);
11274
+ const root = new TransformControlsRoot(this);
11275
+ this._root = root;
11276
+ const gizmo = new TransformControlsGizmo();
11277
+ this._gizmo = gizmo;
11278
+ root.add(gizmo);
11279
+ const plane = new TransformControlsPlane();
11280
+ this._plane = plane;
11281
+ root.add(plane);
10985
11282
  const scope = this;
10986
11283
  function defineProperty(propName2, defaultValue) {
10987
11284
  let propValue = defaultValue;
@@ -10992,16 +11289,16 @@ class TransformControls extends THREE$1.Object3D {
10992
11289
  set: function(value) {
10993
11290
  if (propValue !== value) {
10994
11291
  propValue = value;
10995
- _plane2[propName2] = value;
10996
- _gizmo[propName2] = value;
11292
+ plane[propName2] = value;
11293
+ gizmo[propName2] = value;
10997
11294
  scope.dispatchEvent({ type: propName2 + "-changed", value });
10998
11295
  scope.dispatchEvent(_changeEvent);
10999
11296
  }
11000
11297
  }
11001
11298
  });
11002
11299
  scope[propName2] = defaultValue;
11003
- _plane2[propName2] = defaultValue;
11004
- _gizmo[propName2] = defaultValue;
11300
+ plane[propName2] = defaultValue;
11301
+ gizmo[propName2] = defaultValue;
11005
11302
  }
11006
11303
  defineProperty("camera", camera);
11007
11304
  defineProperty("object", void 0);
@@ -11017,6 +11314,12 @@ class TransformControls extends THREE$1.Object3D {
11017
11314
  defineProperty("showX", true);
11018
11315
  defineProperty("showY", true);
11019
11316
  defineProperty("showZ", true);
11317
+ defineProperty("minX", -Infinity);
11318
+ defineProperty("maxX", Infinity);
11319
+ defineProperty("minY", -Infinity);
11320
+ defineProperty("maxY", Infinity);
11321
+ defineProperty("minZ", -Infinity);
11322
+ defineProperty("maxZ", Infinity);
11020
11323
  const worldPosition = new THREE$1.Vector3();
11021
11324
  const worldPositionStart = new THREE$1.Vector3();
11022
11325
  const worldQuaternion = new THREE$1.Quaternion();
@@ -11058,36 +11361,38 @@ class TransformControls extends THREE$1.Object3D {
11058
11361
  this._onPointerHover = onPointerHover.bind(this);
11059
11362
  this._onPointerMove = onPointerMove.bind(this);
11060
11363
  this._onPointerUp = onPointerUp.bind(this);
11364
+ if (domElement !== null) {
11365
+ this.connect(domElement);
11366
+ }
11367
+ }
11368
+ connect(element) {
11369
+ super.connect(element);
11061
11370
  this.domElement.addEventListener("pointerdown", this._onPointerDown);
11062
11371
  this.domElement.addEventListener("pointermove", this._onPointerHover);
11063
11372
  this.domElement.addEventListener("pointerup", this._onPointerUp);
11373
+ this.domElement.style.touchAction = "none";
11064
11374
  }
11065
- // updateMatrixWorld updates key transformation variables
11066
- updateMatrixWorld() {
11067
- if (this.object !== void 0) {
11068
- this.object.updateMatrixWorld();
11069
- if (this.object.parent === null) {
11070
- console.error("TransformControls: The attached 3D object must be a part of the scene graph.");
11071
- } else {
11072
- this.object.parent.matrixWorld.decompose(this._parentPosition, this._parentQuaternion, this._parentScale);
11073
- }
11074
- this.object.matrixWorld.decompose(this.worldPosition, this.worldQuaternion, this._worldScale);
11075
- this._parentQuaternionInv.copy(this._parentQuaternion).invert();
11076
- this._worldQuaternionInv.copy(this.worldQuaternion).invert();
11077
- }
11078
- this.camera.updateMatrixWorld();
11079
- this.camera.matrixWorld.decompose(this.cameraPosition, this.cameraQuaternion, this._cameraScale);
11080
- if (this.camera.isOrthographicCamera) {
11081
- this.camera.getWorldDirection(this.eye).negate();
11082
- } else {
11083
- this.eye.copy(this.cameraPosition).sub(this.worldPosition).normalize();
11084
- }
11085
- super.updateMatrixWorld(this);
11375
+ disconnect() {
11376
+ this.domElement.removeEventListener("pointerdown", this._onPointerDown);
11377
+ this.domElement.removeEventListener("pointermove", this._onPointerHover);
11378
+ this.domElement.removeEventListener("pointermove", this._onPointerMove);
11379
+ this.domElement.removeEventListener("pointerup", this._onPointerUp);
11380
+ this.domElement.style.touchAction = "auto";
11381
+ }
11382
+ /**
11383
+ * Returns the visual representation of the controls. Add the helper to your scene to
11384
+ * visually transform the attached 3D object.
11385
+ *
11386
+ * @return {TransformControlsRoot} The helper.
11387
+ */
11388
+ getHelper() {
11389
+ return this._root;
11086
11390
  }
11087
11391
  pointerHover(pointer) {
11088
11392
  if (this.object === void 0 || this.dragging === true)
11089
11393
  return;
11090
- _raycaster.setFromCamera(pointer, this.camera);
11394
+ if (pointer !== null)
11395
+ _raycaster.setFromCamera(pointer, this.camera);
11091
11396
  const intersect = intersectObjectWithRay(this._gizmo.picker[this.mode], _raycaster);
11092
11397
  if (intersect) {
11093
11398
  this.axis = intersect.object.name;
@@ -11096,10 +11401,11 @@ class TransformControls extends THREE$1.Object3D {
11096
11401
  }
11097
11402
  }
11098
11403
  pointerDown(pointer) {
11099
- if (this.object === void 0 || this.dragging === true || pointer.button !== 0)
11404
+ if (this.object === void 0 || this.dragging === true || pointer != null && pointer.button !== 0)
11100
11405
  return;
11101
11406
  if (this.axis !== null) {
11102
- _raycaster.setFromCamera(pointer, this.camera);
11407
+ if (pointer !== null)
11408
+ _raycaster.setFromCamera(pointer, this.camera);
11103
11409
  const planeIntersect = intersectObjectWithRay(this._plane, _raycaster, true);
11104
11410
  if (planeIntersect) {
11105
11411
  this.object.updateMatrixWorld();
@@ -11125,9 +11431,10 @@ class TransformControls extends THREE$1.Object3D {
11125
11431
  } else if (axis === "E" || axis === "XYZE" || axis === "XYZ") {
11126
11432
  space = "world";
11127
11433
  }
11128
- if (object === void 0 || axis === null || this.dragging === false || pointer.button !== -1)
11434
+ if (object === void 0 || axis === null || this.dragging === false || pointer !== null && pointer.button !== -1)
11129
11435
  return;
11130
- _raycaster.setFromCamera(pointer, this.camera);
11436
+ if (pointer !== null)
11437
+ _raycaster.setFromCamera(pointer, this.camera);
11131
11438
  const planeIntersect = intersectObjectWithRay(this._plane, _raycaster, true);
11132
11439
  if (!planeIntersect)
11133
11440
  return;
@@ -11181,6 +11488,9 @@ class TransformControls extends THREE$1.Object3D {
11181
11488
  }
11182
11489
  }
11183
11490
  }
11491
+ object.position.x = Math.max(this.minX, Math.min(this.maxX, object.position.x));
11492
+ object.position.y = Math.max(this.minY, Math.min(this.maxY, object.position.y));
11493
+ object.position.z = Math.max(this.minZ, Math.min(this.maxZ, object.position.z));
11184
11494
  } else if (mode === "scale") {
11185
11495
  if (axis.search("XYZ") !== -1) {
11186
11496
  let d = this.pointEnd.length() / this.pointStart.length();
@@ -11257,7 +11567,7 @@ class TransformControls extends THREE$1.Object3D {
11257
11567
  this.dispatchEvent(_objectChangeEvent);
11258
11568
  }
11259
11569
  pointerUp(pointer) {
11260
- if (pointer.button !== 0)
11570
+ if (pointer !== null && pointer.button !== 0)
11261
11571
  return;
11262
11572
  if (this.dragging && this.axis !== null) {
11263
11573
  _mouseUpEvent.mode = this.mode;
@@ -11267,30 +11577,34 @@ class TransformControls extends THREE$1.Object3D {
11267
11577
  this.axis = null;
11268
11578
  }
11269
11579
  dispose() {
11270
- this.domElement.removeEventListener("pointerdown", this._onPointerDown);
11271
- this.domElement.removeEventListener("pointermove", this._onPointerHover);
11272
- this.domElement.removeEventListener("pointermove", this._onPointerMove);
11273
- this.domElement.removeEventListener("pointerup", this._onPointerUp);
11274
- this.traverse(function(child) {
11275
- if (child.geometry)
11276
- child.geometry.dispose();
11277
- if (child.material)
11278
- child.material.dispose();
11279
- });
11580
+ this.disconnect();
11581
+ this._root.dispose();
11280
11582
  }
11281
- // Set current object
11583
+ /**
11584
+ * Sets the 3D object that should be transformed and ensures the controls UI is visible.
11585
+ *
11586
+ * @param {Object3D} object - The 3D object that should be transformed.
11587
+ * @return {TransformControls} A reference to this controls.
11588
+ */
11282
11589
  attach(object) {
11283
11590
  this.object = object;
11284
- this.visible = true;
11591
+ this._root.visible = true;
11285
11592
  return this;
11286
11593
  }
11287
- // Detach from object
11594
+ /**
11595
+ * Removes the current 3D object from the controls and makes the helper UI invisible.
11596
+ *
11597
+ * @return {TransformControls} A reference to this controls.
11598
+ */
11288
11599
  detach() {
11289
11600
  this.object = void 0;
11290
- this.visible = false;
11291
11601
  this.axis = null;
11602
+ this._root.visible = false;
11292
11603
  return this;
11293
11604
  }
11605
+ /**
11606
+ * Resets the object's position, rotation and scale to when the current transform began.
11607
+ */
11294
11608
  reset() {
11295
11609
  if (!this.enabled)
11296
11610
  return;
@@ -11303,28 +11617,68 @@ class TransformControls extends THREE$1.Object3D {
11303
11617
  this.pointStart.copy(this.pointEnd);
11304
11618
  }
11305
11619
  }
11620
+ /**
11621
+ * Returns the raycaster that is used for user interaction. This object is shared between all
11622
+ * instances of `TransformControls`.
11623
+ *
11624
+ * @returns {Raycaster} The internal raycaster.
11625
+ */
11306
11626
  getRaycaster() {
11307
11627
  return _raycaster;
11308
11628
  }
11309
- // TODO: deprecate
11629
+ /**
11630
+ * Returns the transformation mode.
11631
+ *
11632
+ * @returns {'translate'|'rotate'|'scale'} The transformation mode.
11633
+ */
11310
11634
  getMode() {
11311
11635
  return this.mode;
11312
11636
  }
11637
+ /**
11638
+ * Sets the given transformation mode.
11639
+ *
11640
+ * @param {'translate'|'rotate'|'scale'} mode - The transformation mode to set.
11641
+ */
11313
11642
  setMode(mode) {
11314
11643
  this.mode = mode;
11315
11644
  }
11645
+ /**
11646
+ * Sets the translation snap.
11647
+ *
11648
+ * @param {?number} translationSnap - The translation snap to set.
11649
+ */
11316
11650
  setTranslationSnap(translationSnap) {
11317
11651
  this.translationSnap = translationSnap;
11318
11652
  }
11653
+ /**
11654
+ * Sets the rotation snap.
11655
+ *
11656
+ * @param {?number} rotationSnap - The rotation snap to set.
11657
+ */
11319
11658
  setRotationSnap(rotationSnap) {
11320
11659
  this.rotationSnap = rotationSnap;
11321
11660
  }
11661
+ /**
11662
+ * Sets the scale snap.
11663
+ *
11664
+ * @param {?number} scaleSnap - The scale snap to set.
11665
+ */
11322
11666
  setScaleSnap(scaleSnap) {
11323
11667
  this.scaleSnap = scaleSnap;
11324
11668
  }
11669
+ /**
11670
+ * Sets the size of the helper UI.
11671
+ *
11672
+ * @param {number} size - The size to set.
11673
+ */
11325
11674
  setSize(size) {
11326
11675
  this.size = size;
11327
11676
  }
11677
+ /**
11678
+ * Sets the coordinate space in which transformations are applied.
11679
+ *
11680
+ * @param {'world'|'local'} space - The space to set.
11681
+ */
11328
11682
  setSpace(space) {
11329
11683
  this.space = space;
11330
11684
  }
@@ -11400,6 +11754,45 @@ const _unitZ = new THREE$1.Vector3(0, 0, 1);
11400
11754
  const _v1 = new THREE$1.Vector3();
11401
11755
  const _v2 = new THREE$1.Vector3();
11402
11756
  const _v3 = new THREE$1.Vector3();
11757
+ class TransformControlsRoot extends THREE$1.Object3D {
11758
+ constructor(controls) {
11759
+ super();
11760
+ this.isTransformControlsRoot = true;
11761
+ this.controls = controls;
11762
+ this.visible = false;
11763
+ }
11764
+ // updateMatrixWorld updates key transformation variables
11765
+ updateMatrixWorld(force) {
11766
+ const controls = this.controls;
11767
+ if (controls.object !== void 0) {
11768
+ controls.object.updateMatrixWorld();
11769
+ if (controls.object.parent === null) {
11770
+ console.error("TransformControls: The attached 3D object must be a part of the scene graph.");
11771
+ } else {
11772
+ controls.object.parent.matrixWorld.decompose(controls._parentPosition, controls._parentQuaternion, controls._parentScale);
11773
+ }
11774
+ controls.object.matrixWorld.decompose(controls.worldPosition, controls.worldQuaternion, controls._worldScale);
11775
+ controls._parentQuaternionInv.copy(controls._parentQuaternion).invert();
11776
+ controls._worldQuaternionInv.copy(controls.worldQuaternion).invert();
11777
+ }
11778
+ controls.camera.updateMatrixWorld();
11779
+ controls.camera.matrixWorld.decompose(controls.cameraPosition, controls.cameraQuaternion, controls._cameraScale);
11780
+ if (controls.camera.isOrthographicCamera) {
11781
+ controls.camera.getWorldDirection(controls.eye).negate();
11782
+ } else {
11783
+ controls.eye.copy(controls.cameraPosition).sub(controls.worldPosition).normalize();
11784
+ }
11785
+ super.updateMatrixWorld(force);
11786
+ }
11787
+ dispose() {
11788
+ this.traverse(function(child) {
11789
+ if (child.geometry)
11790
+ child.geometry.dispose();
11791
+ if (child.material)
11792
+ child.material.dispose();
11793
+ });
11794
+ }
11795
+ }
11403
11796
  class TransformControlsGizmo extends THREE$1.Object3D {
11404
11797
  constructor() {
11405
11798
  super();
@@ -12025,7 +12418,7 @@ class SimplePlane {
12025
12418
  /** {@link Hideable.visible } */
12026
12419
  set visible(state) {
12027
12420
  this._visible = state;
12028
- this._controls.visible = state;
12421
+ this._controls.object.visible = state;
12029
12422
  this._helper.visible = state;
12030
12423
  this.toggleControls(state);
12031
12424
  }
@@ -12092,7 +12485,7 @@ class SimplePlane {
12092
12485
  this._arrowBoundBox.removeFromParent();
12093
12486
  this._arrowBoundBox.geometry.dispose();
12094
12487
  this._planeMesh.geometry.dispose();
12095
- this._controls.removeFromParent();
12488
+ this._controls.object.removeFromParent();
12096
12489
  this._controls.dispose();
12097
12490
  this.onDisposed.trigger();
12098
12491
  this.onDisposed.reset();
@@ -12128,7 +12521,7 @@ class SimplePlane {
12128
12521
  const container = this.world.renderer.three.domElement;
12129
12522
  const controls = new TransformControls(camera, container);
12130
12523
  this.initializeControls(controls);
12131
- this.world.scene.three.add(controls);
12524
+ this.world.scene.three.add(controls.object);
12132
12525
  return controls;
12133
12526
  }
12134
12527
  initializeControls(controls) {
@@ -12137,7 +12530,7 @@ class SimplePlane {
12137
12530
  controls.showY = false;
12138
12531
  controls.setSpace("local");
12139
12532
  this.createArrowBoundingBox();
12140
- controls.children[0].children[0].add(this._arrowBoundBox);
12533
+ controls.object.children[0].children[0].add(this._arrowBoundBox);
12141
12534
  }
12142
12535
  createArrowBoundingBox() {
12143
12536
  this._arrowBoundBox.geometry = new THREE__namespace.CylinderGeometry(0.18, 0.18, 1.2);