@jgphilpott/polytree 0.0.7 → 0.0.8

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,23 +1,25 @@
1
1
  // Generated by CoffeeScript 2.7.0
2
- var BACK, Box3, BufferAttribute, BufferGeometry, COPLANAR, CSG_Rules, DoubleSide, EPSILON, FRONT, Matrix3, Mesh, OctreeCSG, Plane, Polygon, RAY_EPSILON, Ray, Raycaster, SPANNING, Triangle, Vector2, Vector3, Vertex, _asyncUnionArrayID, _asyncUnionID, _box3$1, _matrix3, _normal1, _polygonID, _ray, _rayDirection, _raycaster1, _v1, _v2, _wP, _wP_EPS_ARR, _wP_EPS_ARR_COUNT, _wV1, _wV2, _wV3, calcWindingNumber_buffer, disposeOctree, edge1, edge2, h, handleIntersectingOctrees, handleObjectForOp, handleObjectForOp_async, isUniqueTriangle, isValidTriangle, nbuf2, nbuf3, pointRounding, polyInside_WindingNumber_buffer, prepareTriangleBuffer, q, rayIntersectsTriangle, raycastIntersectAscSort, returnXYZ, s, splitPolygonArr, splitPolygonByPlane, tmpm3, ttvv0, tv0, tv1, wNPI;
2
+ var Box3, BufferAttribute, BufferGeometry, DoubleSide, Matrix3, Mesh, Ray, Raycaster, Triangle, Vector2, Vector3;
3
3
 
4
- ({Vector2, Vector3, Box3, DoubleSide, Matrix3, Ray, Triangle, BufferGeometry, BufferAttribute, Mesh, Raycaster} = require("three"));
4
+ ({Vector2, Vector3, Mesh, Triangle, Box3, Matrix3, DoubleSide, Ray, Raycaster, BufferGeometry, BufferAttribute} = require("three"));
5
+ // Generated by CoffeeScript 2.7.0
6
+ var BACK, COPLANAR, CSG_Rules, EPSILON, FRONT, Plane, Polygon, Polytree, RAY_EPSILON, SPANNING, Vertex, _asyncUnionArrayID, _asyncUnionID, _matrix3, _normal1, _polygonID, _wP, _wP_EPS_ARR, _wP_EPS_ARR_COUNT, _wV1, _wV2, _wV3, calcWindingNumber_buffer, disposePolytree, edge1, edge2, h, handleIntersectingPolytrees, handleObjectForOp, handleObjectForOp_async, isUniqueTriangle, isValidTriangle, nbuf2, nbuf3, pointRounding, polyInside_WindingNumber_buffer, prepareTriangleBuffer, q, rayIntersectsTriangle, raycastIntersectAscSort, returnXYZ, s, splitPolygonArr, splitPolygonByPlane, tempBox3, tempRay, tempRayDirection, tempRaycaster, tempVector1, tempVector2, tmpm3, triangleVertex0, triangleVertex1, ttvv0, wNPI;
5
7
 
6
- _v1 = new Vector3();
8
+ tempVector1 = new Vector3();
7
9
 
8
- _v2 = new Vector3();
10
+ tempVector2 = new Vector3();
9
11
 
10
- _box3$1 = new Box3();
12
+ tempBox3 = new Box3();
11
13
 
12
- tv0 = new Vector3();
14
+ triangleVertex0 = new Vector3();
13
15
 
14
- tv1 = new Vector3();
16
+ triangleVertex1 = new Vector3();
15
17
 
16
- _raycaster1 = new Raycaster();
18
+ tempRaycaster = new Raycaster();
17
19
 
18
- _ray = new Ray();
20
+ tempRay = new Ray();
19
21
 
20
- _rayDirection = new Vector3(0, 0, 1);
22
+ tempRayDirection = new Vector3(0, 0, 1);
21
23
 
22
24
  EPSILON = 1e-5;
23
25
 
@@ -31,7 +33,7 @@ SPANNING = 3;
31
33
 
32
34
  _polygonID = 0;
33
35
 
