package org.geogebra.common.geogebra3D.euclidian3D.draw; import org.geogebra.common.euclidian.DrawableND; 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.kernel.Matrix.Coords; import org.geogebra.common.kernel.geos.GProperty; import org.geogebra.common.kernel.geos.GeoElement; import org.geogebra.common.kernel.geos.GeoList; /** * Class for drawing GeoList (3D part) * * @author matthieu * */ public class DrawList3D extends Drawable3D { private GeoList geoList; private boolean isVisible; private Drawable3DListsForDrawList3D drawable3DLists; private DrawList3DArray drawables; /** * common constructor * * @param view3D * @param geo */ public DrawList3D(EuclidianView3D view3D, GeoList geo) { super(view3D, geo); drawables = new DrawList3DArray(view3D, this); this.geoList = geo; drawable3DLists = new Drawable3DListsForDrawList3D(); setPickingType(PickingType.POINT_OR_CURVE); } @Override protected boolean updateForItSelf() { // Log.debug("LIST -- "+getGeoElement()); isVisible = geoList.isEuclidianVisible(); if (!isVisible) { return true; } // getView3D().removeGeoToPick(drawables.size()); // go through list elements and create and/or update drawables int size = geoList.size(); drawables.ensureCapacity(size); int oldDrawableSize = drawables.size(); int drawablePos = 0; for (int i = 0; i < size; i++) { GeoElement listElement = geoList.get(i); // only new 3D elements are drawn if (!listElement.hasDrawable3D()) { continue; } // add drawable for listElement if (drawables.addToDrawableList(listElement, drawablePos, oldDrawableSize, this)) { drawablePos++; } } // remove end of list for (int i = drawables.size() - 1; i >= drawablePos; i--) { // getView3D().remove(drawables.get(i).getGeoElement()); Drawable3D d = (Drawable3D) drawables.get(i); if (d.hasTrace()) { d.addLastTrace(); d.getGeoElement().setUndefined(); } else if (!d.hasRecordedTrace()) { drawable3DLists.remove(d); drawables.remove(i); } else { d.getGeoElement().setUndefined(); } } // update for list of lists for (int i = 0; i < drawables.size(); i++) { Drawable3D d = (Drawable3D) drawables.get(i); if (/* createdByDrawList() || */!d.getGeoElement().isLabelSet()) { if (d.waitForUpdate()) { d.update(); } } } /* * // check if a new update is needed in a next loop for (int i = 0; i < * drawables.size(); i++) { Drawable3D d = (Drawable3D) * drawables.get(i); if (!d.getGeoElement().isLabelSet()) { * //Log.debug("\n" +geoList+"\n -- "+d.getGeoElement()+" -- " * +d.waitForUpdate()); if (d.waitForUpdate()){ return false; } } } */ return true; } @Override public void addLastTrace() { for (int i = 0; i < drawables.size(); i++) { Drawable3D d = (Drawable3D) drawables.get(i); d.addLastTrace(); } } /* * http://dev.geogebra.org/trac/changeset/37937 kills ManySpheres.ggb * * @Override public boolean waitForUpdate(){ for (int i = 0; i < * drawables.size(); i++) { Drawable3D d = (Drawable3D) drawables.get(i); if * (!d.getGeoElement().isLabelSet()) { if (d.waitForUpdate()){ return true; * } } } * * return false; } */ @Override protected void updateForView() { int size = drawables.size(); for (int i = 0; i < size; i++) { Drawable3D d = (Drawable3D) drawables.get(i); if (createdByDrawList() || !d.getGeoElement().isLabelSet()) { d.updateForView(); } } } @Override protected void clearTraceForViewChangedByZoomOrTranslate() { int size = drawables.size(); for (int i = 0; i < size; i++) { Drawable3D d = (Drawable3D) drawables.get(i); if (createdByDrawList() || !d.getGeoElement().isLabelSet()) { d.clearTraceForViewChangedByZoomOrTranslate(); } } } @Override public void addToDrawable3DLists(Drawable3DLists lists) { addToDrawable3DLists(lists, DRAW_TYPE_LISTS); } @Override public void removeFromDrawable3DLists(Drawable3DLists lists) { removeFromDrawable3DLists(lists, DRAW_TYPE_LISTS); } /** * * @return drawable lists */ public Drawable3DListsForDrawList3D getDrawable3DLists() { return drawable3DLists; } @Override public void drawOutline(Renderer renderer) { // TODO Auto-generated method stub } @Override public void drawNotTransparentSurface(Renderer renderer) { // TODO Auto-generated method stub } @Override public void drawGeometry(Renderer renderer) { // TODO Auto-generated method stub } @Override public void drawGeometryHidden(Renderer renderer) { // TODO Auto-generated method stub } @Override public void drawHidden(Renderer renderer) { // TODO Auto-generated method stub } @Override public void drawHiding(Renderer renderer) { // TODO Auto-generated method stub } @Override public void drawTransp(Renderer renderer) { // TODO Auto-generated method stub } @Override public Drawable3D drawForPicking(Renderer renderer, boolean intersection, PickingType type) { // not picked as drawable return null; } @Override public void drawLabel(Renderer renderer) { // no label } @Override public boolean drawLabelForPicking(Renderer renderer) { return false; } @Override public boolean isTransparent() { return false; } @Override protected boolean isLabelVisible() { return isVisible(); // as for texts } @Override protected void updateLabel() { for (DrawableND d : drawables) { if (d instanceof DrawList3D || d instanceof DrawText3D) { ((Drawable3D) d).updateLabel(); } } } @Override protected void updateLabelPosition() { for (DrawableND d : drawables) { if (d instanceof DrawList3D || d instanceof DrawText3D) { ((Drawable3D) d).updateLabelPosition(); } } } @Override protected double getColorShift() { return COLOR_SHIFT_NONE; // not needed here } @Override public void setWaitForUpdateVisualStyle(GProperty prop) { super.setWaitForUpdateVisualStyle(prop); for (DrawableND d : drawables) { d.setWaitForUpdateVisualStyle(prop); } // also update for e.g. line width setWaitForUpdate(); } @Override public void setWaitForReset() { super.setWaitForReset(); for (DrawableND d : drawables) { ((Drawable3D) d).setWaitForReset(); } } // @Override // public void setWaitForUpdate(){ // // super.setWaitForUpdate(); // for (DrawableND d : drawables){ // d.setWaitForUpdate(); // } // } @Override protected Drawable3D getDrawablePicked(Drawable3D drawableSource) { pickOrder = drawableSource.getPickOrder(); setPickingType(drawableSource.getPickingType()); return super.getDrawablePicked(drawableSource); } private int pickOrder = DRAW_PICK_ORDER_MAX; @Override public int getPickOrder() { return pickOrder; } @Override public boolean hit(Hitting hitting) { boolean ret = false; double listZNear = Double.NEGATIVE_INFINITY; double listZFar = Double.NEGATIVE_INFINITY; for (DrawableND d : drawables) { final Drawable3D d3d = (Drawable3D) d; if (d3d.hitForList(hitting)) { double zNear = d3d.getZPickNear(); double zFar = d3d.getZPickFar(); if (!ret || zNear > listZNear) { listZNear = zNear; listZFar = zFar; setPickingType(d3d.getPickingType()); pickOrder = d3d.getPickOrder(); ret = true; } } } if (pickOrder == DRAW_PICK_ORDER_POINT) { // list of points are paths pickOrder = DRAW_PICK_ORDER_PATH; } if (ret) { setZPick(listZNear, listZFar); } return ret; } @Override public void enlargeBounds(Coords min, Coords max) { for (DrawableND d : drawables) { ((Drawable3D) d).enlargeBounds(min, max); } } }