InteractorStyleManipulator

Introduction

vtkPVInteractorStyle allows the user to interactively manipulate the camera,
the viewpoint of the scene. The left button is for rotation; shift + left
button is for rolling; the right button is for panning; and shift + right
button is for zooming. This class fires vtkCommand::StartInteractionEvent
and vtkCommand::EndInteractionEvent to signal start and end of interaction.

If you are looking for the source of this in the VTK codebase, you will not
find it there. Rather it is derived from the vtkPVInteractorStyle class in
the ParaView codebase, which can be found in “ParaViewCore/Rendering/VTKExtensions/Rendering/“.

cameraManipulators

Get the collection of camera manipulators.

centerOfRotation

Set/Get the center of rotation. Propagates the center to the manipulators. This
simply sets an interal ivar. It is propagated to a manipulator before the event is
sent to it. Also, changing the CenterOfRotation during interaction i.e. after a
button press but before a button up has no effect until the next button press. The
default value is [0, 0, 0].

rotationFactor

Set/Get the rotation factor. Propagates the rotation factor to the manipulators.
This simply sets an interal ivar. It is propagated to a manipulator before the event
is sent to it. Also, changing the RotationFactor during interaction i.e. after a
button press but before a button up has no effect until the next button press. The
default value is 1.

onMouseMove()

Event binding controlling the effect of moving the mouse.

onLeftButtonDown()

Event binding controlling the effects of pressing mouse button.

onLeftButtonUp()

Event binding controlling the effects of pressing mouse button.

onMiddleButtonDown()

Event binding controlling the effects of pressing mouse button.

onMiddleButtonUp()

Event binding controlling the effects of pressing mouse button.

onRightButtonDown()

Event binding controlling the effects of pressing mouse button.

onRightButtonUp()

Event binding controlling the effects of pressing mouse button.

handleKeyPress()

Unlike mouse events, this is forwarded to all camera manipulators as onKeyDown(interactor) since we
don’t have a mechanism to activate a manipulator by key presses currently.

handleKeyUp()

Unlike mouse events, this is forwarded to all camera manipulators as onKeyUp(interactor) since we
don’t have a mechanism to activate a manipulator by key presses currently.

addManipulator(vtkCameraManipulator)

Adds a camera manipulator to the internal list/

removeAllManipulators()

Removes all manipulators.

findManipulator(button, shift, control)

Returns the chosen camera manipulator based on the modifiers.

dollyToPosition(fact, position, vtkRenderer) (STATIC)

Dolly the renderer’s camera to a specific point

translateCamera(vtkRenderer, toX, toY, fromX, fromY) (STATIC)

Translate the renderer’s camera

dolly(factor)

Invokes either static “dollyToPosition” method in this class, or else
defers to the parents “dolly” method, depending on whether the control
key is pressed.

Source

Presets.js
import Manipulators from 'vtk.js/Sources/Interaction/Manipulators';

const MANIPULTOR_TYPES = {
slice: Manipulators.vtkMouseCameraSliceManipulator,
multiRotate: Manipulators.vtkMouseCameraTrackballMultiRotateManipulator,
pan: Manipulators.vtkMouseCameraTrackballPanManipulator,
roll: Manipulators.vtkMouseCameraTrackballRollManipulator,
rotate: Manipulators.vtkMouseCameraTrackballRotateManipulator,
zoom: Manipulators.vtkMouseCameraTrackballZoomManipulator,
zoomToMouse: Manipulators.vtkMouseCameraTrackballZoomToMouseManipulator,
range: Manipulators.vtkMouseRangeManipulator,
vrPan: Manipulators.vtkVRButtonPanManipulator,
gestureCamera: Manipulators.vtkGestureCameraManipulator,
};

const STYLES = {
'3D': [
{ type: 'rotate' },
{ type: 'pan', options: { shift: true } },
{ type: 'zoom', options: { control: true } },
{ type: 'zoom', options: { alt: true } },
{ type: 'zoom', options: { dragEnabled: false, scrollEnabled: true } },
{ type: 'zoom', options: { button: 3 } },
{ type: 'roll', options: { shift: true, control: true } },
{ type: 'roll', options: { shift: true, alt: true } },
{ type: 'roll', options: { shift: true, button: 3 } },
{ type: 'vrPan' },
{ type: 'gestureCamera' },
],
'2D': [
{ type: 'pan', options: { shift: true } },
{ type: 'zoom', options: { control: true } },
{ type: 'zoom', options: { alt: true } },
{ type: 'zoom', options: { button: 3 } },
{ type: 'roll', options: { shift: true, alt: true } },
{ type: 'roll', options: { shift: true, button: 3 } },
{ type: 'roll', options: { shift: true } },
{ type: 'vrPan' },
{ type: 'gestureCamera' },
],
};

