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