package org.geogebra.common.geogebra3D.euclidian3D; import org.geogebra.common.awt.GColor; import org.geogebra.common.awt.GPoint; 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.EuclidianViewCompanion; import org.geogebra.common.euclidian.event.PointerEventType; import org.geogebra.common.geogebra3D.euclidian3D.openGL.PlotterCursor; import org.geogebra.common.geogebra3D.euclidian3D.openGL.Renderer; import org.geogebra.common.geogebra3D.kernel3D.geos.GeoPoint3D; 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.main.Feature; import org.geogebra.common.main.settings.EuclidianSettings3D; /** * Companion for EuclidianView3D * */ public class EuclidianView3DCompanion extends EuclidianViewCompanion { public EuclidianView3DCompanion(EuclidianView view) { super(view); } private EuclidianView3D view3D; @Override protected void setView(EuclidianView view) { super.setView(view); view3D = (EuclidianView3D) view; } @Override public EuclidianView3D getView() { return view3D; } /** * draws the mouse cursor (for glasses) * * @param renderer1 * renderer */ public void drawMouseCursor(Renderer renderer1) { if (!getView().hasMouse()) { return; } if (getView().getProjection() != EuclidianView3D.PROJECTION_GLASSES) { return; } GPoint mouseLoc = getView().getEuclidianController().getMouseLoc(); if (mouseLoc == null) { return; } 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(); // TODO eye lateralization 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); } getView().drawMouseCursor(renderer1, v); } public void drawFreeCursor(Renderer renderer1) { // free point on xOy plane renderer1.drawCursor(PlotterCursor.TYPE_CROSS2D); } public GeoElement getLabelHit(GPoint p, PointerEventType type) { if (type == PointerEventType.TOUCH) { return null; } return getView().getRenderer().getLabelHit(p); } /** * @return mouse pick width for openGL picking */ public int getMousePickWidth() { return 3; } @Override public boolean isMoveable(GeoElement geo) { return geo.isMoveable(); } public int getCapturingThreshold(PointerEventType type) { return getView().getApplication().getCapturingThreshold(type); } /** * @param zNear * near z-coord */ public void setZNearest(double zNear) { // used for some input3D } public void resetAllVisualStyles() { // used for some input3D } public void resetOwnDrawables() { // used for some input3D } public void update() { // used for some input3D } /** * @param renderer1 * renderer */ public void draw(Renderer renderer1) { // used for some input3D } /** * @param renderer1 * renderer */ public void drawHidden(Renderer renderer1) { // used for some input3D } /** * @param renderer1 * renderer */ public void drawTransp(Renderer renderer1) { // used for some input3D } /** * @param renderer1 * renderer */ public void drawHiding(Renderer renderer1) { // used for some input3D } public double getScreenZOffset() { return 0; } public void drawPointAlready(GeoPoint3D point) { getView().drawPointAlready(point.getMoveMode()); } /** * rotate to default */ public void setDefaultRotAnimation() { getView().setRotAnimation(EuclidianView3D.ANGLE_ROT_OZ, EuclidianView3D.ANGLE_ROT_XOY, false); } public void getXMLForStereo(StringBuilder sb, int eyeDistance, int sep) { if (eyeDistance != EuclidianSettings3D.PROJECTION_PERSPECTIVE_EYE_DISTANCE_DEFAULT) { sb.append("\" distance=\""); sb.append(eyeDistance); } if (sep != EuclidianSettings3D.EYE_SEP_DEFAULT) { sb.append("\" separation=\""); sb.append(sep); } } public void setBackground(GColor color) { if (color != null) { getView().setBackground(color, color); } } /** * * @return true if consumes space key hitted */ public boolean handleSpaceKey() { return false; } protected boolean moveCursorIsVisible() { if (getView().getEuclidianController() .getMoveMode() != EuclidianController.MOVE_NONE && getView().getEuclidianController() .getMoveMode() != EuclidianController.MOVE_VIEW) { return false; } return getView().cursorIsTranslateViewCursor() || getView().getEuclidianController() .getMode() == EuclidianConstants.MODE_TRANSLATEVIEW; } protected void drawTranslateViewCursor(Renderer renderer1, EuclidianCursor cursor, GeoPoint3D cursorOnXOYPlane, CoordMatrix4x4 cursorMatrix) { if (getView().getApplication().has(Feature.DIFFERENT_AXIS_RATIO_3D)) { switch (cursor) { default: case MOVE: renderer1.setMatrix(cursorOnXOYPlane.getDrawingMatrix()); getView().drawPointAlready(cursorOnXOYPlane.getRealMoveMode()); renderer1.drawCursor(PlotterCursor.TYPE_CUBE); break; case RESIZE_X: case RESIZE_Y: case RESIZE_Z: renderer1.setMatrix(cursorMatrix); getView().getRenderer() .drawCursor(PlotterCursor.TYPE_ALREADY_Z); renderer1.drawCursor(PlotterCursor.TYPE_CUBE); break; } } else { renderer1.setMatrix(cursorOnXOYPlane.getDrawingMatrix()); getView().drawPointAlready(cursorOnXOYPlane.getRealMoveMode()); renderer1.drawCursor(PlotterCursor.TYPE_CUBE); } } public void updateStylusBeamForMovedGeo() { // used for some 3D inputs } public boolean isPolarized() { return false; } private boolean isStereoBuffered = false; public void setIsStereoBuffered(boolean flag) { isStereoBuffered = flag; } public boolean isStereoBuffered() { return isStereoBuffered; } public boolean wantsStereo() { return isStereoBuffered(); } /** * * @return true if currently uses hand grabbing (3D input) */ public boolean useHandGrabbing() { return false; } public Coords getHittingOrigin(GPoint mouse) { Coords origin = getView().getPickPoint(mouse); if (getView().getProjection() == EuclidianView3D.PROJECTION_PERSPECTIVE || getView() .getProjection() == EuclidianView3D.PROJECTION_GLASSES) { origin = getView().getRenderer().getPerspEye().copyVector(); } getView().toSceneCoords3D(origin); return origin; } /** * * @return direction for hitting */ public Coords getHittingDirection() { return getView().getViewDirection(); } protected void setPickPointFromMouse(GPoint mouse, Coords pickPoint) { Renderer renderer = getView().getRenderer(); int projection = getView().getProjection(); pickPoint.setX(mouse.getX() + renderer.getLeft()); pickPoint.setY(-mouse.getY() + renderer.getTop()); if (projection == EuclidianView3D.PROJECTION_PERSPECTIVE || projection == EuclidianView3D.PROJECTION_GLASSES) { pickPoint.setZ(0); } else { pickPoint.setZ(renderer.getVisibleDepth()); if (projection == EuclidianView3D.PROJECTION_OBLIQUE) { pickPoint.setX(pickPoint.getX() - pickPoint.getZ() * renderer.getObliqueX()); pickPoint.setY(pickPoint.getY() - pickPoint.getZ() * renderer.getObliqueY()); } } } protected boolean decorationVisible() { return getView().getPointDecorations().shouldBeDrawn(); } /** * * @return true if it has to draw 2D/1D arrows to move free point */ protected boolean drawCrossForFreePoint() { return true; } public void initAxisAndPlane() { // needed for input3D } /** * * @return true if we use depth for hitting */ public boolean useInputDepthForHitting() { return false; } }