package org.geogebra.common.geogebra3D.input3D;
import org.geogebra.common.awt.GColor;
import org.geogebra.common.awt.GPoint;
import org.geogebra.common.awt.GPointWithZ;
import org.geogebra.common.euclidian.EuclidianConstants;
import org.geogebra.common.euclidian.EuclidianController;
import org.geogebra.common.euclidian.EuclidianCursor;
import org.geogebra.common.euclidian.EuclidianView;
import org.geogebra.common.euclidian.Hits;
import org.geogebra.common.euclidian.event.PointerEventType;
import org.geogebra.common.geogebra3D.euclidian3D.EuclidianView3D;
import org.geogebra.common.geogebra3D.euclidian3D.EuclidianView3DCompanion;
import org.geogebra.common.geogebra3D.euclidian3D.draw.DrawSegment3D;
import org.geogebra.common.geogebra3D.euclidian3D.openGL.PlotterCompletingCursor;
import org.geogebra.common.geogebra3D.euclidian3D.openGL.PlotterCursor;
import org.geogebra.common.geogebra3D.euclidian3D.openGL.Renderer;
import org.geogebra.common.geogebra3D.input3D.Input3D.OutOfField;
import org.geogebra.common.geogebra3D.kernel3D.geos.GeoPlane3DConstant;
import org.geogebra.common.geogebra3D.kernel3D.geos.GeoPoint3D;
import org.geogebra.common.geogebra3D.kernel3D.geos.GeoSegment3D;
import org.geogebra.common.kernel.ModeSetter;
import org.geogebra.common.kernel.Matrix.CoordMatrix4x4;
import org.geogebra.common.kernel.Matrix.Coords;
import org.geogebra.common.kernel.geos.GeoElement;
import org.geogebra.common.kernel.kernelND.GeoPointND;
/**
* Companion for EuclidianView3D using Input3D
*
*/
public class EuclidianViewInput3DCompanion extends EuclidianView3DCompanion {
private Input3D input3D;
private Coords completingCursorOrigin;
private Coords mouse3DScreenPosition = null;
private Coords mouse3DScenePosition;
protected CoordMatrix4x4 tmpMatrix4x4_3 = CoordMatrix4x4.Identity();
public EuclidianViewInput3DCompanion(EuclidianView view) {
super(view);
mouse3DScenePosition = new Coords(4);
mouse3DScenePosition.setW(1);
}
public void setInput3D(Input3D input3D) {
this.input3D = input3D;
if (input3D.useCompletingDelay()) {
completingCursorOrigin = Coords.createInhomCoorsInD3();
}
}
@Override
public void drawMouseCursor(Renderer renderer1) {
if (input3D.currentlyUseMouse2D()) {
super.drawMouseCursor(renderer1);
return;
}
if (input3D.hasMouseDirection()) {
return;
}
// use a 3D mouse position
mouse3DScreenPosition = input3D.getMouse3DPosition();
if (input3D.useInputDepthForHitting()) {
mouse3DScenePosition.set(mouse3DScreenPosition);
getView().toSceneCoords3D(mouse3DScenePosition);
for (int i = 1; i <= 3; i++) {
transparentMouseCursorMatrix.set(i, i,
1 / getView().getScale());
}
transparentMouseCursorMatrix.setOrigin(mouse3DScenePosition);
}
if (input3D.useCompletingDelay()) {
if (drawCompletingCursor(renderer1)) {
return;
}
// draw mouse cursor at the same place
renderer1.drawMouseCursor();
return;
}
getView().drawMouseCursor(renderer1, mouse3DScreenPosition);
}
/**
*
* @param renderer1
* @return false if we need also the mouse cursor
*/
private boolean drawCompletingCursor(Renderer renderer1) {
// are we grabbing?
float hittedGeoCompletingDelay = hittedGeo.getCompletingDelay();
if (hittedGeoCompletingDelay > PlotterCompletingCursor.START_DRAW
&& hittedGeoCompletingDelay <= PlotterCompletingCursor.END_DRAW) {
CoordMatrix4x4.Identity(tmpMatrix4x4_3);
completingCursorOrigin
.setValues(getView().getCursor3D().getInhomCoordsInD3(), 3);
getView().toScreenCoords3D(completingCursorOrigin);
return drawCompletingCursor(renderer1, completingCursorOrigin,
hittedGeoCompletingDelay);
}
// are we releasing?
float stationaryCoordsCompletingDelay = stationaryCoords
.getCompletingDelay();
if (stationaryCoordsCompletingDelay > PlotterCompletingCursor.START_DRAW
&& stationaryCoordsCompletingDelay <= PlotterCompletingCursor.END_DRAW) {
CoordMatrix4x4.Identity(tmpMatrix4x4_3);
completingCursorOrigin
.setValues(stationaryCoords.getCurrentCoords(), 3);
getView().toScreenCoords3D(completingCursorOrigin);
drawCompletingCursor(renderer1, completingCursorOrigin,
1 - stationaryCoordsCompletingDelay);
return true;
}
// are we moving?
if (stationaryCoordsCompletingDelay >= 0
&& stationaryCoordsCompletingDelay <= PlotterCompletingCursor.START_DRAW) {
CoordMatrix4x4.Identity(tmpMatrix4x4_3);
completingCursorOrigin
.setValues(stationaryCoords.getCurrentCoords(), 3);
getView().toScreenCoords3D(completingCursorOrigin);
drawCompletingCursor(renderer1, completingCursorOrigin, 1);
return true;
}
// are we over a moveable geo?
if (hittedGeo.getGeo() != null
&& hittedGeoCompletingDelay <= PlotterCompletingCursor.START_DRAW) {
CoordMatrix4x4.Identity(tmpMatrix4x4_3);
completingCursorOrigin
.setValues(getView().getCursor3D().getInhomCoordsInD3(), 3);
getView().toScreenCoords3D(completingCursorOrigin);
return drawCompletingCursor(renderer1, completingCursorOrigin, 0);
}
// nothing hitted
completingCursorOrigin.setValues(mouse3DScreenPosition, 3);
return drawCompletingCursor(renderer1, completingCursorOrigin, 0);
}
/**
* @return false if we need also the mouse cursor
*/
private boolean drawCompletingCursor(Renderer renderer1, Coords origin,
float completingDelay) {
switch (input3D.getOutOfField()) {
case RIGHT:
origin.setX(renderer1.getRight());
origin.setY(0);
origin.setZ(0);
break;
case LEFT:
origin.setX(renderer1.getLeft());
origin.setY(0);
origin.setZ(0);
break;
case TOP:
origin.setX(0);
origin.setY(renderer1.getTop());
origin.setZ(0);
break;
case BOTTOM:
origin.setX(0);
origin.setY(renderer1.getBottom());
origin.setZ(0);
break;
case FAR:
origin.setX(0);
origin.setY(0);
origin.setZ(renderer1.getFar());
break;
default:
case NEAR:
origin.setX(0);
origin.setY(0);
origin.setZ(renderer1.getNear());
break;
}
// draw at the mouse location
if (input3D.getOutOfField() == OutOfField.NO) {
tmpMatrix4x4_3.setOrigin(origin);
renderer1.setMatrix(tmpMatrix4x4_3);
renderer1.drawCompletingCursor(completingDelay, false);
return false;
}
// draw warner
tmpMatrix4x4_3.setOrigin(origin);
renderer1.setMatrix(tmpMatrix4x4_3);
renderer1.drawCompletingCursor(completingDelay, true);
return true;
// Log.debug("" + input3D.getOutOfField());
}
private CoordMatrix4x4 transparentMouseCursorMatrix = new CoordMatrix4x4();
@Override
public void drawTransp(Renderer renderer1) {
// sphere for mouse cursor
if (input3D.useInputDepthForHitting()
&& mouse3DScreenPosition != null) {
renderer1.setMatrix(transparentMouseCursorMatrix);
if (getView()
.getCursor3DType() == EuclidianView3D.PREVIEW_POINT_FREE) {
renderer1.drawCursor(PlotterCursor.TYPE_SPHERE);
} else {
renderer1.drawCursor(PlotterCursor.TYPE_SPHERE_HIGHLIGHTED);
}
}
}
@Override
public void drawHiding(Renderer renderer1) {
// sphere for mouse cursor
if (input3D.useInputDepthForHitting()
&& mouse3DScreenPosition != null) {
renderer1.setMatrix(transparentMouseCursorMatrix);
renderer1.drawCursor(PlotterCursor.TYPE_SPHERE);
}
}
@Override
public void drawFreeCursor(Renderer renderer1) {
if (input3D.currentlyUseMouse2D()) {
super.drawFreeCursor(renderer1);
} else {
// free point in space
renderer1.drawCursor(PlotterCursor.TYPE_CROSS3D);
}
}
@Override
public GeoElement getLabelHit(GPoint p, PointerEventType type) {
if (input3D.currentlyUseMouse2D()) {
return super.getLabelHit(p, type);
}
return null;
}
@Override
public int getMousePickWidth() {
if (input3D.currentlyUseMouse2D()) {
return super.getMousePickWidth();
}
return Renderer.MOUSE_PICK_DEPTH;
}
@Override
public void setHits(PointerEventType type) {
if (!input3D.currentlyUseMouse2D() && (input3D.isRightPressed()
|| input3D.isThirdButtonPressed())) {
return;
}
super.setHits(type);
if (input3D.currentlyUseMouse2D()) {
return;
}
// not moving a geo : see if user stays on the same hit to select it
if (input3D.useCompletingDelay()
&& getView().getEuclidianController()
.getMoveMode() == EuclidianController.MOVE_NONE
&& !input3D.hasCompletedGrabbingDelay()) {
long time = System.currentTimeMillis();
hittedGeo.setHitted(
getView().getHits3D().getTopHits()
.getFirstGeo6dofMoveable(),
time, mouse3DScreenPosition);
// reset hits
GeoElement geoToHit = hittedGeo.getGeo();
getView().getHits3D().init(geoToHit);
getView().updateCursor3D(getView().getHits());
getView().getApplication().setMode(EuclidianConstants.MODE_MOVE);
if (hittedGeo.hasLongDelay(time)) {
input3D.setHasCompletedGrabbingDelay(true);
getView().getEuclidianController().handleMovedElement(geoToHit,
false, PointerEventType.TOUCH);
}
}
}
@Override
public boolean isMoveable(GeoElement geo) {
if (input3D.currentlyUseMouse2D()) {
return super.isMoveable(geo);
}
if (geo.isGeoPlane() && geo.isIndependent()
&& !(geo instanceof GeoPlane3DConstant)) {
return true;
}
return super.isMoveable(geo);
}
@Override
public int getCapturingThreshold(PointerEventType type) {
if (input3D.currentlyUseMouse2D()) {
return super.getCapturingThreshold(type);
}
return 5 * super.getCapturingThreshold(type);
}
@Override
public boolean hasMouse() {
if (input3D.currentlyUseMouse2D()) {
return super.hasMouse();
}
return input3D.hasMouse(getView());
}
private GeoSegment3D stylusBeam;
private DrawSegment3D stylusBeamDrawable;
static private int STYLUS_BEAM_THICKNESS = 9;
@Override
public void initAxisAndPlane() {
if (input3D.hasMouseDirection()) {
stylusBeam = new GeoSegment3D(
getView().getKernel().getConstruction());
stylusBeam.setCoord(Coords.O, Coords.VX);
stylusBeam.setObjColor(GColor.GREEN);
stylusBeam.setLineThickness(STYLUS_BEAM_THICKNESS);
stylusBeamDrawable = new DrawSegment3D(getView(), stylusBeam) {
@Override
protected boolean isVisible() {
return true;
}
};
}
}
private double zNearest = 4;
@Override
public void setZNearest(double zNear) {
if (Double.isNaN(zNear)) {
zNearest = 4;
} else {
zNearest = -zNear;
}
updateStylusBeam();
}
/**
*
* @return current z nearest hit
*/
public double getZNearest() {
return zNearest;
}
/**
* update stylus beam for moved geo
*/
@Override
public void updateStylusBeamForMovedGeo() {
if (getView().getEuclidianController()
.getMoveMode() == EuclidianController.MOVE_NONE) {
return;
}
if (getView().getEuclidianController()
.getMoveMode() != EuclidianController.MOVE_PLANE) {
getView().getCursor3D().setCoords(input3D.getMouse3DScenePosition(),
false);
GeoElement movedGeo = getView().getEuclidianController()
.getMovedGeoElement();
if (movedGeo != null) {
zNearest = movedGeo.distance(getView().getCursor3D());
}
}
updateStylusBeam();
}
private void updateStylusBeam() {
if (input3D.hasMouseDirection() && !input3D.currentlyUseMouse2D()) {
stylusBeam.setCoord(input3D.getMouse3DScenePosition(),
input3D.getMouse3DDirection().mul(zNearest));
stylusBeamDrawable.setWaitForUpdate();
stylusBeamDrawable.update();
}
}
/**
* set coords to stylus end for given length
*
* @param coords
* returned coords
* @param l
* length
*/
public void getStylusBeamEnd(Coords coords, double l) {
coords.setAdd(input3D.getMouse3DScenePosition(),
coords.setMul(input3D.getMouse3DDirection(), l));
}
@Override
public void resetAllVisualStyles() {
if (input3D.hasMouseDirection()) {
stylusBeamDrawable.setWaitForUpdateVisualStyle(null);
}
}
@Override
public void resetOwnDrawables() {
if (input3D.hasMouseDirection()) {
stylusBeamDrawable.setWaitForReset();
}
}
@Override
public void update() {
if (input3D.hasMouseDirection()) {
stylusBeamDrawable.update();
}
}
@Override
public void draw(Renderer renderer1) {
if (drawStylusBeam()) {
stylusBeamDrawable.drawOutline(renderer1);
}
}
@Override
public void drawHidden(Renderer renderer1) {
if (drawStylusBeam()) {
stylusBeamDrawable.drawHidden(renderer1);
}
}
private boolean drawStylusBeam() {
if (!input3D.hasMouseDirection() || input3D.currentlyUseMouse2D()) {
return false;
}
if (input3D.isLeftPressed()) { // show stylus beam only if object is
// moved
if (getView().getEuclidianController()
.getMoveMode() == EuclidianController.MOVE_NONE) {
return false;
}
return hasMouse();
}
if (input3D.isRightPressed() || input3D.isThirdButtonPressed()) {
return false;
}
return hasMouse();
}
@Override
public double getScreenZOffset() {
if (input3D != null && input3D.useScreenZOffset()) {
return getView().getClippingCubeDrawable().getHorizontalDiagonal()
/ 2;
}
return super.getScreenZOffset();
}
@Override
public void drawPointAlready(GeoPoint3D point) {
if (input3D.currentlyUseMouse2D()) {
super.drawPointAlready(point);
return;
}
if (point.hasRegion()) {
super.drawPointAlready(point);
} else if (!point.isPointOnPath()
&& point.getMoveMode() != GeoPointND.MOVE_MODE_NONE) {
getView().getRenderer().drawCursor(PlotterCursor.TYPE_ALREADY_XYZ);
}
}
@Override
public void setDefaultRotAnimation() {
getView().setRotAnimation(input3D.getDefaultRotationOz(),
input3D.getDefaultRotationXOY(), false);
}
@Override
public void getXMLForStereo(StringBuilder sb, int eyeDistance, int sep) {
if (input3D.shouldStoreStereoToXML()) {
super.getXMLForStereo(sb, eyeDistance, sep);
}
}
final private static double GRAY_SCALE_FOR_INPUT3D = 255 * 0.75;
@Override
public void setBackground(GColor color) {
if (input3D.needsGrayBackground()) {
double grayScale = color.getGrayScale();
if (grayScale > GRAY_SCALE_FOR_INPUT3D) {
double factor = GRAY_SCALE_FOR_INPUT3D / grayScale;
GColor darker = GColor.newColor((int) (color.getRed() * factor),
(int) (color.getGreen() * factor),
(int) (color.getBlue() * factor), 255);
getView().setBackground(color, darker);
return;
}
}
super.setBackground(color);
}
@Override
public boolean handleSpaceKey() {
if (getView().getEuclidianController()
.getMoveMode() == EuclidianController.MOVE_NONE) {
hittedGeo.setHitted(getView().getHits3D().getTopHits()
.getFirstGeo6dofMoveable());
// reset hits
GeoElement geoToHit = hittedGeo.getGeo();
getView().getHits3D().init(geoToHit);
getView().updateCursor3D(getView().getHits());
getView().getApplication().setMode(EuclidianConstants.MODE_MOVE);
if (geoToHit != null) {
hittedGeo.consumeLongDelay();
input3D.setHasCompletedGrabbingDelay(true);
getView().getEuclidianController().handleMovedElement(geoToHit,
false, PointerEventType.TOUCH);
return true;
}
return false;
}
releaseGrabbing();
return true;
}
final private void releaseGrabbing() {
getStationaryCoords().consumeLongDelay();
input3D.setHasCompletedGrabbingDelay(false);
getView().getApplication().getSelectionManager()
.clearSelectedGeos(true);
getView().getEuclidianController().endOfWrapMouseReleased(new Hits(),
false, false, PointerEventType.TOUCH);
}
@Override
public void setMode(int mode, ModeSetter m) {
if (input3D.useHandGrabbing() && getView().getEuclidianController()
.getMoveMode() != EuclidianController.MOVE_NONE) {
releaseGrabbing();
}
super.setMode(mode, m);
}
@Override
protected boolean moveCursorIsVisible() {
if (!input3D.hasMouseDirection() || input3D.currentlyUseMouse2D()) {
return super.moveCursorIsVisible();
}
return input3D.isThirdButtonPressed() || input3D.isRightPressed();
}
private Coords tmpCoords1 = new Coords(4);
@Override
protected void drawTranslateViewCursor(Renderer renderer1,
EuclidianCursor cursor, GeoPoint3D cursorOnXOYPlane,
CoordMatrix4x4 cursorMatrix) {
if (!input3D.hasMouseDirection()) {
super.drawTranslateViewCursor(renderer1, cursor, cursorOnXOYPlane,
cursorMatrix);
} else {
if (input3D.currentlyUseMouse2D()) {
GPoint mouseLoc = getView().getEuclidianController()
.getMouseLoc();
if (mouseLoc == null) {
super.drawTranslateViewCursor(renderer1, cursor,
cursorOnXOYPlane, cursorMatrix);
} else {
Coords v;
if (getView()
.getCursor3DType() == EuclidianView3D.CURSOR_DEFAULT) {
// if mouse is over nothing, use mouse coords and screen
// for depth
v = new Coords(mouseLoc.x + renderer1.getLeft(),
-mouseLoc.y + renderer1.getTop(), 0, 1);
} else {
// if mouse is over an object, use its depth and mouse
// coords
Coords eye = renderer1.getPerspEye();
double z = getView().getToScreenMatrix()
.mul(getView().getCursor3D().getCoords()).getZ()
+ 20; // to
// be
// over
double eyeSep = renderer1.getEyeSep();
double x = mouseLoc.x + renderer1.getLeft() + eyeSep
- eye.getX();
double y = -mouseLoc.y + renderer1.getTop()
- eye.getY();
double dz = eye.getZ() - z;
double coeff = dz / eye.getZ();
v = new Coords(x * coeff - eyeSep + eye.getX(),
y * coeff + eye.getY(), z, 1);
}
tmpMatrix4x4_3.setDiagonal3(1 / getView().getScale());
tmpCoords1.setMul(getView().getToSceneMatrix(), v);
tmpMatrix4x4_3.setOrigin(tmpCoords1);
renderer1.setMatrix(tmpMatrix4x4_3);
getView().drawPointAlready(
cursorOnXOYPlane.getRealMoveMode());
renderer1.drawCursor(PlotterCursor.TYPE_CUBE);
}
} else {
if (input3D.isThirdButtonPressed()) { // third button: translate
// view
// let's scale it a bit more
tmpMatrix4x4_3.setDiagonal3(1.5 / getView().getScale());
// show the cursor at mid beam
input3D.getMouse3DPositionShifted(tmpCoords1);
tmpMatrix4x4_3.setOrigin(tmpCoords1);
renderer1.setMatrix(tmpMatrix4x4_3);
renderer1.drawCursor(PlotterCursor.TYPE_ALREADY_XYZ);
renderer1.drawCursor(PlotterCursor.TYPE_CUBE);
} else { // right button: rotate view
// let's scale it a bit more
tmpMatrix4x4_3.setDiagonal3(1.5 / getView().getScale());
tmpCoords1.setMul(getView().getToSceneMatrix(),
input3D.getRightDragElevation().val);
tmpCoords1.setW(0);
tmpCoords1.addInside(
getView().getToSceneMatrix().getOrigin());
tmpMatrix4x4_3.setOrigin(tmpCoords1);
renderer1.setMatrix(tmpMatrix4x4_3);
renderer1.drawCursor(PlotterCursor.TYPE_ROTATION);
}
}
}
}
final static protected float LONG_DELAY = 1500f;
private static class HittedGeo {
private GeoElement geo;
private long startTime, lastTime;
private long delay = -1;
private Coords startMousePosition = new Coords(3);
/**
* say if we should forget current
*
* @param time
* current time
* @return true if from last time enough delay has passed to forget
* current
*/
private boolean forgetCurrent(long time) {
return (time - lastTime) * 8 > LONG_DELAY;
}
public void setHitted(GeoElement newGeo, long time,
Coords mousePosition) {
// Log.debug("\nHittedGeo:\n"+getHits3D());
if (newGeo == null || mousePosition == null) { // reinit geo
if (forgetCurrent(time)) {
geo = null;
delay = -1;
// Log.debug("\n -- geo = null");
}
} else {
if (newGeo == geo) { // remember last time
// check if mouse has changed too much: reset the timer
int threshold = 30;// getCapturingThreshold(PointerEventType.TOUCH);
if (Math.abs(mousePosition.getX()
- startMousePosition.getX()) > threshold
|| Math.abs(mousePosition.getY()
- startMousePosition.getY()) > threshold
|| Math.abs(mousePosition.getZ()
- startMousePosition.getZ()) > threshold) {
startTime = time;
startMousePosition.setValues(mousePosition, 3);
} else {
lastTime = time;
}
} else if (geo == null || forgetCurrent(time)) { // change
// geo
geo = newGeo;
startTime = time;
startMousePosition.setValues(mousePosition, 3);
}
// Log.debug("\n "+(time-startTime)+"-- geo = "+geo);
}
}
/**
* set hitted geo
*
* @param newGeo
* hitted geo
*/
public void setHitted(GeoElement newGeo) {
geo = newGeo;
if (newGeo == null) {
delay = -1;
}
}
/**
*
* @return current geo
*/
public GeoElement getGeo() {
return geo;
}
/**
*
* @param time
* current time
* @return true if hit was long enough to process left press
*/
public boolean hasLongDelay(long time) {
if (geo == null) {
delay = -1;
return false;
}
delay = time - startTime;
if (delay > LONG_DELAY) {
consumeLongDelay();
return true;
}
return false;
}
public void consumeLongDelay() {
geo = null; // consume event
delay = -1;
}
public float getCompletingDelay() {
return delay / LONG_DELAY;
}
}
private HittedGeo hittedGeo = new HittedGeo();
public class StationaryCoords {
private Coords startCoords = new Coords(4),
currentCoords = new Coords(4);
private long startTime;
private long delay;
private Coords newCoords = Coords.createInhomCoorsInD3();
public StationaryCoords() {
startCoords.setUndefined();
delay = -1;
}
public void setCoords(Coords start, Coords translation, long time) {
newCoords.setValues(start, 3);
newCoords.addInside(translation);
updateCoords(time);
}
public void setCoords(Coords start, long time) {
newCoords.setValues(start, 3);
updateCoords(time);
}
public void updateCoords(long time) {
if (startCoords.isDefined()) {
double distance = Math
.abs(startCoords.getX() - newCoords.getX())
+ Math.abs(startCoords.getY() - newCoords.getY())
+ Math.abs(startCoords.getZ() - newCoords.getZ());
// Log.debug("\n -- "+(distance * ((EuclidianView3D)
// ec.view).getScale()));
if (distance * getView().getScale() > 30) {
startCoords.set(newCoords);
startTime = time;
delay = -1;
// Log.debug("\n -- startCoords =\n"+startCoords);
} else {
currentCoords.set(newCoords);
}
} else {
startCoords.set(newCoords);
startTime = time;
delay = -1;
// Log.debug("\n -- startCoords =\n"+startCoords);
}
}
/**
*
* @param time
* current time
* @return true if hit was long enough to process left release
*/
public boolean hasLongDelay(long time) {
if (startCoords.isDefined()) {
delay = time - startTime;
if (delay > LONG_DELAY) {
consumeLongDelay();
return true;
}
} else {
delay = -1;
}
return false;
}
/**
* consume long delay (reset this)
*/
public void consumeLongDelay() {
startCoords.setUndefined(); // consume event
delay = -1;
}
public float getCompletingDelay() {
return delay / LONG_DELAY;
}
public Coords getCurrentCoords() {
return currentCoords;
}
}
private StationaryCoords stationaryCoords = new StationaryCoords();
public StationaryCoords getStationaryCoords() {
return stationaryCoords;
}
@Override
public boolean isPolarized() {
return input3D.useInterlacedPolarization();
}
@Override
public boolean useHandGrabbing() {
return input3D.useHandGrabbing() && !input3D.currentlyUseMouse2D();
}
@Override
public Coords getHittingOrigin(GPoint mouse) {
if (input3D.hasMouseDirection() && !input3D.currentlyUseMouse2D()) {
return input3D.getMouse3DScenePosition();
}
return super.getHittingOrigin(mouse);
}
@Override
public Coords getHittingDirection() {
if (input3D.hasMouseDirection() && !input3D.currentlyUseMouse2D()) {
return input3D.getMouse3DDirection();
}
return super.getHittingDirection();
}
@Override
protected void setPickPointFromMouse(GPoint mouse, Coords pickPoint) {
super.setPickPointFromMouse(mouse, pickPoint);
if (input3D.currentlyUseMouse2D()) {
return;
}
if (mouse instanceof GPointWithZ) {
pickPoint.setZ(((GPointWithZ) mouse).getZ());
}
}
@Override
protected boolean decorationVisible() {
return (!input3D.hasMouseDirection() || input3D.currentlyUseMouse2D())
&& super.decorationVisible();
}
@Override
protected boolean drawCrossForFreePoint() {
return !input3D.hasMouseDirection() || input3D.currentlyUseMouse2D();
}
@Override
public boolean isStereoBuffered() {
return input3D.isStereoBuffered();
}
@Override
public boolean wantsStereo() {
return input3D.wantsStereo();
}
@Override
public boolean useInputDepthForHitting() {
return input3D.useInputDepthForHitting();
}
}