UNPKG

@kitware/vtk.js

Version:

Visualization Toolkit for the Web

369 lines (321 loc) 13.7 kB
import { m as macro } from '../../macros2.js'; import vtkInteractorStyle from '../../Rendering/Core/InteractorStyle.js'; import vtkInteractorStyleConstants from '../../Rendering/Core/InteractorStyle/Constants.js'; import { B as degreesFromRadians } from '../../Common/Core/Math/index.js'; import { Device, Input } from '../../Rendering/Core/RenderWindowInteractor/Constants.js'; const { States } = vtkInteractorStyleConstants; /* eslint-disable no-lonely-if */ // ---------------------------------------------------------------------------- // vtkInteractorStyleTrackballCamera methods // ---------------------------------------------------------------------------- function vtkInteractorStyleTrackballCamera(publicAPI, model) { // Set our className model.classHierarchy.push('vtkInteractorStyleTrackballCamera'); // Public API methods publicAPI.handleMouseMove = callData => { const pos = callData.position; const renderer = model.getRenderer(callData); switch (model.state) { case States.IS_ROTATE: publicAPI.handleMouseRotate(renderer, pos); publicAPI.invokeInteractionEvent({ type: 'InteractionEvent' }); break; case States.IS_PAN: publicAPI.handleMousePan(renderer, pos); publicAPI.invokeInteractionEvent({ type: 'InteractionEvent' }); break; case States.IS_DOLLY: publicAPI.handleMouseDolly(renderer, pos); publicAPI.invokeInteractionEvent({ type: 'InteractionEvent' }); break; case States.IS_SPIN: publicAPI.handleMouseSpin(renderer, pos); publicAPI.invokeInteractionEvent({ type: 'InteractionEvent' }); break; } model.previousPosition = pos; }; //---------------------------------------------------------------------------- publicAPI.handleButton3D = ed => { if (ed && ed.pressed && ed.device === Device.RightController && (ed.input === Input.Trigger || ed.input === Input.TrackPad)) { publicAPI.startCameraPose(); return; } if (ed && !ed.pressed && ed.device === Device.RightController && (ed.input === Input.Trigger || ed.input === Input.TrackPad) && model.state === States.IS_CAMERA_POSE) { publicAPI.endCameraPose(); // return; } }; publicAPI.handleMove3D = ed => { switch (model.state) { case States.IS_CAMERA_POSE: publicAPI.updateCameraPose(ed); break; } }; publicAPI.updateCameraPose = ed => { // move the world in the direction of the // controller const camera = model.getRenderer(ed).getActiveCamera(); const oldTrans = camera.getPhysicalTranslation(); // look at the y axis to determine how fast / what direction to move const speed = 0.5; // ed.gamepad.axes[1]; // 0.05 meters / frame movement const pscale = speed * 0.05 * camera.getPhysicalScale(); // convert orientation to world coordinate direction const dir = camera.physicalOrientationToWorldDirection([ed.orientation.x, ed.orientation.y, ed.orientation.z, ed.orientation.w]); camera.setPhysicalTranslation(oldTrans[0] + dir[0] * pscale, oldTrans[1] + dir[1] * pscale, oldTrans[2] + dir[2] * pscale); }; //---------------------------------------------------------------------------- publicAPI.handleLeftButtonPress = callData => { const pos = callData.position; model.previousPosition = pos; if (callData.shiftKey) { if (callData.controlKey || callData.altKey) { publicAPI.startDolly(); } else { publicAPI.startPan(); } } else { if (callData.controlKey || callData.altKey) { publicAPI.startSpin(); } else { publicAPI.startRotate(); } } }; //-------------------------------------------------------------------------- publicAPI.handleLeftButtonRelease = () => { switch (model.state) { case States.IS_DOLLY: publicAPI.endDolly(); break; case States.IS_PAN: publicAPI.endPan(); break; case States.IS_SPIN: publicAPI.endSpin(); break; case States.IS_ROTATE: publicAPI.endRotate(); break; } }; //---------------------------------------------------------------------------- publicAPI.handleStartMouseWheel = () => { publicAPI.startDolly(); }; //-------------------------------------------------------------------------- publicAPI.handleEndMouseWheel = () => { publicAPI.endDolly(); }; //---------------------------------------------------------------------------- publicAPI.handleStartPinch = callData => { model.previousScale = callData.scale; publicAPI.startDolly(); }; //-------------------------------------------------------------------------- publicAPI.handleEndPinch = () => { publicAPI.endDolly(); }; //---------------------------------------------------------------------------- publicAPI.handleStartRotate = callData => { model.previousRotation = callData.rotation; publicAPI.startRotate(); }; //-------------------------------------------------------------------------- publicAPI.handleEndRotate = () => { publicAPI.endRotate(); }; //---------------------------------------------------------------------------- publicAPI.handleStartPan = callData => { model.previousTranslation = callData.translation; publicAPI.startPan(); }; //-------------------------------------------------------------------------- publicAPI.handleEndPan = () => { publicAPI.endPan(); }; //---------------------------------------------------------------------------- publicAPI.handlePinch = callData => { publicAPI.dollyByFactor(model.getRenderer(callData), callData.scale / model.previousScale); model.previousScale = callData.scale; }; //---------------------------------------------------------------------------- publicAPI.handlePan = callData => { const camera = model.getRenderer(callData).getActiveCamera(); // Calculate the focal depth since we'll be using it a lot let viewFocus = camera.getFocalPoint(); viewFocus = publicAPI.computeWorldToDisplay(model.getRenderer(callData), viewFocus[0], viewFocus[1], viewFocus[2]); const focalDepth = viewFocus[2]; const trans = callData.translation; const lastTrans = model.previousTranslation; const newPickPoint = publicAPI.computeDisplayToWorld(model.getRenderer(callData), viewFocus[0] + trans[0] - lastTrans[0], viewFocus[1] + trans[1] - lastTrans[1], focalDepth); // Has to recalc old mouse point since the viewport has moved, // so can't move it outside the loop const oldPickPoint = publicAPI.computeDisplayToWorld(model.getRenderer(callData), viewFocus[0], viewFocus[1], focalDepth); // Camera motion is reversed const motionVector = []; motionVector[0] = oldPickPoint[0] - newPickPoint[0]; motionVector[1] = oldPickPoint[1] - newPickPoint[1]; motionVector[2] = oldPickPoint[2] - newPickPoint[2]; viewFocus = camera.getFocalPoint(); const viewPoint = camera.getPosition(); camera.setFocalPoint(motionVector[0] + viewFocus[0], motionVector[1] + viewFocus[1], motionVector[2] + viewFocus[2]); camera.setPosition(motionVector[0] + viewPoint[0], motionVector[1] + viewPoint[1], motionVector[2] + viewPoint[2]); if (model._interactor.getLightFollowCamera()) { model.getRenderer(callData).updateLightsGeometryToFollowCamera(); } camera.orthogonalizeViewUp(); model.previousTranslation = callData.translation; }; //---------------------------------------------------------------------------- publicAPI.handleRotate = callData => { const camera = model.getRenderer(callData).getActiveCamera(); camera.roll(callData.rotation - model.previousRotation); camera.orthogonalizeViewUp(); model.previousRotation = callData.rotation; }; //-------------------------------------------------------------------------- publicAPI.handleMouseRotate = (renderer, position) => { if (!model.previousPosition) { return; } const rwi = model._interactor; const dx = position.x - model.previousPosition.x; const dy = position.y - model.previousPosition.y; const size = rwi.getView().getViewportSize(renderer); let deltaElevation = -0.1; let deltaAzimuth = -0.1; if (size[0] && size[1]) { deltaElevation = -20.0 / size[1]; deltaAzimuth = -20.0 / size[0]; } const rxf = dx * deltaAzimuth * model.motionFactor; const ryf = dy * deltaElevation * model.motionFactor; const camera = renderer.getActiveCamera(); if (!Number.isNaN(rxf) && !Number.isNaN(ryf)) { camera.azimuth(rxf); camera.elevation(ryf); camera.orthogonalizeViewUp(); } if (model.autoAdjustCameraClippingRange) { renderer.resetCameraClippingRange(); } if (rwi.getLightFollowCamera()) { renderer.updateLightsGeometryToFollowCamera(); } }; //-------------------------------------------------------------------------- publicAPI.handleMouseSpin = (renderer, position) => { if (!model.previousPosition) { return; } const rwi = model._interactor; const camera = renderer.getActiveCamera(); const center = rwi.getView().getViewportCenter(renderer); const oldAngle = degreesFromRadians(Math.atan2(model.previousPosition.y - center[1], model.previousPosition.x - center[0])); const newAngle = degreesFromRadians(Math.atan2(position.y - center[1], position.x - center[0])) - oldAngle; if (!Number.isNaN(newAngle)) { camera.roll(newAngle); camera.orthogonalizeViewUp(); } }; //-------------------------------------------------------------------------- publicAPI.handleMousePan = (renderer, position) => { if (!model.previousPosition) { return; } const camera = renderer.getActiveCamera(); // Calculate the focal depth since we'll be using it a lot let viewFocus = camera.getFocalPoint(); viewFocus = publicAPI.computeWorldToDisplay(renderer, viewFocus[0], viewFocus[1], viewFocus[2]); const focalDepth = viewFocus[2]; const newPickPoint = publicAPI.computeDisplayToWorld(renderer, position.x, position.y, focalDepth); // Has to recalc old mouse point since the viewport has moved, // so can't move it outside the loop const oldPickPoint = publicAPI.computeDisplayToWorld(renderer, model.previousPosition.x, model.previousPosition.y, focalDepth); // Camera motion is reversed const motionVector = []; motionVector[0] = oldPickPoint[0] - newPickPoint[0]; motionVector[1] = oldPickPoint[1] - newPickPoint[1]; motionVector[2] = oldPickPoint[2] - newPickPoint[2]; viewFocus = camera.getFocalPoint(); const viewPoint = camera.getPosition(); camera.setFocalPoint(motionVector[0] + viewFocus[0], motionVector[1] + viewFocus[1], motionVector[2] + viewFocus[2]); camera.setPosition(motionVector[0] + viewPoint[0], motionVector[1] + viewPoint[1], motionVector[2] + viewPoint[2]); if (model._interactor.getLightFollowCamera()) { renderer.updateLightsGeometryToFollowCamera(); } }; //---------------------------------------------------------------------------- publicAPI.handleMouseDolly = (renderer, position) => { if (!model.previousPosition) { return; } const dy = position.y - model.previousPosition.y; const rwi = model._interactor; const center = rwi.getView().getViewportCenter(renderer); const dyf = model.motionFactor * dy / center[1]; publicAPI.dollyByFactor(renderer, 1.1 ** dyf); }; //---------------------------------------------------------------------------- publicAPI.handleMouseWheel = callData => { const dyf = 1 - callData.spinY / model.zoomFactor; publicAPI.dollyByFactor(model.getRenderer(callData), dyf); }; //---------------------------------------------------------------------------- publicAPI.dollyByFactor = (renderer, factor) => { if (Number.isNaN(factor)) { return; } const camera = renderer.getActiveCamera(); if (camera.getParallelProjection()) { camera.setParallelScale(camera.getParallelScale() / factor); } else { camera.dolly(factor); if (model.autoAdjustCameraClippingRange) { renderer.resetCameraClippingRange(); } } if (model._interactor.getLightFollowCamera()) { renderer.updateLightsGeometryToFollowCamera(); } }; } // ---------------------------------------------------------------------------- // Object factory // ---------------------------------------------------------------------------- const DEFAULT_VALUES = { motionFactor: 10.0, zoomFactor: 10.0 }; // ---------------------------------------------------------------------------- function extend(publicAPI, model, initialValues = {}) { Object.assign(model, DEFAULT_VALUES, initialValues); // Inheritance vtkInteractorStyle.extend(publicAPI, model, initialValues); // Create get-set macros macro.setGet(publicAPI, model, ['motionFactor', 'zoomFactor']); // For more macro methods, see "Sources/macros.js" // Object specific methods vtkInteractorStyleTrackballCamera(publicAPI, model); } // ---------------------------------------------------------------------------- const newInstance = macro.newInstance(extend, 'vtkInteractorStyleTrackballCamera'); // ---------------------------------------------------------------------------- var vtkInteractorStyleTrackballCamera$1 = { newInstance, extend }; export { vtkInteractorStyleTrackballCamera$1 as default, extend, newInstance };