package org.geogebra.common.geogebra3D.euclidian3D.draw; import org.geogebra.common.euclidian.EuclidianController; import org.geogebra.common.geogebra3D.euclidian3D.EuclidianView3D; import org.geogebra.common.geogebra3D.euclidian3D.Hitting; import org.geogebra.common.geogebra3D.euclidian3D.openGL.Renderer; import org.geogebra.common.geogebra3D.euclidian3D.openGL.Renderer.PickingType; import org.geogebra.common.geogebra3D.kernel3D.geos.GeoQuadric3DLimited; import org.geogebra.common.kernel.geos.GProperty; /** * Class for drawing quadrics. * * @author mathieu * */ public class DrawQuadric3DLimited extends Drawable3D { private DrawConic3D drawBottom, drawTop; private DrawQuadric3DPart drawSide; /** * common constructor * * @param view3d * 3D view * @param geo * limited quadric */ public DrawQuadric3DLimited(EuclidianView3D view3d, GeoQuadric3DLimited geo) { super(view3d, geo); drawBottom = new DrawConic3D(view3d, geo.getBottom()); drawTop = new DrawConic3D(view3d, geo.getTop()); drawSide = new DrawQuadric3DPart(view3d, geo.getSide()); // for hightlight drawBottom.setCreatedByDrawList(this); drawTop.setCreatedByDrawList(this); drawSide.setCreatedByDrawList(this); setPickingType(PickingType.POINT_OR_CURVE); } // drawing @Override public void drawGeometry(Renderer renderer) { // no need } @Override public void drawOutline(Renderer renderer) { drawBottom.drawOutline(renderer); drawTop.drawOutline(renderer); } @Override public void drawGeometryHidden(Renderer renderer) { // not used } @Override public void drawHidden(Renderer renderer) { drawBottom.drawHidden(renderer); drawTop.drawHidden(renderer); } @Override protected void drawGeometryForPicking(Renderer renderer, PickingType type) { drawBottom.drawGeometryForPicking(renderer, type); drawTop.drawGeometryForPicking(renderer, type); drawSide.drawGeometryForPicking(renderer, type); } @Override public int getPickOrder() { return DRAW_PICK_ORDER_SURFACE; } @Override public void addToDrawable3DLists(Drawable3DLists lists) { addToDrawable3DLists(lists, DRAW_TYPE_SURFACES); addToDrawable3DLists(lists, DRAW_TYPE_CURVES); } @Override public void removeFromDrawable3DLists(Drawable3DLists lists) { removeFromDrawable3DLists(lists, DRAW_TYPE_SURFACES); removeFromDrawable3DLists(lists, DRAW_TYPE_CURVES); } @Override protected boolean updateForItSelf() { // no need return true; } @Override protected void updateForView() { // for outline update drawBottom.updateForView(); drawTop.updateForView(); } @Override public void update() { drawBottom.update(); drawTop.update(); drawSide.update(); } @Override public void setWaitForUpdateVisualStyle(GProperty prop) { drawBottom.setWaitForUpdateVisualStyle(prop); drawTop.setWaitForUpdateVisualStyle(prop); drawSide.setWaitForUpdateVisualStyle(prop); } @Override public void setWaitForUpdate() { drawBottom.setWaitForUpdate(); drawTop.setWaitForUpdate(); drawSide.setWaitForUpdate(); } @Override public void setWaitForReset() { drawBottom.setWaitForReset(); drawTop.setWaitForReset(); drawSide.setWaitForReset(); } @Override public void drawNotTransparentSurface(Renderer renderer) { drawBottom.drawNotTransparentSurface(renderer); drawTop.drawNotTransparentSurface(renderer); drawSide.drawNotTransparentSurface(renderer); } @Override public void drawTransp(Renderer renderer) { drawBottom.drawTransp(renderer); drawTop.drawTransp(renderer); drawSide.drawTransp(renderer); } @Override public void drawHiding(Renderer renderer) { drawBottom.drawHiding(renderer); drawTop.drawHiding(renderer); drawSide.drawHiding(renderer); } @Override public boolean isTransparent() { if (getPickingType() == PickingType.SURFACE) { return getAlpha() <= EuclidianController.MAX_TRANSPARENT_ALPHA_VALUE_INT; } return false; } @Override protected double getColorShift() { return COLOR_SHIFT_SURFACE; } @Override public boolean hit(Hitting hitting) { if (waitForReset) { // prevent NPE return false; } double d = Double.NaN; PickingType pickingType = PickingType.SURFACE; if (drawBottom.hit(hitting)) { d = drawBottom.getZPickNear(); pickingType = drawBottom.getPickingType(); } if (drawTop.hit(hitting)) { PickingType pickingTypeTop = drawTop.getPickingType(); if (pickingType == PickingType.SURFACE) { if (pickingTypeTop == PickingType.SURFACE) { double dTop = drawTop.getZPickNear(); if (Double.isNaN(d) || dTop > d) { d = dTop; } } else { // pickingTypeTop == PickingType.POINT_OR_CURVE // TODO: opaque bottom d = drawTop.getZPickNear(); pickingType = pickingTypeTop; } } else { // pickingType == PickingType.POINT_OR_CURVE if (pickingTypeTop == PickingType.SURFACE) { // TODO: opaque top } else { // pickingTypeTop == PickingType.POINT_OR_CURVE double dTop = drawTop.getZPickNear(); if (Double.isNaN(d) || dTop > d) { d = dTop; } } } } if (pickingType == PickingType.POINT_OR_CURVE) { // TODO opaque side setZPick(d, d); setPickingType(PickingType.POINT_OR_CURVE); return true; } if (drawSide.hit(hitting)) { double dSide = drawSide.getZPickNear(); if (Double.isNaN(d) || dSide > d) { d = dSide; } setZPick(d, d); setPickingType(PickingType.SURFACE); return true; } return false; } }