function applyDefinitions(definitions, manipulatorStyle) {
manipulatorStyle.removeAllManipulators();
for (let idx = 0; idx < definitions.length; idx++) {
const definition = definitions[idx];
const instance = MANIPULTOR_TYPES[definition.type].newInstance(
definition.options
);
if (instance.isA('vtkCompositeVRManipulator')) {
manipulatorStyle.addVRManipulator(instance);
} else if (instance.isA('vtkCompositeGestureManipulator')) {
manipulatorStyle.addGestureManipulator(instance);
} else {
manipulatorStyle.addMouseManipulator(instance);
}
}

return true;
}

function applyPreset(name, manipulatorStyle) {
return applyDefinitions(STYLES[name], manipulatorStyle);
}

function registerManipulatorType(type, classDef) {
MANIPULTOR_TYPES[type] = classDef;
}

function registerStylePreset(name, definitions) {
STYLES[name] = definitions;
}

export default {
applyDefinitions,
applyPreset,
registerManipulatorType,
registerStylePreset,
};
index.js
import macro from 'vtk.js/Sources/macro';
import vtkInteractorStyle from 'vtk.js/Sources/Rendering/Core/InteractorStyle';

const { vtkDebugMacro } = macro;
const { States } = vtkInteractorStyle;

// ----------------------------------------------------------------------------
// Event Types
// ----------------------------------------------------------------------------

const START_INTERACTION_EVENT = { type: 'StartInteractionEvent' };
const INTERACTION_EVENT = { type: 'InteractionEvent' };
const END_INTERACTION_EVENT = { type: 'EndInteractionEvent' };

// ----------------------------------------------------------------------------
// Global methods
// ----------------------------------------------------------------------------

function translateCamera(renderer, rwi, toX, toY, fromX, fromY) {
const cam = renderer.getActiveCamera();
let viewFocus = cam.getFocalPoint();

viewFocus = rwi
.getInteractorStyle()
.computeWorldToDisplay(renderer, viewFocus[0], viewFocus[1], viewFocus[2]);
const focalDepth = viewFocus[2];

const newPickPoint = rwi
.getInteractorStyle()
.computeDisplayToWorld(renderer, toX, toY, focalDepth);
const oldPickPoint = rwi
.getInteractorStyle()
.computeDisplayToWorld(renderer, fromX, fromY, focalDepth);

// camera motion is reversed
const motionVector = [
oldPickPoint[0] - newPickPoint[0],
oldPickPoint[1] - newPickPoint[1],
oldPickPoint[2] - newPickPoint[2],
];

viewFocus = cam.getFocalPoint();
const viewPoint = cam.getPosition();

cam.setFocalPoint(
motionVector[0] + viewFocus[0],
motionVector[1] + viewFocus[1],
motionVector[2] + viewFocus[2]
);
cam.setPosition(
motionVector[0] + viewPoint[0],
motionVector[1] + viewPoint[1],
motionVector[2] + viewPoint[2]
);
}

function dollyToPosition(fact, position, renderer, rwi) {
const cam = renderer.getActiveCamera();

if (cam.getParallelProjection()) {
// Zoom relatively to the cursor
const aSize = rwi.getView().getSize();
const w = aSize[0];
const h = aSize[1];
const x0 = w / 2;
const y0 = h / 2;
const x1 = position.x;
const y1 = position.y;
translateCamera(renderer, rwi, x0, y0, x1, y1);
cam.setParallelScale(cam.getParallelScale() / fact);
translateCamera(renderer, rwi, x1, y1, x0, y0);
} else {
// Zoom relatively to the cursor position

// Move focal point to cursor position
let viewFocus = cam.getFocalPoint();
const norm = cam.getViewPlaneNormal();

viewFocus = rwi
.getInteractorStyle()
.computeWorldToDisplay(
renderer,
viewFocus[0],
viewFocus[1],
viewFocus[2]
);
const newFp = rwi
.getInteractorStyle()
.computeDisplayToWorld(renderer, position.x, position.y, viewFocus[2]);

cam.setFocalPoint(newFp[0], newFp[1], newFp[2]);

// Move camera in/out along projection direction
cam.dolly(fact);
renderer.resetCameraClippingRange();

// Find new focal point
const newCameraPos = cam.getPosition();
viewFocus = cam.getFocalPoint();
const newPoint = [0, 0, 0];
let t =
norm[0] * (viewFocus[0] - newCameraPos[0]) +
norm[1] * (viewFocus[1] - newCameraPos[1]) +
norm[2] * (viewFocus[2] - newCameraPos[2]);
t /= norm[0] ** 2 + norm[1] ** 2 + norm[2] ** 2;
newPoint[0] = newCameraPos[0] + norm[0] * t;
newPoint[1] = newCameraPos[1] + norm[1] * t;
newPoint[2] = newCameraPos[2] + norm[2] * t;

cam.setFocalPoint(newPoint[0], newPoint[1], newPoint[2]);
renderer.resetCameraClippingRange();
}
}

