/** * Performs a pick at the tap location and conditionally arms the dragging flag, so that dragging can occur if * the next event is an onScroll event. */ public void pick(MotionEvent event) { // Perform the pick at the screen x, y PickedObjectList pickList = getWorldWindow().pick(event.getX(), event.getY()); // Examine the picked objects for Renderables PickedObject topPickedObject = pickList.topPickedObject(); // There is only one placemark on the globe and this.isDraggingArmed = topPickedObject != null && topPickedObject.getUserObject() instanceof Placemark; }
public PickedObject topPickedObject() { for (int idx = 0, len = this.entries.size(); idx < len; idx++) { PickedObject po = this.entries.valueAt(idx); if (po.isOnTop()) { return po; } } return null; }
public static PickedObject fromTerrain(int identifier, Position position) { if (position == null) { throw new IllegalArgumentException( Logger.logMessage(Logger.ERROR, "PickedObject", "fromTerrain", "missingPosition")); } Position positionCopy = new Position(position); PickedObject po = new PickedObject(); po.identifier = identifier; po.userObject = positionCopy; po.terrainPosition = positionCopy; return po; }
/** * Performs a pick at the tap location. */ public void pick(MotionEvent event) { final int PICK_REGION_SIZE = 40; // pixels // Forget our last picked objects togglePickedObjectHighlights(); this.pickedObjects.clear(); // Perform a new pick at the screen x, y PickedObjectList pickList = getWorldWindow().pickShapesInRect( event.getX() - PICK_REGION_SIZE / 2, event.getY() - PICK_REGION_SIZE / 2, PICK_REGION_SIZE, PICK_REGION_SIZE); // pickShapesInRect can return multiple objects, i.e., they're may be more that one 'top object' // So we iterate through the list instead of calling pickList.topPickedObject which returns the // arbitrary 'first' top object. for (int i = 0; i < pickList.count(); i++) { if (pickList.pickedObjectAt(i).isOnTop()) { this.pickedObjects.add(pickList.pickedObjectAt(i).getUserObject()); } } togglePickedObjectHighlights(); }
@Override protected void doRender(RenderContext rc) { // Compute this sightline's center point in Cartesian coordinates. if (!this.determineCenterPoint(rc)) { return; } // Don't render anything if the sightline's coverage area is not visible. if (!this.isVisible(rc)) { return; } // Select the currently active attributes. this.determineActiveAttributes(rc); // Configure the pick color when rendering in pick mode. if (rc.pickMode) { this.pickedObjectId = rc.nextPickedObjectId(); this.pickColor = PickedObject.identifierToUniqueColor(this.pickedObjectId, this.pickColor); } // Enqueue drawables for processing on the OpenGL thread. this.makeDrawable(rc); // Enqueue a picked object that associates the sightline's drawables with its picked object ID. if (rc.pickMode) { rc.offerPickedObject(PickedObject.fromRenderable(this.pickedObjectId, this, rc.currentLayer)); } }
protected void resolvePickRect(DrawContext dc) { if (dc.pickedObjects.count() == 0) { return; // no eligible objects; avoid expensive calls to glReadPixels } // Read the unique fragment colors in the pick rectangle. Set<Color> pickColors = dc.readPixelColors(dc.pickViewport.x, dc.pickViewport.y, dc.pickViewport.width, dc.pickViewport.height); for (Color pickColor : pickColors) { // Convert the fragment color to a picked object ID. This returns zero if the color cannot indicate a picked // object ID. int topObjectId = PickedObject.uniqueColorToIdentifier(pickColor); if (topObjectId != 0) { PickedObject topObject = dc.pickedObjects.pickedObjectWithId(topObjectId); if (topObject != null) { topObject.markOnTop(); } } } // Remove all picked objects not marked as on top. dc.pickedObjects.keepTopObjects(); } }
protected void renderTerrainPickedObject(RenderContext rc) { if (rc.terrain.getSector().isEmpty()) { return; // no terrain to pick } // Acquire a unique picked object ID for terrain. int pickedObjectId = rc.nextPickedObjectId(); // Enqueue a drawable for processing on the OpenGL thread that displays terrain in the unique pick color. Pool<DrawableSurfaceColor> pool = rc.getDrawablePool(DrawableSurfaceColor.class); DrawableSurfaceColor drawable = DrawableSurfaceColor.obtain(pool); drawable.color = PickedObject.identifierToUniqueColor(pickedObjectId, drawable.color); drawable.program = (BasicShaderProgram) rc.getShaderProgram(BasicShaderProgram.KEY); if (drawable.program == null) { drawable.program = (BasicShaderProgram) rc.putShaderProgram(BasicShaderProgram.KEY, new BasicShaderProgram(rc.resources)); } rc.offerSurfaceDrawable(drawable, Double.NEGATIVE_INFINITY /*z-order before all other surface drawables*/); // If the pick ray intersects the terrain, enqueue a picked object that associates the terrain drawable with its // picked object ID and the intersection position. if (rc.pickRay != null && rc.terrain.intersect(rc.pickRay, this.pickPoint)) { rc.globe.cartesianToGeographic(this.pickPoint.x, this.pickPoint.y, this.pickPoint.z, this.pickPos); this.pickPos.altitude = 0; // report the actual altitude, which may not lie on the terrain's surface rc.offerPickedObject(PickedObject.fromTerrain(pickedObjectId, this.pickPos)); } }
public PickedObject terrainPickedObject() { for (int idx = 0, len = this.entries.size(); idx < len; idx++) { PickedObject po = this.entries.valueAt(idx); if (po.isTerrain()) { return po; } } return null; }
@Override public String toString() { StringBuilder sb = new StringBuilder("PickedObjectList{"); for (int idx = 0, len = this.entries.size(); idx < len; idx++) { if (idx > 0) { sb.append(", "); } sb.append(this.entries.valueAt(idx).toString()); } sb.append("}"); return sb.toString(); }
@Override protected void doRender(RenderContext rc) { // Don't render anything if the shape is not visible. if (!this.intersectsFrustum(rc)) { return; } // Select the currently active attributes. Don't render anything if the attributes are unspecified. this.determineActiveAttributes(rc); if (this.activeAttributes == null) { return; } // Keep track of the drawable count to determine whether or not this shape has enqueued drawables. int drawableCount = rc.drawableCount(); if (rc.pickMode) { this.pickedObjectId = rc.nextPickedObjectId(); this.pickColor = PickedObject.identifierToUniqueColor(this.pickedObjectId, this.pickColor); } // Enqueue drawables for processing on the OpenGL thread. this.makeDrawable(rc); // Enqueue a picked object that associates the shape's drawables with its picked object ID. if (rc.pickMode && rc.drawableCount() != drawableCount) { rc.offerPickedObject(PickedObject.fromRenderable(this.pickedObjectId, this, rc.currentLayer)); } }
protected void resolvePick(DrawContext dc) { if (dc.pickedObjects.count() == 0) { return; // no eligible objects; avoid expensive calls to glReadPixels } // Read the fragment color at the pick point. this.pickColor = dc.readPixelColor((int) Math.round(dc.pickPoint.x), (int) Math.round(dc.pickPoint.y), this.pickColor); // Convert the fragment color to a picked object ID. This returns zero if the color cannot indicate a picked // object ID, in which case no objects have been drawn at the pick point. int topObjectId = PickedObject.uniqueColorToIdentifier(this.pickColor); if (topObjectId != 0) { PickedObject terrainObject = dc.pickedObjects.terrainPickedObject(); PickedObject topObject = dc.pickedObjects.pickedObjectWithId(topObjectId); if (topObject != null) { topObject.markOnTop(); dc.pickedObjects.clearPickedObjects(); dc.pickedObjects.offerPickedObject(topObject); dc.pickedObjects.offerPickedObject(terrainObject); // handles null objects and duplicate objects } else { dc.pickedObjects.clearPickedObjects(); // no eligible objects drawn at the pick point } } else { dc.pickedObjects.clearPickedObjects(); // no objects drawn at the pick point } }
public boolean hasNonTerrainObjects() { for (int idx = 0, len = this.entries.size(); idx < len; idx++) { PickedObject po = this.entries.valueAt(idx); if (!po.isTerrain()) { return true; } } return false; }
if (rc.pickMode) { renderData.pickedObjectId = rc.nextPickedObjectId(); renderData.pickColor = PickedObject.identifierToUniqueColor(renderData.pickedObjectId, renderData.pickColor); rc.offerPickedObject(PickedObject.fromRenderable(renderData.pickedObjectId, this, rc.currentLayer));
/** * Performs a pick at the tap location. */ public void pick(MotionEvent event) { // Forget our last picked object this.pickedObject = null; // Perform a new pick at the screen x, y PickedObjectList pickList = getWorldWindow().pick(event.getX(), event.getY()); // Get the top-most object for our new picked object PickedObject topPickedObject = pickList.topPickedObject(); if (topPickedObject != null) { this.pickedObject = topPickedObject.getUserObject(); } }
public void keepTopObjects() { ArrayList<Integer> removalList = new ArrayList<>(); // Collect the indices of picked objects not marked as on top. for (int idx = 0, len = this.entries.size(); idx < len; idx++) { PickedObject po = this.entries.valueAt(idx); if (!po.isOnTop()) { removalList.add(idx); } } // Safely remove the picked objects not marked as on top (without iterating over the entries themselves). for (int idx = 0, len = removalList.size(); idx < len; idx++) { int indexToRemove = removalList.get(idx); this.entries.removeAt(indexToRemove); } } }
public static PickedObject fromRenderable(int identifier, Renderable renderable, Layer layer) { if (renderable == null) { throw new IllegalArgumentException( Logger.logMessage(Logger.ERROR, "PickedObject", "fromRenderable", "missingRenderable")); } if (layer == null) { throw new IllegalArgumentException( Logger.logMessage(Logger.ERROR, "PickedObject", "fromRenderable", "missingLayer")); } PickedObject po = new PickedObject(); po.identifier = identifier; po.userObject = (renderable.getPickDelegate() != null) ? renderable.getPickDelegate() : renderable; po.layer = layer; return po; }
@Override protected void doRender(RenderContext rc) { if (this.sector.isEmpty()) { return; // nothing to render } if (!rc.terrain.getSector().intersects(this.sector)) { return; // no terrain surface to render on } Texture texture = rc.getTexture(this.imageSource); // try to get the texture from the cache if (texture == null) { texture = rc.retrieveTexture(this.imageSource, this.imageOptions); // puts retrieved textures in the cache } if (texture == null) { return; // no texture to draw } // Enqueue a drawable surface texture for processing on the OpenGL thread. SurfaceTextureProgram program = this.getShaderProgram(rc); Pool<DrawableSurfaceTexture> pool = rc.getDrawablePool(DrawableSurfaceTexture.class); DrawableSurfaceTexture drawable = DrawableSurfaceTexture.obtain(pool).set(program, this.sector, texture, texture.getTexCoordTransform()); rc.offerSurfaceDrawable(drawable, 0 /*z-order*/); // Enqueue a picked object that associates the drawable surface texture with this surface image. if (rc.pickMode) { int pickedObjectId = rc.nextPickedObjectId(); PickedObject.identifierToUniqueColor(pickedObjectId, drawable.color); rc.offerPickedObject(PickedObject.fromRenderable(pickedObjectId, this, rc.currentLayer)); } }
/** * Performs a pick at the tap location. */ public void pick(MotionEvent event) { // Forget our last picked object this.pickedObject = null; // Perform a new pick at the screen x, y PickedObjectList pickList = getWorldWindow().pick(event.getX(), event.getY()); // Get the top-most object for our new picked object PickedObject topPickedObject = pickList.topPickedObject(); if (topPickedObject != null) { this.pickedObject = topPickedObject.getUserObject(); } }
if (rc.pickMode) { this.pickedObjectId = rc.nextPickedObjectId(); this.pickColor = PickedObject.identifierToUniqueColor(this.pickedObjectId, this.pickColor); rc.offerPickedObject(PickedObject.fromRenderable(this.pickedObjectId, this, rc.currentLayer));
/** * Performs a pick at the tap location and conditionally arms the dragging flag, so that dragging can occur if * the next event is an onScroll event. */ public void pick(MotionEvent event) { // Reset our last picked object this.pickedObject = null; // Perform the pick at the screen x, y PickedObjectList pickList = getWorldWindow().pick(event.getX(), event.getY()); // Examine the picked objects for Renderables PickedObject topPickedObject = pickList.topPickedObject(); if (topPickedObject != null) { if (topPickedObject.getUserObject() instanceof Renderable) { this.pickedObject = (Renderable) topPickedObject.getUserObject(); } } // Determine whether the dragging flag should be "armed". The prerequisite for dragging that an object must // have been previously selected (via a single tap) and the selected object must manifest a "movable" // capability. this.isDraggingArmed = (this.pickedObject != null) && (this.selectedObject == this.pickedObject) && (this.selectedObject.hasUserProperty(MOVABLE)); }