@xeokit/xeokit-sdk 2.6.62 → 2.6.64

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.
@@ -52174,7 +52174,7 @@ class VBORenderer {
52174
52174
  }
52175
52175
 
52176
52176
  if (this._instancing) {
52177
- if (this._edges) {
52177
+ if (this._edges && state.edgeIndicesBuf) {
52178
52178
  state.edgeIndicesBuf.bind();
52179
52179
  } else {
52180
52180
  if (state.indicesBuf) {
@@ -52182,7 +52182,7 @@ class VBORenderer {
52182
52182
  }
52183
52183
  }
52184
52184
  } else {
52185
- if (this._edges) {
52185
+ if (this._edges && state.edgeIndicesBuf) {
52186
52186
  state.edgeIndicesBuf.bind();
52187
52187
  } else {
52188
52188
  if (state.indicesBuf) {
@@ -52449,7 +52449,9 @@ class TrianglesBatchingRenderer extends VBORenderer {
52449
52449
  } = drawCfg;
52450
52450
 
52451
52451
  if (this._edges) {
52452
- gl.drawElements(gl.LINES, state.edgeIndicesBuf.numItems, state.edgeIndicesBuf.itemType, 0);
52452
+ if (state.edgeIndicesBuf) {
52453
+ gl.drawElements(gl.LINES, state.edgeIndicesBuf.numItems, state.edgeIndicesBuf.itemType, 0);
52454
+ }
52453
52455
  } else {
52454
52456
  const count = frameCtx.pickElementsCount || state.indicesBuf.numItems;
52455
52457
  const offset = frameCtx.pickElementsOffset ? frameCtx.pickElementsOffset * state.indicesBuf.itemByteSize : 0;
@@ -55614,9 +55616,11 @@ class TrianglesSnapRenderer$1 extends VBORenderer{
55614
55616
  //=============================================================
55615
55617
 
55616
55618
  if (frameCtx.snapMode === "edge") {
55617
- state.edgeIndicesBuf.bind();
55618
- gl.drawElements(gl.LINES, state.edgeIndicesBuf.numItems, state.edgeIndicesBuf.itemType, 0);
55619
- state.edgeIndicesBuf.unbind(); // needed?
55619
+ if (state.edgeIndicesBuf) {
55620
+ state.edgeIndicesBuf.bind();
55621
+ gl.drawElements(gl.LINES, state.edgeIndicesBuf.numItems, state.edgeIndicesBuf.itemType, 0);
55622
+ state.edgeIndicesBuf.unbind(); // needed?
55623
+ }
55620
55624
  } else {
55621
55625
  gl.drawArrays(gl.POINTS, 0, state.positionsBuf.numItems);
55622
55626
  }
@@ -57785,7 +57789,9 @@ class TrianglesInstancingRenderer extends VBORenderer {
57785
57789
  } = drawCfg;
57786
57790
 
57787
57791
  if (this._edges) {
57788
- gl.drawElementsInstanced(gl.LINES, state.edgeIndicesBuf.numItems, state.edgeIndicesBuf.itemType, 0, state.numInstances);
57792
+ if (state.edgeIndicesBuf) {
57793
+ gl.drawElementsInstanced(gl.LINES, state.edgeIndicesBuf.numItems, state.edgeIndicesBuf.itemType, 0, state.numInstances);
57794
+ }
57789
57795
  } else {
57790
57796
  gl.drawElementsInstanced(gl.TRIANGLES, state.indicesBuf.numItems, state.indicesBuf.itemType, 0, state.numInstances);
57791
57797
 
@@ -61077,10 +61083,12 @@ class TrianglesSnapRenderer extends VBORenderer {
61077
61083
  this._aFlags.bindArrayBuffer(state.flagsBuf);
61078
61084
  gl.vertexAttribDivisor(this._aFlags.location, 1);
61079
61085
 
61080
- if (frameCtx.snapMode === "edge") {
61081
- state.edgeIndicesBuf.bind();
61082
- gl.drawElementsInstanced(gl.LINES, state.edgeIndicesBuf.numItems, state.edgeIndicesBuf.itemType, 0, state.numInstances);
61083
- state.edgeIndicesBuf.unbind(); // needed?
61086
+ if (frameCtx.snapMode === "edge" ) {
61087
+ if (state.edgeIndicesBuf) {
61088
+ state.edgeIndicesBuf.bind();
61089
+ gl.drawElementsInstanced(gl.LINES, state.edgeIndicesBuf.numItems, state.edgeIndicesBuf.itemType, 0, state.numInstances);
61090
+ state.edgeIndicesBuf.unbind(); // needed?
61091
+ }
61084
61092
  } else {
61085
61093
  gl.drawArraysInstanced(gl.POINTS, 0, state.positionsBuf.numItems, state.numInstances);
61086
61094
  }
@@ -97127,6 +97135,14 @@ class MousePanRotateDollyHandler {
97127
97135
  keyDown[keyCode] = false;
97128
97136
  });
97129
97137
 
97138
+ document.addEventListener("visibilitychange", this._onVisibilityChange = () => {
97139
+ keyDown.splice(0);
97140
+ });
97141
+
97142
+ window.addEventListener("blur", this._onBlur = () => {
97143
+ keyDown.splice(0);
97144
+ });
97145
+
97130
97146
  function setMousedownState(pick = true) {
97131
97147
  setMousedownPositions();
97132
97148
  if (pick) {
@@ -97392,6 +97408,8 @@ class MousePanRotateDollyHandler {
97392
97408
 
97393
97409
  document.removeEventListener("keydown", this._documentKeyDownHandler);
97394
97410
  document.removeEventListener("keyup", this._documentKeyUpHandler);
97411
+ document.removeEventListener("visibilitychange", this._onVisibilityChange);
97412
+ window.removeEventListener("blur", this._onBlur);
97395
97413
  canvas.removeEventListener("mousedown", this._mouseDownHandler);
97396
97414
  document.removeEventListener("mousemove", this._documentMouseMoveHandler);
97397
97415
  canvas.removeEventListener("mousemove", this._canvasMouseMoveHandler);
@@ -97947,6 +97965,14 @@ class KeyboardPanRotateDollyHandler {
97947
97965
  }
97948
97966
  });
97949
97967
 
97968
+ document.addEventListener("visibilitychange", this._onVisibilityChange = () => {
97969
+ keyDownMap.splice(0);
97970
+ });
97971
+
97972
+ window.addEventListener("blur", this._onBlur = () => {
97973
+ keyDownMap.splice(0);
97974
+ });
97975
+
97950
97976
  this._onTick = scene.on("tick", (e) => {
97951
97977
 
97952
97978
  if (!(configs.active && configs.pointerEnabled) || (!scene.input.keyboardEnabled)) {
@@ -98076,6 +98102,8 @@ class KeyboardPanRotateDollyHandler {
98076
98102
 
98077
98103
  this._scene.input.off(this._onSceneMouseMove);
98078
98104
  this._scene.input.off(this._onSceneKeyDown);
98105
+ document.removeEventListener("visibilitychange", this._onVisibilityChange);
98106
+ window.removeEventListener("blur", this._onBlur);
98079
98107
  this._scene.input.off(this._onSceneKeyUp);
98080
98108
  }
98081
98109
  }
@@ -120724,322 +120752,317 @@ class Control {
120724
120752
  */
120725
120753
  this.id = null;
120726
120754
 
120727
- this._viewer = plugin.viewer;
120755
+ const viewer = plugin.viewer;
120756
+ const camera = viewer.camera;
120757
+ const cameraControl = viewer.cameraControl;
120758
+ const scene = viewer.scene;
120759
+ const canvas = scene.canvas.canvas;
120728
120760
 
120729
120761
  this._visible = false;
120730
- this._pos = math.vec3(); // Full-precision position of the center of the Control
120731
- this._origin = math.vec3();
120732
- this._rtcPos = math.vec3();
120733
120762
 
120734
- this._baseDir = math.vec3(); // Saves direction of clip plane when we start dragging an arrow or ring.
120735
- this._rootNode = null; // Root of Node graph that represents this control in the 3D scene
120736
- this._displayMeshes = null; // Meshes that are always visible
120737
- this._affordanceMeshes = null; // Meshes displayed momentarily for affordance
120763
+ let ignoreNextSectionPlaneDirUpdate = false;
120738
120764
 
120739
- this._ignoreNextSectionPlaneDirUpdate = false;
120765
+ // Builds the Entities that represent this Control.
120766
+ const NO_STATE_INHERIT = false;
120767
+ const arrowLength = 1.0;
120768
+ const handleRadius = 0.09;
120769
+ const tubeRadius = 0.01;
120740
120770
 
120741
- this._createNodes();
120742
- this._bindEvents();
120743
- }
120771
+ const rootNode = new Node$2(scene, { // Root of Node graph that represents this control in the 3D scene
120772
+ position: [0, 0, 0],
120773
+ scale: [5, 5, 5],
120774
+ isObject: false
120775
+ });
120744
120776
 
120745
- /**
120746
- * Called by SectionPlanesPlugin to assign this Control to a SectionPlane.
120747
- * SectionPlanesPlugin keeps SectionPlaneControls in a reuse pool.
120748
- * Call with a null or undefined value to disconnect the Control ffrom whatever SectionPlane it was assigned to.
120749
- * @private
120750
- */
120751
- _setSectionPlane(sectionPlane) {
120752
- if (this._sectionPlane) {
120753
- this._sectionPlane.off(this._onSectionPlanePos);
120754
- this._sectionPlane.off(this._onSectionPlaneDir);
120755
- this._onSectionPlanePos = null;
120756
- this._onSectionPlaneDir = null;
120757
- this._sectionPlane = null;
120758
- }
120759
- if (sectionPlane) {
120760
- this.id = sectionPlane.id;
120761
- this._setPos(sectionPlane.pos);
120762
- this._setDir(sectionPlane.dir);
120763
- this._sectionPlane = sectionPlane;
120764
- this._onSectionPlanePos = sectionPlane.on("pos", () => {
120765
- this._setPos(this._sectionPlane.pos);
120766
- });
120767
- this._onSectionPlaneDir = sectionPlane.on("dir", () => {
120768
- if (!this._ignoreNextSectionPlaneDirUpdate) {
120769
- this._setDir(this._sectionPlane.dir);
120770
- } else {
120771
- this._ignoreNextSectionPlaneDirUpdate = false;
120772
- }
120773
- });
120774
- }
120775
- }
120777
+ const pos = math.vec3();
120778
+ const setPos = (function() {
120779
+ const origin = math.vec3();
120780
+ const rtcPos = math.vec3();
120781
+ return function(p) {
120782
+ pos.set(p);
120783
+ worldToRTCPos(p, origin, rtcPos);
120784
+ rootNode.origin = origin;
120785
+ rootNode.position = rtcPos;
120786
+ };
120787
+ })();
120776
120788
 
120777
- /**
120778
- * Gets the {@link SectionPlane} controlled by this Control.
120779
- * @returns {SectionPlane} The SectionPlane.
120780
- */
120781
- get sectionPlane() {
120782
- return this._sectionPlane;
120783
- }
120789
+ const arrowGeometry = (radiusBottom, height) => new ReadableGeometry(rootNode, buildCylinderGeometry({
120790
+ radiusTop: 0.001,
120791
+ radiusBottom: radiusBottom,
120792
+ radialSegments: 32,
120793
+ heightSegments: 1,
120794
+ height: height,
120795
+ openEnded: false
120796
+ }));
120784
120797
 
120785
- /** @private */
120786
- _setPos(xyz) {
120798
+ const tubeGeometry = (radius, height, radialSegments) => new ReadableGeometry(rootNode, buildCylinderGeometry({
120799
+ radiusTop: radius,
120800
+ radiusBottom: radius,
120801
+ radialSegments: radialSegments,
120802
+ heightSegments: 1,
120803
+ height: height,
120804
+ openEnded: false
120805
+ }));
120787
120806
 
120788
- this._pos.set(xyz);
120807
+ const torusGeometry = (tube, arcFraction, tubeSegments) => new ReadableGeometry(rootNode, buildTorusGeometry({
120808
+ radius: arrowLength - 0.2,
120809
+ tube: tube,
120810
+ radialSegments: 64,
120811
+ tubeSegments: tubeSegments,
120812
+ arc: (Math.PI * 2.0) * arcFraction
120813
+ }));
120789
120814
 
120790
- worldToRTCPos(this._pos, this._origin, this._rtcPos);
120815
+ const shapes = {// Reusable geometries
120791
120816
 
120792
- this._rootNode.origin = this._origin;
120793
- this._rootNode.position = this._rtcPos;
120794
- }
120817
+ curve: torusGeometry(tubeRadius, 0.25, 14),
120818
+ curveHandle: torusGeometry(handleRadius, 0.25, 14),
120819
+ hoop: torusGeometry(tubeRadius, 1, 8),
120795
120820
 
120796
- /** @private */
120797
- _setDir(xyz) {
120798
- this._baseDir.set(xyz);
120799
- this._rootNode.quaternion = math.vec3PairToQuaternion(zeroVec$1, xyz, quat$1);
120800
- }
120821
+ arrowHead: arrowGeometry(0.07, 0.2),
120822
+ arrowHeadBig: arrowGeometry(0.09, 0.25),
120823
+ arrowHeadHandle: tubeGeometry(handleRadius, 0.37, 8),
120801
120824
 
120802
- _setSectionPlaneDir(dir) {
120803
- if (this._sectionPlane) {
120804
- this._ignoreNextSectionPlaneDirUpdate = true;
120805
- this._sectionPlane.dir = dir;
120806
- }
120807
- }
120825
+ axis: tubeGeometry(tubeRadius, arrowLength, 20),
120826
+ axisHandle: tubeGeometry(handleRadius, arrowLength, 20)
120827
+ };
120808
120828
 
120809
- /**
120810
- * Sets if this Control is visible.
120811
- *
120812
- * @type {Boolean}
120813
- */
120814
- setVisible(visible = true) {
120815
- if (this._visible === visible) {
120816
- return;
120817
- }
120818
- this._visible = visible;
120819
- var id;
120820
- for (id in this._displayMeshes) {
120821
- if (this._displayMeshes.hasOwnProperty(id)) {
120822
- this._displayMeshes[id].visible = visible;
120823
- }
120824
- }
120825
- if (!visible) {
120826
- for (id in this._affordanceMeshes) {
120827
- if (this._affordanceMeshes.hasOwnProperty(id)) {
120828
- this._affordanceMeshes[id].visible = visible;
120829
- }
120830
- }
120831
- }
120832
- }
120829
+ const colorMaterial = (rgb) => new PhongMaterial(rootNode, {
120830
+ diffuse: rgb,
120831
+ emissive: rgb,
120832
+ ambient: [0.0, 0.0, 0.0],
120833
+ specular: [.6, .6, .3],
120834
+ shininess: 80,
120835
+ lineWidth: 2
120836
+ });
120833
120837
 
120834
- /**
120835
- * Gets if this Control is visible.
120836
- *
120837
- * @type {Boolean}
120838
- */
120839
- getVisible() {
120840
- return this._visible;
120841
- }
120838
+ const highlightMaterial = (rgb, fillAlpha) => new EmphasisMaterial(rootNode, {
120839
+ edges: false,
120840
+ fill: true,
120841
+ fillColor: rgb,
120842
+ fillAlpha: fillAlpha
120843
+ });
120842
120844
 
120843
- /**
120844
- * Sets if this Control is culled. This is called by SectionPlanesPlugin to
120845
- * temporarily hide the Control while a snapshot is being taken by Viewer#getSnapshot().
120846
- * @param culled
120847
- */
120848
- setCulled(culled) {
120849
- var id;
120850
- for (id in this._displayMeshes) {
120851
- if (this._displayMeshes.hasOwnProperty(id)) {
120852
- this._displayMeshes[id].culled = culled;
120853
- }
120854
- }
120855
- if (!culled) {
120856
- for (id in this._affordanceMeshes) {
120857
- if (this._affordanceMeshes.hasOwnProperty(id)) {
120858
- this._affordanceMeshes[id].culled = culled;
120859
- }
120860
- }
120861
- }
120862
- }
120845
+ const pickableMaterial = new PhongMaterial(rootNode, { // Invisible material for pickable handles, which define a pickable 3D area
120846
+ diffuse: [1, 1, 0],
120847
+ alpha: 0, // Invisible
120848
+ alphaMode: "blend"
120849
+ });
120863
120850
 
120864
- /**
120865
- * Builds the Entities that represent this Control.
120866
- * @private
120867
- */
120868
- _createNodes() {
120851
+ const handlers = { };
120852
+ const addAxis = (rgb, axisDirection, hoopDirection) => {
120853
+ const material = colorMaterial(rgb);
120869
120854
 
120870
- const NO_STATE_INHERIT = false;
120871
- const scene = this._viewer.scene;
120872
- const radius = 1.0;
120873
- const handleTubeRadius = 0.06;
120874
- const hoopRadius = radius - 0.2;
120875
- const tubeRadius = 0.01;
120876
- const arrowRadius = 0.07;
120855
+ const rotateToHorizontal = math.rotationMat4v(270 * math.DEGTORAD, [1, 0, 0], math.identityMat4());
120856
+ const hoopRotation = math.quaternionToRotationMat4(math.vec3PairToQuaternion([ 0, 1, 0 ], hoopDirection), math.identityMat4());
120857
+ const hoopMatrix = math.mulMat4(hoopRotation, rotateToHorizontal, math.identityMat4());
120877
120858
 
120878
- this._rootNode = new Node$2(scene, {
120879
- position: [0, 0, 0],
120880
- scale: [5, 5, 5],
120881
- isObject: false
120882
- });
120859
+ const scale = math.scaleMat4v([0.6, 0.6, 0.6], math.identityMat4());
120883
120860
 
120884
- const rootNode = this._rootNode;
120861
+ const scaledArrowMatrix = (t, matR) => {
120862
+ const matT = math.translateMat4v(t, math.identityMat4());
120863
+ const ret = math.identityMat4();
120864
+ math.mulMat4(matT, matR, ret);
120865
+ math.mulMat4(hoopMatrix, ret, ret);
120866
+ return math.mulMat4(ret, scale, math.identityMat4());
120867
+ };
120885
120868
 
120886
- const shapes = {// Reusable geometries
120869
+ const curve = rootNode.addChild(new Mesh(rootNode, {
120870
+ geometry: shapes.curve,
120871
+ material: material,
120872
+ matrix: hoopMatrix,
120873
+ pickable: false,
120874
+ collidable: true,
120875
+ clippable: false,
120876
+ backfaces: true,
120877
+ visible: false,
120878
+ isObject: false
120879
+ }), NO_STATE_INHERIT);
120887
120880
 
120888
- arrowHead: new ReadableGeometry(rootNode, buildCylinderGeometry({
120889
- radiusTop: 0.001,
120890
- radiusBottom: arrowRadius,
120891
- radialSegments: 32,
120892
- heightSegments: 1,
120893
- height: 0.2,
120894
- openEnded: false
120895
- })),
120881
+ const rotateHandle = rootNode.addChild(new Mesh(rootNode, {
120882
+ geometry: shapes.curveHandle,
120883
+ material: pickableMaterial,
120884
+ matrix: hoopMatrix,
120885
+ pickable: true,
120886
+ collidable: true,
120887
+ clippable: false,
120888
+ backfaces: true,
120889
+ visible: false,
120890
+ isObject: false
120891
+ }), NO_STATE_INHERIT);
120896
120892
 
120897
- arrowHeadBig: new ReadableGeometry(rootNode, buildCylinderGeometry({
120898
- radiusTop: 0.001,
120899
- radiusBottom: 0.09,
120900
- radialSegments: 32,
120901
- heightSegments: 1,
120902
- height: 0.25,
120903
- openEnded: false
120904
- })),
120893
+ const arrow1 = rootNode.addChild(new Mesh(rootNode, {
120894
+ geometry: shapes.arrowHead,
120895
+ material: material,
120896
+ matrix: scaledArrowMatrix([ .8, .07, 0 ], math.rotationMat4v(180 * math.DEGTORAD, [0, 0, 1], math.identityMat4())),
120897
+ pickable: true,
120898
+ collidable: true,
120899
+ clippable: false,
120900
+ visible: false,
120901
+ isObject: false
120902
+ }), NO_STATE_INHERIT);
120905
120903
 
120906
- arrowHeadHandle: new ReadableGeometry(rootNode, buildCylinderGeometry({
120907
- radiusTop: 0.09,
120908
- radiusBottom: 0.09,
120909
- radialSegments: 8,
120910
- heightSegments: 1,
120911
- height: 0.37,
120912
- openEnded: false
120913
- })),
120904
+ const arrow2 = rootNode.addChild(new Mesh(rootNode, {
120905
+ geometry: shapes.arrowHead,
120906
+ material: material,
120907
+ matrix: scaledArrowMatrix([ .07, .8, 0 ], math.rotationMat4v(90 * math.DEGTORAD, [0, 0, 1], math.identityMat4())),
120908
+ pickable: true,
120909
+ collidable: true,
120910
+ clippable: false,
120911
+ visible: false,
120912
+ isObject: false
120913
+ }), NO_STATE_INHERIT);
120914
120914
 
120915
- curve: new ReadableGeometry(rootNode, buildTorusGeometry({
120916
- radius: hoopRadius,
120917
- tube: tubeRadius,
120918
- radialSegments: 64,
120919
- tubeSegments: 14,
120920
- arc: (Math.PI * 2.0) / 4.0
120921
- })),
120915
+ const hoop = rootNode.addChild(new Mesh(rootNode, {
120916
+ geometry: shapes.hoop,
120917
+ material: material,
120918
+ highlighted: true,
120919
+ highlightMaterial: highlightMaterial(rgb, 0.6),
120920
+ matrix: hoopMatrix,
120921
+ pickable: false,
120922
+ collidable: true,
120923
+ clippable: false,
120924
+ visible: false,
120925
+ isObject: false
120926
+ }), NO_STATE_INHERIT);
120922
120927
 
120923
- curveHandle: new ReadableGeometry(rootNode, buildTorusGeometry({
120924
- radius: hoopRadius,
120925
- tube: handleTubeRadius,
120926
- radialSegments: 64,
120927
- tubeSegments: 14,
120928
- arc: (Math.PI * 2.0) / 4.0
120929
- })),
120930
120928
 
120931
- hoop: new ReadableGeometry(rootNode, buildTorusGeometry({
120932
- radius: hoopRadius,
120933
- tube: tubeRadius,
120934
- radialSegments: 64,
120935
- tubeSegments: 8,
120936
- arc: (Math.PI * 2.0)
120937
- })),
120929
+ const axisRotation = math.quaternionToRotationMat4(math.vec3PairToQuaternion([ 0, 1, 0 ], axisDirection), math.identityMat4());
120938
120930
 
120939
- axis: new ReadableGeometry(rootNode, buildCylinderGeometry({
120940
- radiusTop: tubeRadius,
120941
- radiusBottom: tubeRadius,
120942
- radialSegments: 20,
120943
- heightSegments: 1,
120944
- height: radius,
120945
- openEnded: false
120946
- })),
120931
+ const translatedAxisMatrix = (yOffset) => math.mulMat4(axisRotation, math.translateMat4c(0, yOffset, 0, math.identityMat4()), math.identityMat4());
120932
+ const arrowMatrix = translatedAxisMatrix(arrowLength + .1);
120933
+ const shaftMatrix = translatedAxisMatrix(arrowLength / 2);
120947
120934
 
120948
- axisHandle: new ReadableGeometry(rootNode, buildCylinderGeometry({
120949
- radiusTop: 0.08,
120950
- radiusBottom: 0.08,
120951
- radialSegments: 20,
120952
- heightSegments: 1,
120953
- height: radius,
120954
- openEnded: false
120955
- }))
120956
- };
120935
+ const arrow = rootNode.addChild(new Mesh(rootNode, {
120936
+ geometry: shapes.arrowHead,
120937
+ material: material,
120938
+ matrix: arrowMatrix,
120939
+ pickable: false,
120940
+ collidable: true,
120941
+ clippable: false,
120942
+ visible: false,
120943
+ isObject: false
120944
+ }), NO_STATE_INHERIT);
120957
120945
 
120958
- const materials = { // Reusable materials
120946
+ const arrowHandle = rootNode.addChild(new Mesh(rootNode, {
120947
+ geometry: shapes.arrowHeadHandle,
120948
+ material: pickableMaterial,
120949
+ matrix: arrowMatrix,
120950
+ pickable: true,
120951
+ collidable: true,
120952
+ clippable: false,
120953
+ visible: false,
120954
+ isObject: false
120955
+ }), NO_STATE_INHERIT);
120959
120956
 
120960
- pickable: new PhongMaterial(rootNode, { // Invisible material for pickable handles, which define a pickable 3D area
120961
- diffuse: [1, 1, 0],
120962
- alpha: 0, // Invisible
120963
- alphaMode: "blend"
120964
- }),
120957
+ const shaft = rootNode.addChild(new Mesh(rootNode, {
120958
+ geometry: shapes.axis,
120959
+ material: material,
120960
+ matrix: shaftMatrix,
120961
+ pickable: false,
120962
+ collidable: true,
120963
+ clippable: false,
120964
+ visible: false,
120965
+ isObject: false
120966
+ }), NO_STATE_INHERIT);
120965
120967
 
120966
- red: new PhongMaterial(rootNode, {
120967
- diffuse: [1, 0.0, 0.0],
120968
- emissive: [1, 0.0, 0.0],
120969
- ambient: [0.0, 0.0, 0.0],
120970
- specular: [.6, .6, .3],
120971
- shininess: 80,
120972
- lineWidth: 2
120973
- }),
120968
+ const shaftHandle = rootNode.addChild(new Mesh(rootNode, {
120969
+ geometry: shapes.axisHandle,
120970
+ material: pickableMaterial,
120971
+ matrix: shaftMatrix,
120972
+ pickable: true,
120973
+ collidable: true,
120974
+ clippable: false,
120975
+ visible: false,
120976
+ isObject: false
120977
+ }), NO_STATE_INHERIT);
120974
120978
 
120975
- highlightRed: new EmphasisMaterial(rootNode, { // Emphasis for red rotation affordance hoop
120976
- edges: false,
120977
- fill: true,
120978
- fillColor: [1, 0, 0],
120979
- fillAlpha: 0.6
120980
- }),
120979
+ const bigArrowHead = rootNode.addChild(new Mesh(rootNode, {
120980
+ geometry: shapes.arrowHeadBig,
120981
+ material: material,
120982
+ matrix: arrowMatrix,
120983
+ pickable: false,
120984
+ collidable: true,
120985
+ clippable: false,
120986
+ visible: false,
120987
+ isObject: false
120988
+ }), NO_STATE_INHERIT);
120981
120989
 
120982
- green: new PhongMaterial(rootNode, {
120983
- diffuse: [0.0, 1, 0.0],
120984
- emissive: [0.0, 1, 0.0],
120985
- ambient: [0.0, 0.0, 0.0],
120986
- specular: [.6, .6, .3],
120987
- shininess: 80,
120988
- lineWidth: 2
120989
- }),
120990
+ const closestPointOnAxis = (function() {
120991
+ const worldAxis = math.vec4();
120992
+ const org = math.vec3();
120993
+ const dir = math.vec3();
120994
+ return (canvasPos, dst) => {
120995
+ localToWorldVec(rgb, worldAxis);
120990
120996
 
120991
- highlightGreen: new EmphasisMaterial(rootNode, { // Emphasis for green rotation affordance hoop
120992
- edges: false,
120993
- fill: true,
120994
- fillColor: [0, 1, 0],
120995
- fillAlpha: 0.6
120996
- }),
120997
+ const P = pos;
120998
+ const D = worldAxis;
120997
120999
 
120998
- blue: new PhongMaterial(rootNode, {
120999
- diffuse: [0.0, 0.0, 1],
121000
- emissive: [0.0, 0.0, 1],
121001
- ambient: [0.0, 0.0, 0.0],
121002
- specular: [.6, .6, .3],
121003
- shininess: 80,
121004
- lineWidth: 2
121005
- }),
121000
+ math.canvasPosToWorldRay(canvas, scene.camera.viewMatrix, scene.camera.projMatrix, scene.camera.projection, canvasPos, org, dir);
121006
121001
 
121007
- highlightBlue: new EmphasisMaterial(rootNode, { // Emphasis for blue rotation affordance hoop
121008
- edges: false,
121009
- fill: true,
121010
- fillColor: [0, 0, 1],
121011
- fillAlpha: 0.2
121012
- }),
121002
+ const d01 = math.dotVec3(D, dir);
121003
+ const v = math.subVec3(org, P, dst);
121004
+ const v0 = math.dotVec3(v, D);
121005
+ const v1 = math.dotVec3(v, dir);
121006
+ const det = 1 - d01 * d01;
121013
121007
 
121014
- center: new PhongMaterial(rootNode, {
121015
- diffuse: [0.0, 0.0, 0.0],
121016
- emissive: [0, 0, 0],
121017
- ambient: [0.0, 0.0, 0.0],
121018
- specular: [.6, .6, .3],
121019
- shininess: 80
121020
- }),
121008
+ if (Math.abs(det) > 1e-10) { // if lines are not parallel
121009
+ const s = (v0 - d01 * v1) / det;
121010
+ math.addVec3(P, math.mulVec3Scalar(D, s, dst), dst);
121011
+ return true;
121012
+ } else {
121013
+ return false;
121014
+ }
121015
+ };
121016
+ })();
121017
+ const initOffset = math.vec3();
121018
+ const tempVec3 = math.vec3();
121019
+ handlers[arrowHandle.id] = handlers[shaftHandle.id] = {
121020
+ setActivated: a => bigArrowHead.visible = a,
121021
+ initDragAction: (initCanvasPos) => {
121022
+ return closestPointOnAxis(initCanvasPos, initOffset) && math.subVec3(initOffset, pos, initOffset) && ((canvasPos) => {
121023
+ if (closestPointOnAxis(canvasPos, tempVec3)) {
121024
+ math.subVec3(tempVec3, initOffset, tempVec3);
121025
+ setPos(tempVec3);
121026
+ if (self._sectionPlane) {
121027
+ self._sectionPlane.pos = tempVec3;
121028
+ }
121029
+ }
121030
+ });
121031
+ }
121032
+ };
121021
121033
 
121022
- highlightBall: new EmphasisMaterial(rootNode, {
121023
- edges: false,
121024
- fill: true,
121025
- fillColor: [0.5, 0.5, 0.5],
121026
- fillAlpha: 0.5,
121027
- vertices: false
121028
- }),
121034
+ const lastCanvasPos = math.vec2();
121035
+ handlers[rotateHandle.id] = {
121036
+ setActivated: a => hoop.visible = a,
121037
+ initDragAction: (initCanvasPos) => {
121038
+ lastCanvasPos.set(initCanvasPos);
121039
+ return canvasPos => {
121040
+ dragRotateSectionPlane(rgb, lastCanvasPos, canvasPos);
121041
+ lastCanvasPos.set(canvasPos);
121042
+ };
121043
+ }
121044
+ };
121029
121045
 
121030
- highlightPlane: new EmphasisMaterial(rootNode, {
121031
- edges: true,
121032
- edgeWidth: 3,
121033
- fill: false,
121034
- fillColor: [0.5, 0.5, .5],
121035
- fillAlpha: 0.5,
121036
- vertices: false
121037
- })
121046
+ return {
121047
+ set visible(v) {
121048
+ arrow.visible = arrowHandle.visible = shaft.visible = shaftHandle.visible = curve.visible = rotateHandle.visible = arrow1.visible = arrow2.visible = v;
121049
+ if (! v) {
121050
+ bigArrowHead.visible = v;
121051
+ hoop.visible = v;
121052
+ }
121053
+ },
121054
+ set culled(c) {
121055
+ arrow.culled = arrowHandle.culled = shaft.culled = shaftHandle.culled = curve.culled = rotateHandle.culled = arrow1.culled = arrow2.culled = c;
121056
+ if (! c) {
121057
+ bigArrowHead.culled = c;
121058
+ hoop.culled = c;
121059
+ }
121060
+ }
121061
+ };
121038
121062
  };
121039
121063
 
121040
- this._displayMeshes = {
121041
-
121042
- plane: rootNode.addChild(new Mesh(rootNode, {
121064
+ this._displayMeshes = [ // Meshes that are always visible
121065
+ rootNode.addChild(new Mesh(rootNode, { // plane
121043
121066
  geometry: new ReadableGeometry(rootNode, {
121044
121067
  primitive: "triangles",
121045
121068
  positions: [
@@ -121073,7 +121096,7 @@ class Control {
121073
121096
  isObject: false
121074
121097
  }), NO_STATE_INHERIT),
121075
121098
 
121076
- planeFrame: rootNode.addChild(new Mesh(rootNode, { // Visible frame
121099
+ rootNode.addChild(new Mesh(rootNode, { // Visible frame
121077
121100
  geometry: new ReadableGeometry(rootNode, buildTorusGeometry({
121078
121101
  center: [0, 0, 0],
121079
121102
  radius: 1.7,
@@ -121105,310 +121128,17 @@ class Control {
121105
121128
  isObject: false
121106
121129
  }), NO_STATE_INHERIT),
121107
121130
 
121108
- //----------------------------------------------------------------------------------------------------------
121109
- //
121110
- //----------------------------------------------------------------------------------------------------------
121111
-
121112
- xCurve: rootNode.addChild(new Mesh(rootNode, { // Red hoop about Y-axis
121113
- geometry: shapes.curve,
121114
- material: materials.red,
121115
- matrix: (function () {
121116
- const rotate2 = math.rotationMat4v(90 * math.DEGTORAD, [0, 1, 0], math.identityMat4());
121117
- const rotate1 = math.rotationMat4v(270 * math.DEGTORAD, [1, 0, 0], math.identityMat4());
121118
- return math.mulMat4(rotate1, rotate2, math.identityMat4());
121119
- })(),
121120
- pickable: false,
121121
- collidable: true,
121122
- clippable: false,
121123
- backfaces: true,
121124
- visible: false,
121125
- isObject: false
121126
- }), NO_STATE_INHERIT),
121127
-
121128
- xCurveHandle: rootNode.addChild(new Mesh(rootNode, { // Red hoop about Y-axis
121129
- geometry: shapes.curveHandle,
121130
- material: materials.pickable,
121131
- matrix: (function () {
121132
- const rotate2 = math.rotationMat4v(90 * math.DEGTORAD, [0, 1, 0], math.identityMat4());
121133
- const rotate1 = math.rotationMat4v(270 * math.DEGTORAD, [1, 0, 0], math.identityMat4());
121134
- return math.mulMat4(rotate1, rotate2, math.identityMat4());
121135
- })(),
121136
- pickable: true,
121137
- collidable: true,
121138
- clippable: false,
121139
- backfaces: true,
121140
- visible: false,
121141
- isObject: false
121142
- }), NO_STATE_INHERIT),
121143
-
121144
- xCurveArrow1: rootNode.addChild(new Mesh(rootNode, {
121145
- geometry: shapes.arrowHead,
121146
- material: materials.red,
121147
- matrix: (function () {
121148
- const translate = math.translateMat4c(0., -0.07, -0.8, math.identityMat4());
121149
- const scale = math.scaleMat4v([0.6, 0.6, 0.6], math.identityMat4());
121150
- const rotate = math.rotationMat4v(0 * math.DEGTORAD, [0, 0, 1], math.identityMat4());
121151
- return math.mulMat4(math.mulMat4(translate, scale, math.identityMat4()), rotate, math.identityMat4());
121152
- })(),
121153
- pickable: true,
121154
- collidable: true,
121155
- clippable: false,
121156
- visible: false,
121157
- isObject: false
121158
- }), NO_STATE_INHERIT),
121159
-
121160
- xCurveArrow2: rootNode.addChild(new Mesh(rootNode, {
121161
- geometry: shapes.arrowHead,
121162
- material: materials.red,
121163
- matrix: (function () {
121164
- const translate = math.translateMat4c(0.0, -0.8, -0.07, math.identityMat4());
121165
- const scale = math.scaleMat4v([0.6, 0.6, 0.6], math.identityMat4());
121166
- const rotate = math.rotationMat4v(90 * math.DEGTORAD, [1, 0, 0], math.identityMat4());
121167
- return math.mulMat4(math.mulMat4(translate, scale, math.identityMat4()), rotate, math.identityMat4());
121168
- })(),
121169
- pickable: true,
121170
- collidable: true,
121171
- clippable: false,
121172
- visible: false,
121173
- isObject: false
121174
- }), NO_STATE_INHERIT),
121175
-
121176
- //----------------------------------------------------------------------------------------------------------
121177
- //
121178
- //----------------------------------------------------------------------------------------------------------
121179
-
121180
- yCurve: rootNode.addChild(new Mesh(rootNode, {
121181
- geometry: shapes.curve,
121182
- material: materials.green,
121183
- rotation: [-90, 0, 0],
121184
- pickable: false,
121185
- collidable: true,
121186
- clippable: false,
121187
- backfaces: true,
121188
- visible: false,
121189
- isObject: false
121190
- }), NO_STATE_INHERIT),
121191
-
121192
- yCurveHandle: rootNode.addChild(new Mesh(rootNode, {
121193
- geometry: shapes.curveHandle,
121194
- material: materials.pickable,
121195
- rotation: [-90, 0, 0],
121196
- pickable: true,
121197
- collidable: true,
121198
- clippable: false,
121199
- backfaces: true,
121200
- visible: false,
121201
- isObject: false
121202
- }), NO_STATE_INHERIT),
121203
-
121204
- yCurveArrow1: rootNode.addChild(new Mesh(rootNode, {
121205
- geometry: shapes.arrowHead,
121206
- material: materials.green,
121207
- matrix: (function () {
121208
- const translate = math.translateMat4c(0.07, 0, -0.8, math.identityMat4());
121209
- const scale = math.scaleMat4v([0.6, 0.6, 0.6], math.identityMat4());
121210
- const rotate = math.rotationMat4v(90 * math.DEGTORAD, [0, 0, 1], math.identityMat4());
121211
- return math.mulMat4(math.mulMat4(translate, scale, math.identityMat4()), rotate, math.identityMat4());
121212
- })(),
121213
- pickable: true,
121214
- collidable: true,
121215
- clippable: false,
121216
- visible: false,
121217
- isObject: false
121218
- }), NO_STATE_INHERIT),
121219
-
121220
- yCurveArrow2: rootNode.addChild(new Mesh(rootNode, {
121221
- geometry: shapes.arrowHead,
121222
- material: materials.green,
121223
- matrix: (function () {
121224
- const translate = math.translateMat4c(0.8, 0.0, -0.07, math.identityMat4());
121225
- const scale = math.scaleMat4v([0.6, 0.6, 0.6], math.identityMat4());
121226
- const rotate = math.rotationMat4v(90 * math.DEGTORAD, [1, 0, 0], math.identityMat4());
121227
- return math.mulMat4(math.mulMat4(translate, scale, math.identityMat4()), rotate, math.identityMat4());
121228
- })(),
121229
- pickable: true,
121230
- collidable: true,
121231
- clippable: false,
121232
- visible: false,
121233
- isObject: false
121234
- }), NO_STATE_INHERIT),
121235
-
121236
- //----------------------------------------------------------------------------------------------------------
121237
- //
121238
- //----------------------------------------------------------------------------------------------------------
121239
-
121240
- zCurve: rootNode.addChild(new Mesh(rootNode, { // Blue hoop about Z-axis
121241
- geometry: shapes.curve,
121242
- material: materials.blue,
121243
- matrix: math.rotationMat4v(180 * math.DEGTORAD, [1, 0, 0], math.identityMat4()),
121244
- pickable: false,
121245
- collidable: true,
121246
- clippable: false,
121247
- visible: false,
121248
- isObject: false
121249
- }), NO_STATE_INHERIT),
121250
-
121251
- zCurveHandle: rootNode.addChild(new Mesh(rootNode, {
121252
- geometry: shapes.curveHandle,
121253
- material: materials.pickable,
121254
- matrix: math.rotationMat4v(180 * math.DEGTORAD, [1, 0, 0], math.identityMat4()),
121255
- pickable: true,
121256
- collidable: true,
121257
- clippable: false,
121258
- visible: false,
121259
- isObject: false
121260
- }), NO_STATE_INHERIT),
121261
-
121262
- zCurveCurveArrow1: rootNode.addChild(new Mesh(rootNode, {
121263
- geometry: shapes.arrowHead,
121264
- material: materials.blue,
121265
- matrix: (function () {
121266
- const translate = math.translateMat4c(.8, -0.07, 0, math.identityMat4());
121267
- const scale = math.scaleMat4v([0.6, 0.6, 0.6], math.identityMat4());
121268
- return math.mulMat4(translate, scale, math.identityMat4());
121269
- })(),
121270
- pickable: true,
121271
- collidable: true,
121272
- clippable: false,
121273
- visible: false,
121274
- isObject: false
121275
- }), NO_STATE_INHERIT),
121276
-
121277
- zCurveArrow2: rootNode.addChild(new Mesh(rootNode, {
121278
- geometry: shapes.arrowHead,
121279
- material: materials.blue,
121280
- matrix: (function () {
121281
- const translate = math.translateMat4c(.05, -0.8, 0, math.identityMat4());
121282
- const scale = math.scaleMat4v([0.6, 0.6, 0.6], math.identityMat4());
121283
- const rotate = math.rotationMat4v(90 * math.DEGTORAD, [0, 0, 1], math.identityMat4());
121284
- return math.mulMat4(math.mulMat4(translate, scale, math.identityMat4()), rotate, math.identityMat4());
121285
- })(),
121286
- pickable: true,
121287
- collidable: true,
121288
- clippable: false,
121289
- visible: false,
121290
- isObject: false
121291
- }), NO_STATE_INHERIT),
121292
-
121293
- //----------------------------------------------------------------------------------------------------------
121294
- //
121295
- //----------------------------------------------------------------------------------------------------------
121296
-
121297
- center: rootNode.addChild(new Mesh(rootNode, {
121131
+ rootNode.addChild(new Mesh(rootNode, { // center
121298
121132
  geometry: new ReadableGeometry(rootNode, buildSphereGeometry({
121299
121133
  radius: 0.05
121300
121134
  })),
121301
- material: materials.center,
121302
- pickable: false,
121303
- collidable: true,
121304
- clippable: false,
121305
- visible: false,
121306
- isObject: false
121307
- }), NO_STATE_INHERIT),
121308
-
121309
- //----------------------------------------------------------------------------------------------------------
121310
- //
121311
- //----------------------------------------------------------------------------------------------------------
121312
-
121313
- xAxisArrow: rootNode.addChild(new Mesh(rootNode, {
121314
- geometry: shapes.arrowHead,
121315
- material: materials.red,
121316
- matrix: (function () {
121317
- const translate = math.translateMat4c(0, radius + .1, 0, math.identityMat4());
121318
- const rotate = math.rotationMat4v(-90 * math.DEGTORAD, [0, 0, 1], math.identityMat4());
121319
- return math.mulMat4(rotate, translate, math.identityMat4());
121320
- })(),
121321
- pickable: false,
121322
- collidable: true,
121323
- clippable: false,
121324
- visible: false,
121325
- isObject: false
121326
- }), NO_STATE_INHERIT),
121327
-
121328
- xAxisArrowHandle: rootNode.addChild(new Mesh(rootNode, {
121329
- geometry: shapes.arrowHeadHandle,
121330
- material: materials.pickable,
121331
- matrix: (function () {
121332
- const translate = math.translateMat4c(0, radius + .1, 0, math.identityMat4());
121333
- const rotate = math.rotationMat4v(-90 * math.DEGTORAD, [0, 0, 1], math.identityMat4());
121334
- return math.mulMat4(rotate, translate, math.identityMat4());
121335
- })(),
121336
- pickable: true,
121337
- collidable: true,
121338
- clippable: false,
121339
- visible: false,
121340
- isObject: false
121341
- }), NO_STATE_INHERIT),
121342
-
121343
- xAxis: rootNode.addChild(new Mesh(rootNode, {
121344
- geometry: shapes.axis,
121345
- material: materials.red,
121346
- matrix: (function () {
121347
- const translate = math.translateMat4c(0, radius / 2, 0, math.identityMat4());
121348
- const rotate = math.rotationMat4v(-90 * math.DEGTORAD, [0, 0, 1], math.identityMat4());
121349
- return math.mulMat4(rotate, translate, math.identityMat4());
121350
- })(),
121351
- pickable: false,
121352
- collidable: true,
121353
- clippable: false,
121354
- visible: false,
121355
- isObject: false
121356
- }), NO_STATE_INHERIT),
121357
-
121358
- xAxisHandle: rootNode.addChild(new Mesh(rootNode, {
121359
- geometry: shapes.axisHandle,
121360
- material: materials.pickable,
121361
- matrix: (function () {
121362
- const translate = math.translateMat4c(0, radius / 2, 0, math.identityMat4());
121363
- const rotate = math.rotationMat4v(-90 * math.DEGTORAD, [0, 0, 1], math.identityMat4());
121364
- return math.mulMat4(rotate, translate, math.identityMat4());
121365
- })(),
121366
- pickable: true,
121367
- collidable: true,
121368
- clippable: false,
121369
- visible: false,
121370
- isObject: false
121371
- }), NO_STATE_INHERIT),
121372
-
121373
- //----------------------------------------------------------------------------------------------------------
121374
- //
121375
- //----------------------------------------------------------------------------------------------------------
121376
-
121377
- yAxisArrow: rootNode.addChild(new Mesh(rootNode, {
121378
- geometry: shapes.arrowHead,
121379
- material: materials.green,
121380
- matrix: (function () {
121381
- const translate = math.translateMat4c(0, radius + .1, 0, math.identityMat4());
121382
- const rotate = math.rotationMat4v(180 * math.DEGTORAD, [1, 0, 0], math.identityMat4());
121383
- return math.mulMat4(rotate, translate, math.identityMat4());
121384
- })(),
121385
- pickable: false,
121386
- collidable: true,
121387
- clippable: false,
121388
- visible: false,
121389
- isObject: false
121390
- }), NO_STATE_INHERIT),
121391
-
121392
- yAxisArrowHandle: rootNode.addChild(new Mesh(rootNode, {
121393
- geometry: shapes.arrowHeadHandle,
121394
- material: materials.pickable,
121395
- matrix: (function () {
121396
- const translate = math.translateMat4c(0, radius + .1, 0, math.identityMat4());
121397
- const rotate = math.rotationMat4v(180 * math.DEGTORAD, [1, 0, 0], math.identityMat4());
121398
- return math.mulMat4(rotate, translate, math.identityMat4());
121399
- })(),
121400
- pickable: true,
121401
- collidable: true,
121402
- clippable: false,
121403
- visible: false,
121404
- opacity: 0.2,
121405
- isObject: false
121406
- }), NO_STATE_INHERIT),
121407
-
121408
- yShaft: rootNode.addChild(new Mesh(rootNode, {
121409
- geometry: shapes.axis,
121410
- material: materials.green,
121411
- position: [0, -radius / 2, 0],
121135
+ material: new PhongMaterial(rootNode, {
121136
+ diffuse: [0.0, 0.0, 0.0],
121137
+ emissive: [0, 0, 0],
121138
+ ambient: [0.0, 0.0, 0.0],
121139
+ specular: [.6, .6, .3],
121140
+ shininess: 80
121141
+ }),
121412
121142
  pickable: false,
121413
121143
  collidable: true,
121414
121144
  clippable: false,
@@ -121416,349 +121146,69 @@ class Control {
121416
121146
  isObject: false
121417
121147
  }), NO_STATE_INHERIT),
121418
121148
 
121419
- yShaftHandle: rootNode.addChild(new Mesh(rootNode, {
121420
- geometry: shapes.axisHandle,
121421
- material: materials.pickable,
121422
- position: [0, -radius / 2, 0],
121423
- pickable: true,
121424
- collidable: true,
121425
- clippable: false,
121426
- visible: false,
121427
- isObject: false
121428
- }), NO_STATE_INHERIT),
121429
-
121430
121149
  //----------------------------------------------------------------------------------------------------------
121431
121150
  //
121432
121151
  //----------------------------------------------------------------------------------------------------------
121433
121152
 
121434
- zAxisArrow: rootNode.addChild(new Mesh(rootNode, {
121435
- geometry: shapes.arrowHead,
121436
- material: materials.blue,
121437
- matrix: (function () {
121438
- const translate = math.translateMat4c(0, radius + .1, 0, math.identityMat4());
121439
- const rotate = math.rotationMat4v(-90 * math.DEGTORAD, [0.8, 0, 0], math.identityMat4());
121440
- return math.mulMat4(rotate, translate, math.identityMat4());
121441
- })(),
121442
- pickable: false,
121443
- collidable: true,
121444
- clippable: false,
121445
- visible: false,
121446
- isObject: false
121447
- }), NO_STATE_INHERIT),
121448
-
121449
- zAxisArrowHandle: rootNode.addChild(new Mesh(rootNode, {
121450
- geometry: shapes.arrowHeadHandle,
121451
- material: materials.pickable,
121452
- matrix: (function () {
121453
- const translate = math.translateMat4c(0, radius + .1, 0, math.identityMat4());
121454
- const rotate = math.rotationMat4v(-90 * math.DEGTORAD, [0.8, 0, 0], math.identityMat4());
121455
- return math.mulMat4(rotate, translate, math.identityMat4());
121456
- })(),
121457
- pickable: true,
121458
- collidable: true,
121459
- clippable: false,
121460
- visible: false,
121461
- isObject: false
121462
- }), NO_STATE_INHERIT),
121463
-
121464
-
121465
- zShaft: rootNode.addChild(new Mesh(rootNode, {
121466
- geometry: shapes.axis,
121467
- material: materials.blue,
121468
- matrix: (function () {
121469
- const translate = math.translateMat4c(0, radius / 2, 0, math.identityMat4());
121470
- const rotate = math.rotationMat4v(-90 * math.DEGTORAD, [1, 0, 0], math.identityMat4());
121471
- return math.mulMat4(rotate, translate, math.identityMat4());
121472
- })(),
121473
- clippable: false,
121474
- pickable: false,
121475
- collidable: true,
121476
- visible: false,
121477
- isObject: false
121478
- }), NO_STATE_INHERIT),
121479
-
121480
- zAxisHandle: rootNode.addChild(new Mesh(rootNode, {
121481
- geometry: shapes.axisHandle,
121482
- material: materials.pickable,
121483
- matrix: (function () {
121484
- const translate = math.translateMat4c(0, radius / 2, 0, math.identityMat4());
121485
- const rotate = math.rotationMat4v(-90 * math.DEGTORAD, [1, 0, 0], math.identityMat4());
121486
- return math.mulMat4(rotate, translate, math.identityMat4());
121487
- })(),
121488
- clippable: false,
121489
- pickable: true,
121490
- collidable: true,
121491
- visible: false,
121492
- isObject: false
121493
- }), NO_STATE_INHERIT)
121494
- };
121495
-
121496
- this._affordanceMeshes = {
121497
-
121498
- planeFrame: rootNode.addChild(new Mesh(rootNode, {
121499
- geometry: new ReadableGeometry(rootNode, buildTorusGeometry({
121500
- center: [0, 0, 0],
121501
- radius: 2,
121502
- tube: tubeRadius,
121503
- radialSegments: 4,
121504
- tubeSegments: 4,
121505
- arc: Math.PI * 2.0
121506
- })),
121507
- material: new PhongMaterial(rootNode, {
121508
- ambient: [1, 1, 1],
121509
- diffuse: [0, 0, 0],
121510
- emissive: [1, 1, 0]
121511
- }),
121512
- highlighted: true,
121513
- highlightMaterial: new EmphasisMaterial(rootNode, {
121514
- edges: false,
121515
- filled: true,
121516
- fillColor: [1, 1, 0],
121517
- fillAlpha: 1.0
121518
- }),
121519
- pickable: false,
121520
- collidable: false,
121521
- clippable: false,
121522
- visible: false,
121523
- scale: [1, 1, 1],
121524
- rotation: [0, 0, 45],
121525
- isObject: false
121526
- }), NO_STATE_INHERIT),
121527
-
121528
- xHoop: rootNode.addChild(new Mesh(rootNode, { // Full
121529
- geometry: shapes.hoop,
121530
- material: materials.red,
121531
- highlighted: true,
121532
- highlightMaterial: materials.highlightRed,
121533
- matrix: (function () {
121534
- const rotate2 = math.rotationMat4v(90 * math.DEGTORAD, [0, 1, 0], math.identityMat4());
121535
- const rotate1 = math.rotationMat4v(270 * math.DEGTORAD, [1, 0, 0], math.identityMat4());
121536
- return math.mulMat4(rotate1, rotate2, math.identityMat4());
121537
- })(),
121538
- pickable: false,
121539
- collidable: true,
121540
- clippable: false,
121541
- visible: false,
121542
- isObject: false
121543
- }), NO_STATE_INHERIT),
121544
-
121545
- yHoop: rootNode.addChild(new Mesh(rootNode, {
121546
- geometry: shapes.hoop,
121547
- material: materials.green,
121548
- highlighted: true,
121549
- highlightMaterial: materials.highlightGreen,
121550
- rotation: [-90, 0, 0],
121551
- pickable: false,
121552
- collidable: true,
121553
- clippable: false,
121554
- visible: false,
121555
- isObject: false
121556
- }), NO_STATE_INHERIT),
121557
-
121558
- zHoop: rootNode.addChild(new Mesh(rootNode, { // Blue hoop about Z-axis
121559
- geometry: shapes.hoop,
121560
- material: materials.blue,
121561
- highlighted: true,
121562
- highlightMaterial: materials.highlightBlue,
121563
- matrix: math.rotationMat4v(180 * math.DEGTORAD, [1, 0, 0], math.identityMat4()),
121564
- pickable: false,
121565
- collidable: true,
121566
- clippable: false,
121567
- backfaces: true,
121568
- visible: false,
121569
- isObject: false
121570
- }), NO_STATE_INHERIT),
121571
-
121572
- xAxisArrow: rootNode.addChild(new Mesh(rootNode, {
121573
- geometry: shapes.arrowHeadBig,
121574
- material: materials.red,
121575
- matrix: (function () {
121576
- const translate = math.translateMat4c(0, radius + .1, 0, math.identityMat4());
121577
- const rotate = math.rotationMat4v(-90 * math.DEGTORAD, [0, 0, 1], math.identityMat4());
121578
- return math.mulMat4(rotate, translate, math.identityMat4());
121579
- })(),
121580
- pickable: false,
121581
- collidable: true,
121582
- clippable: false,
121583
- visible: false,
121584
- isObject: false
121585
- }), NO_STATE_INHERIT),
121586
-
121587
- yAxisArrow: rootNode.addChild(new Mesh(rootNode, {
121588
- geometry: shapes.arrowHeadBig,
121589
- material: materials.green,
121590
- matrix: (function () {
121591
- const translate = math.translateMat4c(0, radius + .1, 0, math.identityMat4());
121592
- const rotate = math.rotationMat4v(180 * math.DEGTORAD, [1, 0, 0], math.identityMat4());
121593
- return math.mulMat4(rotate, translate, math.identityMat4());
121594
- })(),
121595
- pickable: false,
121596
- collidable: true,
121597
- clippable: false,
121598
- visible: false,
121599
- isObject: false
121600
- }), NO_STATE_INHERIT),
121601
-
121602
- zAxisArrow: rootNode.addChild(new Mesh(rootNode, {
121603
- geometry: shapes.arrowHeadBig,
121604
- material: materials.blue,
121605
- matrix: (function () {
121606
- const translate = math.translateMat4c(0, radius + .1, 0, math.identityMat4());
121607
- const rotate = math.rotationMat4v(-90 * math.DEGTORAD, [0.8, 0, 0], math.identityMat4());
121608
- return math.mulMat4(rotate, translate, math.identityMat4());
121609
- })(),
121610
- pickable: false,
121611
- collidable: true,
121612
- clippable: false,
121613
- visible: false,
121614
- isObject: false
121615
- }), NO_STATE_INHERIT)
121616
- };
121617
- }
121618
-
121619
- _bindEvents() {
121620
-
121621
- const self = this;
121622
-
121623
- var grabbed = false;
121624
-
121625
- const DRAG_ACTIONS = {
121626
- none: -1,
121627
- xTranslate: 0,
121628
- yTranslate: 1,
121629
- zTranslate: 2,
121630
- xRotate: 3,
121631
- yRotate: 4,
121632
- zRotate: 5
121633
- };
121634
-
121635
- const rootNode = this._rootNode;
121636
-
121637
- var nextDragAction = null; // As we hover grabbed an arrow or hoop, self is the action we would do if we then dragged it.
121638
- var dragAction = null; // Action we're doing while we drag an arrow or hoop.
121639
- const lastCanvasPos = math.vec2();
121640
-
121641
- const xBaseAxis = math.vec3([1, 0, 0]);
121642
- const yBaseAxis = math.vec3([0, 1, 0]);
121643
- const zBaseAxis = math.vec3([0, 0, 1]);
121153
+ addAxis([1,0,0], [ 1, 0, 0 ], [ 1, 0, 0 ]),
121154
+ addAxis([0,1,0], [ 0, -1, 0 ], [ 0, 1, 0 ]),
121155
+ addAxis([0,0,1], [ 0, 0, -1 ], [ 0, 0, -1 ])
121156
+ ];
121644
121157
 
121645
- const canvas = this._viewer.scene.canvas.canvas;
121646
- const camera = this._viewer.camera;
121647
- const scene = this._viewer.scene;
121158
+ const cleanups = [ ];
121648
121159
 
121649
121160
  { // Keep gizmo screen size constant
121650
-
121651
- const tempVec3a = math.vec3([0, 0, 0]);
121652
121161
  let lastDist = -1;
121653
-
121654
- this._onCameraViewMatrix = scene.camera.on("viewMatrix", () => {
121655
- });
121656
-
121657
- this._onCameraProjMatrix = scene.camera.on("projMatrix", () => {
121658
- });
121659
-
121660
- this._onSceneTick = scene.on("tick", () => {
121661
-
121662
- const dist = Math.abs(math.lenVec3(math.subVec3(scene.camera.eye, this._pos, tempVec3a)));
121663
-
121664
- if (dist !== lastDist) {
121665
- if (camera.projection === "perspective") {
121666
- const worldSize = (Math.tan(camera.perspective.fov * math.DEGTORAD)) * dist;
121667
- const size = 0.07 * worldSize;
121668
- rootNode.scale = [size, size, size];
121669
- lastDist = dist;
121162
+ const setRootNodeScale = size => rootNode.scale = [size, size, size];
121163
+ const onSceneTick = scene.on("tick", () => {
121164
+ const dist = Math.abs(math.distVec3(camera.eye, pos));
121165
+ if (camera.projection === "perspective") {
121166
+ if (dist !== lastDist) {
121167
+ setRootNodeScale(0.07 * dist * Math.tan(camera.perspective.fov * math.DEGTORAD));
121670
121168
  }
121169
+ } else if (camera.projection === "ortho") {
121170
+ setRootNodeScale(camera.ortho.scale / 10);
121671
121171
  }
121672
-
121673
- if (camera.projection === "ortho") {
121674
- const worldSize = camera.ortho.scale / 10;
121675
- const size = worldSize;
121676
- rootNode.scale = [size, size, size];
121677
- lastDist = dist;
121678
- }
121172
+ lastDist = dist;
121679
121173
  });
121174
+ cleanups.push(() => scene.off(onSceneTick));
121680
121175
  }
121681
121176
 
121682
- const getClickCoordsWithinElement = (function () {
121683
- const canvasPos = new Float64Array(2);
121684
- return function (event) {
121685
- if (!event) {
121686
- event = window.event;
121687
- canvasPos[0] = event.x;
121688
- canvasPos[1] = event.y;
121689
- } else {
121690
- var element = event.target;
121691
- var totalOffsetLeft = 0;
121692
- var totalOffsetTop = 0;
121693
-
121694
- while (element.offsetParent) {
121695
- totalOffsetLeft += element.offsetLeft;
121696
- totalOffsetTop += element.offsetTop;
121697
- element = element.offsetParent;
121698
- }
121699
- canvasPos[0] = event.pageX - totalOffsetLeft;
121700
- canvasPos[1] = event.pageY - totalOffsetTop;
121701
- }
121702
- return canvasPos;
121703
- };
121704
- })();
121705
-
121706
121177
  const localToWorldVec = (function () {
121707
121178
  const mat = math.mat4();
121708
121179
  return function (localVec, worldVec) {
121709
- math.quaternionToMat4(self._rootNode.quaternion, mat);
121180
+ math.quaternionToMat4(rootNode.quaternion, mat);
121710
121181
  math.transformVec3(mat, localVec, worldVec);
121711
121182
  math.normalizeVec3(worldVec);
121712
121183
  return worldVec;
121713
121184
  };
121714
121185
  })();
121715
121186
 
121716
- var getTranslationPlane = (function () {
121717
- const planeNormal = math.vec3();
121718
- return function (worldAxis) {
121719
- const absX = Math.abs(worldAxis[0]);
121720
- if (absX > Math.abs(worldAxis[1]) && absX > Math.abs(worldAxis[2])) {
121721
- math.cross3Vec3(worldAxis, [0, 1, 0], planeNormal);
121722
- } else {
121723
- math.cross3Vec3(worldAxis, [1, 0, 0], planeNormal);
121724
- }
121725
- math.cross3Vec3(planeNormal, worldAxis, planeNormal);
121726
- math.normalizeVec3(planeNormal);
121727
- return planeNormal;
121728
- }
121729
- })();
121730
-
121731
- const dragTranslateSectionPlane = (function () {
121732
- const p1 = math.vec3();
121733
- const p2 = math.vec3();
121734
- const worldAxis = math.vec4();
121735
- return function (baseAxis, fromMouse, toMouse) {
121736
- localToWorldVec(baseAxis, worldAxis);
121737
- const planeNormal = getTranslationPlane(worldAxis, fromMouse, toMouse);
121738
- getPointerPlaneIntersect(fromMouse, planeNormal, p1);
121739
- getPointerPlaneIntersect(toMouse, planeNormal, p2);
121740
- math.subVec3(p2, p1);
121741
- const dot = math.dotVec3(p2, worldAxis);
121742
- self._pos[0] += worldAxis[0] * dot;
121743
- self._pos[1] += worldAxis[1] * dot;
121744
- self._pos[2] += worldAxis[2] * dot;
121745
- self._rootNode.position = self._pos;
121746
- if (self._sectionPlane) {
121747
- self._sectionPlane.pos = self._pos;
121748
- }
121187
+ const getTranslationPlane = (worldAxis, planeNormal) => {
121188
+ const absX = Math.abs(worldAxis[0]);
121189
+ if (absX > Math.abs(worldAxis[1]) && absX > Math.abs(worldAxis[2])) {
121190
+ math.cross3Vec3(worldAxis, [0, 1, 0], planeNormal);
121191
+ } else {
121192
+ math.cross3Vec3(worldAxis, [1, 0, 0], planeNormal);
121749
121193
  }
121750
- })();
121194
+ math.cross3Vec3(planeNormal, worldAxis, planeNormal);
121195
+ math.normalizeVec3(planeNormal);
121196
+ };
121751
121197
 
121198
+ const self = this;
121752
121199
  var dragRotateSectionPlane = (function () {
121753
121200
  const p1 = math.vec4();
121754
121201
  const p2 = math.vec4();
121755
121202
  const c = math.vec4();
121756
121203
  const worldAxis = math.vec4();
121204
+ const dir = math.vec3();
121205
+ const mat = math.mat4();
121206
+ const planeNormal = math.vec3();
121757
121207
  return function (baseAxis, fromMouse, toMouse) {
121758
121208
  localToWorldVec(baseAxis, worldAxis);
121759
121209
  const hasData = getPointerPlaneIntersect(fromMouse, worldAxis, p1) && getPointerPlaneIntersect(toMouse, worldAxis, p2);
121760
121210
  if (!hasData) { // Find intersections with view plane and project down to origin
121761
- const planeNormal = getTranslationPlane(worldAxis, fromMouse, toMouse);
121211
+ getTranslationPlane(worldAxis, planeNormal);
121762
121212
  getPointerPlaneIntersect(fromMouse, planeNormal, p1, 1); // Ensure plane moves closer to camera so angles become workable
121763
121213
  getPointerPlaneIntersect(toMouse, planeNormal, p2, 1);
121764
121214
  var dot = math.dotVec3(p1, worldAxis);
@@ -121779,9 +121229,15 @@ class Control {
121779
121229
  if (math.dotVec3(c, worldAxis) < 0.0) {
121780
121230
  incDegrees = -incDegrees;
121781
121231
  }
121782
- self._rootNode.rotate(baseAxis, incDegrees);
121783
- rotateSectionPlane();
121784
- }
121232
+ rootNode.rotate(baseAxis, incDegrees);
121233
+
121234
+ if (self._sectionPlane) {
121235
+ math.quaternionToMat4(rootNode.quaternion, mat); // << ---
121236
+ math.transformVec3(mat, [0, 0, 1], dir);
121237
+ ignoreNextSectionPlaneDirUpdate = true;
121238
+ self._sectionPlane.dir = dir;
121239
+ }
121240
+ };
121785
121241
  })();
121786
121242
 
121787
121243
  var getPointerPlaneIntersect = (function () {
@@ -121810,221 +121266,210 @@ class Control {
121810
121266
  return true;
121811
121267
  }
121812
121268
  return false;
121813
- }
121814
- })();
121815
-
121816
- const rotateSectionPlane = (function () {
121817
- const dir = math.vec3();
121818
- const mat = math.mat4();
121819
- return function () {
121820
- if (self.sectionPlane) {
121821
- math.quaternionToMat4(rootNode.quaternion, mat); // << ---
121822
- math.transformVec3(mat, [0, 0, 1], dir);
121823
- self._setSectionPlaneDir(dir);
121824
- }
121825
121269
  };
121826
121270
  })();
121827
121271
 
121828
121272
  {
121829
- var down = false;
121830
- var lastAffordanceMesh;
121831
-
121832
- this._onCameraControlHover = this._viewer.cameraControl.on("hoverEnter", (hit) => {
121833
- if (!this._visible) {
121834
- return;
121835
- }
121836
- if (down) {
121837
- return;
121838
- }
121839
- grabbed = false;
121840
- if (lastAffordanceMesh) {
121841
- lastAffordanceMesh.visible = false;
121842
- }
121843
- var affordanceMesh;
121844
- const meshId = hit.entity.id;
121845
- switch (meshId) {
121846
-
121847
- case this._displayMeshes.xAxisArrowHandle.id:
121848
- affordanceMesh = this._affordanceMeshes.xAxisArrow;
121849
- nextDragAction = DRAG_ACTIONS.xTranslate;
121850
- break;
121851
-
121852
- case this._displayMeshes.xAxisHandle.id:
121853
- affordanceMesh = this._affordanceMeshes.xAxisArrow;
121854
- nextDragAction = DRAG_ACTIONS.xTranslate;
121855
- break;
121856
-
121857
- case this._displayMeshes.yAxisArrowHandle.id:
121858
- affordanceMesh = this._affordanceMeshes.yAxisArrow;
121859
- nextDragAction = DRAG_ACTIONS.yTranslate;
121860
- break;
121861
-
121862
- case this._displayMeshes.yShaftHandle.id:
121863
- affordanceMesh = this._affordanceMeshes.yAxisArrow;
121864
- nextDragAction = DRAG_ACTIONS.yTranslate;
121865
- break;
121866
-
121867
- case this._displayMeshes.zAxisArrowHandle.id:
121868
- affordanceMesh = this._affordanceMeshes.zAxisArrow;
121869
- nextDragAction = DRAG_ACTIONS.zTranslate;
121870
- break;
121273
+ let deactivateActive = null;
121274
+ let currentDrag = null;
121275
+ cleanups.push(() => { if (currentDrag) { currentDrag.cleanup(); } });
121276
+ const canvasPos = math.vec2();
121277
+
121278
+ const copyCanvasPos = (event, vec2) => {
121279
+ vec2[0] = event.clientX;
121280
+ vec2[1] = event.clientY;
121281
+ transformToNode(canvas.ownerDocument.documentElement, canvas, vec2);
121282
+ };
121871
121283
 
121872
- case this._displayMeshes.zAxisHandle.id:
121873
- affordanceMesh = this._affordanceMeshes.zAxisArrow;
121874
- nextDragAction = DRAG_ACTIONS.zTranslate;
121875
- break;
121284
+ const pickHandler = (e) => {
121285
+ copyCanvasPos(e, canvasPos);
121286
+ const pickResult = viewer.scene.pick({ canvasPos: canvasPos });
121287
+ const pickEntity = pickResult && pickResult.entity;
121288
+ const pickId = pickEntity && pickEntity.id;
121289
+ return (pickId in handlers) && handlers[pickId];
121290
+ };
121876
121291
 
121877
- case this._displayMeshes.xCurveHandle.id:
121878
- affordanceMesh = this._affordanceMeshes.xHoop;
121879
- nextDragAction = DRAG_ACTIONS.xRotate;
121880
- break;
121292
+ const startDrag = (event, matchesEvent) => {
121293
+ const handler = pickHandler(matchesEvent(event));
121294
+ if (handler) {
121295
+ if (currentDrag) {
121296
+ currentDrag.cleanup();
121297
+ }
121881
121298
 
121882
- case this._displayMeshes.yCurveHandle.id:
121883
- affordanceMesh = this._affordanceMeshes.yHoop;
121884
- nextDragAction = DRAG_ACTIONS.yRotate;
121885
- break;
121299
+ const dragAction = handler.initDragAction(canvasPos);
121300
+ if (dragAction) {
121301
+ cameraControl.pointerEnabled = false; // or .active = false ?
121302
+ handler.setActivated(true);
121303
+
121304
+ currentDrag = {
121305
+ onChange: event => {
121306
+ const e = matchesEvent(event);
121307
+ if (e) {
121308
+ copyCanvasPos(e, canvasPos);
121309
+ dragAction(canvasPos);
121310
+ }
121311
+ },
121312
+ cleanup: function() {
121313
+ currentDrag = null;
121314
+ cameraControl.pointerEnabled = true; // or .active = true ?
121315
+ handler.setActivated(false);
121316
+ }
121317
+ };
121318
+ }
121319
+ }
121320
+ };
121886
121321
 
121887
- case this._displayMeshes.zCurveHandle.id:
121888
- affordanceMesh = this._affordanceMeshes.zHoop;
121889
- nextDragAction = DRAG_ACTIONS.zRotate;
121890
- break;
121322
+ const addCanvasEventListener = (type, listener) => {
121323
+ canvas.addEventListener(type, listener);
121324
+ cleanups.push(() => canvas.removeEventListener(type, listener));
121325
+ };
121891
121326
 
121892
- default:
121893
- nextDragAction = DRAG_ACTIONS.none;
121894
- return; // Not clicked an arrow or hoop
121895
- }
121896
- if (affordanceMesh) {
121897
- affordanceMesh.visible = true;
121327
+ addCanvasEventListener("mousedown", (e) => {
121328
+ e.preventDefault();
121329
+ if (e.which === 1) {
121330
+ startDrag(e, event => (event.which === 1) && event);
121898
121331
  }
121899
- lastAffordanceMesh = affordanceMesh;
121900
- grabbed = true;
121901
121332
  });
121902
121333
 
121903
- this._onCameraControlHoverLeave = this._viewer.cameraControl.on("hoverOutEntity", (hit) => {
121904
- if (!this._visible) {
121905
- return;
121906
- }
121907
- if (lastAffordanceMesh) {
121908
- lastAffordanceMesh.visible = false;
121334
+ addCanvasEventListener("mousemove", (e) => {
121335
+ if (currentDrag) {
121336
+ currentDrag.onChange(e);
121337
+ } else {
121338
+ if (deactivateActive) {
121339
+ deactivateActive();
121340
+ }
121341
+ const handler = pickHandler(e);
121342
+ if (handler) {
121343
+ handler.setActivated(true);
121344
+ deactivateActive = () => handler.setActivated(false);
121345
+ } else {
121346
+ deactivateActive = null;
121347
+ }
121909
121348
  }
121910
- lastAffordanceMesh = null;
121911
- nextDragAction = DRAG_ACTIONS.none;
121912
121349
  });
121913
121350
 
121914
- canvas.addEventListener("mousedown", this._canvasMouseDownListener = (e) => {
121915
- e.preventDefault();
121916
- if (!this._visible) {
121917
- return;
121918
- }
121919
- if (!grabbed) {
121920
- return;
121921
- }
121922
- this._viewer.cameraControl.pointerEnabled = false;
121923
- switch (e.which) {
121924
- case 1: // Left button
121925
- down = true;
121926
- var canvasPos = getClickCoordsWithinElement(e);
121927
- dragAction = nextDragAction;
121928
- lastCanvasPos[0] = canvasPos[0];
121929
- lastCanvasPos[1] = canvasPos[1];
121930
- break;
121351
+ addCanvasEventListener("mouseup", (e) => {
121352
+ if (currentDrag) {
121353
+ currentDrag.onChange(e);
121354
+ currentDrag.cleanup();
121931
121355
  }
121932
121356
  });
121933
121357
 
121934
- canvas.addEventListener("mousemove", this._canvasMouseMoveListener = (e) => {
121935
- if (!this._visible) {
121936
- return;
121937
- }
121938
- if (!down) {
121939
- return;
121940
- }
121941
- var canvasPos = getClickCoordsWithinElement(e);
121942
- const x = canvasPos[0];
121943
- const y = canvasPos[1];
121944
121358
 
121945
- switch (dragAction) {
121946
- case DRAG_ACTIONS.xTranslate:
121947
- dragTranslateSectionPlane(xBaseAxis, lastCanvasPos, canvasPos);
121948
- break;
121949
- case DRAG_ACTIONS.yTranslate:
121950
- dragTranslateSectionPlane(yBaseAxis, lastCanvasPos, canvasPos);
121951
- break;
121952
- case DRAG_ACTIONS.zTranslate:
121953
- dragTranslateSectionPlane(zBaseAxis, lastCanvasPos, canvasPos);
121954
- break;
121955
- case DRAG_ACTIONS.xRotate:
121956
- dragRotateSectionPlane(xBaseAxis, lastCanvasPos, canvasPos);
121957
- break;
121958
- case DRAG_ACTIONS.yRotate:
121959
- dragRotateSectionPlane(yBaseAxis, lastCanvasPos, canvasPos);
121960
- break;
121961
- case DRAG_ACTIONS.zRotate:
121962
- dragRotateSectionPlane(zBaseAxis, lastCanvasPos, canvasPos);
121963
- break;
121359
+ addCanvasEventListener("touchstart", event => {
121360
+ event.preventDefault();
121361
+ if (event.touches.length === 1)
121362
+ {
121363
+ const touchStartId = event.touches[0].identifier;
121364
+ startDrag(event, event => [...event.changedTouches].find(e => e.identifier === touchStartId));
121964
121365
  }
121366
+ });
121965
121367
 
121966
- lastCanvasPos[0] = x;
121967
- lastCanvasPos[1] = y;
121368
+ addCanvasEventListener("touchmove", event => {
121369
+ event.preventDefault();
121370
+ currentDrag && currentDrag.onChange(event);
121968
121371
  });
121969
121372
 
121970
- canvas.addEventListener("mouseup", this._canvasMouseUpListener = (e) => {
121971
- if (!this._visible) {
121972
- return;
121973
- }
121974
- this._viewer.cameraControl.pointerEnabled = true;
121975
- if (!down) {
121976
- return;
121373
+ addCanvasEventListener("touchend", event => {
121374
+ event.preventDefault();
121375
+ if (currentDrag) {
121376
+ currentDrag.onChange(event);
121377
+ currentDrag.cleanup();
121977
121378
  }
121978
- switch (e.which) {
121979
- }
121980
- down = false;
121981
- grabbed = false;
121982
121379
  });
121380
+ }
121983
121381
 
121984
- canvas.addEventListener("wheel", this._canvasWheelListener = (e) => {
121985
- if (!this._visible) {
121986
- return;
121987
- }
121988
- var delta = Math.max(-1, Math.min(1, -e.deltaY * 40));
121989
- if (delta === 0) {
121990
- return;
121382
+ this._unbindSectionPlane = () => { };
121383
+
121384
+ this.__setSectionPlane = sectionPlane => {
121385
+ this.id = sectionPlane.id;
121386
+ this._sectionPlane = sectionPlane;
121387
+ const setPosFromSectionPlane = () => setPos(sectionPlane.pos);
121388
+ const setDirFromSectionPlane = () => rootNode.quaternion = math.vec3PairToQuaternion(zeroVec$1, sectionPlane.dir, quat$1);
121389
+ setPosFromSectionPlane();
121390
+ setDirFromSectionPlane();
121391
+ const onSectionPlanePos = sectionPlane.on("pos", setPosFromSectionPlane);
121392
+ const onSectionPlaneDir = sectionPlane.on("dir", () => {
121393
+ if (!ignoreNextSectionPlaneDirUpdate) {
121394
+ setDirFromSectionPlane();
121395
+ } else {
121396
+ ignoreNextSectionPlaneDirUpdate = false;
121991
121397
  }
121992
121398
  });
121993
- }
121399
+
121400
+ this._unbindSectionPlane = () => {
121401
+ this.id = null;
121402
+ this._sectionPlane = null;
121403
+ sectionPlane.off(onSectionPlanePos);
121404
+ sectionPlane.off(onSectionPlaneDir);
121405
+ this._unbindSectionPlane = () => { };
121406
+ };
121407
+ };
121408
+
121409
+ this.__destroy = () => {
121410
+ cleanups.forEach(c => c());
121411
+ this._unbindSectionPlane();
121412
+ rootNode.destroy();
121413
+ this._displayMeshes = [ ];
121414
+ for (let id in handlers) {
121415
+ delete handlers[id];
121416
+ }
121417
+ };
121994
121418
  }
121995
121419
 
121996
121420
  _destroy() {
121997
- this._unbindEvents();
121998
- this._destroyNodes();
121421
+ this.__destroy();
121999
121422
  }
122000
121423
 
122001
- _unbindEvents() {
122002
-
122003
- const viewer = this._viewer;
122004
- const scene = viewer.scene;
122005
- const canvas = scene.canvas.canvas;
122006
- const camera = viewer.camera;
122007
- const cameraControl = viewer.cameraControl;
122008
-
122009
- scene.off(this._onSceneTick);
121424
+ /**
121425
+ * Called by SectionPlanesPlugin to assign this Control to a SectionPlane.
121426
+ * SectionPlanesPlugin keeps SectionPlaneControls in a reuse pool.
121427
+ * Call with a null or undefined value to disconnect the Control ffrom whatever SectionPlane it was assigned to.
121428
+ * @private
121429
+ */
121430
+ _setSectionPlane(sectionPlane) {
121431
+ this._unbindSectionPlane();
121432
+ if (sectionPlane) {
121433
+ this.__setSectionPlane(sectionPlane);
121434
+ }
121435
+ }
122010
121436
 
122011
- canvas.removeEventListener("mousedown", this._canvasMouseDownListener);
122012
- canvas.removeEventListener("mousemove", this._canvasMouseMoveListener);
122013
- canvas.removeEventListener("mouseup", this._canvasMouseUpListener);
122014
- canvas.removeEventListener("wheel", this._canvasWheelListener);
121437
+ /**
121438
+ * Gets the {@link SectionPlane} controlled by this Control.
121439
+ * @returns {SectionPlane} The SectionPlane.
121440
+ */
121441
+ get sectionPlane() {
121442
+ return this._sectionPlane;
121443
+ }
122015
121444
 
122016
- camera.off(this._onCameraViewMatrix);
122017
- camera.off(this._onCameraProjMatrix);
121445
+ /**
121446
+ * Sets if this Control is visible.
121447
+ *
121448
+ * @type {Boolean}
121449
+ */
121450
+ setVisible(visible = true) {
121451
+ if (this._visible !== visible) {
121452
+ this._visible = visible;
121453
+ this._displayMeshes.forEach(m => m.visible = visible);
121454
+ }
121455
+ }
122018
121456
 
122019
- cameraControl.off(this._onCameraControlHover);
122020
- cameraControl.off(this._onCameraControlHoverLeave);
121457
+ /**
121458
+ * Gets if this Control is visible.
121459
+ *
121460
+ * @type {Boolean}
121461
+ */
121462
+ getVisible() {
121463
+ return this._visible;
122021
121464
  }
122022
121465
 
122023
- _destroyNodes() {
122024
- this._setSectionPlane(null);
122025
- this._rootNode.destroy();
122026
- this._displayMeshes = {};
122027
- this._affordanceMeshes = {};
121466
+ /**
121467
+ * Sets if this Control is culled. This is called by SectionPlanesPlugin to
121468
+ * temporarily hide the Control while a snapshot is being taken by Viewer#getSnapshot().
121469
+ * @param culled
121470
+ */
121471
+ setCulled(culled) {
121472
+ this._displayMeshes.forEach(m => m.culled = culled);
122028
121473
  }
122029
121474
  }
122030
121475