34
- OctreeCSG = class OctreeCSG {
36
+ Polytree = class Polytree {
35
37
  constructor(box, parent) {
36
38
  this.polygons = [];
37
39
  this.replacedPolygons = [];
@@ -42,7 +44,7 @@ OctreeCSG = class OctreeCSG {
42
44
  this.parent = parent;
43
45
  this.level = 0;
44
46
  this.polygonArrays = void 0;
45
- // @isOctree = true
47
+ // @isPolytree = true
46
48
  this.addPolygonsArrayToRoot(this.polygons);
47
49
  }
48
50
 
@@ -133,33 +135,33 @@ OctreeCSG = class OctreeCSG {
133
135
  return this;
134
136
  }
135
137
 
136
- newOctree(box, parent) {
138
+ newPolytree(box, parent) {
137
139
  return new this.constructor(box, parent);
138
140
  }
139
141
 
140
142
  split(level) {
141
- var box, found, halfsize, i, i1, k, l, len, m, o, polygon, ref, ref1, subTrees, v, x, y, z;
143
+ var box, found, halfsize, i, k, l, len, m, n, o, polygon, ref, ref1, subTrees, vectorPosition, x, y, z;
142
144
  if (!this.box) {
143
145
  return;
144
146
  }
145
147
  subTrees = [];
146
- halfsize = _v2.copy(this.box.max).sub(this.box.min).multiplyScalar(0.5);
148
+ halfsize = tempVector2.copy(this.box.max).sub(this.box.min).multiplyScalar(0.5);
147
149
  for (x = k = 0; k <= 1; x = ++k) {
148
150
  for (y = l = 0; l <= 1; y = ++l) {
149
151
  for (z = m = 0; m <= 1; z = ++m) {
150
152
  box = new Box3();
151
- v = _v1.set(x, y, z);
152
- box.min.copy(this.box.min).add(v.multiply(halfsize));
153
+ vectorPosition = tempVector1.set(x, y, z);
154
+ box.min.copy(this.box.min).add(vectorPosition.multiply(halfsize));
153
155
  box.max.copy(box.min).add(halfsize);
154
156
  box.expandByScalar(EPSILON);
155
- subTrees.push(this.newOctree(box, this));
157
+ subTrees.push(this.newPolytree(box, this));
156
158
  }
157
159
  }
158
160
  }
159
161
  polygon = void 0;
160
162
  while (polygon = this.polygons.pop()) {
161
163
  found = false;
162
- for (i = o = 0, ref = subTrees.length; (0 <= ref ? o < ref : o > ref); i = 0 <= ref ? ++o : --o) {
164
+ for (i = n = 0, ref = subTrees.length; (0 <= ref ? n < ref : n > ref); i = 0 <= ref ? ++n : --n) {
163
165
  if (subTrees[i].box.containsPoint(polygon.getMidpoint())) {
164
166
  subTrees[i].polygons.push(polygon);
165
167
  found = true;
@@ -170,15 +172,16 @@ OctreeCSG = class OctreeCSG {
170
172
  throw new Error(`Unable to find subtree for triangle at level ${level}`);
171
173
  }
172
174
  }
173
- for (i = i1 = 0, ref1 = subTrees.length; (0 <= ref1 ? i1 < ref1 : i1 > ref1); i = 0 <= ref1 ? ++i1 : --i1) {
175
+ for (i = o = 0, ref1 = subTrees.length; (0 <= ref1 ? o < ref1 : o > ref1); i = 0 <= ref1 ? ++o : --o) {
174
176
  subTrees[i].level = level + 1;
175
177
  len = subTrees[i].polygons.length;
176
178
  // if (len !== 0) {
177
- if (len > OctreeCSG.polygonsPerTree && level < OctreeCSG.maxLevel) {
179
+ if (len > Polytree.polygonsPerTree && level < Polytree.maxLevel) {
178
180
  subTrees[i].split(level + 1);
179
181
  }
180
182
  this.subTrees.push(subTrees[i]);
181
183
  }
184
+ // }
182
185
  return this;
183
186
  }
184
187
 
@@ -192,7 +195,7 @@ OctreeCSG = class OctreeCSG {
192
195
  processTree() {
193
196
  var i, k, l, ref, ref1, results1;
194
197
  if (!this.isEmpty()) {
195
- _box3$1.copy(this.box);
198
+ tempBox3.copy(this.box);
196
199
  for (i = k = 0, ref = this.polygons.length; (0 <= ref ? k < ref : k > ref); i = 0 <= ref ? ++k : --k) {
197
200
  this.box.expandByPoint(this.polygons[i].triangle.a);
198
201
  this.box.expandByPoint(this.polygons[i].triangle.b);
@@ -273,23 +276,23 @@ OctreeCSG = class OctreeCSG {
273
276
  polygons = this.getRayPolygons(ray);
274
277
  for (i = k = 0, ref = polygons.length; (0 <= ref ? k < ref : k > ref); i = 0 <= ref ? ++k : --k) {
275
278
  result = void 0;
276
- if (OctreeCSG.rayIntersectTriangleType === "regular") {
277
- result = ray.intersectTriangle(polygons[i].triangle.a, polygons[i].triangle.b, polygons[i].triangle.c, false, _v1);
279
+ if (Polytree.rayIntersectTriangleType === "regular") {
280
+ result = ray.intersectTriangle(polygons[i].triangle.a, polygons[i].triangle.b, polygons[i].triangle.c, false, tempVector1);
278
281
  if (result) {
279
- _v1.applyMatrix4(matrixWorld);
280
- distance = _v1.distanceTo(ray.origin);
282
+ tempVector1.applyMatrix4(matrixWorld);
283
+ distance = tempVector1.distanceTo(ray.origin);
281
284
  if (distance < 0 || distance > 2e308) {
282
285
  console.warn("[rayIntersect] Failed ray distance check", ray);
283
286
  } else {
284
287
  intersects.push({
285
288
  distance: distance,
286
289
  polygon: polygons[i],
287
- position: _v1.clone()
290
+ position: tempVector1.clone()
288
291
  });
289
292
  }
290
293
  }
291
294
  } else {
292
- result = rayIntersectsTriangle(ray, polygons[i].triangle, _v1);
295
+ result = rayIntersectsTriangle(ray, polygons[i].triangle, tempVector1);
293
296
  if (result) {
294
297
  newdistance = result.clone().sub(ray.origin).length();
295
298
  if (distance > newdistance) {
@@ -570,11 +573,11 @@ OctreeCSG = class OctreeCSG {
570
573
  return true;
571
574
  }
572
575
 
573
- markIntesectingPolygons(targetOctree) {
576
+ markIntesectingPolygons(targetPolytree) {
574
577
  return this.polygonArrays.forEach(function(polygonsArray) {
575
578
  if (polygonsArray.length) {
576
579
  return polygonsArray.forEach(function(polygon) {
577
- return polygon.intersects = targetOctree.isPolygonIntersecting(polygon);
580
+ return polygon.intersects = targetPolytree.isPolygonIntersecting(polygon);
578
581
  });
579
582
  }
580
583
  });
@@ -582,9 +585,9 @@ OctreeCSG = class OctreeCSG {
582
585
 
583
586
  // if @polygons.length > 0
584
587
  // @polygons.forEach (polygon) ->
585
- // polygon.intersects = targetOctree.isPolygonIntersecting(polygon)
588
+ // polygon.intersects = targetPolytree.isPolygonIntersecting(polygon)
586
589
  // for i in [0...@subTrees.length]
587
- // @subTrees[i].markIntesectingPolygons(targetOctree)
590
+ // @subTrees[i].markIntesectingPolygons(targetPolytree)
588
591
  resetPolygons(resetOriginal = true) {
589
592
  return this.polygonArrays.forEach(function(polygonsArray) {
590
593
  if (polygonsArray.length) {
@@ -600,8 +603,8 @@ OctreeCSG = class OctreeCSG {
600
603
  // polygon.reset(resetOriginal)
601
604
  // for i in [0...@subTrees.length]
602
605
  // @subTrees[i].resetPolygons(resetOriginal)
603
- handleIntersectingPolygons(targetOctree, targetOctreeBuffer) {
604
- var currentPolygon, i, i1, inside, intersects, j, k, l, m, o, point, polygon, polygonStack, ref, ref1, ref2, ref3, ref4, results1, splitResults, target, targetPolygons;
606
+ handleIntersectingPolygons(targetPolytree, targetPolytreeBuffer) {
607
+ var currentPolygon, i, inside, intersects, j, k, l, m, n, o, point, polygon, polygonStack, ref, ref1, ref2, ref3, ref4, results1, splitResults, target, targetPolygons;
605
608
  // if @polygons.length > 0
606
609
  // polygonStack = @polygons.filter (polygon) -> (polygon.valid == true) and (polygon.intersects == true) and (polygon.state == "undecided")
607
610
  // currentPolygon = polygonStack.pop()
@@ -610,7 +613,7 @@ OctreeCSG = class OctreeCSG {
610
613
  // continue
611
614
  // unless currentPolygon.valid
612
615
  // continue
613
- // targetPolygons = targetOctree.getPolygonsIntersectingPolygon(currentPolygon)
616
+ // targetPolygons = targetPolytree.getPolygonsIntersectingPolygon(currentPolygon)
614
617
  // if targetPolygons.length > 0
615
618
  // for j in [0...targetPolygons.length]
616
619
  // target = targetPolygons[j]
@@ -642,42 +645,42 @@ OctreeCSG = class OctreeCSG {
642
645
  // unless currentPolygon.valid
643
646
  // continue
644
647
  // inside = false
645
- // if targetOctree.box.containsPoint(currentPolygon.getMidpoint())
646
- // if OctreeCSG.useWindingNumber is true
647
- // inside = polyInside_WindingNumber_buffer(targetOctreeBuffer, currentPolygon.getMidpoint(), currentPolygon.coplanar)
648
+ // if targetPolytree.box.containsPoint(currentPolygon.getMidpoint())
649
+ // if Polytree.useWindingNumber is true
650
+ // inside = polyInside_WindingNumber_buffer(targetPolytreeBuffer, currentPolygon.getMidpoint(), currentPolygon.coplanar)
648
651
  // else
649
- // point = pointRounding(_v2.copy(currentPolygon.getMidpoint()))
650
- // if OctreeCSG.useOctreeRay isnt true and targetOctree.mesh
651
- // _rayDirection.copy(currentPolygon.plane.normal)
652
- // _raycaster1.set(point, _rayDirection)
653
- // intersects = _raycaster1.intersectObject(targetOctree.mesh)
652
+ // point = pointRounding(tempVector2.copy(currentPolygon.getMidpoint()))
653
+ // if Polytree.usePolytreeRay isnt true and targetPolytree.mesh
654
+ // tempRayDirection.copy(currentPolygon.plane.normal)
655
+ // tempRaycaster.set(point, tempRayDirection)
656
+ // intersects = tempRaycaster.intersectObject(targetPolytree.mesh)
654
657
  // if intersects.length
655
- // if _rayDirection.dot(intersects[0].face.normal) > 0
658
+ // if tempRayDirection.dot(intersects[0].face.normal) > 0
656
659
  // inside = true
657
660
  // unless inside or not currentPolygon.coplanar
658
661
  // for j in [0..._wP_EPS_ARR_COUNT]
659
- // _raycaster1.ray.origin.copy(point).add(_wP_EPS_ARR[j])
660
- // intersects = _raycaster1.intersectObject(targetOctree.mesh)
662
+ // tempRaycaster.ray.origin.copy(point).add(_wP_EPS_ARR[j])
663
+ // intersects = tempRaycaster.intersectObject(targetPolytree.mesh)
661
664
  // if intersects.length
662
- // if _rayDirection.dot(intersects[0].face.normal) > 0
665
+ // if tempRayDirection.dot(intersects[0].face.normal) > 0
663
666
  // inside = true
664
667
  // break
665
668
  // else
666
- // _ray.origin.copy(point)
667
- // _rayDirection.copy(currentPolygon.plane.normal)
668
- // _ray.direction.copy(currentPolygon.plane.normal)
669
- // intersects = targetOctree.rayIntersect(_ray, targetOctree.originalMatrixWorld)
669
+ // tempRay.origin.copy(point)
670
+ // tempRayDirection.copy(currentPolygon.plane.normal)
671
+ // tempRay.direction.copy(currentPolygon.plane.normal)
672
+ // intersects = targetPolytree.rayIntersect(tempRay, targetPolytree.originalMatrixWorld)
670
673
  // if intersects.length
671
- // if _rayDirection.dot(intersects[0].polygon.plane.normal) > 0
674
+ // if tempRayDirection.dot(intersects[0].polygon.plane.normal) > 0
672
675
  // inside = true
673
676
  // unless inside or not currentPolygon.coplanar
674
677
  // for j in [0..._wP_EPS_ARR_COUNT]
675
- // _ray.origin.copy(point).add(_wP_EPS_ARR[j])
676
- // _rayDirection.copy(currentPolygon.plane.normal)
677
- // _ray.direction.copy(currentPolygon.plane.normal)
678
- // intersects = targetOctree.rayIntersect(_ray, targetOctree.originalMatrixWorld)
678
+ // tempRay.origin.copy(point).add(_wP_EPS_ARR[j])
679
+ // tempRayDirection.copy(currentPolygon.plane.normal)
680
+ // tempRay.direction.copy(currentPolygon.plane.normal)
681
+ // intersects = targetPolytree.rayIntersect(tempRay, targetPolytree.originalMatrixWorld)
679
682
  // if intersects.length
680
- // if _rayDirection.dot(intersects[0].polygon.plane.normal) > 0
683
+ // if tempRayDirection.dot(intersects[0].polygon.plane.normal) > 0
681
684
  // inside = true
682
685
  // break
683
686
  // if inside is true
@@ -686,7 +689,7 @@ OctreeCSG = class OctreeCSG {
686
689
  // currentPolygon.setState("outside")
687
690
  // currentPolygon = polygonStack.pop()
688
691
  // for i in [0...@subTrees.length]
689
- // @subTrees[i].handleIntersectingPolygons(targetOctree, targetOctreeBuffer)
692
+ // @subTrees[i].handleIntersectingPolygons(targetPolytree, targetPolytreeBuffer)
690
693
  if (this.polygons.length > 0) {
691
694
  polygonStack = this.polygons.filter(function(polygon) {
692
695
  return (polygon.valid === true) && (polygon.intersects === true) && (polygon.state === "undecided");
@@ -699,7 +702,7 @@ OctreeCSG = class OctreeCSG {
699
702
  if (!currentPolygon.valid) {
700
703
  continue;
701
704
  }
702
- targetPolygons = targetOctree.getPolygonsIntersectingPolygon(currentPolygon);
705
+ targetPolygons = targetPolytree.getPolygonsIntersectingPolygon(currentPolygon);
703
706
  if (targetPolygons.length > 0) {
704
707
  for (j = k = 0, ref = targetPolygons.length; (0 <= ref ? k < ref : k > ref); j = 0 <= ref ? ++k : --k) {
705
708
  target = targetPolygons[j];
@@ -743,26 +746,26 @@ OctreeCSG = class OctreeCSG {
743
746
  continue;
744
747
  }
745
748
  inside = false;
746
- if (targetOctree.box.containsPoint(currentPolygon.getMidpoint())) {
747
- if (OctreeCSG.useWindingNumber === true) {
748
- inside = polyInside_WindingNumber_buffer(targetOctreeBuffer, currentPolygon.getMidpoint(), currentPolygon.coplanar);
749
+ if (targetPolytree.box.containsPoint(currentPolygon.getMidpoint())) {
750
+ if (Polytree.useWindingNumber === true) {
751
+ inside = polyInside_WindingNumber_buffer(targetPolytreeBuffer, currentPolygon.getMidpoint(), currentPolygon.coplanar);
749
752
  } else {
750
- point = pointRounding(_v2.copy(currentPolygon.getMidpoint()));
751
- if (OctreeCSG.useOctreeRay !== true && targetOctree.mesh) {
752
- _rayDirection.copy(currentPolygon.plane.normal);
753
- _raycaster1.set(point, _rayDirection);
754
- intersects = _raycaster1.intersectObject(targetOctree.mesh);
753
+ point = pointRounding(tempVector2.copy(currentPolygon.getMidpoint()));
754
+ if (Polytree.usePolytreeRay !== true && targetPolytree.mesh) {
755
+ tempRayDirection.copy(currentPolygon.plane.normal);
756
+ tempRaycaster.set(point, tempRayDirection);
757
+ intersects = tempRaycaster.intersectObject(targetPolytree.mesh);
755
758
  if (intersects.length) {
756
- if (_rayDirection.dot(intersects[0].face.normal) > 0) {
759
+ if (tempRayDirection.dot(intersects[0].face.normal) > 0) {
757
760
  inside = true;
758
761
  }
759
762
  }
760
763
  if (!(inside || !currentPolygon.coplanar)) {
761
764
  for (j = m = 0, ref2 = _wP_EPS_ARR_COUNT; (0 <= ref2 ? m < ref2 : m > ref2); j = 0 <= ref2 ? ++m : --m) {
762
- _raycaster1.ray.origin.copy(point).add(_wP_EPS_ARR[j]);
763
- intersects = _raycaster1.intersectObject(targetOctree.mesh);
765
+ tempRaycaster.ray.origin.copy(point).add(_wP_EPS_ARR[j]);
766
+ intersects = tempRaycaster.intersectObject(targetPolytree.mesh);
764
767
  if (intersects.length) {
765
- if (_rayDirection.dot(intersects[0].face.normal) > 0) {
768
+ if (tempRayDirection.dot(intersects[0].face.normal) > 0) {
766
769
  inside = true;
767
770
  break;
768
771
  }
@@ -770,23 +773,23 @@ OctreeCSG = class OctreeCSG {
770
773
  }
771
774
  }
772
775
  } else {
773
- _ray.origin.copy(point);
774
- _rayDirection.copy(currentPolygon.plane.normal);
775
- _ray.direction.copy(currentPolygon.plane.normal);
776
- intersects = targetOctree.rayIntersect(_ray, targetOctree.originalMatrixWorld);
776
+ tempRay.origin.copy(point);
777
+ tempRayDirection.copy(currentPolygon.plane.normal);
778
+ tempRay.direction.copy(currentPolygon.plane.normal);
779
+ intersects = targetPolytree.rayIntersect(tempRay, targetPolytree.originalMatrixWorld);
777
780
  if (intersects.length) {
778
- if (_rayDirection.dot(intersects[0].polygon.plane.normal) > 0) {
781
+ if (tempRayDirection.dot(intersects[0].polygon.plane.normal) > 0) {
779
782
  inside = true;
780
783
  }
781
784
  }
782
785
  if (!(inside || !currentPolygon.coplanar)) {
783
- for (j = o = 0, ref3 = _wP_EPS_ARR_COUNT; (0 <= ref3 ? o < ref3 : o > ref3); j = 0 <= ref3 ? ++o : --o) {
784
- _ray.origin.copy(point).add(_wP_EPS_ARR[j]);
785
- _rayDirection.copy(currentPolygon.plane.normal);
786
- _ray.direction.copy(currentPolygon.plane.normal);
787
- intersects = targetOctree.rayIntersect(_ray, targetOctree.originalMatrixWorld);
786
+ for (j = n = 0, ref3 = _wP_EPS_ARR_COUNT; (0 <= ref3 ? n < ref3 : n > ref3); j = 0 <= ref3 ? ++n : --n) {
787
+ tempRay.origin.copy(point).add(_wP_EPS_ARR[j]);
788
+ tempRayDirection.copy(currentPolygon.plane.normal);
789
+ tempRay.direction.copy(currentPolygon.plane.normal);
790
+ intersects = targetPolytree.rayIntersect(tempRay, targetPolytree.originalMatrixWorld);
788
791
  if (intersects.length) {
789
- if (_rayDirection.dot(intersects[0].polygon.plane.normal) > 0) {
792
+ if (tempRayDirection.dot(intersects[0].polygon.plane.normal) > 0) {
790
793
  inside = true;
791
794
  break;
792
795
  }
@@ -805,8 +808,8 @@ OctreeCSG = class OctreeCSG {
805
808
  }
806
809
  }
807
810
  results1 = [];
808
- for (i = i1 = 0, ref4 = this.subTrees.length; (0 <= ref4 ? i1 < ref4 : i1 > ref4); i = 0 <= ref4 ? ++i1 : --i1) {
809
- results1.push(this.subTrees[i].handleIntersectingPolygons(targetOctree, targetOctreeBuffer));
811
+ for (i = o = 0, ref4 = this.subTrees.length; (0 <= ref4 ? o < ref4 : o > ref4); i = 0 <= ref4 ? ++o : --o) {
812
+ results1.push(this.subTrees[i].handleIntersectingPolygons(targetPolytree, targetPolytreeBuffer));
810
813
  }
811
814
  return results1;
812
815
  }
@@ -939,7 +942,7 @@ OctreeCSG = class OctreeCSG {
939
942
  // @polygons.forEach (p) -> p.shared = index
940
943
  // for i in [0...@subTrees.length]
941
944
  // @subTrees[i].setPolygonIndex(index)
942
- OctreeCSG.prototype.isOctree = true;
945
+ Polytree.prototype.isPolytree = true;
943
946
 
944
947
  raycastIntersectAscSort = function(a, b) {
945
948
  return a.distance - b.distance;
@@ -953,7 +956,7 @@ pointRounding = function(point, num = 15) {
953
956
  };
954
957
 
955
958
  splitPolygonByPlane = function(polygon, plane, result = []) {
956
- var b, f, i, j, k, l, m, newPolys, npI, o, polygonType, ref, ref1, ref2, ref3, returnPolygon, t, ti, tj, type, types, v, vi, vj;
959
+ var backVertices, currentType, currentVertex, distanceToPlane, frontVertices, i, intersectionParameter, k, l, m, n, newPolygons, nextIndex, nextType, nextVertex, polygonIndex, polygonType, ref, ref1, ref2, ref3, returnPolygon, type, types, vertexParameter;
957
960
  returnPolygon = {
958
961
  polygon: polygon,
959
962
  type: "undecided"
@@ -961,8 +964,8 @@ splitPolygonByPlane = function(polygon, plane, result = []) {
961
964
  polygonType = 0;
962
965
  types = [];
963
966
  for (i = k = 0, ref = polygon.vertices.length; (0 <= ref ? k < ref : k > ref); i = 0 <= ref ? ++k : --k) {
964
- t = plane.normal.dot(polygon.vertices[i].pos) - plane.w;
965
- type = t < -EPSILON ? BACK : t > EPSILON ? FRONT : COPLANAR;
967
+ distanceToPlane = plane.normal.dot(polygon.vertices[i].pos) - plane.w;
968
+ type = distanceToPlane < -EPSILON ? BACK : distanceToPlane > EPSILON ? FRONT : COPLANAR;
966
969
  polygonType |= type;
967
970
  types.push(type);
968
971
  }
@@ -980,55 +983,55 @@ splitPolygonByPlane = function(polygon, plane, result = []) {
980
983
  result.push(returnPolygon);
981
984
  break;
982
985
  case SPANNING:
983
- f = [];
984
- b = [];
986
+ frontVertices = [];
987
+ backVertices = [];
985
988
  for (i = l = 0, ref1 = polygon.vertices.length; (0 <= ref1 ? l < ref1 : l > ref1); i = 0 <= ref1 ? ++l : --l) {
986
- j = (i + 1) % polygon.vertices.length;
987
- ti = types[i];
988
- tj = types[j];
989
- vi = polygon.vertices[i];
990
- vj = polygon.vertices[j];
991
- if (ti !== BACK) {
992
- f.push(vi);
989
+ nextIndex = (i + 1) % polygon.vertices.length;
990
+ currentType = types[i];
991
+ nextType = types[nextIndex];
992
+ currentVertex = polygon.vertices[i];
993
+ nextVertex = polygon.vertices[nextIndex];
994
+ if (currentType !== BACK) {
995
+ frontVertices.push(currentVertex);
993
996
  }
994
- if (ti !== FRONT) {
995
- b.push(ti !== BACK ? vi.clone() : vi);
997
+ if (currentType !== FRONT) {
998
+ backVertices.push(currentType !== BACK ? currentVertex.clone() : currentVertex);
996
999
  }
997
- if ((ti | tj) === SPANNING) {
998
- t = (plane.w - plane.normal.dot(vi.pos)) / plane.normal.dot(tv0.copy(vj.pos).sub(vi.pos));
999
- v = vi.interpolate(vj, t);
1000
- f.push(v);
1001
- b.push(v.clone());
1000
+ if ((currentType | nextType) === SPANNING) {
1001
+ intersectionParameter = (plane.w - plane.normal.dot(currentVertex.pos)) / plane.normal.dot(triangleVertex0.copy(nextVertex.pos).sub(currentVertex.pos));
1002
+ vertexParameter = currentVertex.interpolate(nextVertex, intersectionParameter);
1003
+ frontVertices.push(vertexParameter);
1004
+ backVertices.push(vertexParameter.clone());
1002
1005
  }
1003
1006
  }
1004
- if (f.length >= 3) {
1005
- if (f.length > 3) {
1006
- newPolys = splitPolygonArr(f);
1007
- for (npI = m = 0, ref2 = newPolys.length; (0 <= ref2 ? m < ref2 : m > ref2); npI = 0 <= ref2 ? ++m : --m) {
1007
+ if (frontVertices.length >= 3) {
1008
+ if (frontVertices.length > 3) {
1009
+ newPolygons = splitPolygonArr(frontVertices);
1010
+ for (polygonIndex = m = 0, ref2 = newPolygons.length; (0 <= ref2 ? m < ref2 : m > ref2); polygonIndex = 0 <= ref2 ? ++m : --m) {
1008
1011
  result.push({
1009
- polygon: new Polygon(newPolys[npI], polygon.shared),
1012
+ polygon: new Polygon(newPolygons[polygonIndex], polygon.shared),
1010
1013
  type: "front"
1011
1014
  });
1012
1015
  }
1013
1016
  } else {
1014
1017
  result.push({
1015
- polygon: new Polygon(f, polygon.shared),
1018
+ polygon: new Polygon(frontVertices, polygon.shared),
1016
1019
  type: "front"
1017
1020
  });
1018
1021
  }
1019
1022
  }
1020
- if (b.length >= 3) {
1021
- if (b.length > 3) {
1022
- newPolys = splitPolygonArr(b);
1023
- for (npI = o = 0, ref3 = newPolys.length; (0 <= ref3 ? o < ref3 : o > ref3); npI = 0 <= ref3 ? ++o : --o) {
1023
+ if (backVertices.length >= 3) {
1024
+ if (backVertices.length > 3) {
1025
+ newPolygons = splitPolygonArr(backVertices);
1026
+ for (polygonIndex = n = 0, ref3 = newPolygons.length; (0 <= ref3 ? n < ref3 : n > ref3); polygonIndex = 0 <= ref3 ? ++n : --n) {
1024
1027
  result.push({
1025
- polygon: new Polygon(newPolys[npI], polygon.shared),
1028
+ polygon: new Polygon(newPolygons[polygonIndex], polygon.shared),
1026
1029
  type: "back"
1027
1030
  });
1028
1031
  }
1029
1032
  } else {
1030
1033
  result.push({
1031
- polygon: new Polygon(b, polygon.shared),
1034
+ polygon: new Polygon(backVertices, polygon.shared),
1032
1035
  type: "back"
1033
1036
  });
1034
1037
  }
@@ -1183,7 +1186,7 @@ CSG_Rules = {
1183
1186
  }
1184
1187
  };
1185
1188
 
1186
- // class OctreeCSG { };
1189
+ // class Polytree { };
1187
1190
  /*
1188
1191
  Union:
1189
1192
  - Combine all polygons from A and B, except:
@@ -1209,132 +1212,134 @@ Intersect:
1209
1212
  d. outside and coplanar-back
1210
1213
  e. outside
1211
1214
  */
1212
- OctreeCSG.union = function(octreeA, octreeB, buildTargetOctree = true) {
1213
- var currentMeshSideA, currentMeshSideB, octree, trianglesSet;
1214
- octree = new OctreeCSG();
1215
+ Polytree.union = function(polytreeA, polytreeB, buildTargetPolytree = true) {
1216
+ var currentMeshSideA, currentMeshSideB, polytree, trianglesSet;
1217
+ polytree = new Polytree();
1215
1218
  trianglesSet = new Set();
1216
- if (octreeA.box.intersectsBox(octreeB.box)) {
1219
+ if (polytreeA.box.intersectsBox(polytreeB.box)) {
1217
1220
  currentMeshSideA = void 0;
1218
1221
  currentMeshSideB = void 0;
1219
- if (octreeA.mesh) {
1220
- currentMeshSideA = octreeA.mesh.material.side;
1221
- octreeA.mesh.material.side = DoubleSide;
1222
- }
1223
- if (octreeB.mesh) {
1224
- currentMeshSideB = octreeB.mesh.material.side;
1225
- octreeB.mesh.material.side = DoubleSide;
1226
- }
1227
- octreeA.resetPolygons(false);
1228
- octreeB.resetPolygons(false);
1229
- octreeA.markIntesectingPolygons(octreeB);
1230
- octreeB.markIntesectingPolygons(octreeA);
1231
- handleIntersectingOctrees(octreeA, octreeB);
1232
- octreeA.deleteReplacedPolygons();
1233
- octreeB.deleteReplacedPolygons();
1234
- octreeA.deletePolygonsByStateRules(CSG_Rules.union.a);
1235
- octreeB.deletePolygonsByStateRules(CSG_Rules.union.b);
1236
- octreeA.getPolygonCloneCallback(octree.addPolygon.bind(octree), trianglesSet);
1237
- octreeB.getPolygonCloneCallback(octree.addPolygon.bind(octree), trianglesSet);
1238
- if (octreeA.mesh && octreeA.mesh.material.side !== currentMeshSideA) {
1239
- octreeA.mesh.material.side = currentMeshSideA;
1240
- }
1241
- if (octreeB.mesh && octreeB.mesh.material.side !== currentMeshSideB) {
1242
- octreeB.mesh.material.side = currentMeshSideB;
1222
+ if (polytreeA.mesh) {
1223
+ currentMeshSideA = polytreeA.mesh.material.side;
1224
+ polytreeA.mesh.material.side = DoubleSide;
1225
+ }
1226
+ if (polytreeB.mesh) {
1227
+ currentMeshSideB = polytreeB.mesh.material.side;
1228
+ polytreeB.mesh.material.side = DoubleSide;
1229
+ }
1230
+ polytreeA.resetPolygons(false);
1231
+ polytreeB.resetPolygons(false);
1232
+ polytreeA.markIntesectingPolygons(polytreeB);
1233
+ polytreeB.markIntesectingPolygons(polytreeA);
1234
+ handleIntersectingPolytrees(polytreeA, polytreeB);
1235
+ polytreeA.deleteReplacedPolygons();
1236
+ polytreeB.deleteReplacedPolygons();
1237
+ polytreeA.deletePolygonsByStateRules(CSG_Rules.union.a);
1238
+ polytreeB.deletePolygonsByStateRules(CSG_Rules.union.b);
1239
+ polytreeA.getPolygonCloneCallback(polytree.addPolygon.bind(polytree), trianglesSet);
1240
+ polytreeB.getPolygonCloneCallback(polytree.addPolygon.bind(polytree), trianglesSet);
1241
+ if (polytreeA.mesh && polytreeA.mesh.material.side !== currentMeshSideA) {
1242
+ polytreeA.mesh.material.side = currentMeshSideA;
1243
+ }
1244
+ if (polytreeB.mesh && polytreeB.mesh.material.side !== currentMeshSideB) {
1245
+ polytreeB.mesh.material.side = currentMeshSideB;
1243
1246
  }
1244
1247
  } else {
1245
- octreeA.getPolygonCloneCallback(octree.addPolygon.bind(octree), trianglesSet);
1246
- octreeB.getPolygonCloneCallback(octree.addPolygon.bind(octree), trianglesSet);
1248
+ polytreeA.getPolygonCloneCallback(polytree.addPolygon.bind(polytree), trianglesSet);
1249
+ polytreeB.getPolygonCloneCallback(polytree.addPolygon.bind(polytree), trianglesSet);
1247
1250
  }
1248
1251
  trianglesSet.clear();
1249
1252
  trianglesSet = void 0;
1250
- octree.markPolygonsAsOriginal();
1251
- buildTargetOctree && octree.buildTree();
1252
- return octree;
1253
+ polytree.markPolygonsAsOriginal();
1254
+ buildTargetPolytree && polytree.buildTree();
1255
+ return polytree;
1253
1256
  };
1254
1257
 
1255
- OctreeCSG.subtract = function(octreeA, octreeB, buildTargetOctree = true) {
1256
- var currentMeshSideA, currentMeshSideB, octree, trianglesSet;
1257
- octree = new OctreeCSG();
1258
+ Polytree.subtract = function(polytreeA, polytreeB, buildTargetPolytree = true) {
1259
+ var currentMeshSideA, currentMeshSideB, polytree, trianglesSet;
1260
+ polytree = new Polytree();
1258
1261
  trianglesSet = new Set();
1259
- if (octreeA.box.intersectsBox(octreeB.box)) {
1262
+ if (polytreeA.box.intersectsBox(polytreeB.box)) {
1260
1263
  currentMeshSideA = void 0;
1261
1264
  currentMeshSideB = void 0;
1262
- if (octreeA.mesh) {
1263
- currentMeshSideA = octreeA.mesh.material.side;
1264
- octreeA.mesh.material.side = DoubleSide;
1265
- }
1266
- if (octreeB.mesh) {
1267
- currentMeshSideB = octreeB.mesh.material.side;
1268
- octreeB.mesh.material.side = DoubleSide;
1269
- }
1270
- octreeA.resetPolygons(false);
1271
- octreeB.resetPolygons(false);
1272
- octreeA.markIntesectingPolygons(octreeB);
1273
- octreeB.markIntesectingPolygons(octreeA);
1274
- handleIntersectingOctrees(octreeA, octreeB);
1275
- octreeA.deleteReplacedPolygons();
1276
- octreeB.deleteReplacedPolygons();
1277
- octreeA.deletePolygonsByStateRules(CSG_Rules.subtract.a);
1278
- octreeB.deletePolygonsByStateRules(CSG_Rules.subtract.b);
1279
- octreeB.deletePolygonsByIntersection(false);
1280
- octreeB.invert();
1281
- octreeA.getPolygonCloneCallback(octree.addPolygon.bind(octree), trianglesSet);
1282
- octreeB.getPolygonCloneCallback(octree.addPolygon.bind(octree), trianglesSet);
1283
- if (octreeA.mesh && octreeA.mesh.material.side !== currentMeshSideA) {
1284
- octreeA.mesh.material.side = currentMeshSideA;
1285
- }
1286
- if (octreeB.mesh && octreeB.mesh.material.side !== currentMeshSideB) {
1287
- octreeB.mesh.material.side = currentMeshSideB;
1265
+ if (polytreeA.mesh) {
1266
+ currentMeshSideA = polytreeA.mesh.material.side;
1267
+ polytreeA.mesh.material.side = DoubleSide;
1268
+ }
1269
+ if (polytreeB.mesh) {
1270
+ currentMeshSideB = polytreeB.mesh.material.side;
1271
+ polytreeB.mesh.material.side = DoubleSide;
1272
+ }
1273
+ polytreeA.resetPolygons(false);
1274
+ polytreeB.resetPolygons(false);
1275
+ polytreeA.markIntesectingPolygons(polytreeB);
1276
+ polytreeB.markIntesectingPolygons(polytreeA);
1277
+ handleIntersectingPolytrees(polytreeA, polytreeB);
1278
+ polytreeA.deleteReplacedPolygons();
1279
+ polytreeB.deleteReplacedPolygons();
1280
+ polytreeA.deletePolygonsByStateRules(CSG_Rules.subtract.a);
1281
+ polytreeB.deletePolygonsByStateRules(CSG_Rules.subtract.b);
1282
+ polytreeB.deletePolygonsByIntersection(false);
1283
+ polytreeB.invert();
1284
+ polytreeA.getPolygonCloneCallback(polytree.addPolygon.bind(polytree), trianglesSet);
1285
+ polytreeB.getPolygonCloneCallback(polytree.addPolygon.bind(polytree), trianglesSet);
1286
+ if (polytreeA.mesh && polytreeA.mesh.material.side !== currentMeshSideA) {
1287
+ polytreeA.mesh.material.side = currentMeshSideA;
1288
+ }
1289
+ if (polytreeB.mesh && polytreeB.mesh.material.side !== currentMeshSideB) {
1290
+ polytreeB.mesh.material.side = currentMeshSideB;
1288
1291
  }
1289
1292
  } else {
1290
- octreeA.getPolygonCloneCallback(octree.addPolygon.bind(octree), trianglesSet);
1293
+ polytreeA.getPolygonCloneCallback(polytree.addPolygon.bind(polytree), trianglesSet);
1291
1294
  }
1292
1295
  trianglesSet.clear();
1293
1296
  trianglesSet = void 0;
1294
- octree.markPolygonsAsOriginal();
1295
- buildTargetOctree && octree.buildTree();
1296
- // octree.invert()
1297
- return octree;
1297
+ polytree.markPolygonsAsOriginal();
1298
+ buildTargetPolytree && polytree.buildTree();
1299
+ // polytree.invert()
1300
+ return polytree;
1298
1301
  };
1299
1302
 
1300
- OctreeCSG.intersect = function(octreeA, octreeB, buildTargetOctree = true) {
1301
- var currentMeshSideA, currentMeshSideB, octree, trianglesSet;
1302
- octree = new OctreeCSG();
1303
+ Polytree.intersect = function(polytreeA, polytreeB, buildTargetPolytree = true) {
1304
+ var currentMeshSideA, currentMeshSideB, polytree, trianglesSet;
1305
+ polytree = new Polytree();
1303
1306
  trianglesSet = new Set();
1304
- if (octreeA.box.intersectsBox(octreeB.box)) {
1307
+ if (polytreeA.box.intersectsBox(polytreeB.box)) {
1305
1308
  currentMeshSideA = void 0;
1306
1309
  currentMeshSideB = void 0;
1307
- if (octreeA.mesh) {
1308
- currentMeshSideA = octreeA.mesh.material.side;
1309
- octreeA.mesh.material.side = DoubleSide;
1310
- }
1311
- if (octreeB.mesh) {
1312
- currentMeshSideB = octreeB.mesh.material.side;
1313
- octreeB.mesh.material.side = DoubleSide;
1314
- }
1315
- octreeA.resetPolygons(false);
1316
- octreeB.resetPolygons(false);
1317
- octreeA.markIntesectingPolygons(octreeB);
1318
- octreeB.markIntesectingPolygons(octreeA);
1319
- handleIntersectingOctrees(octreeA, octreeB);
1320
- octreeA.deleteReplacedPolygons();
1321
- octreeB.deleteReplacedPolygons();
1322
- octreeA.deletePolygonsByStateRules(CSG_Rules.intersect.a);
1323
- octreeB.deletePolygonsByStateRules(CSG_Rules.intersect.b);
1324
- octreeA.deletePolygonsByIntersection(false);
1325
- octreeB.deletePolygonsByIntersection(false);
1326
- octreeA.getPolygonCloneCallback(octree.addPolygon.bind(octree), trianglesSet);
1327
- octreeB.getPolygonCloneCallback(octree.addPolygon.bind(octree), trianglesSet);
1328
- if (octreeA.mesh && octreeA.mesh.material.side !== currentMeshSideA) {
1329
- octreeA.mesh.material.side = currentMeshSideA;
1330
- }
1331
- if (octreeB.mesh && octreeB.mesh.material.side !== currentMeshSideB) {
1332
- octreeB.mesh.material.side = currentMeshSideB;
1310
+ if (polytreeA.mesh) {
1311
+ currentMeshSideA = polytreeA.mesh.material.side;
1312
+ polytreeA.mesh.material.side = DoubleSide;
1313
+ }
1314
+ if (polytreeB.mesh) {
1315
+ currentMeshSideB = polytreeB.mesh.material.side;
1316
+ polytreeB.mesh.material.side = DoubleSide;
1317
+ }
1318
+ polytreeA.resetPolygons(false);
1319
+ polytreeB.resetPolygons(false);
1320
+ polytreeA.markIntesectingPolygons(polytreeB);
1321
+ polytreeB.markIntesectingPolygons(polytreeA);
1322
+ handleIntersectingPolytrees(polytreeA, polytreeB);
1323
+ polytreeA.deleteReplacedPolygons();
1324
+ polytreeB.deleteReplacedPolygons();
1325
+ polytreeA.deletePolygonsByStateRules(CSG_Rules.intersect.a);
1326
+ polytreeB.deletePolygonsByStateRules(CSG_Rules.intersect.b);
1327
+ polytreeA.deletePolygonsByIntersection(false);
1328
+ polytreeB.deletePolygonsByIntersection(false);
1329
+ polytreeA.getPolygonCloneCallback(polytree.addPolygon.bind(polytree), trianglesSet);
1330
+ polytreeB.getPolygonCloneCallback(polytree.addPolygon.bind(polytree), trianglesSet);
1331
+ if (polytreeA.mesh && polytreeA.mesh.material.side !== currentMeshSideA) {
1332
+ polytreeA.mesh.material.side = currentMeshSideA;
1333
+ }
1334
+ if (polytreeB.mesh && polytreeB.mesh.material.side !== currentMeshSideB) {
1335
+ polytreeB.mesh.material.side = currentMeshSideB;
1333
1336
  }
1334
1337
  }
1335
1338
  trianglesSet.clear();
1336
1339
  trianglesSet = void 0;
1337
- return octree.markPolygons;
1340
+ polytree.markPolygonsAsOriginal();
1341
+ buildTargetPolytree && polytree.buildTree();
1342
+ return polytree;
1338
1343
  };
1339
1344
 
1340
1345
  CSG_Rules = {
@@ -1457,7 +1462,7 @@ CSG_Rules = {
1457
1462
  }
1458
1463
  };
1459
1464
 
1460
- // class OctreeCSG { };
1465
+ // class Polytree { };
1461
1466
  /*
1462
1467
  Union:
1463
1468
  - Combine all polygons from A and B, except:
@@ -1483,205 +1488,205 @@ Intersect:
1483
1488
  d. outside and coplanar-back
1484
1489
  e. outside
1485
1490
  */
1486
- OctreeCSG.union = function(octreeA, octreeB, buildTargetOctree = true) {
1487
- var currentMeshSideA, currentMeshSideB, octree, trianglesSet;
1488
- octree = new OctreeCSG();
1491
+ Polytree.union = function(polytreeA, polytreeB, buildTargetPolytree = true) {
1492
+ var currentMeshSideA, currentMeshSideB, polytree, trianglesSet;
1493
+ polytree = new Polytree();
1489
1494
  trianglesSet = new Set();
1490
- if (octreeA.box.intersectsBox(octreeB.box)) {
1495
+ if (polytreeA.box.intersectsBox(polytreeB.box)) {
1491
1496
  currentMeshSideA = void 0;
1492
1497
  currentMeshSideB = void 0;
1493
- if (octreeA.mesh) {
1494
- currentMeshSideA = octreeA.mesh.material.side;
1495
- octreeA.mesh.material.side = DoubleSide;
1496
- }
1497
- if (octreeB.mesh) {
1498
- currentMeshSideB = octreeB.mesh.material.side;
1499
- octreeB.mesh.material.side = DoubleSide;
1500
- }
1501
- octreeA.resetPolygons(false);
1502
- octreeB.resetPolygons(false);
1503
- octreeA.markIntesectingPolygons(octreeB);
1504
- octreeB.markIntesectingPolygons(octreeA);
1505
- handleIntersectingOctrees(octreeA, octreeB);
1506
- octreeA.deleteReplacedPolygons();
1507
- octreeB.deleteReplacedPolygons();
1508
- octreeA.deletePolygonsByStateRules(CSG_Rules.union.a);
1509
- octreeB.deletePolygonsByStateRules(CSG_Rules.union.b);
1510
- octreeA.getPolygonCloneCallback(octree.addPolygon.bind(octree), trianglesSet);
1511
- octreeB.getPolygonCloneCallback(octree.addPolygon.bind(octree), trianglesSet);
1512
- if (octreeA.mesh && octreeA.mesh.material.side !== currentMeshSideA) {
1513
- octreeA.mesh.material.side = currentMeshSideA;
1514
- }
1515
- if (octreeB.mesh && octreeB.mesh.material.side !== currentMeshSideB) {
1516
- octreeB.mesh.material.side = currentMeshSideB;
1498
+ if (polytreeA.mesh) {
1499
+ currentMeshSideA = polytreeA.mesh.material.side;
1500
+ polytreeA.mesh.material.side = DoubleSide;
1501
+ }
1502
+ if (polytreeB.mesh) {
1503
+ currentMeshSideB = polytreeB.mesh.material.side;
1504
+ polytreeB.mesh.material.side = DoubleSide;
1505
+ }
1506
+ polytreeA.resetPolygons(false);
1507
+ polytreeB.resetPolygons(false);
1508
+ polytreeA.markIntesectingPolygons(polytreeB);
1509
+ polytreeB.markIntesectingPolygons(polytreeA);
1510
+ handleIntersectingPolytrees(polytreeA, polytreeB);
1511
+ polytreeA.deleteReplacedPolygons();
1512
+ polytreeB.deleteReplacedPolygons();
1513
+ polytreeA.deletePolygonsByStateRules(CSG_Rules.union.a);
1514
+ polytreeB.deletePolygonsByStateRules(CSG_Rules.union.b);
1515
+ polytreeA.getPolygonCloneCallback(polytree.addPolygon.bind(polytree), trianglesSet);
1516
+ polytreeB.getPolygonCloneCallback(polytree.addPolygon.bind(polytree), trianglesSet);
1517
+ if (polytreeA.mesh && polytreeA.mesh.material.side !== currentMeshSideA) {
1518
+ polytreeA.mesh.material.side = currentMeshSideA;
1519
+ }
1520
+ if (polytreeB.mesh && polytreeB.mesh.material.side !== currentMeshSideB) {
1521
+ polytreeB.mesh.material.side = currentMeshSideB;
1517
1522
  }
1518
1523
  } else {
1519
- octreeA.getPolygonCloneCallback(octree.addPolygon.bind(octree), trianglesSet);
1520
- octreeB.getPolygonCloneCallback(octree.addPolygon.bind(octree), trianglesSet);
1524
+ polytreeA.getPolygonCloneCallback(polytree.addPolygon.bind(polytree), trianglesSet);
1525
+ polytreeB.getPolygonCloneCallback(polytree.addPolygon.bind(polytree), trianglesSet);
1521
1526
  }
1522
1527
  trianglesSet.clear();
1523
1528
  trianglesSet = void 0;
1524
- octree.markPolygonsAsOriginal();
1525
- buildTargetOctree && octree.buildTree();
1526
- return octree;
1529
+ polytree.markPolygonsAsOriginal();
1530
+ buildTargetPolytree && polytree.buildTree();
1531
+ return polytree;
1527
1532
  };
1528
1533
 
1529
- OctreeCSG.subtract = function(octreeA, octreeB, buildTargetOctree = true) {
1530
- var currentMeshSideA, currentMeshSideB, octree, trianglesSet;
1531
- octree = new OctreeCSG();
1534
+ Polytree.subtract = function(polytreeA, polytreeB, buildTargetPolytree = true) {
1535
+ var currentMeshSideA, currentMeshSideB, polytree, trianglesSet;
1536
+ polytree = new Polytree();
1532
1537
  trianglesSet = new Set();
1533
- if (octreeA.box.intersectsBox(octreeB.box)) {
1538
+ if (polytreeA.box.intersectsBox(polytreeB.box)) {
1534
1539
  currentMeshSideA = void 0;
1535
1540
  currentMeshSideB = void 0;
1536
- if (octreeA.mesh) {
1537
- currentMeshSideA = octreeA.mesh.material.side;
1538
- octreeA.mesh.material.side = DoubleSide;
1539
- }
1540
- if (octreeB.mesh) {
1541
- currentMeshSideB = octreeB.mesh.material.side;
1542
- octreeB.mesh.material.side = DoubleSide;
1543
- }
1544
- octreeA.resetPolygons(false);
1545
- octreeB.resetPolygons(false);
1546
- octreeA.markIntesectingPolygons(octreeB);
1547
- octreeB.markIntesectingPolygons(octreeA);
1548
- handleIntersectingOctrees(octreeA, octreeB);
1549
- octreeA.deleteReplacedPolygons();
1550
- octreeB.deleteReplacedPolygons();
1551
- octreeA.deletePolygonsByStateRules(CSG_Rules.subtract.a);
1552
- octreeB.deletePolygonsByStateRules(CSG_Rules.subtract.b);
1553
- octreeB.deletePolygonsByIntersection(false);
1554
- octreeB.invert();
1555
- octreeA.getPolygonCloneCallback(octree.addPolygon.bind(octree), trianglesSet);
1556
- octreeB.getPolygonCloneCallback(octree.addPolygon.bind(octree), trianglesSet);
1557
- if (octreeA.mesh && octreeA.mesh.material.side !== currentMeshSideA) {
1558
- octreeA.mesh.material.side = currentMeshSideA;
1559
- }
1560
- if (octreeB.mesh && octreeB.mesh.material.side !== currentMeshSideB) {
1561
- octreeB.mesh.material.side = currentMeshSideB;
1541
+ if (polytreeA.mesh) {
1542
+ currentMeshSideA = polytreeA.mesh.material.side;
1543
+ polytreeA.mesh.material.side = DoubleSide;
1544
+ }
1545
+ if (polytreeB.mesh) {
1546
+ currentMeshSideB = polytreeB.mesh.material.side;
1547
+ polytreeB.mesh.material.side = DoubleSide;
1548
+ }
1549
+ polytreeA.resetPolygons(false);
1550
+ polytreeB.resetPolygons(false);
1551
+ polytreeA.markIntesectingPolygons(polytreeB);
1552
+ polytreeB.markIntesectingPolygons(polytreeA);
1553
+ handleIntersectingPolytrees(polytreeA, polytreeB);
1554
+ polytreeA.deleteReplacedPolygons();
1555
+ polytreeB.deleteReplacedPolygons();
1556
+ polytreeA.deletePolygonsByStateRules(CSG_Rules.subtract.a);
1557
+ polytreeB.deletePolygonsByStateRules(CSG_Rules.subtract.b);
1558
+ polytreeB.deletePolygonsByIntersection(false);
1559
+ polytreeB.invert();
1560
+ polytreeA.getPolygonCloneCallback(polytree.addPolygon.bind(polytree), trianglesSet);
1561
+ polytreeB.getPolygonCloneCallback(polytree.addPolygon.bind(polytree), trianglesSet);
1562
+ if (polytreeA.mesh && polytreeA.mesh.material.side !== currentMeshSideA) {
1563
+ polytreeA.mesh.material.side = currentMeshSideA;
1564
+ }
1565
+ if (polytreeB.mesh && polytreeB.mesh.material.side !== currentMeshSideB) {
1566
+ polytreeB.mesh.material.side = currentMeshSideB;
1562
1567
  }
1563
1568
  } else {
1564
- octreeA.getPolygonCloneCallback(octree.addPolygon.bind(octree), trianglesSet);
1569
+ polytreeA.getPolygonCloneCallback(polytree.addPolygon.bind(polytree), trianglesSet);
1565
1570
  }
1566
1571
  trianglesSet.clear();
1567
1572
  trianglesSet = void 0;
1568
- octree.markPolygonsAsOriginal();
1569
- buildTargetOctree && octree.buildTree();
1570
- // octree.invert()
1571
- return octree;
1573
+ polytree.markPolygonsAsOriginal();
1574
+ buildTargetPolytree && polytree.buildTree();
1575
+ // polytree.invert()
1576
+ return polytree;
1572
1577
  };
1573
1578
 
1574
1579
  /*
1575
1580
  Intersect:
1576
1581
  1. Delete all polygons in A that are:
1577
- a. inside and coplanar-back
1578
- b. outside and coplanar-front
1579
- c. outside and coplanar-back
1580
- d. outside
1582
+ a. inside and coplanar-back
1583
+ b. outside and coplanar-front
1584
+ c. outside and coplanar-back
1585
+ d. outside
1581
1586
  2. Delete all polygons in B that are:
1582
- a. inside and coplanar-front
1583
- b. inside and coplanar-back
1584
- c. outside and coplanar-front
1585
- d. outside and coplanar-back
1586
- e. outside
1587
+ a. inside and coplanar-front
1588
+ b. inside and coplanar-back
1589
+ c. outside and coplanar-front
1590
+ d. outside and coplanar-back
1591
+ e. outside
1587
1592
  */
1588
- OctreeCSG.intersect = function(octreeA, octreeB, buildTargetOctree = true) {
1589
- var currentMeshSideA, currentMeshSideB, octree, trianglesSet;
1590
- octree = new OctreeCSG();
1593
+ Polytree.intersect = function(polytreeA, polytreeB, buildTargetPolytree = true) {
1594
+ var currentMeshSideA, currentMeshSideB, polytree, trianglesSet;
1595
+ polytree = new Polytree();
1591
1596
  trianglesSet = new Set();
1592
- if (octreeA.box.intersectsBox(octreeB.box)) {
1597
+ if (polytreeA.box.intersectsBox(polytreeB.box)) {
1593
1598
  currentMeshSideA = void 0;
1594
1599
  currentMeshSideB = void 0;
1595
- if (octreeA.mesh) {
1596
- currentMeshSideA = octreeA.mesh.material.side;
1597
- octreeA.mesh.material.side = DoubleSide;
1598
- }
1599
- if (octreeB.mesh) {
1600
- currentMeshSideB = octreeB.mesh.material.side;
1601
- octreeB.mesh.material.side = DoubleSide;
1602
- }
1603
- octreeA.resetPolygons(false);
1604
- octreeB.resetPolygons(false);
1605
- octreeA.markIntesectingPolygons(octreeB);
1606
- octreeB.markIntesectingPolygons(octreeA);
1607
- handleIntersectingOctrees(octreeA, octreeB);
1608
- octreeA.deleteReplacedPolygons();
1609
- octreeB.deleteReplacedPolygons();
1610
- octreeA.deletePolygonsByStateRules(CSG_Rules.intersect.a);
1611
- octreeB.deletePolygonsByStateRules(CSG_Rules.intersect.b);
1612
- octreeA.deletePolygonsByIntersection(false);
1613
- octreeB.deletePolygonsByIntersection(false);
1614
- octreeA.getPolygonCloneCallback(octree.addPolygon.bind(octree), trianglesSet);
1615
- octreeB.getPolygonCloneCallback(octree.addPolygon.bind(octree), trianglesSet);
1616
- if (octreeA.mesh) {
1617
- if (octreeA.mesh.material.side !== currentMeshSideA) {
1618
- octreeA.mesh.material.side = currentMeshSideA;
1619
- }
1620
- }
1621
- if (octreeB.mesh) {
1622
- if (octreeB.mesh.material.side !== currentMeshSideB) {
1623
- octreeB.mesh.material.side = currentMeshSideB;
1600
+ if (polytreeA.mesh) {
1601
+ currentMeshSideA = polytreeA.mesh.material.side;
1602
+ polytreeA.mesh.material.side = DoubleSide;
1603
+ }
1604
+ if (polytreeB.mesh) {
1605
+ currentMeshSideB = polytreeB.mesh.material.side;
1606
+ polytreeB.mesh.material.side = DoubleSide;
1607
+ }
1608
+ polytreeA.resetPolygons(false);
1609
+ polytreeB.resetPolygons(false);
1610
+ polytreeA.markIntesectingPolygons(polytreeB);
1611
+ polytreeB.markIntesectingPolygons(polytreeA);
1612
+ handleIntersectingPolytrees(polytreeA, polytreeB);
1613
+ polytreeA.deleteReplacedPolygons();
1614
+ polytreeB.deleteReplacedPolygons();
1615
+ polytreeA.deletePolygonsByStateRules(CSG_Rules.intersect.a);
1616
+ polytreeB.deletePolygonsByStateRules(CSG_Rules.intersect.b);
1617
+ polytreeA.deletePolygonsByIntersection(false);
1618
+ polytreeB.deletePolygonsByIntersection(false);
1619
+ polytreeA.getPolygonCloneCallback(polytree.addPolygon.bind(polytree), trianglesSet);
1620
+ polytreeB.getPolygonCloneCallback(polytree.addPolygon.bind(polytree), trianglesSet);
1621
+ if (polytreeA.mesh) {
1622
+ if (polytreeA.mesh.material.side !== currentMeshSideA) {
1623
+ polytreeA.mesh.material.side = currentMeshSideA;
1624
+ }
1625
+ }
1626
+ if (polytreeB.mesh) {
1627
+ if (polytreeB.mesh.material.side !== currentMeshSideB) {
1628
+ polytreeB.mesh.material.side = currentMeshSideB;
1624
1629
  }
1625
1630
  }
1626
1631
  }
1627
1632
  trianglesSet.clear();
1628
1633
  trianglesSet = void 0;
1629
- octree.markPolygonsAsOriginal();
1630
- buildTargetOctree && octree.buildTree();
1631
- return octree;
1634
+ polytree.markPolygonsAsOriginal();
1635
+ buildTargetPolytree && polytree.buildTree();
1636
+ return polytree;
1632
1637
  };
1633
1638
 
1634
- OctreeCSG.meshUnion = function(mesh1, mesh2, targetMaterial) {
1635
- var octreeA, octreeB, resultMesh, resultOctree;
1636
- octreeA = void 0;
1637
- octreeB = void 0;
1639
+ Polytree.meshUnion = function(mesh1, mesh2, targetMaterial) {
1640
+ var polytreeA, polytreeB, resultMesh, resultPolytree;
1641
+ polytreeA = void 0;
1642
+ polytreeB = void 0;
1638
1643
  if (targetMaterial && Array.isArray(targetMaterial)) {
1639
- octreeA = OctreeCSG.fromMesh(mesh1, 0);
1640
- octreeB = OctreeCSG.fromMesh(mesh2, 1);
1644
+ polytreeA = Polytree.fromMesh(mesh1, 0);
1645
+ polytreeB = Polytree.fromMesh(mesh2, 1);
1641
1646
  } else {
1642
- octreeA = OctreeCSG.fromMesh(mesh1);
1643
- octreeB = OctreeCSG.fromMesh(mesh2);
1647
+ polytreeA = Polytree.fromMesh(mesh1);
1648
+ polytreeB = Polytree.fromMesh(mesh2);
1644
1649
  targetMaterial = targetMaterial !== void 0 ? targetMaterial : (Array.isArray(mesh1.material) ? mesh1.material[0] : mesh1.material).clone();
1645
1650
  }
1646
- resultOctree = OctreeCSG.union(octreeA, octreeB, false);
1647
- resultMesh = OctreeCSG.toMesh(resultOctree, targetMaterial);
1648
- disposeOctree(octreeA, octreeB, resultOctree);
1651
+ resultPolytree = Polytree.union(polytreeA, polytreeB, false);
1652
+ resultMesh = Polytree.toMesh(resultPolytree, targetMaterial);
1653
+ disposePolytree(polytreeA, polytreeB, resultPolytree);
1649
1654
  return resultMesh;
1650
1655
  };
1651
1656
 
1652
- OctreeCSG.meshSubtract = function(mesh1, mesh2, targetMaterial) {
1653
- var octreeA, octreeB, resultMesh, resultOctree;
1654
- octreeA = void 0;
1655
- octreeB = void 0;
1657
+ Polytree.meshSubtract = function(mesh1, mesh2, targetMaterial) {
1658
+ var polytreeA, polytreeB, resultMesh, resultPolytree;
1659
+ polytreeA = void 0;
1660
+ polytreeB = void 0;
1656
1661
  if (targetMaterial && Array.isArray(targetMaterial)) {
1657
- octreeA = OctreeCSG.fromMesh(mesh1, 0);
1658
- octreeB = OctreeCSG.fromMesh(mesh2, 1);
1662
+ polytreeA = Polytree.fromMesh(mesh1, 0);
1663
+ polytreeB = Polytree.fromMesh(mesh2, 1);
1659
1664
  } else {
1660
- octreeA = OctreeCSG.fromMesh(mesh1);
1661
- octreeB = OctreeCSG.fromMesh(mesh2);
1665
+ polytreeA = Polytree.fromMesh(mesh1);
1666
+ polytreeB = Polytree.fromMesh(mesh2);
1662
1667
  targetMaterial = targetMaterial !== void 0 ? targetMaterial : (Array.isArray(mesh1.material) ? mesh1.material[0] : mesh1.material).clone();
1663
1668
  }
1664
- resultOctree = OctreeCSG.subtract(octreeA, octreeB, false);
1665
- resultMesh = OctreeCSG.toMesh(resultOctree, targetMaterial);
1666
- disposeOctree(octreeA, octreeB, resultOctree);
1669
+ resultPolytree = Polytree.subtract(polytreeA, polytreeB, false);
1670
+ resultMesh = Polytree.toMesh(resultPolytree, targetMaterial);
1671
+ disposePolytree(polytreeA, polytreeB, resultPolytree);
1667
1672
  return resultMesh;
1668
1673
  };
1669
1674
 
1670
- OctreeCSG.meshIntersect = function(mesh1, mesh2, targetMaterial) {
1671
- var octreeA, octreeB, resultMesh, resultOctree;
1672
- octreeA = void 0;
1673
- octreeB = void 0;
1675
+ Polytree.meshIntersect = function(mesh1, mesh2, targetMaterial) {
1676
+ var polytreeA, polytreeB, resultMesh, resultPolytree;
1677
+ polytreeA = void 0;
1678
+ polytreeB = void 0;
1674
1679
  if (targetMaterial && Array.isArray(targetMaterial)) {
1675
- octreeA = OctreeCSG.fromMesh(mesh1, 0);
1676
- octreeB = OctreeCSG.fromMesh(mesh2, 1);
1680
+ polytreeA = Polytree.fromMesh(mesh1, 0);
1681
+ polytreeB = Polytree.fromMesh(mesh2, 1);
1677
1682
  } else {
1678
- octreeA = OctreeCSG.fromMesh(mesh1);
1679
- octreeB = OctreeCSG.fromMesh(mesh2);
1683
+ polytreeA = Polytree.fromMesh(mesh1);
1684
+ polytreeB = Polytree.fromMesh(mesh2);
1680
1685
  targetMaterial = targetMaterial !== void 0 ? targetMaterial : (Array.isArray(mesh1.material) ? mesh1.material[0] : mesh1.material).clone();
1681
1686
  }
1682
- resultOctree = OctreeCSG.intersect(octreeA, octreeB, false);
1683
- resultMesh = OctreeCSG.toMesh(resultOctree, targetMaterial);
1684
- disposeOctree(octreeA, octreeB, resultOctree);
1687
+ resultPolytree = Polytree.intersect(polytreeA, polytreeB, false);
1688
+ resultMesh = Polytree.toMesh(resultPolytree, targetMaterial);
1689
+ disposePolytree(polytreeA, polytreeB, resultPolytree);
1685
1690
  return resultMesh;
1686
1691
  };
1687
1692
 
@@ -1689,45 +1694,45 @@ _asyncUnionID = 0;
1689
1694
 
1690
1695
  _asyncUnionArrayID = 0;
1691
1696
 
1692
- OctreeCSG.disposeOctree = true;
1697
+ Polytree.disposePolytree = true;
1693
1698
 
1694
- OctreeCSG.async = {
1699
+ Polytree.async = {
1695
1700
  batchSize: 100,
1696
- union: function(octreeA, octreeB, buildTargetOctree = true) {
1701
+ union: function(polytreeA, polytreeB, buildTargetPolytree = true) {
1697
1702
  return new Promise(function(resolve, reject) {
1698
1703
  var e, result;
1699
1704
  try {
1700
1705
  // const id = _asyncUnionID++
1701
1706
  // console.log("Promise Union ##{id} started")
1702
- result = OctreeCSG.union(octreeA, octreeB, buildTargetOctree);
1707
+ result = Polytree.union(polytreeA, polytreeB, buildTargetPolytree);
1703
1708
  resolve(result);
1704
- return disposeOctree(octreeA, octreeB);
1709
+ return disposePolytree(polytreeA, polytreeB);
1705
1710
  } catch (error) {
1706
1711
  e = error;
1707
1712
  return reject(e);
1708
1713
  }
1709
1714
  });
1710
1715
  },
1711
- subtract: function(octreeA, octreeB, buildTargetOctree = true) {
1716
+ subtract: function(polytreeA, polytreeB, buildTargetPolytree = true) {
1712
1717
  return new Promise(function(resolve, reject) {
1713
1718
  var e, result;
1714
1719
  try {
1715
- result = OctreeCSG.subtract(octreeA, octreeB, buildTargetOctree);
1720
+ result = Polytree.subtract(polytreeA, polytreeB, buildTargetPolytree);
1716
1721
  resolve(result);
1717
- return disposeOctree(octreeA, octreeB);
1722
+ return disposePolytree(polytreeA, polytreeB);
1718
1723
  } catch (error) {
1719
1724
  e = error;
1720
1725
  return reject(e);
1721
1726
  }
1722
1727
  });
1723
1728
  },
1724
- intersect: function(octreeA, octreeB, buildTargetOctree = true) {
1729
+ intersect: function(polytreeA, polytreeB, buildTargetPolytree = true) {
1725
1730
  return new Promise(function(resolve, reject) {
1726
1731
  var e, result;
1727
1732
  try {
1728
- result = OctreeCSG.intersect(octreeA, octreeB, buildTargetOctree);
1733
+ result = Polytree.intersect(polytreeA, polytreeB, buildTargetPolytree);
1729
1734
  resolve(result);
1730
- return disposeOctree(octreeA, octreeB);
1735
+ return disposePolytree(polytreeA, polytreeB);
1731
1736
  } catch (error) {
1732
1737
  e = error;
1733
1738
  return reject(e);
@@ -1736,89 +1741,89 @@ OctreeCSG.async = {
1736
1741
  },
1737
1742
  unionArray: function(objArr, materialIndexMax = 2e308) {
1738
1743
  return new Promise(function(resolve, reject) {
1739
- var batch, batches, currentIndex, e, hasLeftOver, i, k, l, leftOverOctree, mainOctree, mainOctreeUsed, materialIndex, octreesArray, promise, promises, ref, ref1, result, tempOctree, usingBatches;
1744
+ var batch, batches, currentIndex, e, hasLeftOver, i, k, l, leftOverPolytree, mainPolytree, mainPolytreeUsed, materialIndex, polytreesArray, promise, promises, ref, ref1, result, tempPolytree, usingBatches;
1740
1745
  try {
1741
- usingBatches = OctreeCSG.async.batchSize > 4 && OctreeCSG.async.batchSize < objArr.length;
1746
+ usingBatches = Polytree.async.batchSize > 4 && Polytree.async.batchSize < objArr.length;
1742
1747
  // const id = _asyncUnionArrayID++
1743
1748
  // console.log("Promise Union Array ##{id}", usingBatches)
1744
- mainOctree = void 0;
1745
- mainOctreeUsed = false;
1749
+ mainPolytree = void 0;
1750
+ mainPolytreeUsed = false;
1746
1751
  promises = [];
1747
1752
  if (usingBatches) {
1748
1753
  batches = [];
1749
1754
  currentIndex = 0;
1750
1755
  while (currentIndex < objArr.length) {
1751
- batches.push(objArr.slice(currentIndex, currentIndex + OctreeCSG.async.batchSize));
1752
- currentIndex += OctreeCSG.async.batchSize;
1756
+ batches.push(objArr.slice(currentIndex, currentIndex + Polytree.async.batchSize));
1757
+ currentIndex += Polytree.async.batchSize;
1753
1758
  }
1754
1759
  batch = batches.shift();
1755
1760
  while (batch) {
1756
- promise = OctreeCSG.async.unionArray(batch, 0);
1761
+ promise = Polytree.async.unionArray(batch, 0);
1757
1762
  promises.push(promise);
1758
1763
  batch = batches.shift();
1759
1764
  }
1760
1765
  usingBatches = true;
1761
- mainOctreeUsed = true;
1766
+ mainPolytreeUsed = true;
1762
1767
  objArr.length = 0;
1763
1768
  } else {
1764
- octreesArray = [];
1769
+ polytreesArray = [];
1765
1770
  for (i = k = 0, ref = objArr.length; (0 <= ref ? k < ref : k > ref); i = 0 <= ref ? ++k : --k) {
1766
1771
  materialIndex = i > materialIndexMax ? materialIndexMax : i;
1767
- tempOctree = void 0;
1772
+ tempPolytree = void 0;
1768
1773
  if (objArr[i].isMesh) {
1769
- tempOctree = OctreeCSG.fromMesh(objArr[i], materialIndexMax > -1 ? materialIndex : void 0);
1774
+ tempPolytree = Polytree.fromMesh(objArr[i], materialIndexMax > -1 ? materialIndex : void 0);
1770
1775
  } else {
1771
- tempOctree = objArr[i];
1776
+ tempPolytree = objArr[i];
1772
1777
  if (materialIndexMax > -1) {
1773
- tempOctree.setPolygonIndex(materialIndex);
1778
+ tempPolytree.setPolygonIndex(materialIndex);
1774
1779
  }
1775
1780
  }
1776
- tempOctree.octreeIndex = i;
1777
- octreesArray.push(tempOctree);
1781
+ tempPolytree.polytreeIndex = i;
1782
+ polytreesArray.push(tempPolytree);
1778
1783
  }
1779
- mainOctree = octreesArray.shift();
1784
+ mainPolytree = polytreesArray.shift();
1780
1785
  result = void 0;
1781
1786
  hasLeftOver = false;
1782
- leftOverOctree = void 0;
1783
- for (i = l = 0, ref1 = octreesArray.length; l < ref1; i = l += 2) {
1784
- if (i + 1 >= octreesArray.length) {
1785
- leftOverOctree = octreesArray[i];
1787
+ leftOverPolytree = void 0;
1788
+ for (i = l = 0, ref1 = polytreesArray.length; l < ref1; i = l += 2) {
1789
+ if (i + 1 >= polytreesArray.length) {
1790
+ leftOverPolytree = polytreesArray[i];
1786
1791
  hasLeftOver = true;
1787
1792
  break;
1788
1793
  }
1789
- promise = OctreeCSG.async.union(octreesArray[i], octreesArray[i + 1]);
1794
+ promise = Polytree.async.union(polytreesArray[i], polytreesArray[i + 1]);
1790
1795
  promises.push(promise);
1791
1796
  }
1792
- if (leftOverOctree) {
1793
- promise = OctreeCSG.async.union(mainOctree, leftOverOctree);
1797
+ if (leftOverPolytree) {
1798
+ promise = Polytree.async.union(mainPolytree, leftOverPolytree);
1794
1799
  promises.push(promise);
1795
- mainOctreeUsed = true;
1800
+ mainPolytreeUsed = true;
1796
1801
  }
1797
1802
  }
1798
1803
  return Promise.allSettled(promises).then(function(results) {
1799
- var octrees;
1800
- octrees = [];
1804
+ var polytrees;
1805
+ polytrees = [];
1801
1806
  results.forEach(function(r) {
1802
1807
  if (r.status === "fulfilled") {
1803
- return octrees.push(r.value);
1808
+ return polytrees.push(r.value);
1804
1809
  }
1805
1810
  });
1806
- if (!mainOctreeUsed) {
1807
- octrees.unshift(mainOctree);
1811
+ if (!mainPolytreeUsed) {
1812
+ polytrees.unshift(mainPolytree);
1808
1813
  }
1809
- if (octrees.length > 0) {
1810
- if (octrees.length === 1) {
1811
- return resolve(octrees[0]);
1812
- } else if (octrees.length > 3) {
1813
- return OctreeCSG.async.unionArray(octrees, usingBatches ? 0 : -1).then(function(result) {
1814
+ if (polytrees.length > 0) {
1815
+ if (polytrees.length === 1) {
1816
+ return resolve(polytrees[0]);
1817
+ } else if (polytrees.length > 3) {
1818
+ return Polytree.async.unionArray(polytrees, usingBatches ? 0 : -1).then(function(result) {
1814
1819
  return resolve(result);
1815
1820
  }).catch(function(e) {
1816
1821
  return reject(e);
1817
1822
  });
1818
1823
  } else {
1819
- return OctreeCSG.async.union(octrees[0], octrees[1]).then(function(result) {
1820
- if (octrees.length === 3) {
1821
- return OctreeCSG.async.union(result, octrees[2]).then(function(result) {
1824
+ return Polytree.async.union(polytrees[0], polytrees[1]).then(function(result) {
1825
+ if (polytrees.length === 3) {
1826
+ return Polytree.async.union(result, polytrees[2]).then(function(result) {
1822
1827
  return resolve(result);
1823
1828
  }).catch(function(e) {
1824
1829
  return reject(e);
@@ -1831,7 +1836,7 @@ OctreeCSG.async = {
1831
1836
  });
1832
1837
  }
1833
1838
  } else {
1834
- return reject('Unable to find any result octree');
1839
+ return reject('Unable to find any result polytree');
1835
1840
  }
1836
1841
  });
1837
1842
  } catch (error) {
@@ -1842,87 +1847,87 @@ OctreeCSG.async = {
1842
1847
  },
1843
1848
  subtractArray: function(objArr, materialIndexMax = 2e308) {
1844
1849
  return new Promise(function(resolve, reject) {
1845
- var batch, batches, currentIndex, e, hasLeftOver, i, k, l, leftOverOctree, mainOctree, mainOctreeUsed, materialIndex, octreesArray, promise, promises, ref, ref1, result, tempOctree, usingBatches;
1850
+ var batch, batches, currentIndex, e, hasLeftOver, i, k, l, leftOverPolytree, mainPolytree, mainPolytreeUsed, materialIndex, polytreesArray, promise, promises, ref, ref1, result, tempPolytree, usingBatches;
1846
1851
  try {
1847
- usingBatches = OctreeCSG.async.batchSize > 4 && OctreeCSG.async.batchSize < objArr.length;
1848
- mainOctree = void 0;
1849
- mainOctreeUsed = false;
1852
+ usingBatches = Polytree.async.batchSize > 4 && Polytree.async.batchSize < objArr.length;
1853
+ mainPolytree = void 0;
1854
+ mainPolytreeUsed = false;
1850
1855
  promises = [];
1851
1856
  if (usingBatches) {
1852
1857
  batches = [];
1853
1858
  currentIndex = 0;
1854
1859
  while (currentIndex < objArr.length) {
1855
- batches.push(objArr.slice(currentIndex, currentIndex + OctreeCSG.async.batchSize));
1856
- currentIndex += OctreeCSG.async.batchSize;
1860
+ batches.push(objArr.slice(currentIndex, currentIndex + Polytree.async.batchSize));
1861
+ currentIndex += Polytree.async.batchSize;
1857
1862
  }
1858
1863
  batch = batches.shift();
1859
1864
  while (batch) {
1860
- promise = OctreeCSG.async.subtractArray(batch, 0);
1865
+ promise = Polytree.async.subtractArray(batch, 0);
1861
1866
  promises.push(promise);
1862
1867
  batch = batches.shift();
1863
1868
  }
1864
1869
  usingBatches = true;
1865
- mainOctreeUsed = true;
1870
+ mainPolytreeUsed = true;
1866
1871
  objArr.length = 0;
1867
1872
  } else {
1868
- octreesArray = [];
1873
+ polytreesArray = [];
1869
1874
  for (i = k = 0, ref = objArr.length; (0 <= ref ? k < ref : k > ref); i = 0 <= ref ? ++k : --k) {
1870
1875
  materialIndex = i > materialIndexMax ? materialIndexMax : i;
1871
- tempOctree = void 0;
1876
+ tempPolytree = void 0;
1872
1877
  if (objArr[i].isMesh) {
1873
- tempOctree = OctreeCSG.fromMesh(objArr[i], materialIndexMax > -1 ? materialIndex : void 0);
1878
+ tempPolytree = Polytree.fromMesh(objArr[i], materialIndexMax > -1 ? materialIndex : void 0);
1874
1879
  } else {
1875
- tempOctree = objArr[i];
1880
+ tempPolytree = objArr[i];
1876
1881
  if (materialIndexMax > -1) {
1877
- tempOctree.setPolygonIndex(materialIndex);
1882
+ tempPolytree.setPolygonIndex(materialIndex);
1878
1883
  }
1879
1884
  }
1880
- tempOctree.octreeIndex = i;
1881
- octreesArray.push(tempOctree);
1885
+ tempPolytree.polytreeIndex = i;
1886
+ polytreesArray.push(tempPolytree);
1882
1887
  }
1883
- mainOctree = octreesArray.shift();
1888
+ mainPolytree = polytreesArray.shift();
1884
1889
  result = void 0;
1885
1890
  hasLeftOver = false;
1886
- leftOverOctree = void 0;
1887
- for (i = l = 0, ref1 = octreesArray.length; l < ref1; i = l += 2) {
1888
- if (i + 1 >= octreesArray.length) {
1889
- leftOverOctree = octreesArray[i];
1891
+ leftOverPolytree = void 0;
1892
+ for (i = l = 0, ref1 = polytreesArray.length; l < ref1; i = l += 2) {
1893
+ if (i + 1 >= polytreesArray.length) {
1894
+ leftOverPolytree = polytreesArray[i];
1890
1895
  hasLeftOver = true;
1891
1896
  break;
1892
1897
  }
1893
- promise = OctreeCSG.async.subtract(octreesArray[i], octreesArray[i + 1]);
1898
+ promise = Polytree.async.subtract(polytreesArray[i], polytreesArray[i + 1]);
1894
1899
  promises.push(promise);
1895
1900
  }
1896
- if (leftOverOctree) {
1897
- promise = OctreeCSG.async.subtract(mainOctree, leftOverOctree);
1901
+ if (leftOverPolytree) {
1902
+ promise = Polytree.async.subtract(mainPolytree, leftOverPolytree);
1898
1903
  promises.push(promise);
1899
- mainOctreeUsed = true;
1904
+ mainPolytreeUsed = true;
1900
1905
  }
1901
1906
  }
1902
1907
  return Promise.allSettled(promises).then(function(results) {
1903
- var octrees;
1904
- octrees = [];
1908
+ var polytrees;
1909
+ polytrees = [];
1905
1910
  results.forEach(function(r) {
1906
1911
  if (r.status === "fulfilled") {
1907
- return octrees.push(r.value);
1912
+ return polytrees.push(r.value);
1908
1913
  }
1909
1914
  });
1910
- if (!mainOctreeUsed) {
1911
- octrees.unshift(mainOctree);
1915
+ if (!mainPolytreeUsed) {
1916
+ polytrees.unshift(mainPolytree);
1912
1917
  }
1913
- if (octrees.length > 0) {
1914
- if (octrees.length === 1) {
1915
- return resolve(octrees[0]);
1916
- } else if (octrees.length > 3) {
1917
- return OctreeCSG.async.subtractArray(octrees, usingBatches ? 0 : -1).then(function(result) {
1918
+ if (polytrees.length > 0) {
1919
+ if (polytrees.length === 1) {
1920
+ return resolve(polytrees[0]);
1921
+ } else if (polytrees.length > 3) {
1922
+ return Polytree.async.subtractArray(polytrees, usingBatches ? 0 : -1).then(function(result) {
1918
1923
  return resolve(result);
1919
1924
  }).catch(function(e) {
1920
1925
  return reject(e);
1921
1926
  });
1922
1927
  } else {
1923
- return OctreeCSG.async.subtract(octrees[0], octrees[1]).then(function(result) {
1924
- if (octrees.length === 3) {
1925
- return OctreeCSG.async.subtract(result, octrees[2]).then(function(result) {
1928
+ return Polytree.async.subtract(polytrees[0], polytrees[1]).then(function(result) {
1929
+ if (polytrees.length === 3) {
1930
+ return Polytree.async.subtract(result, polytrees[2]).then(function(result) {
1926
1931
  return resolve(result);
1927
1932
  }).catch(function(e) {
1928
1933
  return reject(e);
@@ -1935,7 +1940,7 @@ OctreeCSG.async = {
1935
1940
  });
1936
1941
  }
1937
1942
  } else {
1938
- return reject('Unable to find any result octree');
1943
+ return reject('Unable to find any result polytree');
1939
1944
  }
1940
1945
  });
1941
1946
  } catch (error) {
@@ -1946,87 +1951,87 @@ OctreeCSG.async = {
1946
1951
  },
1947
1952
  intersectArray: function(objArr, materialIndexMax = 2e308) {
1948
1953
  return new Promise(function(resolve, reject) {
1949
- var batch, batches, currentIndex, e, hasLeftOver, i, k, l, leftOverOctree, mainOctree, mainOctreeUsed, materialIndex, octreesArray, promise, promises, ref, ref1, result, tempOctree, usingBatches;
1954
+ var batch, batches, currentIndex, e, hasLeftOver, i, k, l, leftOverPolytree, mainPolytree, mainPolytreeUsed, materialIndex, polytreesArray, promise, promises, ref, ref1, result, tempPolytree, usingBatches;
1950
1955
  try {
1951
- usingBatches = OctreeCSG.async.batchSize > 4 && OctreeCSG.async.batchSize < objArr.length;
1952
- mainOctree = void 0;
1953
- mainOctreeUsed = false;
1956
+ usingBatches = Polytree.async.batchSize > 4 && Polytree.async.batchSize < objArr.length;
1957
+ mainPolytree = void 0;
1958
+ mainPolytreeUsed = false;
1954
1959
  promises = [];
1955
1960
  if (usingBatches) {
1956
1961
  batches = [];
1957
1962
  currentIndex = 0;
1958
1963
  while (currentIndex < objArr.length) {
1959
- batches.push(objArr.slice(currentIndex, currentIndex + OctreeCSG.async.batchSize));
1960
- currentIndex += OctreeCSG.async.batchSize;
1964
+ batches.push(objArr.slice(currentIndex, currentIndex + Polytree.async.batchSize));
1965
+ currentIndex += Polytree.async.batchSize;
1961
1966
  }
1962
1967
  batch = batches.shift();
1963
1968
  while (batch) {
1964
- promise = OctreeCSG.async.intersectArray(batch, 0);
1969
+ promise = Polytree.async.intersectArray(batch, 0);
1965
1970
  promises.push(promise);
1966
1971
  batch = batches.shift();
1967
1972
  }
1968
1973
  usingBatches = true;
1969
- mainOctreeUsed = true;
1974
+ mainPolytreeUsed = true;
1970
1975
  objArr.length = 0;
1971
1976
  } else {
1972
- octreesArray = [];
1977
+ polytreesArray = [];
1973
1978
  for (i = k = 0, ref = objArr.length; (0 <= ref ? k < ref : k > ref); i = 0 <= ref ? ++k : --k) {
1974
1979
  materialIndex = i > materialIndexMax ? materialIndexMax : i;
1975
- tempOctree = void 0;
1980
+ tempPolytree = void 0;
1976
1981
  if (objArr[i].isMesh) {
1977
- tempOctree = OctreeCSG.fromMesh(objArr[i], materialIndexMax > -1 ? materialIndex : void 0);
1982
+ tempPolytree = Polytree.fromMesh(objArr[i], materialIndexMax > -1 ? materialIndex : void 0);
1978
1983
  } else {
1979
- tempOctree = objArr[i];
1984
+ tempPolytree = objArr[i];
1980
1985
  if (materialIndexMax > -1) {
1981
- tempOctree.setPolygonIndex(materialIndex);
1986
+ tempPolytree.setPolygonIndex(materialIndex);
1982
1987
  }
1983
1988
  }
1984
- tempOctree.octreeIndex = i;
1985
- octreesArray.push(tempOctree);
1989
+ tempPolytree.polytreeIndex = i;
1990
+ polytreesArray.push(tempPolytree);
1986
1991
  }
1987
- mainOctree = octreesArray.shift();
1992
+ mainPolytree = polytreesArray.shift();
1988
1993
  result = void 0;
1989
1994
  hasLeftOver = false;
1990
- leftOverOctree = void 0;
1991
- for (i = l = 0, ref1 = octreesArray.length; l < ref1; i = l += 2) {
1992
- if (i + 1 >= octreesArray.length) {
1993
- leftOverOctree = octreesArray[i];
1995
+ leftOverPolytree = void 0;
1996
+ for (i = l = 0, ref1 = polytreesArray.length; l < ref1; i = l += 2) {
1997
+ if (i + 1 >= polytreesArray.length) {
1998
+ leftOverPolytree = polytreesArray[i];
1994
1999
  hasLeftOver = true;
1995
2000
  break;
1996
2001
  }
1997
- promise = OctreeCSG.async.intersect(octreesArray[i], octreesArray[i + 1]);
2002
+ promise = Polytree.async.intersect(polytreesArray[i], polytreesArray[i + 1]);
1998
2003
  promises.push(promise);
1999
2004
  }
2000
- if (leftOverOctree) {
2001
- promise = OctreeCSG.async.intersect(mainOctree, leftOverOctree);
2005
+ if (leftOverPolytree) {
2006
+ promise = Polytree.async.intersect(mainPolytree, leftOverPolytree);
2002
2007
  promises.push(promise);
2003
- mainOctreeUsed = true;
2008
+ mainPolytreeUsed = true;
2004
2009
  }
2005
2010
  }
2006
2011
  return Promise.allSettled(promises).then(function(results) {
2007
- var octrees;
2008
- octrees = [];
2012
+ var polytrees;
2013
+ polytrees = [];
2009
2014
  results.forEach(function(r) {
2010
2015
  if (r.status === "fulfilled") {
2011
- return octrees.push(r.value);
2016
+ return polytrees.push(r.value);
2012
2017
  }
2013
2018
  });
2014
- if (!mainOctreeUsed) {
2015
- octrees.unshift(mainOctree);
2019
+ if (!mainPolytreeUsed) {
2020
+ polytrees.unshift(mainPolytree);
2016
2021
  }
2017
- if (octrees.length > 0) {
2018
- if (octrees.length === 1) {
2019
- return resolve(octrees[0]);
2020
- } else if (octrees.length > 3) {
2021
- return OctreeCSG.async.intersectArray(octrees, usingBatches ? 0 : -1).then(function(result) {
2022
+ if (polytrees.length > 0) {
2023
+ if (polytrees.length === 1) {
2024
+ return resolve(polytrees[0]);
2025
+ } else if (polytrees.length > 3) {
2026
+ return Polytree.async.intersectArray(polytrees, usingBatches ? 0 : -1).then(function(result) {
2022
2027
  return resolve(result);
2023
2028
  }).catch(function(e) {
2024
2029
  return reject(e);
2025
2030
  });
2026
2031
  } else {
2027
- return OctreeCSG.async.intersect(octrees[0], octrees[1]).then(function(result) {
2028
- if (octrees.length === 3) {
2029
- return OctreeCSG.async.intersect(result, octrees[2]).then(function(result) {
2032
+ return Polytree.async.intersect(polytrees[0], polytrees[1]).then(function(result) {
2033
+ if (polytrees.length === 3) {
2034
+ return Polytree.async.intersect(result, polytrees[2]).then(function(result) {
2030
2035
  return resolve(result);
2031
2036
  }).catch(function(e) {
2032
2037
  return reject(e);
@@ -2039,7 +2044,7 @@ OctreeCSG.async = {
2039
2044
  });
2040
2045
  }
2041
2046
  } else {
2042
- return reject('Unable to find any result octree');
2047
+ return reject('Unable to find any result polytree');
2043
2048
  }
2044
2049
  });
2045
2050
  } catch (error) {
@@ -2048,78 +2053,78 @@ OctreeCSG.async = {
2048
2053
  }
2049
2054
  });
2050
2055
  },
2051
- operation: function(obj, returnOctrees = false, buildTargetOctree = true, options = {
2056
+ operation: function(obj, returnPolytrees = false, buildTargetPolytree = true, options = {
2052
2057
  objCounter: 0
2053
2058
  }, firstRun = true) {
2054
2059
  return new Promise(function(resolve, reject) {
2055
- var e, material, octreeA, octreeB, promise, promises, resultOctree;
2060
+ var e, material, polytreeA, polytreeB, promise, promises, resultPolytree;
2056
2061
  try {
2057
- octreeA = void 0;
2058
- octreeB = void 0;
2059
- resultOctree = void 0;
2062
+ polytreeA = void 0;
2063
+ polytreeB = void 0;
2064
+ resultPolytree = void 0;
2060
2065
  material = void 0;
2061
2066
  if (obj.material) {
2062
2067
  material = obj.material;
2063
2068
  }
2064
2069
  promises = [];
2065
2070
  if (obj.objA) {
2066
- promise = handleObjectForOp_async(obj.objA, returnOctrees, buildTargetOctree, options, 0);
2071
+ promise = handleObjectForOp_async(obj.objA, returnPolytrees, buildTargetPolytree, options, 0);
2067
2072
  promises.push(promise);
2068
2073
  }
2069
2074
  if (obj.objB) {
2070
- promise = handleObjectForOp_async(obj.objB, returnOctrees, buildTargetOctree, options, 1);
2075
+ promise = handleObjectForOp_async(obj.objB, returnPolytrees, buildTargetPolytree, options, 1);
2071
2076
  promises.push(promise);
2072
2077
  }
2073
2078
  return Promise.allSettled(promises).then(function(results) {
2074
- var octrees, resultPromise;
2075
- octrees = [];
2079
+ var polytrees, resultPromise;
2080
+ polytrees = [];
2076
2081
  results.forEach(function(r) {
2077
2082
  if (r.status === "fulfilled") {
2078
2083
  if (r.value.objIndex === 0) {
2079
- return octreeA = r.value;
2084
+ return polytreeA = r.value;
2080
2085
  } else if (r.value.objIndex === 1) {
2081
- return octreeB = r.value;
2086
+ return polytreeB = r.value;
2082
2087
  }
2083
2088
  }
2084
2089
  });
2085
- if (returnOctrees === true) {
2086
- obj.objA = octreeA.original;
2087
- octreeA = octreeA.result;
2088
- obj.objB = octreeB.original;
2089
- octreeB = octreeB.result;
2090
+ if (returnPolytrees === true) {
2091
+ obj.objA = polytreeA.original;
2092
+ polytreeA = polytreeA.result;
2093
+ obj.objB = polytreeB.original;
2094
+ polytreeB = polytreeB.result;
2090
2095
  }
2091
2096
  resultPromise = void 0;
2092
2097
  switch (obj.op) {
2093
2098
  case 'union':
2094
- resultPromise = OctreeCSG.async.union(octreeA, octreeB, buildTargetOctree);
2099
+ resultPromise = Polytree.async.union(polytreeA, polytreeB, buildTargetPolytree);
2095
2100
  break;
2096
2101
  case 'subtract':
2097
- resultPromise = OctreeCSG.async.subtract(octreeA, octreeB, buildTargetOctree);
2102
+ resultPromise = Polytree.async.subtract(polytreeA, polytreeB, buildTargetPolytree);
2098
2103
  break;
2099
2104
  case 'intersect':
2100
- resultPromise = OctreeCSG.async.intersect(octreeA, octreeB, buildTargetOctree);
2105
+ resultPromise = Polytree.async.intersect(polytreeA, polytreeB, buildTargetPolytree);
2101
2106
  }
2102
- return resultPromise.then(function(resultOctree) {
2107
+ return resultPromise.then(function(resultPolytree) {
2103
2108
  var mesh;
2104
2109
  if (firstRun && material) {
2105
- mesh = OctreeCSG.toMesh(resultOctree, material);
2106
- if (!returnOctrees) {
2107
- disposeOctree(resultOctree);
2110
+ mesh = Polytree.toMesh(resultPolytree, material);
2111
+ if (!returnPolytrees) {
2112
+ disposePolytree(resultPolytree);
2108
2113
  }
2109
- resolve(returnOctrees ? {
2114
+ resolve(returnPolytrees ? {
2110
2115
  result: mesh,
2111
2116
  operationTree: obj
2112
2117
  } : mesh);
2113
- } else if (firstRun && returnOctrees) {
2118
+ } else if (firstRun && returnPolytrees) {
2114
2119
  resolve({
2115
- result: resultOctree,
2120
+ result: resultPolytree,
2116
2121
  operationTree: obj
2117
2122
  });
2118
2123
  } else {
2119
- resolve(resultOctree);
2124
+ resolve(resultPolytree);
2120
2125
  }
2121
- if (!returnOctrees) {
2122
- return disposeOctree(octreeA, octreeB);
2126
+ if (!returnPolytrees) {
2127
+ return disposePolytree(polytreeA, polytreeB);
2123
2128
  }
2124
2129
  }).catch(function(e) {
2125
2130
  return reject(e);
@@ -2133,126 +2138,126 @@ OctreeCSG.async = {
2133
2138
  }
2134
2139
  };
2135
2140
 
2136
- OctreeCSG.unionArray = function(objArr, materialIndexMax = 2e308) {
2137
- var i, k, materialIndex, octreeA, octreeB, octreesArray, ref, resultOctree, tempOctree;
2138
- octreesArray = [];
2141
+ Polytree.unionArray = function(objArr, materialIndexMax = 2e308) {
2142
+ var i, k, materialIndex, polytreeA, polytreeB, polytreesArray, ref, resultPolytree, tempPolytree;
2143
+ polytreesArray = [];
2139
2144
  for (i = k = 0, ref = objArr.length; (0 <= ref ? k < ref : k > ref); i = 0 <= ref ? ++k : --k) {
2140
2145
  materialIndex = i > materialIndexMax ? materialIndexMax : i;
2141
- tempOctree = void 0;
2146
+ tempPolytree = void 0;
2142
2147
  if (objArr[i].isMesh) {
2143
- tempOctree = OctreeCSG.fromMesh(objArr[i], materialIndex);
2148
+ tempPolytree = Polytree.fromMesh(objArr[i], materialIndex);
2144
2149
  } else {
2145
- tempOctree = objArr[i];
2146
- tempOctree.setPolygonIndex(materialIndex);
2150
+ tempPolytree = objArr[i];
2151
+ tempPolytree.setPolygonIndex(materialIndex);
2147
2152
  }
2148
- tempOctree.octreeIndex = i;
2149
- octreesArray.push(tempOctree);
2153
+ tempPolytree.polytreeIndex = i;
2154
+ polytreesArray.push(tempPolytree);
2150
2155
  }
2151
- octreeA = octreesArray.shift();
2152
- octreeB = octreesArray.shift();
2153
- while (octreeA && octreeB) {
2154
- resultOctree = OctreeCSG.union(octreeA, octreeB);
2155
- disposeOctree(octreeA, octreeB);
2156
- octreeA = resultOctree;
2157
- octreeB = octreesArray.shift();
2156
+ polytreeA = polytreesArray.shift();
2157
+ polytreeB = polytreesArray.shift();
2158
+ while (polytreeA && polytreeB) {
2159
+ resultPolytree = Polytree.union(polytreeA, polytreeB);
2160
+ disposePolytree(polytreeA, polytreeB);
2161
+ polytreeA = resultPolytree;
2162
+ polytreeB = polytreesArray.shift();
2158
2163
  }
2159
- return octreeA;
2164
+ return polytreeA;
2160
2165
  };
2161
2166
 
2162
- OctreeCSG.subtractArray = function(objArr, materialIndexMax = 2e308) {
2163
- var i, k, materialIndex, octreeA, octreeB, octreesArray, ref, resultOctree, tempOctree;
2164
- octreesArray = [];
2167
+ Polytree.subtractArray = function(objArr, materialIndexMax = 2e308) {
2168
+ var i, k, materialIndex, polytreeA, polytreeB, polytreesArray, ref, resultPolytree, tempPolytree;
2169
+ polytreesArray = [];
2165
2170
  for (i = k = 0, ref = objArr.length; (0 <= ref ? k < ref : k > ref); i = 0 <= ref ? ++k : --k) {
2166
2171
  materialIndex = i > materialIndexMax ? materialIndexMax : i;
2167
- tempOctree = void 0;
2172
+ tempPolytree = void 0;
2168
2173
  if (objArr[i].isMesh) {
2169
- tempOctree = OctreeCSG.fromMesh(objArr[i], materialIndex);
2174
+ tempPolytree = Polytree.fromMesh(objArr[i], materialIndex);
2170
2175
  } else {
2171
- tempOctree = objArr[i];
2172
- tempOctree.setPolygonIndex(materialIndex);
2176
+ tempPolytree = objArr[i];
2177
+ tempPolytree.setPolygonIndex(materialIndex);
2173
2178
  }
2174
- tempOctree.octreeIndex = i;
2175
- octreesArray.push(tempOctree);
2179
+ tempPolytree.polytreeIndex = i;
2180
+ polytreesArray.push(tempPolytree);
2176
2181
  }
2177
- octreeA = octreesArray.shift();
2178
- octreeB = octreesArray.shift();
2179
- while (octreeA && octreeB) {
2180
- resultOctree = OctreeCSG.subtract(octreeA, octreeB);
2181
- disposeOctree(octreeA, octreeB);
2182
- octreeA = resultOctree;
2183
- octreeB = octreesArray.shift();
2182
+ polytreeA = polytreesArray.shift();
2183
+ polytreeB = polytreesArray.shift();
2184
+ while (polytreeA && polytreeB) {
2185
+ resultPolytree = Polytree.subtract(polytreeA, polytreeB);
2186
+ disposePolytree(polytreeA, polytreeB);
2187
+ polytreeA = resultPolytree;
2188
+ polytreeB = polytreesArray.shift();
2184
2189
  }
2185
- return octreeA;
2190
+ return polytreeA;
2186
2191
  };
2187
2192
 
2188
- OctreeCSG.intersectArray = function(objArr, materialIndexMax = 2e308) {
2189
- var i, k, materialIndex, octreeA, octreeB, octreesArray, ref, resultOctree, tempOctree;
2190
- octreesArray = [];
2193
+ Polytree.intersectArray = function(objArr, materialIndexMax = 2e308) {
2194
+ var i, k, materialIndex, polytreeA, polytreeB, polytreesArray, ref, resultPolytree, tempPolytree;
2195
+ polytreesArray = [];
2191
2196
  for (i = k = 0, ref = objArr.length; (0 <= ref ? k < ref : k > ref); i = 0 <= ref ? ++k : --k) {
2192
2197
  materialIndex = i > materialIndexMax ? materialIndexMax : i;
2193
- tempOctree = void 0;
2198
+ tempPolytree = void 0;
2194
2199
  if (objArr[i].isMesh) {
2195
- tempOctree = OctreeCSG.fromMesh(objArr[i], materialIndex);
2200
+ tempPolytree = Polytree.fromMesh(objArr[i], materialIndex);
2196
2201
  } else {
2197
- tempOctree = objArr[i];
2198
- tempOctree.setPolygonIndex(materialIndex);
2202
+ tempPolytree = objArr[i];
2203
+ tempPolytree.setPolygonIndex(materialIndex);
2199
2204
  }
2200
- tempOctree.octreeIndex = i;
2201
- octreesArray.push(tempOctree);
2205
+ tempPolytree.polytreeIndex = i;
2206
+ polytreesArray.push(tempPolytree);
2202
2207
  }
2203
- octreeA = octreesArray.shift();
2204
- octreeB = octreesArray.shift();
2205
- while (octreeA && octreeB) {
2206
- resultOctree = OctreeCSG.intersect(octreeA, octreeB);
2207
- disposeOctree(octreeA, octreeB);
2208
- octreeA = resultOctree;
2209
- octreeB = octreesArray.shift();
2208
+ polytreeA = polytreesArray.shift();
2209
+ polytreeB = polytreesArray.shift();
2210
+ while (polytreeA && polytreeB) {
2211
+ resultPolytree = Polytree.intersect(polytreeA, polytreeB);
2212
+ disposePolytree(polytreeA, polytreeB);
2213
+ polytreeA = resultPolytree;
2214
+ polytreeB = polytreesArray.shift();
2210
2215
  }
2211
- return octreeA;
2216
+ return polytreeA;
2212
2217
  };
2213
2218
 
2214
- OctreeCSG.operation = function(obj, returnOctrees = false, buildTargetOctree = true, options = {
2219
+ Polytree.operation = function(obj, returnPolytrees = false, buildTargetPolytree = true, options = {
2215
2220
  objCounter: 0
2216
2221
  }, firstRun = true) {
2217
- var material, mesh, octreeA, octreeB, resultOctree;
2218
- octreeA = void 0;
2219
- octreeB = void 0;
2220
- resultOctree = void 0;
2222
+ var material, mesh, polytreeA, polytreeB, resultPolytree;
2223
+ polytreeA = void 0;
2224
+ polytreeB = void 0;
2225
+ resultPolytree = void 0;
2221
2226
  material = void 0;
2222
2227
  if (obj.material) {
2223
2228
  material = obj.material;
2224
2229
  }
2225
2230
  if (obj.objA) {
2226
- octreeA = handleObjectForOp(obj.objA, returnOctrees, buildTargetOctree, options);
2227
- if (returnOctrees === true) {
2228
- obj.objA = octreeA.original;
2229
- octreeA = octreeA.result;
2231
+ polytreeA = handleObjectForOp(obj.objA, returnPolytrees, buildTargetPolytree, options);
2232
+ if (returnPolytrees === true) {
2233
+ obj.objA = polytreeA.original;
2234
+ polytreeA = polytreeA.result;
2230
2235
  }
2231
2236
  }
2232
2237
  if (obj.objB) {
2233
- octreeB = handleObjectForOp(obj.objB, returnOctrees, buildTargetOctree, options);
2234
- if (returnOctrees === true) {
2235
- obj.objB = octreeB.original;
2236
- octreeB = octreeB.result;
2238
+ polytreeB = handleObjectForOp(obj.objB, returnPolytrees, buildTargetPolytree, options);
2239
+ if (returnPolytrees === true) {
2240
+ obj.objB = polytreeB.original;
2241
+ polytreeB = polytreeB.result;
2237
2242
  }
2238
2243
  }
2239
2244
  switch (obj.op) {
2240
2245
  case 'union':
2241
- resultOctree = OctreeCSG.union(octreeA, octreeB, buildTargetOctree);
2246
+ resultPolytree = Polytree.union(polytreeA, polytreeB, buildTargetPolytree);
2242
2247
  break;
2243
2248
  case 'subtract':
2244
- resultOctree = OctreeCSG.subtract(octreeA, octreeB, buildTargetOctree);
2249
+ resultPolytree = Polytree.subtract(polytreeA, polytreeB, buildTargetPolytree);
2245
2250
  break;
2246
2251
  case 'intersect':
2247
- resultOctree = OctreeCSG.intersect(octreeA, octreeB, buildTargetOctree);
2252
+ resultPolytree = Polytree.intersect(polytreeA, polytreeB, buildTargetPolytree);
2248
2253
  }
2249
- if (!returnOctrees) {
2250
- disposeOctree(octreeA, octreeB);
2254
+ if (!returnPolytrees) {
2255
+ disposePolytree(polytreeA, polytreeB);
2251
2256
  }
2252
2257
  if (firstRun && material) {
2253
- mesh = OctreeCSG.toMesh(resultOctree, material);
2254
- disposeOctree(resultOctree);
2255
- if (returnOctrees) {
2258
+ mesh = Polytree.toMesh(resultPolytree, material);
2259
+ disposePolytree(resultPolytree);
2260
+ if (returnPolytrees) {
2256
2261
  return {
2257
2262
  result: mesh,
2258
2263
  operationTree: obj
@@ -2261,37 +2266,37 @@ OctreeCSG.operation = function(obj, returnOctrees = false, buildTargetOctree = t
2261
2266
  return mesh;
2262
2267
  }
2263
2268
  }
2264
- if (firstRun && returnOctrees) {
2269
+ if (firstRun && returnPolytrees) {
2265
2270
  return {
2266
- result: resultOctree,
2271
+ result: resultPolytree,
2267
2272
  operationTree: obj
2268
2273
  };
2269
2274
  }
2270
- return resultOctree;
2275
+ return resultPolytree;
2271
2276
  };
2272
2277
 
2273
- handleObjectForOp = function(obj, returnOctrees, buildTargetOctree, options) {
2278
+ handleObjectForOp = function(obj, returnPolytrees, buildTargetPolytree, options) {
2274
2279
  var returnObj;
2275
2280
  returnObj = void 0;
2276
2281
  if (obj.isMesh) {
2277
- returnObj = OctreeCSG.fromMesh(obj, options.objCounter++);
2278
- if (returnOctrees) {
2282
+ returnObj = Polytree.fromMesh(obj, options.objCounter++);
2283
+ if (returnPolytrees) {
2279
2284
  returnObj = {
2280
2285
  result: returnObj,
2281
2286
  original: returnObj.clone()
2282
2287
  };
2283
2288
  }
2284
- } else if (obj.isOctree) {
2289
+ } else if (obj.isPolytree) {
2285
2290
  returnObj = obj;
2286
- if (returnOctrees) {
2291
+ if (returnPolytrees) {
2287
2292
  returnObj = {
2288
2293
  result: obj,
2289
2294
  original: obj.clone()
2290
2295
  };
2291
2296
  }
2292
2297
  } else if (obj.op) {
2293
- returnObj = OctreeCSG.operation(obj, returnOctrees, buildTargetOctree, options, false);
2294
- if (returnOctrees) {
2298
+ returnObj = Polytree.operation(obj, returnPolytrees, buildTargetPolytree, options, false);
2299
+ if (returnPolytrees) {
2295
2300
  returnObj = {
2296
2301
  result: returnObj,
2297
2302
  original: obj
@@ -2301,14 +2306,14 @@ handleObjectForOp = function(obj, returnOctrees, buildTargetOctree, options) {
2301
2306
  return returnObj;
2302
2307
  };
2303
2308
 
2304
- handleObjectForOp_async = function(obj, returnOctrees, buildTargetOctree, options, objIndex) {
2309
+ handleObjectForOp_async = function(obj, returnPolytrees, buildTargetPolytree, options, objIndex) {
2305
2310
  return new Promise(function(resolve, reject) {
2306
2311
  var e, returnObj;
2307
2312
  try {
2308
2313
  returnObj = void 0;
2309
2314
  if (obj.isMesh) {
2310
- returnObj = OctreeCSG.fromMesh(obj, options.objCounter++);
2311
- if (returnOctrees) {
2315
+ returnObj = Polytree.fromMesh(obj, options.objCounter++);
2316
+ if (returnPolytrees) {
2312
2317
  returnObj = {
2313
2318
  result: returnObj,
2314
2319
  original: returnObj.clone()
@@ -2316,9 +2321,9 @@ handleObjectForOp_async = function(obj, returnOctrees, buildTargetOctree, option
2316
2321
  }
2317
2322
  returnObj.objIndex = objIndex;
2318
2323
  return resolve(returnObj);
2319
- } else if (obj.isOctree) {
2324
+ } else if (obj.isPolytree) {
2320
2325
  returnObj = obj;
2321
- if (returnOctrees) {
2326
+ if (returnPolytrees) {
2322
2327
  returnObj = {
2323
2328
  result: obj,
2324
2329
  original: obj.clone()
@@ -2327,8 +2332,8 @@ handleObjectForOp_async = function(obj, returnOctrees, buildTargetOctree, option
2327
2332
  returnObj.objIndex = objIndex;
2328
2333
  return resolve(returnObj);
2329
2334
  } else if (obj.op) {
2330
- return OctreeCSG.async.operation(obj, returnOctrees, buildTargetOctree, options, false).then(function(returnObj) {
2331
- if (returnOctrees) {
2335
+ return Polytree.async.operation(obj, returnPolytrees, buildTargetPolytree, options, false).then(function(returnObj) {
2336
+ if (returnPolytrees) {
2332
2337
  returnObj = {
2333
2338
  result: returnObj,
2334
2339
  original: obj
@@ -2388,9 +2393,9 @@ tmpm3 = new Matrix3();
2388
2393
 
2389
2394
  ttvv0 = new Vector3();
2390
2395
 
2391
- OctreeCSG.toGeometry = function(octree) {
2396
+ Polytree.toGeometry = function(polytree) {
2392
2397
  var colors, defaultGroup, geometry, groupBase, groups, i, index, k, l, len1, m, normals, polygon, polygons, positions, ref, ref1, triangleCount, uvs, vertices, verticesLen;
2393
- polygons = octree.getPolygons();
2398
+ polygons = polytree.getPolygons();
2394
2399
  triangleCount = polygons.length;
2395
2400
  // let validPolygons = [];
2396
2401
  // let trianglesSet = new Set();
@@ -2472,19 +2477,19 @@ OctreeCSG.toGeometry = function(octree) {
2472
2477
  return geometry;
2473
2478
  };
2474
2479
 
2475
- OctreeCSG.toMesh = function(octree, toMaterial) {
2480
+ Polytree.toMesh = function(polytree, toMaterial) {
2476
2481
  var geometry;
2477
- geometry = OctreeCSG.toGeometry(octree);
2482
+ geometry = Polytree.toGeometry(polytree);
2478
2483
  return new Mesh(geometry, toMaterial);
2479
2484
  };
2480
2485
 
2481
- OctreeCSG.fromMesh = function(obj, objectIndex, octree = new OctreeCSG(), buildTargetOctree = true) {
2482
- var color, colorattr, geometry, group, groups, i, index, j, k, l, len1, m, normal, normalattr, o, polygon, polys, pos, posattr, ref, ref1, uv, uvattr, vertices, vi, vp, vt;
2483
- if (obj.isOctree) {
2486
+ Polytree.fromMesh = function(obj, objectIndex, polytree = new Polytree(), buildTargetPolytree = true) {
2487
+ var color, colorattr, geometry, group, groups, i, index, j, k, l, len1, m, n, normal, normalattr, polygon, polys, pos, posattr, positionIndex, ref, ref1, uvCoords, uvIndex, uvattr, vertexIndex, vertices;
2488
+ if (obj.isPolytree) {
2484
2489
  return obj;
2485
2490
  }
2486
- if (OctreeCSG.rayIntersectTriangleType === "regular") {
2487
- octree.originalMatrixWorld = obj.matrixWorld.clone();
2491
+ if (Polytree.rayIntersectTriangleType === "regular") {
2492
+ polytree.originalMatrixWorld = obj.matrixWorld.clone();
2488
2493
  }
2489
2494
  obj.updateWorldMatrix(true, true);
2490
2495
  geometry = obj.geometry;
@@ -2501,23 +2506,23 @@ OctreeCSG.fromMesh = function(obj, objectIndex, octree = new OctreeCSG(), buildT
2501
2506
  for (i = k = 0, ref = index.length; k < ref; i = k += 3) {
2502
2507
  vertices = [];
2503
2508
  for (j = l = 0; l < 3; j = ++l) {
2504
- vi = index[i + j];
2505
- vp = vi * 3;
2506
- vt = vi * 2;
2507
- pos = new Vector3(posattr.array[vp], posattr.array[vp + 1], posattr.array[vp + 2]);
2508
- normal = new Vector3(normalattr.array[vp], normalattr.array[vp + 1], normalattr.array[vp + 2]);
2509
+ vertexIndex = index[i + j];
2510
+ positionIndex = vertexIndex * 3;
2511
+ uvIndex = vertexIndex * 2;
2512
+ pos = new Vector3(posattr.array[positionIndex], posattr.array[positionIndex + 1], posattr.array[positionIndex + 2]);
2513
+ normal = new Vector3(normalattr.array[positionIndex], normalattr.array[positionIndex + 1], normalattr.array[positionIndex + 2]);
2509
2514
  pos.applyMatrix4(obj.matrix);
2510
2515
  normal.applyMatrix3(tmpm3);
2511
- uv = uvattr ? {
2512
- x: uvattr.array[vt],
2513
- y: uvattr.array[vt + 1]
2516
+ uvCoords = uvattr ? {
2517
+ x: uvattr.array[uvIndex],
2518
+ y: uvattr.array[uvIndex + 1]
2514
2519
  } : void 0;
2515
2520
  color = colorattr ? {
2516
- x: colorattr.array[vt],
2517
- y: colorattr.array[vt + 1],
2518
- z: colorattr.array[vt + 2]
2521
+ x: colorattr.array[uvIndex],
2522
+ y: colorattr.array[uvIndex + 1],
2523
+ z: colorattr.array[uvIndex + 2]
2519
2524
  } : void 0;
2520
- vertices.push(new Vertex(pos, normal, uv, color));
2525
+ vertices.push(new Vertex(pos, normal, uvCoords, color));
2521
2526
  }
2522
2527
  if ((objectIndex === void 0) && groups && groups.length > 0) {
2523
2528
  polygon = void 0;
@@ -2537,18 +2542,18 @@ OctreeCSG.fromMesh = function(obj, objectIndex, octree = new OctreeCSG(), buildT
2537
2542
  polys.push(polygon);
2538
2543
  }
2539
2544
  }
2540
- for (i = o = 0, ref1 = polys.length; (0 <= ref1 ? o < ref1 : o > ref1); i = 0 <= ref1 ? ++o : --o) {
2545
+ for (i = n = 0, ref1 = polys.length; (0 <= ref1 ? n < ref1 : n > ref1); i = 0 <= ref1 ? ++n : --n) {
2541
2546
  if (isValidTriangle(polys[i].triangle)) {
2542
- octree.addPolygon(polys[i]);
2547
+ polytree.addPolygon(polys[i]);
2543
2548
  } else {
2544
2549
  polys[i].delete();
2545
2550
  }
2546
2551
  }
2547
- buildTargetOctree && octree.buildTree();
2548
- if (OctreeCSG.useOctreeRay !== true) {
2549
- octree.mesh = obj;
2552
+ buildTargetPolytree && polytree.buildTree();
2553
+ if (Polytree.usePolytreeRay !== true) {
2554
+ polytree.mesh = obj;
2550
2555
  }
2551
- return octree;
2556
+ return polytree;
2552
2557
  };
2553
2558
 
2554
2559
  isValidTriangle = function(triangle) {
@@ -2622,9 +2627,9 @@ Plane = class Plane {
2622
2627
  };
2623
2628
 
2624
2629
  Plane.fromPoints = function(a, b, c) {
2625
- var n;
2626
- n = tv0.copy(b).sub(a).cross(tv1.copy(c).sub(a)).normalize().clone();
2627
- return new Plane(n, n.dot(a));
2630
+ var planeNormal;
2631
+ planeNormal = triangleVertex0.copy(b).sub(a).cross(triangleVertex1.copy(c).sub(a)).normalize().clone();
2632
+ return new Plane(planeNormal, planeNormal.dot(a));
2628
2633
  };
2629
2634
 
2630
2635
  // class Polygon
@@ -2758,10 +2763,10 @@ Polygon = class Polygon {
2758
2763
 
2759
2764
  };
2760
2765
 
2761
- disposeOctree = function(...octrees) {
2762
- if (OctreeCSG.disposeOctree) {
2763
- return octrees.forEach(function(octree) {
2764
- return octree.delete();
2766
+ disposePolytree = function(...polytrees) {
2767
+ if (Polytree.disposePolytree) {
2768
+ return polytrees.forEach(function(polytree) {
2769
+ return polytree.delete();
2765
2770
  });
2766
2771
  }
2767
2772
  };
@@ -2832,23 +2837,23 @@ polyInside_WindingNumber_buffer = function(trianglesArr, point, coplanar) {
2832
2837
  };
2833
2838
 
2834
2839
  // -----
2835
- handleIntersectingOctrees = function(octreeA, octreeB, bothOctrees = true) {
2836
- var octreeA_buffer, octreeB_buffer;
2837
- octreeA_buffer = void 0;
2838
- octreeB_buffer = void 0;
2839
- if (OctreeCSG.useWindingNumber === true) {
2840
- if (bothOctrees) {
2841
- octreeA_buffer = prepareTriangleBuffer(octreeA.getPolygons());
2840
+ handleIntersectingPolytrees = function(polytreeA, polytreeB, bothPolytrees = true) {
2841
+ var polytreeA_buffer, polytreeB_buffer;
2842
+ polytreeA_buffer = void 0;
2843
+ polytreeB_buffer = void 0;
2844
+ if (Polytree.useWindingNumber === true) {
2845
+ if (bothPolytrees) {
2846
+ polytreeA_buffer = prepareTriangleBuffer(polytreeA.getPolygons());
2842
2847
  }
2843
- octreeB_buffer = prepareTriangleBuffer(octreeB.getPolygons());
2848
+ polytreeB_buffer = prepareTriangleBuffer(polytreeB.getPolygons());
2844
2849
  }
2845
- octreeA.handleIntersectingPolygons(octreeB, octreeB_buffer);
2846
- if (bothOctrees) {
2847
- octreeB.handleIntersectingPolygons(octreeA, octreeA_buffer);
2850
+ polytreeA.handleIntersectingPolygons(polytreeB, polytreeB_buffer);
2851
+ if (bothPolytrees) {
2852
+ polytreeB.handleIntersectingPolygons(polytreeA, polytreeA_buffer);
2848
2853
  }
2849
- if (octreeA_buffer !== void 0) {
2850
- octreeA_buffer = void 0;
2851
- return octreeB_buffer = void 0;
2854
+ if (polytreeA_buffer !== void 0) {
2855
+ polytreeA_buffer = void 0;
2856
+ return polytreeB_buffer = void 0;
2852
2857
  }
2853
2858
  };
2854
2859
 
@@ -2912,28 +2917,17 @@ rayIntersectsTriangle = function(ray, triangle, target = new Vector3()) {
2912
2917
  return null;
2913
2918
  };
2914
2919
 
2915
- OctreeCSG.rayIntersectsTriangle = rayIntersectsTriangle;
2916
-
2917
- OctreeCSG.useOctreeRay = true;
2920
+ Polytree.rayIntersectsTriangle = rayIntersectsTriangle;
2918
2921
 
2919
- OctreeCSG.useWindingNumber = false;
2922
+ Polytree.usePolytreeRay = true;
2920
2923
 
2921
- OctreeCSG.rayIntersectTriangleType = "MollerTrumbore"; // "regular" (three.js' ray.intersectTriangle; "MollerTrumbore" (Moller Trumbore algorithm);
2924
+ Polytree.useWindingNumber = false;
2922
2925
 
2923
- OctreeCSG.maxLevel = 16;
2926
+ Polytree.rayIntersectTriangleType = "MollerTrumbore"; // "regular" (three.js' ray.intersectTriangle; "MollerTrumbore" (Moller Trumbore algorithm);
2924
2927
 
2925
- OctreeCSG.polygonsPerTree = 100;
2928
+ Polytree.maxLevel = 16;
2926
2929
 
2927
- // OctreeCSG.Octree = Octree
2928
- module.exports = {
2929
- default: OctreeCSG,
2930
- CSG: OctreeCSG,
2931
- OctreeCSG: OctreeCSG,
2932
- Polygon: Polygon,
2933
- Plane: Plane,
2934
- Vertex: Vertex,
2935
- rayIntersectsTriangle: rayIntersectsTriangle
2936
- };
2930
+ Polytree.polygonsPerTree = 100;
2937
2931
  // Generated by CoffeeScript 2.7.0
2938
2932
 
2939
2933
  /* Determines the intersection segment (if any) between two triangles in 3D space.
@@ -3324,6 +3318,7 @@ resolveCoplanarTriangleIntersection = function(vertex1TriangleA, vertex2Triangle
3324
3318
  };
3325
3319
 
3326
3320
  trianglesOverlap2D = function(vertex1TriangleA, vertex2TriangleA, vertex3TriangleA, vertex1TriangleB, vertex2TriangleB, vertex3TriangleB) {
3321
+ var aE, aMax, aMin, aS, bE, bMax, bMin, bS, extractSegment, isLineDegenerate, maxAx, maxAy, maxBx, maxBy, minAx, minAy, minBx, minBy, spanAx, spanAy;
3327
3322
  // Early handle point-degenerate cases explicitly and efficiently.
3328
3323
  if (pointsEqual2D(vertex1TriangleB, vertex2TriangleB, EPS2D) && pointsEqual2D(vertex2TriangleB, vertex3TriangleB, EPS2D)) {
3329
3324
  return pointInTriangleInclusive2D(vertex1TriangleB, vertex1TriangleA, vertex2TriangleA, vertex3TriangleA, EPS2D);
@@ -3331,6 +3326,60 @@ trianglesOverlap2D = function(vertex1TriangleA, vertex2TriangleA, vertex3Triangl
3331
3326
  if (pointsEqual2D(vertex1TriangleA, vertex2TriangleA, EPS2D) && pointsEqual2D(vertex2TriangleA, vertex3TriangleA, EPS2D)) {
3332
3327
  return pointInTriangleInclusive2D(vertex1TriangleA, vertex1TriangleB, vertex2TriangleB, vertex3TriangleB, EPS2D);
3333
3328
  }
3329
+ // If both are line-degenerate (not points): reduce to segment overlap test.
3330
+ isLineDegenerate = function(v1, v2, v3) {
3331
+ return (pointsEqual2D(v1, v2, EPS2D) && !pointsEqual2D(v2, v3, EPS2D)) || (pointsEqual2D(v2, v3, EPS2D) && !pointsEqual2D(v1, v2, EPS2D)) || (pointsEqual2D(v3, v1, EPS2D) && !pointsEqual2D(v1, v2, EPS2D));
3332
+ };
3333
+ extractSegment = function(v1, v2, v3) {
3334
+ // Return the two distinct endpoints in stable order.
3335
+ if (pointsEqual2D(v1, v2, EPS2D)) {
3336
+ return [v2, v3];
3337
+ } else if (pointsEqual2D(v2, v3, EPS2D)) {
3338
+ return [v1, v2];
3339
+ } else {
3340
+ return [
3341
+ v1,
3342
+ v2 // fallback (should not reach if collinear case handled earlier)
3343
+ ];
3344
+ }
3345
+ };
3346
+ if (isLineDegenerate(vertex1TriangleA, vertex2TriangleA, vertex3TriangleA) && isLineDegenerate(vertex1TriangleB, vertex2TriangleB, vertex3TriangleB)) {
3347
+ [aS, aE] = extractSegment(vertex1TriangleA, vertex2TriangleA, vertex3TriangleA);
3348
+ [bS, bE] = extractSegment(vertex1TriangleB, vertex2TriangleB, vertex3TriangleB);
3349
+ // Fast reject by axis-aligned bounding boxes.
3350
+ minAx = Math.min(aS.x, aE.x);
3351
+ maxAx = Math.max(aS.x, aE.x);
3352
+ minAy = Math.min(aS.y, aE.y);
3353
+ maxAy = Math.max(aS.y, aE.y);
3354
+ minBx = Math.min(bS.x, bE.x);
3355
+ maxBx = Math.max(bS.x, bE.x);
3356
+ minBy = Math.min(bS.y, bE.y);
3357
+ maxBy = Math.max(bS.y, bE.y);
3358
+ if (maxAx < minBx - EPS2D || maxBx < minAx - EPS2D || maxAy < minBy - EPS2D || maxBy < minAy - EPS2D) {
3359
+ return false;
3360
+ }
3361
+ // Collinear check: orientation of any mixed triple should be ~0; since we know each triangle is a line, test one.
3362
+ if (Math.abs(triangleOrientation2D(aS, aE, bS)) > EPS2D) {
3363
+ return false;
3364
+ }
3365
+ // 1D overlap test along dominant axis (choose axis with larger span to reduce precision issues).
3366
+ spanAx = Math.abs(aE.x - aS.x);
3367
+ spanAy = Math.abs(aE.y - aS.y);
3368
+ if (spanAx >= spanAy) {
3369
+ // Project onto X.
3370
+ aMin = Math.min(aS.x, aE.x) - EPS2D;
3371
+ aMax = Math.max(aS.x, aE.x) + EPS2D;
3372
+ bMin = Math.min(bS.x, bE.x) - EPS2D;
3373
+ bMax = Math.max(bS.x, bE.x) + EPS2D;
3374
+ return !(aMax < bMin || bMax < aMin);
3375
+ } else {
3376
+ aMin = Math.min(aS.y, aE.y) - EPS2D;
3377
+ aMax = Math.max(aS.y, aE.y) + EPS2D;
3378
+ bMin = Math.min(bS.y, bE.y) - EPS2D;
3379
+ bMax = Math.max(bS.y, bE.y) + EPS2D;
3380
+ return !(aMax < bMin || bMax < aMin);
3381
+ }
3382
+ }
3334
3383
  if (triangleOrientation2D(vertex1TriangleA, vertex2TriangleA, vertex3TriangleA) < 0) { // If triangle A is CW.
3335
3384
  if (triangleOrientation2D(vertex1TriangleB, vertex2TriangleB, vertex3TriangleB) < 0) { // If both A and B are CW → reorder both.
3336
3385
  return triangleIntersectionCCW2D(vertex1TriangleA, vertex3TriangleA, vertex2TriangleA, vertex1TriangleB, vertex3TriangleB, vertex2TriangleB); // Only A is CW → reorder A.
@@ -3389,132 +3438,79 @@ triangleIntersectionCCW2D = function(vertex1TriangleA, vertex2TriangleA, vertex3
3389
3438
  };
3390
3439
 
3391
3440
  intersectionTestEdge2D = function(vertex1TriangleA, vertex2TriangleA, vertex3TriangleA, vertex1TriangleB, vertex2TriangleB, vertex3TriangleB) {
3392
- // If vertex3TriangleB is on or to the left of edge vertex1TriangleB-vertex2TriangleA.
3393
- if (triangleOrientation2D(vertex3TriangleB, vertex1TriangleB, vertex2TriangleA) >= 0) {
3394
- // If vertex1TriangleA is on or to the left of edge vertex1TriangleB-vertex2TriangleA.
3395
- if (triangleOrientation2D(vertex1TriangleA, vertex1TriangleB, vertex2TriangleA) >= 0) {
3396
- // If vertex1TriangleA is on or to the left of edge vertex2TriangleA-vertex3TriangleB.
3397
- if (triangleOrientation2D(vertex1TriangleA, vertex2TriangleA, vertex3TriangleB) >= 0) {
3398
- return true; // Then vertex1TriangleA is outside edge vertex2TriangleA-vertex3TriangleB.
3399
- } else {
3400
- return false; // Then vertex1TriangleA is outside edge vertex1TriangleB-vertex2TriangleA.
3401
- }
3402
- } else {
3403
-
3404
- // If vertex2TriangleA is on or to the left of edge vertex3TriangleA-vertex1TriangleB.
3405
- if (triangleOrientation2D(vertex2TriangleA, vertex3TriangleA, vertex1TriangleB) >= 0) {
3406
- // If vertex3TriangleA is on or to the left of edge vertex1TriangleA-vertex1TriangleB.
3407
- if (triangleOrientation2D(vertex3TriangleA, vertex1TriangleA, vertex1TriangleB) >= 0) {
3408
- return true; // Then vertex3TriangleA is outside edge vertex1TriangleA-vertex1TriangleB.
3409
- } else {
3410
- return false; // Then vertex2TriangleA is outside edge vertex3TriangleA-vertex1TriangleB.
3411
- }
3412
- } else {
3413
- return false; // Then vertex3TriangleB is outside edge vertex1TriangleB-vertex2TriangleA.
3414
- }
3441
+ var a1, a2, b1, b2, edgesA, edgesB, i, j, len, len1, segmentIntersectsInclusive;
3442
+ segmentIntersectsInclusive = function(a1, a2, b1, b2) {
3443
+ var maxAx, maxAy, maxBx, maxBy, minAx, minAy, minBx, minBy, o1, o2, o3, o4;
3444
+ // Fast reject by bounding boxes.
3445
+ minAx = Math.min(a1.x, a2.x);
3446
+ maxAx = Math.max(a1.x, a2.x);
3447
+ minAy = Math.min(a1.y, a2.y);
3448
+ maxAy = Math.max(a1.y, a2.y);
3449
+ minBx = Math.min(b1.x, b2.x);
3450
+ maxBx = Math.max(b1.x, b2.x);
3451
+ minBy = Math.min(b1.y, b2.y);
3452
+ maxBy = Math.max(b1.y, b2.y);
3453
+ if (maxAx < minBx || maxBx < minAx || maxAy < minBy || maxBy < minAy) {
3454
+ return false;
3455
+ }
3456
+ o1 = triangleOrientation2D(a1, a2, b1);
3457
+ o2 = triangleOrientation2D(a1, a2, b2);
3458
+ o3 = triangleOrientation2D(b1, b2, a1);
3459
+ o4 = triangleOrientation2D(b1, b2, a2);
3460
+ if ((o1 > 0 && o2 < 0 || o1 < 0 && o2 > 0) && (o3 > 0 && o4 < 0 || o3 < 0 && o4 > 0)) {
3461
+ return true; // Proper intersection.
3415
3462
  }
3416
- } else {
3417
3463
 
3418
- // If vertex3TriangleB is on or to the left of edge vertex1TriangleB-vertex3TriangleA.
3419
- if (triangleOrientation2D(vertex3TriangleB, vertex1TriangleB, vertex3TriangleA) >= 0) {
3420
- // If vertex1TriangleA is on or to the left of edge vertex1TriangleB-vertex3TriangleA.
3421
- if (triangleOrientation2D(vertex1TriangleA, vertex1TriangleB, vertex3TriangleA) >= 0) {
3422
- // If vertex1TriangleA is on or to the left of edge vertex3TriangleA-vertex3TriangleB.
3423
- if (triangleOrientation2D(vertex1TriangleA, vertex3TriangleA, vertex3TriangleB) >= 0) {
3424
- return true;
3425
- } else {
3426
- // Then vertex2TriangleA is on or to the left of edge vertex3TriangleA-vertex3TriangleB.
3427
- if (triangleOrientation2D(vertex2TriangleA, vertex3TriangleA, vertex3TriangleB) >= 0) {
3428
- return true; // Then vertex2TriangleA is outside edge vertex3TriangleA-vertex3TriangleB.
3429
- } else {
3430
- return false; // Then vertex1TriangleA is outside edge vertex1TriangleB-vertex3TriangleA.
3431
- }
3432
- }
3433
- } else {
3434
- return false; // Then vertex3TriangleB is outside edge vertex1TriangleB-vertex3TriangleA.
3464
+ // Collinear / endpoint inclusion checks.
3465
+ if (Math.abs(o1) <= EPS2D && pointOnSegmentInclusive2D(b1, a1, a2, EPS2D)) {
3466
+ return true;
3467
+ }
3468
+ if (Math.abs(o2) <= EPS2D && pointOnSegmentInclusive2D(b2, a1, a2, EPS2D)) {
3469
+ return true;
3470
+ }
3471
+ if (Math.abs(o3) <= EPS2D && pointOnSegmentInclusive2D(a1, b1, b2, EPS2D)) {
3472
+ return true;
3473
+ }
3474
+ if (Math.abs(o4) <= EPS2D && pointOnSegmentInclusive2D(a2, b1, b2, EPS2D)) {
3475
+ return true;
3476
+ }
3477
+ return false;
3478
+ };
3479
+ edgesA = [[vertex1TriangleA, vertex2TriangleA], [vertex2TriangleA, vertex3TriangleA], [vertex3TriangleA, vertex1TriangleA]];
3480
+ edgesB = [[vertex1TriangleB, vertex2TriangleB], [vertex2TriangleB, vertex3TriangleB], [vertex3TriangleB, vertex1TriangleB]];
3481
+ for (i = 0, len = edgesA.length; i < len; i++) {
3482
+ [a1, a2] = edgesA[i];
3483
+ for (j = 0, len1 = edgesB.length; j < len1; j++) {
3484
+ [b1, b2] = edgesB[j];
3485
+ if (segmentIntersectsInclusive(a1, a2, b1, b2)) {
3486
+ return true;
3435
3487
  }
3436
- } else {
3437
- return false;
3438
3488
  }
3439
3489
  }
3490
+ return false;
3440
3491
  };
3441
3492
 
3442
3493
  intersectionTestVertex2D = function(vertex1TriangleA, vertex2TriangleA, vertex3TriangleA, vertex1TriangleB, vertex2TriangleB, vertex3TriangleB) {
3443
- // If vertex3TriangleB is on or to the left of edge vertex1TriangleB-vertex2TriangleA.
3444
- if (triangleOrientation2D(vertex3TriangleB, vertex1TriangleB, vertex2TriangleA) >= 0) {
3445
- // If vertex3TriangleB is on or to the right of edge vertex2TriangleB-vertex2TriangleA.
3446
- if (triangleOrientation2D(vertex3TriangleB, vertex2TriangleB, vertex2TriangleA) <= 0) {
3447
- // If vertex1TriangleA is on the right of edge vertex1TriangleB-vertex2TriangleA.
3448
- if (triangleOrientation2D(vertex1TriangleA, vertex1TriangleB, vertex2TriangleA) > 0) {
3449
- // If vertex1TriangleA is on or to the left of edge vertex2TriangleB-vertex2TriangleA.
3450
- if (triangleOrientation2D(vertex1TriangleA, vertex2TriangleB, vertex2TriangleA) <= 0) {
3451
- return true; // Then vertex1TriangleA is outside edge vertex2TriangleB-vertex2TriangleA.
3452
- } else {
3453
- return false; // Then vertex1TriangleA is on or to the left of edge vertex1TriangleB-vertex2TriangleA.
3454
- }
3455
- } else {
3456
-
3457
- // If vertex1TriangleA is on or to the left of edge vertex1TriangleB-vertex3TriangleA.
3458
- if (triangleOrientation2D(vertex1TriangleA, vertex1TriangleB, vertex3TriangleA) >= 0) {
3459
- // If vertex2TriangleA is on or to the left of edge vertex3TriangleA-vertex1TriangleB.
3460
- if (triangleOrientation2D(vertex2TriangleA, vertex3TriangleA, vertex1TriangleB) >= 0) {
3461
- return true; // Then vertex2TriangleA is outside edge vertex3TriangleA-vertex1TriangleB.
3462
- } else {
3463
- return false; // Then vertex1TriangleA is outside edge vertex1TriangleB-vertex3TriangleA.
3464
- }
3465
- } else {
3466
- return false; // Then vertex3TriangleB is on the left of edge vertex2TriangleB-vertex2TriangleA.
3467
- }
3468
- }
3469
- } else {
3470
-
3471
- // If vertex1TriangleA is on or to the left of edge vertex2TriangleB-vertex2TriangleA.
3472
- if (triangleOrientation2D(vertex1TriangleA, vertex2TriangleB, vertex2TriangleA) <= 0) {
3473
- // If vertex3TriangleB is on or to the left of edge vertex2TriangleB-vertex3TriangleA.
3474
- if (triangleOrientation2D(vertex3TriangleB, vertex2TriangleB, vertex3TriangleA) <= 0) {
3475
- // If vertex2TriangleA is on or to the left of edge vertex3TriangleA-vertex2TriangleB.
3476
- if (triangleOrientation2D(vertex2TriangleA, vertex3TriangleA, vertex2TriangleB) >= 0) {
3477
- return true; // Then vertex2TriangleA is outside edge vertex3TriangleA-vertex2TriangleB.
3478
- } else {
3479
- return false; // Then vertex3TriangleB is outside edge vertex2TriangleB-vertex3TriangleA.
3480
- }
3481
- } else {
3482
- return false; // Then vertex1TriangleA is outside edge vertex2TriangleB-vertex2TriangleA.
3483
- }
3484
- } else {
3485
- return false; // Then vertex3TriangleB is outside edge vertex1TriangleB-vertex2TriangleA.
3486
- }
3487
- }
3488
- } else {
3489
-
3490
- // If vertex3TriangleB is on or to the left of edge vertex1TriangleB-vertex3TriangleA.
3491
- if (triangleOrientation2D(vertex3TriangleB, vertex1TriangleB, vertex3TriangleA) >= 0) {
3492
- // If vertex2TriangleA is on or to the left of edge vertex3TriangleA-vertex3TriangleB.
3493
- if (triangleOrientation2D(vertex2TriangleA, vertex3TriangleA, vertex3TriangleB) >= 0) {
3494
- // If vertex1TriangleA is on or to the left of edge vertex1TriangleB-vertex3TriangleA.
3495
- if (triangleOrientation2D(vertex1TriangleA, vertex1TriangleB, vertex3TriangleA) >= 0) {
3496
- return true; // Then vertex1TriangleA is outside edge vertex1TriangleB-vertex3TriangleA.
3497
- } else {
3498
- return false; // Then vertex2TriangleA is outside edge vertex3TriangleA-vertex3TriangleB.
3499
- }
3500
- } else {
3501
-
3502
- // If vertex2TriangleA is on or to the left of edge vertex3TriangleA-vertex2TriangleB.
3503
- if (triangleOrientation2D(vertex2TriangleA, vertex3TriangleA, vertex2TriangleB) >= 0) {
3504
- // If vertex3TriangleB is on or to the left of edge vertex3TriangleA-vertex2TriangleB.
3505
- if (triangleOrientation2D(vertex3TriangleB, vertex3TriangleA, vertex2TriangleB) >= 0) {
3506
- return true; // Then vertex3TriangleB is outside edge vertex3TriangleA-vertex2TriangleB.
3507
- } else {
3508
- return false; // Then vertex2TriangleA is outside edge vertex3TriangleA-vertex2TriangleB.
3509
- }
3510
- } else {
3511
- return false; // Then vertex3TriangleB is outside edge vertex1TriangleB-vertex3TriangleA.
3512
- }
3513
- }
3514
- } else {
3515
- return false;
3516
- }
3494
+ if (pointInTriangleInclusive2D(vertex1TriangleB, vertex1TriangleA, vertex2TriangleA, vertex3TriangleA, EPS2D)) {
3495
+ // Returns true if any vertex of triangle B lies inside (or on) triangle A OR any vertex of triangle A lies inside (or on) triangle B.
3496
+ return true;
3497
+ }
3498
+ if (pointInTriangleInclusive2D(vertex2TriangleB, vertex1TriangleA, vertex2TriangleA, vertex3TriangleA, EPS2D)) {
3499
+ return true;
3500
+ }
3501
+ if (pointInTriangleInclusive2D(vertex3TriangleB, vertex1TriangleA, vertex2TriangleA, vertex3TriangleA, EPS2D)) {
3502
+ return true;
3503
+ }
3504
+ if (pointInTriangleInclusive2D(vertex1TriangleA, vertex1TriangleB, vertex2TriangleB, vertex3TriangleB, EPS2D)) {
3505
+ return true;
3506
+ }
3507
+ if (pointInTriangleInclusive2D(vertex2TriangleA, vertex1TriangleB, vertex2TriangleB, vertex3TriangleB, EPS2D)) {
3508
+ return true;
3509
+ }
3510
+ if (pointInTriangleInclusive2D(vertex3TriangleA, vertex1TriangleB, vertex2TriangleB, vertex3TriangleB, EPS2D)) {
3511
+ return true;
3517
3512
  }
3513
+ return false;
3518
3514
  };
3519
3515
 
3520
3516
  constructIntersection = function(vertex1TriangleA, vertex2TriangleA, vertex3TriangleA, vertex1TriangleB, vertex2TriangleB, vertex3TriangleB, additions) {
@@ -3539,11 +3535,17 @@ constructIntersection = function(vertex1TriangleA, vertex2TriangleA, vertex3Tria
3539
3535
  tempVector1.subVectors(vertex1TriangleA, vertex1TriangleB);
3540
3536
  tempVector2.subVectors(vertex1TriangleA, vertex3TriangleA);
3541
3537
  alpha = tempVector1.dot(additions.normal2) / tempVector2.dot(additions.normal2);
3538
+ if (!isFinite(alpha)) {
3539
+ return false;
3540
+ }
3542
3541
  tempVector1.copy(tempVector2).multiplyScalar(alpha);
3543
3542
  additions.source.subVectors(vertex1TriangleA, tempVector1);
3544
3543
  tempVector1.subVectors(vertex1TriangleB, vertex1TriangleA);
3545
3544
  tempVector2.subVectors(vertex1TriangleB, vertex3TriangleB);
3546
3545
  alpha = tempVector1.dot(additions.normal1) / tempVector2.dot(additions.normal1);
3546
+ if (!isFinite(alpha)) {
3547
+ return false;
3548
+ }
3547
3549
  tempVector1.copy(tempVector2).multiplyScalar(alpha);
3548
3550
  additions.target.subVectors(vertex1TriangleB, tempVector1);
3549
3551
  return true;
@@ -3552,11 +3554,17 @@ constructIntersection = function(vertex1TriangleA, vertex2TriangleA, vertex3Tria
3552
3554
  tempVector1.subVectors(vertex1TriangleB, vertex1TriangleA);
3553
3555
  tempVector2.subVectors(vertex1TriangleB, vertex2TriangleB);
3554
3556
  alpha = tempVector1.dot(additions.normal1) / tempVector2.dot(additions.normal1);
3557
+ if (!isFinite(alpha)) {
3558
+ return false;
3559
+ }
3555
3560
  tempVector1.copy(tempVector2).multiplyScalar(alpha);
3556
3561
  additions.source.subVectors(vertex1TriangleB, tempVector1);
3557
3562
  tempVector1.subVectors(vertex1TriangleB, vertex1TriangleA);
3558
3563
  tempVector2.subVectors(vertex1TriangleB, vertex3TriangleB);
3559
3564
  alpha = tempVector1.dot(additions.normal1) / tempVector2.dot(additions.normal1);
3565
+ if (!isFinite(alpha)) {
3566
+ return false;
3567
+ }
3560
3568
  tempVector1.copy(tempVector2).multiplyScalar(alpha);
3561
3569
  additions.target.subVectors(vertex1TriangleB, tempVector1);
3562
3570
  return true;
@@ -3577,11 +3585,17 @@ constructIntersection = function(vertex1TriangleA, vertex2TriangleA, vertex3Tria
3577
3585
  tempVector1.subVectors(vertex1TriangleB, vertex1TriangleA);
3578
3586
  tempVector2.subVectors(vertex1TriangleB, vertex2TriangleB);
3579
3587
  alpha = tempVector1.dot(additions.normal1) / tempVector2.dot(additions.normal1);
3588
+ if (!isFinite(alpha)) {
3589
+ return false;
3590
+ }
3580
3591
  tempVector1.copy(tempVector2).multiplyScalar(alpha);
3581
3592
  additions.source.subVectors(vertex1TriangleB, tempVector1);
3582
3593
  tempVector1.subVectors(vertex1TriangleB, vertex1TriangleA);
3583
3594
  tempVector2.subVectors(vertex1TriangleB, vertex3TriangleB);
3584
3595
  alpha = tempVector1.dot(additions.normal1) / tempVector2.dot(additions.normal1);
3596
+ if (!isFinite(alpha)) {
3597
+ return false;
3598
+ }
3585
3599
  tempVector1.copy(tempVector2).multiplyScalar(alpha);
3586
3600
  additions.target.subVectors(vertex1TriangleB, tempVector1);
3587
3601
  return true;
@@ -3590,11 +3604,17 @@ constructIntersection = function(vertex1TriangleA, vertex2TriangleA, vertex3Tria
3590
3604
  tempVector1.subVectors(vertex1TriangleA, vertex1TriangleB);
3591
3605
  tempVector2.subVectors(vertex1TriangleA, vertex3TriangleA);
3592
3606
  alpha = tempVector1.dot(additions.normal2) / tempVector2.dot(additions.normal2);
3607
+ if (!isFinite(alpha)) {
3608
+ return false;
3609
+ }
3593
3610
  tempVector1.copy(tempVector2).multiplyScalar(alpha);
3594
3611
  additions.source.subVectors(vertex1TriangleA, tempVector1);
3595
3612
  tempVector1.subVectors(vertex1TriangleA, vertex1TriangleB);
3596
3613
  tempVector2.subVectors(vertex1TriangleA, vertex2TriangleA);
3597
3614
  alpha = tempVector1.dot(additions.normal2) / tempVector2.dot(additions.normal2);
3615
+ if (!isFinite(alpha)) {
3616
+ return false;
3617
+ }
3598
3618
  tempVector1.copy(tempVector2).multiplyScalar(alpha);
3599
3619
  additions.target.subVectors(vertex1TriangleA, tempVector1);
3600
3620
  return true;
@@ -3603,5 +3623,31 @@ constructIntersection = function(vertex1TriangleA, vertex2TriangleA, vertex3Tria
3603
3623
  }
3604
3624
  return false; // If none of the above, no intersection found.
3605
3625
  };
3626
+ // Generated by CoffeeScript 2.7.0
3627
+ module.exports.Polytree = Polytree;
3628
+
3629
+ module.exports.Plane = Plane;
3630
+
3631
+ module.exports.Vertex = Vertex;
3632
+
3633
+ module.exports.Polygon = Polygon;
3634
+
3635
+ module.exports.rayIntersectsTriangle = rayIntersectsTriangle;
3636
+
3637
+ module.exports.triangleIntersectsTriangle = triangleIntersectsTriangle;
3638
+
3639
+ module.exports.resolveTriangleIntersection = resolveTriangleIntersection;
3640
+
3641
+ module.exports.resolveCoplanarTriangleIntersection = resolveCoplanarTriangleIntersection;
3642
+
3643
+ module.exports.trianglesOverlap2D = trianglesOverlap2D;
3644
+
3645
+ module.exports.triangleOrientation2D = triangleOrientation2D;
3646
+
3647
+ module.exports.triangleIntersectionCCW2D = triangleIntersectionCCW2D;
3648
+
3649
+ module.exports.intersectionTestEdge2D = intersectionTestEdge2D;
3650
+
3651
+ module.exports.intersectionTestVertex2D = intersectionTestVertex2D;
3606
3652
 
3607
- module.exports = {triangleIntersectsTriangle, resolveTriangleIntersection, resolveCoplanarTriangleIntersection, trianglesOverlap2D, triangleOrientation2D, triangleIntersectionCCW2D, intersectionTestEdge2D, intersectionTestVertex2D, constructIntersection};
3653
+ module.exports.constructIntersection = constructIntersection;