@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.mjs CHANGED
@@ -5,7 +5,7 @@ var __publicField = (obj, key, value) => {
5
5
  return value;
6
6
  };
7
7
  import * as THREE$1 from "three";
8
- import { BufferAttribute, Vector3, Vector2, Plane, Line3, Triangle, Sphere, Matrix4, Box3, BackSide, DoubleSide, FrontSide, Mesh, Ray, Raycaster, Quaternion, Object3D, Euler, MeshBasicMaterial, LineBasicMaterial, CylinderGeometry, BoxGeometry, BufferGeometry, Float32BufferAttribute, OctahedronGeometry, Line, SphereGeometry, TorusGeometry, PlaneGeometry } from "three";
8
+ import { BufferAttribute, Vector3, Vector2, Plane, Line3, Triangle, Sphere, Matrix4, Box3, BackSide, DoubleSide, FrontSide, Mesh, Ray, Raycaster, Quaternion, Controls, Euler, Object3D, MeshBasicMaterial, LineBasicMaterial, CylinderGeometry, BoxGeometry, BufferGeometry, Float32BufferAttribute, OctahedronGeometry, Line, SphereGeometry, TorusGeometry, PlaneGeometry } from "three";
9
9
  import * as FRAGS from "@thatopen/fragments";
10
10
  import { FragmentsGroup, Serializer } from "@thatopen/fragments";
11
11
  import * as WEBIFC from "web-ifc";
@@ -4002,6 +4002,9 @@ const _plane = new Plane();
4002
4002
  const _closestPoint = new Vector3();
4003
4003
  const _triangle = new Triangle();