function dollyByFactor(interactor, renderer, factor) {
if (Number.isNaN(factor)) {
return;
}

const camera = renderer.getActiveCamera();
if (camera.getParallelProjection()) {
camera.setParallelScale(camera.getParallelScale() / factor);
} else {
camera.dolly(factor);
renderer.resetCameraClippingRange();
}

if (interactor.getLightFollowCamera()) {
renderer.updateLightsGeometryToFollowCamera();
}
}

// ----------------------------------------------------------------------------
// Static API
// ----------------------------------------------------------------------------

export const STATIC = {
dollyToPosition,
translateCamera,
dollyByFactor,
};

// ----------------------------------------------------------------------------
// vtkInteractorStyleManipulator methods
// ----------------------------------------------------------------------------

function vtkInteractorStyleManipulator(publicAPI, model) {
// Set our className
model.classHierarchy.push('vtkInteractorStyleManipulator');

model.mouseManipulators = [];
model.vrManipulators = [];
model.gestureManipulators = [];
model.currentManipulator = null;
model.currentWheelManipulator = null;
model.centerOfRotation = [0, 0, 0];
model.rotationFactor = 1;

//-------------------------------------------------------------------------
publicAPI.removeAllManipulators = () => {
publicAPI.removeAllMouseManipulators();
publicAPI.removeAllVRManipulators();
publicAPI.removeAllGestureManipulators();
};

//-------------------------------------------------------------------------
publicAPI.removeAllMouseManipulators = () => {
model.mouseManipulators = [];
};

//-------------------------------------------------------------------------
publicAPI.removeAllVRManipulators = () => {
model.vrManipulators = [];
};

//-------------------------------------------------------------------------
publicAPI.removeAllGestureManipulators = () => {
model.gestureManipulators = [];
};

//-------------------------------------------------------------------------
publicAPI.removeMouseManipulator = (index) => {
if (model.mouseManipulators.length > index) {
model.mouseManipulators[index] = null;
}
};

//-------------------------------------------------------------------------
publicAPI.removeVRManipulator = (index) => {
if (model.vrManipulators.length > index) {
model.vrManipulators[index] = null;
}
};

//-------------------------------------------------------------------------
publicAPI.removeGestureManipulator = (index) => {
if (model.gestureManipulators.length > index) {
model.gestureManipulators[index] = null;
}
};

//-------------------------------------------------------------------------
publicAPI.getMouseManipulator = (index) => {
let manipulator = null;
if (model.mouseManipulators.length > index) {
manipulator = model.mouseManipulators[index];
}
return manipulator;
};

//-------------------------------------------------------------------------
publicAPI.getVRManipulator = (index) => {
let manipulator = null;
if (model.vrManipulators.length > index) {
manipulator = model.vrManipulators[index];
}
return manipulator;
};

//-------------------------------------------------------------------------
publicAPI.getGestureManipulator = (index) => {
let manipulator = null;
if (model.gestureManipulators.length > index) {
manipulator = model.gestureManipulators[index];
}
return manipulator;
};

//-------------------------------------------------------------------------
publicAPI.addMouseManipulator = (manipulator) => {
const index = model.mouseManipulators.length;
model.mouseManipulators.push(manipulator);
return index;
};

//-------------------------------------------------------------------------
publicAPI.addVRManipulator = (manipulator) => {
const index = model.vrManipulators.length;
model.vrManipulators.push(manipulator);
return index;
};

//-------------------------------------------------------------------------
publicAPI.addGestureManipulator = (manipulator) => {
const index = model.gestureManipulators.length;
model.gestureManipulators.push(manipulator);
manipulator.setInteractorStyle(publicAPI);
return index;
};

//-------------------------------------------------------------------------
publicAPI.getNumberOfMouseManipulators = () => model.mouseManipulators.length;

//-------------------------------------------------------------------------
publicAPI.getNumberOfVRManipulators = () => model.vrManipulators.length;

//-------------------------------------------------------------------------
publicAPI.getNumberOfGestureManipulators = () =>
model.gestureManipulators.length;

//-------------------------------------------------------------------------
publicAPI.resetCurrentManipulator = () => {
model.currentManipulator = null;
model.currentWheelManipulator = null;
};

//-------------------------------------------------------------------------
// Mouse
//-------------------------------------------------------------------------
publicAPI.handleLeftButtonPress = (callData) => {
model.previousPosition = callData.position;
publicAPI.onButtonDown(1, callData);
};

//-------------------------------------------------------------------------
publicAPI.handleMiddleButtonPress = (callData) => {
model.previousPosition = callData.position;
publicAPI.onButtonDown(2, callData);
};

//-------------------------------------------------------------------------
publicAPI.handleRightButtonPress = (callData) => {
model.previousPosition = callData.position;
publicAPI.onButtonDown(3, callData);
};

//-------------------------------------------------------------------------
publicAPI.handleButton3D = (ed) => {
if (!ed) {
return;
}

// Look for a matching 3D camera interactor.
model.currentManipulator = publicAPI.findVRManipulator(
ed.device,
ed.input,
ed.pressed
);
if (model.currentManipulator) {
model.currentManipulator.onButton3D(
publicAPI,
ed.pokedRenderer,
model.state,
ed.device,
ed.input,
ed.pressed
);
if (ed.pressed) {
publicAPI.startCameraPose();
} else {
publicAPI.endCameraPose();
}
} else {
vtkDebugMacro('No manipulator found');
}
};

//-------------------------------------------------------------------------
publicAPI.handleMove3D = (ed) => {
if (model.currentManipulator && model.state === States.IS_CAMERA_POSE) {
model.currentManipulator.onMove3D(
publicAPI,
ed.pokedRenderer,
model.state,
ed
);
}
};

//-------------------------------------------------------------------------
publicAPI.onButtonDown = (button, callData) => {
// Must not be processing an interaction to start another.
if (model.currentManipulator) {
return;
}

// Look for a matching camera interactor.
model.currentManipulator = publicAPI.findMouseManipulator(
button,
callData.shiftKey,
callData.controlKey,
callData.altKey
);
if (model.currentManipulator) {
if (model.currentManipulator.setCenter) {
model.currentManipulator.setCenter(model.centerOfRotation);
}
if (model.currentManipulator.setRotationFactor) {
model.currentManipulator.setRotationFactor(model.rotationFactor);
}
model.currentManipulator.startInteraction();
model.currentManipulator.onButtonDown(
model.interactor,
callData.pokedRenderer,
callData.position
);
model.interactor.requestAnimation(publicAPI.onButtonDown);
publicAPI.invokeStartInteractionEvent(START_INTERACTION_EVENT);
} else {
vtkDebugMacro('No manipulator found');
}
};

//-------------------------------------------------------------------------
publicAPI.findMouseManipulator = (button, shift, control, alt) => {
// Look for a matching camera manipulator
let manipulator = null;
let count = model.mouseManipulators.length;
while (count--) {
const manip = model.mouseManipulators[count];
if (
manip &&
manip.getButton() === button &&
manip.getShift() === shift &&
manip.getControl() === control &&
manip.getAlt() === alt &&
manip.isDragEnabled()
) {
manipulator = manip;
}
}
return manipulator;
};
//-------------------------------------------------------------------------
publicAPI.findVRManipulator = (device, input) => {
// Look for a matching camera manipulator
let manipulator = null;
let count = model.vrManipulators.length;
while (count--) {
const manip = model.vrManipulators[count];
if (manip && manip.getDevice() === device && manip.getInput() === input) {
manipulator = manip;
}
}
return manipulator;
};

//-------------------------------------------------------------------------
publicAPI.handleLeftButtonRelease = () => {
publicAPI.onButtonUp(1);
};

//-------------------------------------------------------------------------
publicAPI.handleMiddleButtonRelease = () => {
publicAPI.onButtonUp(2);
};

//-------------------------------------------------------------------------
publicAPI.handleRightButtonRelease = () => {
publicAPI.onButtonUp(3);
};

//-------------------------------------------------------------------------
publicAPI.onButtonUp = (button) => {
if (!model.currentManipulator) {
return;
}
if (
model.currentManipulator.getButton &&
model.currentManipulator.getButton() === button
) {
model.currentManipulator.onButtonUp(model.interactor);
model.currentManipulator.endInteraction();
model.currentManipulator = null;
model.interactor.cancelAnimation(publicAPI.onButtonDown);
publicAPI.invokeEndInteractionEvent(END_INTERACTION_EVENT);
}
};

//-------------------------------------------------------------------------
publicAPI.handleStartMouseWheel = (callData) => {
// Must not be processing a wheel interaction to start another.
if (model.currentWheelManipulator) {
return;
}

let manipulator = null;
let count = model.mouseManipulators.length;
while (count--) {
const manip = model.mouseManipulators[count];
if (
manip.isScrollEnabled() &&
manip.getShift() === callData.shiftKey &&
manip.getControl() === callData.controlKey &&
manip.getAlt() === callData.altKey
) {
manipulator = manip;
}
}
if (manipulator) {
model.currentWheelManipulator = manipulator;
model.currentWheelManipulator.onStartScroll(
model.interactor,
callData.pokedRenderer,
callData.spinY
);
model.currentWheelManipulator.startInteraction();
model.interactor.requestAnimation(publicAPI.handleStartMouseWheel);
publicAPI.invokeStartInteractionEvent(START_INTERACTION_EVENT);
} else {
vtkDebugMacro('No manipulator found');
}
};

//-------------------------------------------------------------------------
publicAPI.handleEndMouseWheel = () => {
if (!model.currentWheelManipulator) {
return;
}
if (model.currentWheelManipulator.onEndScroll) {
model.currentWheelManipulator.onEndScroll(model.interactor);
model.currentWheelManipulator.endInteraction();
model.currentWheelManipulator = null;
model.interactor.cancelAnimation(publicAPI.handleStartMouseWheel);
publicAPI.invokeEndInteractionEvent(END_INTERACTION_EVENT);
}
};

//-------------------------------------------------------------------------
publicAPI.handleMouseWheel = (callData) => {
if (
model.currentWheelManipulator &&
model.currentWheelManipulator.onScroll
) {
model.currentWheelManipulator.onScroll(
model.interactor,
callData.pokedRenderer,
callData.spinY
);
publicAPI.invokeInteractionEvent(INTERACTION_EVENT);
}
};

//-------------------------------------------------------------------------
publicAPI.handleMouseMove = (callData) => {
if (model.currentManipulator && model.currentManipulator.onMouseMove) {
model.currentManipulator.onMouseMove(
model.interactor,
callData.pokedRenderer,
callData.position
);
publicAPI.invokeInteractionEvent(INTERACTION_EVENT);
}
};

//-------------------------------------------------------------------------
publicAPI.handleKeyPress = (callData) => {
model.mouseManipulators
.filter((m) => m.onKeyDown)
.forEach((manipulator) => {
manipulator.onKeyDown(model.interactor, callData.key);
publicAPI.invokeInteractionEvent(INTERACTION_EVENT);
});
};

//-------------------------------------------------------------------------
publicAPI.handleKeyUp = (callData) => {
model.mouseManipulators.filter((m) => m.onKeyUp).forEach((manipulator) => {
manipulator.onKeyUp(model.interactor, callData.key);
publicAPI.invokeInteractionEvent(INTERACTION_EVENT);
});
};

//-------------------------------------------------------------------------
// Gesture
//-------------------------------------------------------------------------

publicAPI.handleStartPinch = (callData) => {
publicAPI.startDolly();
let count = model.gestureManipulators.length;
while (count--) {
const manipulator = model.gestureManipulators[count];
if (manipulator.isPinchEnabled()) {
manipulator.onStartPinch(model.interactor, callData.scale);
manipulator.startInteraction();
}
}
model.interactor.requestAnimation(publicAPI.handleStartPinch);
publicAPI.invokeStartInteractionEvent(START_INTERACTION_EVENT);
};

//--------------------------------------------------------------------------
publicAPI.handleEndPinch = () => {
publicAPI.endDolly();
let count = model.gestureManipulators.length;
while (count--) {
const manipulator = model.gestureManipulators[count];
if (manipulator.isPinchEnabled()) {
manipulator.onEndPinch(model.interactor);
manipulator.endInteraction();
}
}
model.interactor.cancelAnimation(publicAPI.handleStartPinch);
publicAPI.invokeEndInteractionEvent(END_INTERACTION_EVENT);
};

//----------------------------------------------------------------------------
publicAPI.handleStartRotate = (callData) => {
publicAPI.startRotate();
let count = model.gestureManipulators.length;
while (count--) {
const manipulator = model.gestureManipulators[count];
if (manipulator.isRotateEnabled()) {
manipulator.onStartRotate(model.interactor, callData.rotation);
manipulator.startInteraction();
}
}
model.interactor.requestAnimation(publicAPI.handleStartRotate);
publicAPI.invokeStartInteractionEvent(START_INTERACTION_EVENT);
};

//--------------------------------------------------------------------------
publicAPI.handleEndRotate = () => {
publicAPI.endRotate();
let count = model.gestureManipulators.length;
while (count--) {
const manipulator = model.gestureManipulators[count];
if (manipulator.isRotateEnabled()) {
manipulator.onEndRotate(model.interactor);
manipulator.endInteraction();
}
}
model.interactor.cancelAnimation(publicAPI.handleStartRotate);
publicAPI.invokeEndInteractionEvent(END_INTERACTION_EVENT);
};

//----------------------------------------------------------------------------
publicAPI.handleStartPan = (callData) => {
publicAPI.startPan();
let count = model.gestureManipulators.length;
while (count--) {
const manipulator = model.gestureManipulators[count];
if (manipulator.isPanEnabled()) {
manipulator.onStartPan(model.interactor, callData.translation);
manipulator.startInteraction();
}
}
model.interactor.requestAnimation(publicAPI.handleStartPan);
publicAPI.invokeStartInteractionEvent(START_INTERACTION_EVENT);
};

//--------------------------------------------------------------------------
publicAPI.handleEndPan = () => {
publicAPI.endPan();
let count = model.gestureManipulators.length;
while (count--) {
const manipulator = model.gestureManipulators[count];
if (manipulator.isPanEnabled()) {
manipulator.onEndPan(model.interactor);
manipulator.endInteraction();
}
}
model.interactor.cancelAnimation(publicAPI.handleStartPan);
publicAPI.invokeEndInteractionEvent(END_INTERACTION_EVENT);
};

//----------------------------------------------------------------------------
publicAPI.handlePinch = (callData) => {
let count = model.gestureManipulators.length;
let actionCount = 0;
while (count--) {
const manipulator = model.gestureManipulators[count];
if (manipulator.isPinchEnabled()) {
manipulator.onPinch(
model.interactor,
callData.pokedRenderer,
callData.scale
);
actionCount++;
}
}
if (actionCount) {
publicAPI.invokeInteractionEvent(INTERACTION_EVENT);
}
};

//----------------------------------------------------------------------------
publicAPI.handlePan = (callData) => {
let count = model.gestureManipulators.length;
let actionCount = 0;
while (count--) {
const manipulator = model.gestureManipulators[count];
if (manipulator.isPanEnabled()) {
manipulator.onPan(
model.interactor,
callData.pokedRenderer,
callData.translation
);
actionCount++;
}
}
if (actionCount) {
publicAPI.invokeInteractionEvent(INTERACTION_EVENT);
}
};

//----------------------------------------------------------------------------
publicAPI.handleRotate = (callData) => {
let count = model.gestureManipulators.length;
let actionCount = 0;
while (count--) {
const manipulator = model.gestureManipulators[count];
if (manipulator.isRotateEnabled()) {
manipulator.onRotate(
model.interactor,
callData.pokedRenderer,
callData.rotation
);
actionCount++;
}
}
if (actionCount) {
publicAPI.invokeInteractionEvent(INTERACTION_EVENT);
}
};
}

// ----------------------------------------------------------------------------
// Object factory
// ----------------------------------------------------------------------------

const DEFAULT_VALUES = {
currentManipulator: null,
currentWheelManipulator: null,
// mouseManipulators: null,
// vrManipulators: null,
// gestureManipulators: null,
centerOfRotation: [0, 0, 0],
rotationFactor: 1,
};

// ----------------------------------------------------------------------------

export 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, ['rotationFactor']);

macro.setGetArray(publicAPI, model, ['centerOfRotation'], 3);

// Object specific methods
vtkInteractorStyleManipulator(publicAPI, model);
}

// ----------------------------------------------------------------------------

export const newInstance = macro.newInstance(
extend,
'vtkInteractorStyleManipulator'
);

// ----------------------------------------------------------------------------

export default Object.assign({ newInstance, extend }, STATIC);