4004
4004
  class ConvexHull {
4005
+ /**
4006
+ * Constructs a new convex hull.
4007
+ */
4005
4008
  constructor() {
4006
4009
  this.tolerance = -1;
4007
4010
  this.faces = [];
@@ -4010,16 +4013,29 @@ class ConvexHull {
4010
4013
  this.unassigned = new VertexList();
4011
4014
  this.vertices = [];
4012
4015
  }
4016
+ /**
4017
+ * Computes to convex hull for the given array of points.
4018
+ *
4019
+ * @param {Array<Vector3>} points - The array of points in 3D space.
4020
+ * @return {ConvexHull} A reference to this convex hull.
4021
+ */
4013
4022
  setFromPoints(points) {
4014
4023
  if (points.length >= 4) {
4015
4024
  this.makeEmpty();
4016
4025
  for (let i = 0, l = points.length; i < l; i++) {
4017
4026
  this.vertices.push(new VertexNode(points[i]));
4018
4027
  }
4019
- this.compute();
4028
+ this._compute();
4020
4029
  }
4021
4030
  return this;
4022
4031
  }
4032
+ /**
4033
+ * Computes the convex hull of the given 3D object (including its descendants),
4034
+ * accounting for the world transforms of both the 3D object and its descendants.
4035
+ *
4036
+ * @param {Object3D} object - The 3D object to compute the convex hull for.
4037
+ * @return {ConvexHull} A reference to this convex hull.
4038
+ */
4023
4039
  setFromObject(object) {
4024
4040
  const points = [];
4025
4041
  object.updateMatrixWorld(true);
@@ -4038,6 +4054,12 @@ class ConvexHull {
4038
4054
  });
4039
4055
  return this.setFromPoints(points);
4040
4056
  }
4057
+ /**
4058
+ * Returns `true` if the given point lies in the convex hull.
4059
+ *
4060
+ * @param {Vector3} point - The point to test.
4061
+ * @return {boolean} Whether the given point lies in the convex hull or not.
4062
+ */
4041
4063
  containsPoint(point) {
4042
4064
  const faces = this.faces;
4043
4065
  for (let i = 0, l = faces.length; i < l; i++) {
@@ -4047,6 +4069,13 @@ class ConvexHull {
4047
4069
  }
4048
4070
  return true;
4049
4071
  }
4072
+ /**
4073
+ * Computes the intersections point of the given ray and this convex hull.
4074
+ *
4075
+ * @param {Ray} ray - The ray to test.
4076
+ * @param {Vector3} target - The target vector that is used to store the method's result.
4077
+ * @return {Vector3|null} The intersection point. Returns `null` if not intersection was detected.
4078
+ */
4050
4079
  intersectRay(ray2, target) {
4051
4080
  const faces = this.faces;
4052
4081
  let tNear = -Infinity;
@@ -4076,16 +4105,35 @@ class ConvexHull {
4076
4105
  }
4077
4106
  return target;
4078
4107
  }
4108
+ /**
4109
+ * Returns `true` if the given ray intersects with this convex hull.
4110
+ *
4111
+ * @param {Ray} ray - The ray to test.
4112
+ * @return {boolean} Whether the given ray intersects with this convex hull or not.
4113
+ */
4079
4114
  intersectsRay(ray2) {
4080
4115
  return this.intersectRay(ray2, _v1$1) !== null;
4081
4116
  }
4117
+ /**
4118
+ * Makes the convex hull empty.
4119
+ *
4120
+ * @return {ConvexHull} A reference to this convex hull.
4121
+ */
4082
4122
  makeEmpty() {
4083
4123
  this.faces = [];
4084
4124
  this.vertices = [];
4085
4125
  return this;
4086
4126
  }
4087
- // Adds a vertex to the 'assigned' list of vertices and assigns it to the given face
4088
- addVertexToFace(vertex, face) {
4127
+ // private
4128
+ /**
4129
+ * Adds a vertex to the 'assigned' list of vertices and assigns it to the given face.
4130
+ *
4131
+ * @private
4132
+ * @param {VertexNode} vertex - The vertex to add.
4133
+ * @param {Face} face - The target face.
4134
+ * @return {ConvexHull} A reference to this convex hull.
4135
+ */
4136
+ _addVertexToFace(vertex, face) {
4089
4137
  vertex.face = face;
4090
4138
  if (face.outside === null) {
4091
4139
  this.assigned.append(vertex);
@@ -4095,8 +4143,17 @@ class ConvexHull {
4095
4143
  face.outside = vertex;
4096
4144
  return this;
4097
4145
  }
4098
- // Removes a vertex from the 'assigned' list of vertices and from the given face
4099
- removeVertexFromFace(vertex, face) {
4146
+ /**
4147
+ * Removes a vertex from the 'assigned' list of vertices and from the given face.
4148
+ * It also makes sure that the link from 'face' to the first vertex it sees in 'assigned'
4149
+ * is linked correctly after the removal.
4150
+ *
4151
+ * @private
4152
+ * @param {VertexNode} vertex - The vertex to remove.
4153
+ * @param {Face} face - The target face.
4154
+ * @return {ConvexHull} A reference to this convex hull.
4155
+ */
4156
+ _removeVertexFromFace(vertex, face) {
4100
4157
  if (vertex === face.outside) {
4101
4158
  if (vertex.next !== null && vertex.next.face === face) {
4102
4159
  face.outside = vertex.next;
@@ -4107,8 +4164,15 @@ class ConvexHull {
4107
4164
  this.assigned.remove(vertex);
4108
4165
  return this;
4109
4166
  }
4110
- // Removes all the visible vertices that a given face is able to see which are stored in the 'assigned' vertex list
4111
- removeAllVerticesFromFace(face) {
4167
+ /**
4168
+ * Removes all the visible vertices that a given face is able to see which are stored in
4169
+ * the 'assigned' vertex list.
4170
+ *
4171
+ * @private
4172
+ * @param {Face} face - The target face.
4173
+ * @return {VertexNode|undefined} A reference to this convex hull.
4174
+ */
4175
+ _removeAllVerticesFromFace(face) {
4112
4176
  if (face.outside !== null) {
4113
4177
  const start = face.outside;
4114
4178
  let end = face.outside;
@@ -4121,9 +4185,20 @@ class ConvexHull {
4121
4185
  return start;
4122
4186
  }
4123
4187
  }
4124
- // Removes all the visible vertices that 'face' is able to see
4125
- deleteFaceVertices(face, absorbingFace) {
4126
- const faceVertices = this.removeAllVerticesFromFace(face);
4188
+ /**
4189
+ * Removes all the visible vertices that `face` is able to see.
4190
+ *
4191
+ * - If `absorbingFace` doesn't exist, then all the removed vertices will be added to the 'unassigned' vertex list.
4192
+ * - If `absorbingFace` exists, then this method will assign all the vertices of 'face' that can see 'absorbingFace'.
4193
+ * - If a vertex cannot see `absorbingFace`, it's added to the 'unassigned' vertex list.
4194
+ *
4195
+ * @private
4196
+ * @param {Face} face - The given face.
4197
+ * @param {Face} [absorbingFace] - An optional face that tries to absorb the vertices of the first face.
4198
+ * @return {ConvexHull} A reference to this convex hull.
4199
+ */
4200
+ _deleteFaceVertices(face, absorbingFace) {
4201
+ const faceVertices = this._removeAllVerticesFromFace(face);
4127
4202
  if (faceVertices !== void 0) {
4128
4203
  if (absorbingFace === void 0) {
4129
4204
  this.unassigned.appendChain(faceVertices);
@@ -4133,7 +4208,7 @@ class ConvexHull {
4133
4208
  const nextVertex = vertex.next;
4134
4209
  const distance = absorbingFace.distanceToPoint(vertex.point);
4135
4210
  if (distance > this.tolerance) {
4136
- this.addVertexToFace(vertex, absorbingFace);
4211
+ this._addVertexToFace(vertex, absorbingFace);
4137
4212
  } else {
4138
4213
  this.unassigned.append(vertex);
4139
4214
  }
@@ -4143,8 +4218,14 @@ class ConvexHull {
4143
4218
  }
4144
4219
  return this;
4145
4220
  }
4146
- // Reassigns as many vertices as possible from the unassigned list to the new faces
4147
- resolveUnassignedPoints(newFaces) {
4221
+ /**
4222
+ * Reassigns as many vertices as possible from the unassigned list to the new faces.
4223
+ *
4224
+ * @private
4225
+ * @param {Array<Face>} newFaces - The new faces.
4226
+ * @return {ConvexHull} A reference to this convex hull.
4227
+ */
4228
+ _resolveUnassignedPoints(newFaces) {
4148
4229
  if (this.unassigned.isEmpty() === false) {
4149
4230
  let vertex = this.unassigned.first();
4150
4231
  do {
@@ -4164,15 +4245,21 @@ class ConvexHull {
4164
4245
  }
4165
4246
  }
4166
4247
  if (maxFace !== null) {
4167
- this.addVertexToFace(vertex, maxFace);
4248
+ this._addVertexToFace(vertex, maxFace);
4168
4249
  }
4169
4250
  vertex = nextVertex;
4170
4251
  } while (vertex !== null);
4171
4252
  }
4172
4253
  return this;
4173
4254
  }
4174
- // Computes the extremes of a simplex which will be the initial hull
4175
- computeExtremes() {
4255
+ /**
4256
+ * Computes the extremes values (min/max vectors) which will be used to
4257
+ * compute the initial hull.
4258
+ *
4259
+ * @private
4260
+ * @return {Object} The extremes.
4261
+ */
4262
+ _computeExtremes() {
4176
4263
  const min = new Vector3();
4177
4264
  const max = new Vector3();
4178
4265
  const minVertices = [];
@@ -4201,11 +4288,16 @@ class ConvexHull {
4201
4288
  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)));
4202
4289
  return { min: minVertices, max: maxVertices };
4203
4290
  }
4204
- // Computes the initial simplex assigning to its faces all the points
4205
- // that are candidates to form part of the hull
4206
- computeInitialHull() {
4291
+ /**
4292
+ * Computes the initial simplex assigning to its faces all the points that are
4293
+ * candidates to form part of the hull.
4294
+ *
4295
+ * @private
4296
+ * @return {ConvexHull} A reference to this convex hull.
4297
+ */
4298
+ _computeInitialHull() {
4207
4299
  const vertices = this.vertices;
4208
- const extremes = this.computeExtremes();
4300
+ const extremes = this._computeExtremes();
4209
4301
  const min = extremes.min;
4210
4302
  const max = extremes.max;
4211
4303
  let maxDistance = 0;
@@ -4288,14 +4380,19 @@ class ConvexHull {
4288
4380
  }
4289
4381
  }
4290
4382
  if (maxFace !== null) {
4291
- this.addVertexToFace(vertex, maxFace);
4383
+ this._addVertexToFace(vertex, maxFace);
4292
4384
  }
4293
4385
  }
4294
4386
  }
4295
4387
  return this;
4296
4388
  }
4297
- // Removes inactive faces
4298
- reindexFaces() {
4389
+ /**
4390
+ * Removes inactive (e.g. deleted) faces from the internal face list.
4391
+ *
4392
+ * @private
4393
+ * @return {ConvexHull} A reference to this convex hull.
4394
+ */
4395
+ _reindexFaces() {
4299
4396
  const activeFaces = [];
4300
4397
  for (let i = 0; i < this.faces.length; i++) {
4301
4398
  const face = this.faces[i];
@@ -4306,8 +4403,17 @@ class ConvexHull {
4306
4403
  this.faces = activeFaces;
4307
4404
  return this;
4308
4405
  }
4309
- // Finds the next vertex to create faces with the current hull
4310
- nextVertexToAdd() {
4406
+ /**
4407
+ * Finds the next vertex to create faces with the current hull.
4408
+ *
4409
+ * - Let the initial face be the first face existing in the 'assigned' vertex list.
4410
+ * - If a face doesn't exist then return since there're no vertices left.
4411
+ * - Otherwise for each vertex that face sees find the one furthest away from it.
4412
+ *
4413
+ * @private
4414
+ * @return {?VertexNode} The next vertex to add.
4415
+ */
4416
+ _nextVertexToAdd() {
4311
4417
  if (this.assigned.isEmpty() === false) {
4312
4418
  let eyeVertex, maxDistance = 0;
4313
4419
  const eyeFace = this.assigned.first().face;
@@ -4323,11 +4429,20 @@ class ConvexHull {
4323
4429
  return eyeVertex;
4324
4430
  }
4325
4431
  }
4326
- // Computes a chain of half edges in CCW order called the 'horizon'.
4327
- // For an edge to be part of the horizon it must join a face that can see
4328
- // 'eyePoint' and a face that cannot see 'eyePoint'.
4329
- computeHorizon(eyePoint, crossEdge, face, horizon) {
4330
- this.deleteFaceVertices(face);
4432
+ /**
4433
+ * Computes a chain of half edges in CCW order called the 'horizon'. For an edge
4434
+ * to be part of the horizon it must join a face that can see 'eyePoint' and a face
4435
+ * that cannot see 'eyePoint'.
4436
+ *
4437
+ * @private
4438
+ * @param {Vector3} eyePoint - The 3D-coordinates of a point.
4439
+ * @param {HalfEdge} crossEdge - The edge used to jump to the current face.
4440
+ * @param {Face} face - The current face being tested.
4441
+ * @param {Array<HalfEdge>} horizon - The edges that form part of the horizon in CCW order.
4442
+ * @return {ConvexHull} A reference to this convex hull.
4443
+ */
4444
+ _computeHorizon(eyePoint, crossEdge, face, horizon) {
4445
+ this._deleteFaceVertices(face);
4331
4446
  face.mark = Deleted;
4332
4447
  let edge;
4333
4448
  if (crossEdge === null) {
@@ -4340,7 +4455,7 @@ class ConvexHull {
4340
4455
  const oppositeFace = twinEdge.face;
4341
4456
  if (oppositeFace.mark === Visible) {
4342
4457
  if (oppositeFace.distanceToPoint(eyePoint) > this.tolerance) {
4343
- this.computeHorizon(eyePoint, twinEdge, oppositeFace, horizon);
4458
+ this._computeHorizon(eyePoint, twinEdge, oppositeFace, horizon);
4344
4459
  } else {
4345
4460
  horizon.push(edge);
4346
4461
  }
@@ -4349,22 +4464,38 @@ class ConvexHull {
4349
4464
  } while (edge !== crossEdge);
4350
4465
  return this;
4351
4466
  }
4352
- // Creates a face with the vertices 'eyeVertex.point', 'horizonEdge.tail' and 'horizonEdge.head' in CCW order
4353
- addAdjoiningFace(eyeVertex, horizonEdge) {
4467
+ /**
4468
+ * Creates a face with the vertices 'eyeVertex.point', 'horizonEdge.tail' and 'horizonEdge.head'
4469
+ * in CCW order. All the half edges are created in CCW order thus the face is always pointing
4470
+ * outside the hull.
4471
+ *
4472
+ * @private
4473
+ * @param {VertexNode} eyeVertex - The vertex that is added to the hull.
4474
+ * @param {HalfEdge} horizonEdge - A single edge of the horizon.
4475
+ * @return {HalfEdge} The half edge whose vertex is the eyeVertex.
4476
+ */
4477
+ _addAdjoiningFace(eyeVertex, horizonEdge) {
4354
4478
  const face = Face.create(eyeVertex, horizonEdge.tail(), horizonEdge.head());
4355
4479
  this.faces.push(face);
4356
4480
  face.getEdge(-1).setTwin(horizonEdge.twin);
4357
4481
  return face.getEdge(0);
4358
4482
  }
4359
- // Adds 'horizon.length' faces to the hull, each face will be linked with the
4360
- // horizon opposite face and the face on the left/right
4361
- addNewFaces(eyeVertex, horizon) {
4483
+ /**
4484
+ * Adds 'horizon.length' faces to the hull, each face will be linked with the horizon
4485
+ * opposite face and the face on the left/right.
4486
+ *
4487
+ * @private
4488
+ * @param {VertexNode} eyeVertex - The vertex that is added to the hull.
4489
+ * @param {Array<HalfEdge>} horizon - The horizon.
4490
+ * @return {ConvexHull} A reference to this convex hull.
4491
+ */
4492
+ _addNewFaces(eyeVertex, horizon) {
4362
4493
  this.newFaces = [];
4363
4494
  let firstSideEdge = null;
4364
4495
  let previousSideEdge = null;
4365
4496
  for (let i = 0; i < horizon.length; i++) {
4366
4497
  const horizonEdge = horizon[i];
4367
- const sideEdge = this.addAdjoiningFace(eyeVertex, horizonEdge);
4498
+ const sideEdge = this._addAdjoiningFace(eyeVertex, horizonEdge);
4368
4499
  if (firstSideEdge === null) {
4369
4500
  firstSideEdge = sideEdge;
4370
4501
  } else {
@@ -4376,34 +4507,62 @@ class ConvexHull {
4376
4507
  firstSideEdge.next.setTwin(previousSideEdge);
4377
4508
  return this;
4378
4509
  }
4379
- // Adds a vertex to the hull
4380
- addVertexToHull(eyeVertex) {
4510
+ /**
4511
+ * Adds a vertex to the hull with the following algorithm:
4512
+ *
4513
+ * - Compute the 'horizon' which is a chain of half edges. For an edge to belong to this group
4514
+ * it must be the edge connecting a face that can see 'eyeVertex' and a face which cannot see 'eyeVertex'.
4515
+ * - All the faces that can see 'eyeVertex' have its visible vertices removed from the assigned vertex list.
4516
+ * - A new set of faces is created with each edge of the 'horizon' and 'eyeVertex'. Each face is connected
4517
+ * with the opposite horizon face and the face on the left/right.
4518
+ * - The vertices removed from all the visible faces are assigned to the new faces if possible.
4519
+ *
4520
+ * @private
4521
+ * @param {VertexNode} eyeVertex - The vertex to add.
4522
+ * @return {ConvexHull} A reference to this convex hull.
4523
+ */
4524
+ _addVertexToHull(eyeVertex) {
4381
4525
  const horizon = [];
4382
4526
  this.unassigned.clear();
4383
- this.removeVertexFromFace(eyeVertex, eyeVertex.face);
4384
- this.computeHorizon(eyeVertex.point, null, eyeVertex.face, horizon);
4385
- this.addNewFaces(eyeVertex, horizon);
4386
- this.resolveUnassignedPoints(this.newFaces);
4527
+ this._removeVertexFromFace(eyeVertex, eyeVertex.face);
4528
+ this._computeHorizon(eyeVertex.point, null, eyeVertex.face, horizon);
4529
+ this._addNewFaces(eyeVertex, horizon);
4530
+ this._resolveUnassignedPoints(this.newFaces);
4387
4531
  return this;
4388
4532
  }
4389
- cleanup() {
4533
+ /**
4534
+ * Cleans up internal properties after computing the convex hull.
4535
+ *
4536
+ * @private
4537
+ * @return {ConvexHull} A reference to this convex hull.
4538
+ */
4539
+ _cleanup() {
4390
4540
  this.assigned.clear();
4391
4541
  this.unassigned.clear();
4392
4542
  this.newFaces = [];
4393
4543
  return this;
4394
4544
  }
4395
- compute() {
4545
+ /**
4546
+ * Starts the execution of the quick hull algorithm.
4547
+ *
4548
+ * @private
4549
+ * @return {ConvexHull} A reference to this convex hull.
4550
+ */
4551
+ _compute() {
4396
4552
  let vertex;
4397
- this.computeInitialHull();
4398
- while ((vertex = this.nextVertexToAdd()) !== void 0) {
4399
- this.addVertexToHull(vertex);
4553
+ this._computeInitialHull();
4554
+ while ((vertex = this._nextVertexToAdd()) !== void 0) {
4555
+ this._addVertexToHull(vertex);
4400
4556
  }
4401
- this.reindexFaces();
4402
- this.cleanup();
4557
+ this._reindexFaces();
4558
+ this._cleanup();
4403
4559
  return this;
4404
4560
  }
4405
4561
  }
4406
4562
  class Face {
4563
+ /**
4564
+ * Constructs a new face.
4565
+ */
4407
4566
  constructor() {
4408
4567
  this.normal = new Vector3();
4409
4568
  this.midpoint = new Vector3();
@@ -4413,6 +4572,15 @@ class Face {
4413
4572
  this.mark = Visible;
4414
4573
  this.edge = null;
4415
4574
  }
4575
+ /**
4576
+ * Creates a face from the given vertex nodes.
4577
+ *
4578
+ * @private
4579
+ * @param {VertexNode} a - The first vertex node.
4580
+ * @param {VertexNode} b - The second vertex node.
4581
+ * @param {VertexNode} c - The third vertex node.
4582
+ * @return {Face} The created face.
4583
+ */
4416
4584
  static create(a, b, c) {
4417
4585
  const face = new Face();
4418
4586
  const e0 = new HalfEdge(a, face);
@@ -4424,6 +4592,13 @@ class Face {
4424
4592
  face.edge = e0;
4425
4593
  return face.compute();
4426
4594
  }
4595
+ /**
4596
+ * Returns an edge by the given index.
4597
+ *
4598
+ * @private
4599
+ * @param {number} i - The edge index.
4600
+ * @return {HalfEdge} The edge.
4601
+ */
4427
4602
  getEdge(i) {
4428
4603
  let edge = this.edge;
4429
4604
  while (i > 0) {
@@ -4436,6 +4611,12 @@ class Face {
4436
4611
  }
4437
4612
  return edge;
4438
4613
  }
4614
+ /**
4615
+ * Computes all properties of the face.
4616
+ *
4617
+ * @private
4618
+ * @return {Face} A reference to this face.
4619
+ */
4439
4620
  compute() {
4440
4621
  const a = this.edge.tail();
4441
4622
  const b = this.edge.head();
@@ -4447,11 +4628,24 @@ class Face {
4447
4628
  this.constant = this.normal.dot(this.midpoint);
4448
4629
  return this;
4449
4630
  }
4631
+ /**
4632
+ * Returns the signed distance from a given point to the plane representation of this face.
4633
+ *
4634
+ * @private
4635
+ * @param {Vector3} point - The point to compute the distance to.
4636
+ * @return {number} The distance.
4637
+ */
4450
4638
  distanceToPoint(point) {
4451
4639
  return this.normal.dot(point) - this.constant;
4452
4640
  }
4453
4641
  }
4454
4642
  class HalfEdge {
4643
+ /**
4644
+ * Constructs a new half edge.
4645
+ *
4646
+ * @param {VertexNode} vertex - A reference to its destination vertex.
4647
+ * @param {Face} face - A reference to its face.
4648
+ */
4455
4649
  constructor(vertex, face) {
4456
4650
  this.vertex = vertex;
4457
4651
  this.prev = null;
@@ -4459,12 +4653,30 @@ class HalfEdge {
4459
4653
  this.twin = null;
4460
4654
  this.face = face;
4461
4655
  }
4656
+ /**
4657
+ * Returns the destination vertex.
4658
+ *
4659
+ * @private
4660
+ * @return {VertexNode} The destination vertex.
4661
+ */
4462
4662
  head() {
4463
4663
  return this.vertex;
4464
4664
  }
4665
+ /**
4666
+ * Returns the origin vertex.
4667
+ *
4668
+ * @private
4669
+ * @return {VertexNode} The destination vertex.
4670
+ */
4465
4671
  tail() {
4466
4672
  return this.prev ? this.prev.vertex : null;
4467
4673
  }
4674
+ /**
4675
+ * Returns the Euclidean length (straight-line length) of the edge.
4676
+ *
4677
+ * @private
4678
+ * @return {number} The edge's length.
4679
+ */
4468
4680
  length() {
4469
4681
  const head = this.head();
4470
4682
  const tail = this.tail();
@@ -4473,6 +4685,12 @@ class HalfEdge {
4473
4685
  }
4474
4686
  return -1;
4475
4687
  }
4688
+ /**
4689
+ * Returns the square of the Euclidean length (straight-line length) of the edge.
4690
+ *
4691
+ * @private
4692
+ * @return {number} The square of the edge's length.
4693
+ */
4476
4694
  lengthSquared() {
4477
4695
  const head = this.head();
4478
4696
  const tail = this.tail();
@@ -4481,6 +4699,14 @@ class HalfEdge {
4481
4699
  }
4482
4700
  return -1;
4483
4701
  }
4702
+ /**
4703
+ * Sets the twin edge of this half-edge. It also ensures that the twin reference
4704
+ * of the given half-edge is correctly set.
4705
+ *
4706
+ * @private
4707
+ * @param {HalfEdge} edge - The twin edge to set.
4708
+ * @return {HalfEdge} A reference to this edge.
4709
+ */
4484
4710
  setTwin(edge) {
4485
4711
  this.twin = edge;
4486
4712
  edge.twin = this;
@@ -4488,6 +4714,11 @@ class HalfEdge {
4488
4714
  }
4489
4715
  }
4490
4716
  class VertexNode {
4717
+ /**
4718
+ * Constructs a new vertex node.
4719
+ *
4720
+ * @param {Vector3} point - A point in 3D space.
4721
+ */
4491
4722
  constructor(point) {
4492
4723
  this.point = point;
4493
4724
  this.prev = null;
@@ -4496,21 +4727,49 @@ class VertexNode {
4496
4727
  }
4497
4728
  }
4498
4729
  class VertexList {
4730
+ /**
4731
+ * Constructs a new vertex list.
4732
+ */
4499
4733
  constructor() {
4500
4734
  this.head = null;
4501
4735
  this.tail = null;
4502
4736
  }
4737
+ /**
4738
+ * Returns the head reference.
4739
+ *
4740
+ * @private
4741
+ * @return {VertexNode} The head reference.
4742
+ */
4503
4743
  first() {
4504
4744
  return this.head;
4505
4745
  }
4746
+ /**
4747
+ * Returns the tail reference.
4748
+ *
4749
+ * @private
4750
+ * @return {VertexNode} The tail reference.
4751
+ */
4506
4752
  last() {
4507
4753
  return this.tail;
4508
4754
  }
4755
+ /**
4756
+ * Clears the linked list.
4757
+ *
4758
+ * @private
4759
+ * @return {VertexList} A reference to this vertex list.
4760
+ */
4509
4761
  clear() {
4510
4762
  this.head = this.tail = null;
4511
4763
  return this;
4512
4764
  }
4513
- // Inserts a vertex before the target vertex
4765
+ /**
4766
+ * Inserts a vertex before a target vertex.
4767
+ *
4768
+ * @private
4769
+ * @param {VertexNode} target - The target.
4770
+ * @param {VertexNode} vertex - The vertex to insert.
4771
+ * @return {VertexList} A reference to this vertex list.
4772
+ */
4514
4773
  insertBefore(target, vertex) {
4515
4774
  vertex.prev = target.prev;
4516
4775
  vertex.next = target;
@@ -4522,7 +4781,14 @@ class VertexList {
4522
4781
  target.prev = vertex;
4523
4782
  return this;
4524
4783
  }
4525
- // Inserts a vertex after the target vertex
4784
+ /**
4785
+ * Inserts a vertex after 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
+ */
4526
4792
  insertAfter(target, vertex) {
4527
4793
  vertex.prev = target;
4528
4794
  vertex.next = target.next;
@@ -4534,7 +4800,13 @@ class VertexList {
4534
4800
  target.next = vertex;
4535
4801
  return this;
4536
4802
  }
4537
- // Appends a vertex to the end of the linked list
4803
+ /**
4804
+ * Appends a vertex to this vertex list.
4805
+ *
4806
+ * @private
4807
+ * @param {VertexNode} vertex - The vertex to append.
4808
+ * @return {VertexList} A reference to this vertex list.
4809
+ */
4538
4810
  append(vertex) {
4539
4811
  if (this.head === null) {
4540
4812
  this.head = vertex;
@@ -4546,7 +4818,13 @@ class VertexList {
4546
4818
  this.tail = vertex;
4547
4819
  return this;
4548
4820
  }
4549
- // Appends a chain of vertices where 'vertex' is the head.
4821
+ /**
4822
+ * Appends a chain of vertices where the given vertex is the head.
4823
+ *
4824
+ * @private
4825
+ * @param {VertexNode} vertex - The head vertex of a chain of vertices.
4826
+ * @return {VertexList} A reference to this vertex list.
4827
+ */
4550
4828
  appendChain(vertex) {
4551
4829
  if (this.head === null) {
4552
4830
  this.head = vertex;
@@ -4560,7 +4838,13 @@ class VertexList {
4560
4838
  this.tail = vertex;
4561
4839
  return this;
4562
4840
  }
4563
- // Removes a vertex from the linked list
4841
+ /**
4842
+ * Removes a vertex from the linked list.
4843
+ *
4844
+ * @private
4845
+ * @param {VertexNode} vertex - The vertex to remove.
4846
+ * @return {VertexList} A reference to this vertex list.
4847
+ */
4564
4848
  remove(vertex) {
4565
4849
  if (vertex.prev === null) {
4566
4850
  this.head = vertex.next;
@@ -4574,7 +4858,14 @@ class VertexList {
4574
4858
  }
4575
4859
  return this;
4576
4860
  }
4577
- // Removes a list of vertices whose 'head' is 'a' and whose 'tail' is b
4861
+ /**
4862
+ * Removes a sublist of vertices from the linked list.
4863
+ *
4864
+ * @private
4865
+ * @param {VertexNode} a - The head of the sublist.
4866
+ * @param {VertexNode} b - The tail of the sublist.
4867
+ * @return {VertexList} A reference to this vertex list.
4868
+ */
4578
4869
  removeSubList(a, b) {
4579
4870
  if (a.prev === null) {
4580
4871
  this.head = b.next;
@@ -4588,6 +4879,12 @@ class VertexList {
4588
4879
  }
4589
4880
  return this;
4590
4881
  }
4882
+ /**
4883
+ * Returns `true` if the linked list is empty.
4884
+ *
4885
+ * @private
4886
+ * @return {boolean} Whether the linked list is empty or not.
4887
+ */
4591
4888
  isEmpty() {
4592
4889
  return this.head === null;
4593
4890
  }
@@ -6293,7 +6590,7 @@ const _Components = class _Components {
6293
6590
  /**
6294
6591
  * The version of the @thatopen/components library.
6295
6592
  */
6296
- __publicField(_Components, "release", "2.4.8");
6593
+ __publicField(_Components, "release", "2.4.9");
6297
6594
  let Components = _Components;
6298
6595
  class SimpleWorld extends Base {
6299
6596
  constructor() {
@@ -10789,7 +11086,7 @@ class SimpleGrid {
10789
11086
 
10790
11087
  `,
10791
11088
  extensions: {
10792
- derivatives: true
11089
+ // derivatives: true,
10793
11090
  }
10794
11091
  });
10795
11092
  this.three = new THREE$1.Mesh(geometry, material);
@@ -10943,26 +11240,26 @@ const _unit = {
10943
11240
  Z: new Vector3(0, 0, 1)
10944
11241
  };
10945
11242
  const _changeEvent = { type: "change" };
10946
- const _mouseDownEvent = { type: "mouseDown" };
11243
+ const _mouseDownEvent = { type: "mouseDown", mode: null };
10947
11244
  const _mouseUpEvent = { type: "mouseUp", mode: null };
10948
11245
  const _objectChangeEvent = { type: "objectChange" };
10949
- class TransformControls extends Object3D {
10950
- constructor(camera, domElement) {
10951
- super();
10952
- if (domElement === void 0) {
10953
- console.warn('THREE.TransformControls: The second parameter "domElement" is now mandatory.');
10954
- domElement = document;
10955
- }
10956
- this.isTransformControls = true;
10957
- this.visible = false;
10958
- this.domElement = domElement;
10959
- this.domElement.style.touchAction = "none";
10960
- const _gizmo = new TransformControlsGizmo();
10961
- this._gizmo = _gizmo;
10962
- this.add(_gizmo);
10963
- const _plane2 = new TransformControlsPlane();
10964
- this._plane = _plane2;
10965
- this.add(_plane2);
11246
+ class TransformControls extends Controls {
11247
+ /**
11248
+ * Constructs a new controls instance.
11249
+ *
11250
+ * @param {Camera} camera - The camera of the rendered scene.
11251
+ * @param {?HTMLDOMElement} domElement - The HTML element used for event listeners.
11252
+ */
11253
+ constructor(camera, domElement = null) {
11254
+ super(void 0, domElement);
11255
+ const root = new TransformControlsRoot(this);
11256
+ this._root = root;
11257
+ const gizmo = new TransformControlsGizmo();
11258
+ this._gizmo = gizmo;
11259
+ root.add(gizmo);
11260
+ const plane = new TransformControlsPlane();
11261
+ this._plane = plane;
11262
+ root.add(plane);
10966
11263
  const scope = this;
10967
11264
  function defineProperty(propName2, defaultValue) {
10968
11265
  let propValue = defaultValue;
@@ -10973,16 +11270,16 @@ class TransformControls extends Object3D {
10973
11270
  set: function(value) {
10974
11271
  if (propValue !== value) {
10975
11272
  propValue = value;
10976
- _plane2[propName2] = value;
10977
- _gizmo[propName2] = value;
11273
+ plane[propName2] = value;
11274
+ gizmo[propName2] = value;
10978
11275
  scope.dispatchEvent({ type: propName2 + "-changed", value });
10979
11276
  scope.dispatchEvent(_changeEvent);
10980
11277
  }
10981
11278
  }
10982
11279
  });
10983
11280
  scope[propName2] = defaultValue;
10984
- _plane2[propName2] = defaultValue;
10985
- _gizmo[propName2] = defaultValue;
11281
+ plane[propName2] = defaultValue;
11282
+ gizmo[propName2] = defaultValue;
10986
11283
  }
10987
11284
  defineProperty("camera", camera);
10988
11285
  defineProperty("object", void 0);
@@ -10998,6 +11295,12 @@ class TransformControls extends Object3D {
10998
11295
  defineProperty("showX", true);
10999
11296
  defineProperty("showY", true);
11000
11297
  defineProperty("showZ", true);
11298
+ defineProperty("minX", -Infinity);
11299
+ defineProperty("maxX", Infinity);
11300
+ defineProperty("minY", -Infinity);
11301
+ defineProperty("maxY", Infinity);
11302
+ defineProperty("minZ", -Infinity);
11303
+ defineProperty("maxZ", Infinity);
11001
11304
  const worldPosition = new Vector3();
11002
11305
  const worldPositionStart = new Vector3();
11003
11306
  const worldQuaternion = new Quaternion();
@@ -11039,36 +11342,38 @@ class TransformControls extends Object3D {
11039
11342
  this._onPointerHover = onPointerHover.bind(this);
11040
11343
  this._onPointerMove = onPointerMove.bind(this);
11041
11344
  this._onPointerUp = onPointerUp.bind(this);
11345
+ if (domElement !== null) {
11346
+ this.connect(domElement);
11347
+ }
11348
+ }
11349
+ connect(element) {
11350
+ super.connect(element);
11042
11351
  this.domElement.addEventListener("pointerdown", this._onPointerDown);
11043
11352
  this.domElement.addEventListener("pointermove", this._onPointerHover);
11044
11353
  this.domElement.addEventListener("pointerup", this._onPointerUp);
11354
+ this.domElement.style.touchAction = "none";
11045
11355
  }
11046
- // updateMatrixWorld updates key transformation variables
11047
- updateMatrixWorld() {
11048
- if (this.object !== void 0) {
11049
- this.object.updateMatrixWorld();
11050
- if (this.object.parent === null) {
11051
- console.error("TransformControls: The attached 3D object must be a part of the scene graph.");
11052
- } else {
11053
- this.object.parent.matrixWorld.decompose(this._parentPosition, this._parentQuaternion, this._parentScale);
11054
- }
11055
- this.object.matrixWorld.decompose(this.worldPosition, this.worldQuaternion, this._worldScale);
11056
- this._parentQuaternionInv.copy(this._parentQuaternion).invert();
11057
- this._worldQuaternionInv.copy(this.worldQuaternion).invert();
11058
- }
11059
- this.camera.updateMatrixWorld();
11060
- this.camera.matrixWorld.decompose(this.cameraPosition, this.cameraQuaternion, this._cameraScale);
11061
- if (this.camera.isOrthographicCamera) {
11062
- this.camera.getWorldDirection(this.eye).negate();
11063
- } else {
11064
- this.eye.copy(this.cameraPosition).sub(this.worldPosition).normalize();
11065
- }
11066
- super.updateMatrixWorld(this);
11356
+ disconnect() {
11357
+ this.domElement.removeEventListener("pointerdown", this._onPointerDown);
11358
+ this.domElement.removeEventListener("pointermove", this._onPointerHover);
11359
+ this.domElement.removeEventListener("pointermove", this._onPointerMove);
11360
+ this.domElement.removeEventListener("pointerup", this._onPointerUp);
11361
+ this.domElement.style.touchAction = "auto";
11362
+ }
11363
+ /**
11364
+ * Returns the visual representation of the controls. Add the helper to your scene to
11365
+ * visually transform the attached 3D object.
11366
+ *
11367
+ * @return {TransformControlsRoot} The helper.
11368
+ */
11369
+ getHelper() {
11370
+ return this._root;
11067
11371
  }
11068
11372
  pointerHover(pointer) {
11069
11373
  if (this.object === void 0 || this.dragging === true)
11070
11374
  return;
11071
- _raycaster.setFromCamera(pointer, this.camera);
11375
+ if (pointer !== null)
11376
+ _raycaster.setFromCamera(pointer, this.camera);
11072
11377
  const intersect = intersectObjectWithRay(this._gizmo.picker[this.mode], _raycaster);
11073
11378
  if (intersect) {
11074
11379
  this.axis = intersect.object.name;
@@ -11077,10 +11382,11 @@ class TransformControls extends Object3D {
11077
11382
  }
11078
11383
  }
11079
11384
  pointerDown(pointer) {
11080
- if (this.object === void 0 || this.dragging === true || pointer.button !== 0)
11385
+ if (this.object === void 0 || this.dragging === true || pointer != null && pointer.button !== 0)
11081
11386
  return;
11082
11387
  if (this.axis !== null) {
11083
- _raycaster.setFromCamera(pointer, this.camera);
11388
+ if (pointer !== null)
11389
+ _raycaster.setFromCamera(pointer, this.camera);
11084
11390
  const planeIntersect = intersectObjectWithRay(this._plane, _raycaster, true);
11085
11391
  if (planeIntersect) {
11086
11392
  this.object.updateMatrixWorld();
@@ -11106,9 +11412,10 @@ class TransformControls extends Object3D {
11106
11412
  } else if (axis === "E" || axis === "XYZE" || axis === "XYZ") {
11107
11413
  space = "world";
11108
11414
  }
11109
- if (object === void 0 || axis === null || this.dragging === false || pointer.button !== -1)
11415
+ if (object === void 0 || axis === null || this.dragging === false || pointer !== null && pointer.button !== -1)
11110
11416
  return;
11111
- _raycaster.setFromCamera(pointer, this.camera);
11417
+ if (pointer !== null)
11418
+ _raycaster.setFromCamera(pointer, this.camera);
11112
11419
  const planeIntersect = intersectObjectWithRay(this._plane, _raycaster, true);
11113
11420
  if (!planeIntersect)
11114
11421
  return;
@@ -11162,6 +11469,9 @@ class TransformControls extends Object3D {
11162
11469
  }
11163
11470
  }
11164
11471
  }
11472
+ object.position.x = Math.max(this.minX, Math.min(this.maxX, object.position.x));
11473
+ object.position.y = Math.max(this.minY, Math.min(this.maxY, object.position.y));
11474
+ object.position.z = Math.max(this.minZ, Math.min(this.maxZ, object.position.z));
11165
11475
  } else if (mode === "scale") {
11166
11476
  if (axis.search("XYZ") !== -1) {
11167
11477
  let d = this.pointEnd.length() / this.pointStart.length();
@@ -11238,7 +11548,7 @@ class TransformControls extends Object3D {
11238
11548
  this.dispatchEvent(_objectChangeEvent);
11239
11549
  }
11240
11550
  pointerUp(pointer) {
11241
- if (pointer.button !== 0)
11551
+ if (pointer !== null && pointer.button !== 0)
11242
11552
  return;
11243
11553
  if (this.dragging && this.axis !== null) {
11244
11554
  _mouseUpEvent.mode = this.mode;
@@ -11248,30 +11558,34 @@ class TransformControls extends Object3D {
11248
11558
  this.axis = null;
11249
11559
  }
11250
11560
  dispose() {
11251
- this.domElement.removeEventListener("pointerdown", this._onPointerDown);
11252
- this.domElement.removeEventListener("pointermove", this._onPointerHover);
11253
- this.domElement.removeEventListener("pointermove", this._onPointerMove);
11254
- this.domElement.removeEventListener("pointerup", this._onPointerUp);
11255
- this.traverse(function(child) {
11256
- if (child.geometry)
11257
- child.geometry.dispose();
11258
- if (child.material)
11259
- child.material.dispose();
11260
- });
11561
+ this.disconnect();
11562
+ this._root.dispose();
11261
11563
  }
11262
- // Set current object
11564
+ /**
11565
+ * Sets the 3D object that should be transformed and ensures the controls UI is visible.
11566
+ *
11567
+ * @param {Object3D} object - The 3D object that should be transformed.
11568
+ * @return {TransformControls} A reference to this controls.
11569
+ */
11263
11570
  attach(object) {
11264
11571
  this.object = object;
11265
- this.visible = true;
11572
+ this._root.visible = true;
11266
11573
  return this;
11267
11574
  }
11268
- // Detach from object
11575
+ /**
11576
+ * Removes the current 3D object from the controls and makes the helper UI invisible.
11577
+ *
11578
+ * @return {TransformControls} A reference to this controls.
11579
+ */
11269
11580
  detach() {
11270
11581
  this.object = void 0;
11271
- this.visible = false;
11272
11582
  this.axis = null;
11583
+ this._root.visible = false;
11273
11584
  return this;
11274
11585
  }
11586
+ /**
11587
+ * Resets the object's position, rotation and scale to when the current transform began.
11588
+ */
11275
11589
  reset() {
11276
11590
  if (!this.enabled)
11277
11591
  return;
@@ -11284,28 +11598,68 @@ class TransformControls extends Object3D {
11284
11598
  this.pointStart.copy(this.pointEnd);
11285
11599
  }
11286
11600
  }
11601
+ /**
11602
+ * Returns the raycaster that is used for user interaction. This object is shared between all
11603
+ * instances of `TransformControls`.
11604
+ *
11605
+ * @returns {Raycaster} The internal raycaster.
11606
+ */
11287
11607
  getRaycaster() {
11288
11608
  return _raycaster;
11289
11609
  }
11290
- // TODO: deprecate
11610
+ /**
11611
+ * Returns the transformation mode.
11612
+ *
11613
+ * @returns {'translate'|'rotate'|'scale'} The transformation mode.
11614
+ */
11291
11615
  getMode() {
11292
11616
  return this.mode;
11293
11617
  }
11618
+ /**
11619
+ * Sets the given transformation mode.
11620
+ *
11621
+ * @param {'translate'|'rotate'|'scale'} mode - The transformation mode to set.
11622
+ */
11294
11623
  setMode(mode) {
11295
11624
  this.mode = mode;
11296
11625
  }
11626
+ /**
11627
+ * Sets the translation snap.
11628
+ *
11629
+ * @param {?number} translationSnap - The translation snap to set.
11630
+ */
11297
11631
  setTranslationSnap(translationSnap) {
11298
11632
  this.translationSnap = translationSnap;
11299
11633
  }
11634
+ /**
11635
+ * Sets the rotation snap.
11636
+ *
11637
+ * @param {?number} rotationSnap - The rotation snap to set.
11638
+ */
11300
11639
  setRotationSnap(rotationSnap) {
11301
11640
  this.rotationSnap = rotationSnap;
11302
11641
  }
11642
+ /**
11643
+ * Sets the scale snap.
11644
+ *
11645
+ * @param {?number} scaleSnap - The scale snap to set.
11646
+ */
11303
11647
  setScaleSnap(scaleSnap) {
11304
11648
  this.scaleSnap = scaleSnap;
11305
11649
  }
11650
+ /**
11651
+ * Sets the size of the helper UI.
11652
+ *
11653
+ * @param {number} size - The size to set.
11654
+ */
11306
11655
  setSize(size) {
11307
11656
  this.size = size;
11308
11657
  }
11658
+ /**
11659
+ * Sets the coordinate space in which transformations are applied.
11660
+ *
11661
+ * @param {'world'|'local'} space - The space to set.
11662
+ */
11309
11663
  setSpace(space) {
11310
11664
  this.space = space;
11311
11665
  }
@@ -11381,6 +11735,45 @@ const _unitZ = new Vector3(0, 0, 1);
11381
11735
  const _v1 = new Vector3();
11382
11736
  const _v2 = new Vector3();
11383
11737
  const _v3 = new Vector3();
11738
+ class TransformControlsRoot extends Object3D {
11739
+ constructor(controls) {
11740
+ super();
11741
+ this.isTransformControlsRoot = true;
11742
+ this.controls = controls;
11743
+ this.visible = false;
11744
+ }
11745
+ // updateMatrixWorld updates key transformation variables
11746
+ updateMatrixWorld(force) {
11747
+ const controls = this.controls;
11748
+ if (controls.object !== void 0) {
11749
+ controls.object.updateMatrixWorld();
11750
+ if (controls.object.parent === null) {
11751
+ console.error("TransformControls: The attached 3D object must be a part of the scene graph.");
11752
+ } else {
11753
+ controls.object.parent.matrixWorld.decompose(controls._parentPosition, controls._parentQuaternion, controls._parentScale);
11754
+ }
11755
+ controls.object.matrixWorld.decompose(controls.worldPosition, controls.worldQuaternion, controls._worldScale);
11756
+ controls._parentQuaternionInv.copy(controls._parentQuaternion).invert();
11757
+ controls._worldQuaternionInv.copy(controls.worldQuaternion).invert();
11758
+ }
11759
+ controls.camera.updateMatrixWorld();
11760
+ controls.camera.matrixWorld.decompose(controls.cameraPosition, controls.cameraQuaternion, controls._cameraScale);
11761
+ if (controls.camera.isOrthographicCamera) {
11762
+ controls.camera.getWorldDirection(controls.eye).negate();
11763
+ } else {
11764
+ controls.eye.copy(controls.cameraPosition).sub(controls.worldPosition).normalize();
11765
+ }
11766
+ super.updateMatrixWorld(force);
11767
+ }
11768
+ dispose() {
11769
+ this.traverse(function(child) {
11770
+ if (child.geometry)
11771
+ child.geometry.dispose();
11772
+ if (child.material)
11773
+ child.material.dispose();
11774
+ });
11775
+ }
11776
+ }
11384
11777
  class TransformControlsGizmo extends Object3D {
11385
11778
  constructor() {
11386
11779
  super();
@@ -12006,7 +12399,7 @@ class SimplePlane {
12006
12399
  /** {@link Hideable.visible } */
12007
12400
  set visible(state) {
12008
12401
  this._visible = state;
12009
- this._controls.visible = state;
12402
+ this._controls.object.visible = state;
12010
12403
  this._helper.visible = state;
12011
12404
  this.toggleControls(state);
12012
12405
  }
@@ -12073,7 +12466,7 @@ class SimplePlane {
12073
12466
  this._arrowBoundBox.removeFromParent();
12074
12467
  this._arrowBoundBox.geometry.dispose();
12075
12468
  this._planeMesh.geometry.dispose();
12076
- this._controls.removeFromParent();
12469
+ this._controls.object.removeFromParent();
12077
12470
  this._controls.dispose();
12078
12471
  this.onDisposed.trigger();
12079
12472
  this.onDisposed.reset();
@@ -12109,7 +12502,7 @@ class SimplePlane {
12109
12502
  const container = this.world.renderer.three.domElement;
12110
12503
  const controls = new TransformControls(camera, container);
12111
12504
  this.initializeControls(controls);
12112
- this.world.scene.three.add(controls);
12505
+ this.world.scene.three.add(controls.object);
12113
12506
  return controls;
12114
12507
  }
12115
12508
  initializeControls(controls) {
@@ -12118,7 +12511,7 @@ class SimplePlane {
12118
12511
  controls.showY = false;
12119
12512
  controls.setSpace("local");
12120
12513
  this.createArrowBoundingBox();
12121
- controls.children[0].children[0].add(this._arrowBoundBox);
12514
+ controls.object.children[0].children[0].add(this._arrowBoundBox);
12122
12515
  }
12123
12516
  createArrowBoundingBox() {
12124
12517
  this._arrowBoundBox.geometry = new THREE$1.CylinderGeometry(0.18, 0.18, 1.2);