From 6800661db3ff069bc4f65a398dfb325c7f9ca650 Mon Sep 17 00:00:00 2001 From: AlexisDrogoul Date: Sun, 17 Oct 2021 19:09:51 +0700 Subject: [PATCH] Fixes #3232 and simplifies some layer operations in OpenGL --- .../gama/common/interfaces/ILayerManager.java | 18 +- .../gama/outputs/display/LayerManager.java | 39 +- .../statements/draw/DrawingAttributes.java | 410 ++++++++++++++---- .../src/ummisco/gama/opengl/OpenGL.java | 34 +- .../renderer/helpers/PickingHelper.java | 5 + .../opengl/renderer/helpers/SceneHelper.java | 82 +++- .../gama/opengl/scene/AbstractObject.java | 137 ++++-- .../ummisco/gama/opengl/scene/ModelScene.java | 166 ++++++- .../gama/opengl/scene/ObjectDrawer.java | 55 ++- .../opengl/scene/geometry/GeometryDrawer.java | 160 ++++++- .../opengl/scene/geometry/GeometryObject.java | 19 +- .../opengl/scene/layers/AxesLayerObject.java | 29 ++ .../gama/opengl/scene/layers/LayerObject.java | 71 +-- .../scene/layers/OverlayLayerObject.java | 6 +- .../gama/opengl/scene/mesh/MeshObject.java | 19 +- .../scene/resources/ResourceObject.java | 19 +- .../gama/opengl/scene/text/StringObject.java | 18 +- .../opengl/view/SWTOpenGLDisplaySurface.java | 11 +- .../ui/views/displays/DisplaySurfaceMenu.java | 216 ++++++--- 19 files changed, 1164 insertions(+), 350 deletions(-) diff --git a/msi.gama.core/src/msi/gama/common/interfaces/ILayerManager.java b/msi.gama.core/src/msi/gama/common/interfaces/ILayerManager.java index 6a9c8654d3..94eefee572 100644 --- a/msi.gama.core/src/msi/gama/common/interfaces/ILayerManager.java +++ b/msi.gama.core/src/msi/gama/common/interfaces/ILayerManager.java @@ -1,12 +1,12 @@ /******************************************************************************************************* * - * msi.gama.common.interfaces.ILayerManager.java, in plugin msi.gama.core, is part of the source code of the GAMA - * modeling and simulation platform (v. 1.8.1) + * ILayerManager.java, in msi.gama.core, is part of the source code of the + * GAMA modeling and simulation platform (v.1.8.2). * - * (c) 2007-2020 UMI 209 UMMISCO IRD/SU & Partners + * (c) 2007-2021 UMI 209 UMMISCO IRD/SU & Partners (IRIT, MIAT, TLU, CTU) * * Visit https://github.com/gama-platform/gama for license information and contacts. - * + * ********************************************************************************************************/ package msi.gama.common.interfaces; @@ -78,6 +78,16 @@ public interface ILayerManager extends ItemList, IDisposable { */ boolean isProvidingWorldCoordinates(); + /** + * Checks for mouse menu event layer. + * + * @return true, if successful + */ boolean hasMouseMenuEventLayer(); + /** + * Force redrawing layers. + */ + void forceRedrawingLayers(); + } diff --git a/msi.gama.core/src/msi/gama/outputs/display/LayerManager.java b/msi.gama.core/src/msi/gama/outputs/display/LayerManager.java index 4b23008a27..7518811f99 100644 --- a/msi.gama.core/src/msi/gama/outputs/display/LayerManager.java +++ b/msi.gama.core/src/msi/gama/outputs/display/LayerManager.java @@ -162,28 +162,26 @@ public void drawLayersOn(final IGraphics g) { // If the experiment is already closed if (scope == null || scope.interrupted()) return; scope.setGraphics(g); - try { - boolean changed = false; - // First we compute all the data and verify if anything is changed - for (final ILayer dis : layers) { - if (scope.interrupted()) return; - changed |= dis.getData().compute(scope, g); - } - if (changed) { - for (final ILayer l : layers) { l.forceRedrawingOnce(); } - surface.layersChanged(); - } - if (g.beginDrawingLayers()) { + boolean changed = false; + // First we compute all the data and verify if anything is changed + for (final ILayer dis : layers) { + if (scope.interrupted()) return; + changed |= dis.getData().compute(scope, g); + } + if (changed) { forceRedrawingLayers(); } + + if (g.beginDrawingLayers()) { + try { // We separate in two phases: updating of the data and then drawing for (final ILayer dis : layers) { if (scope.interrupted()) return; dis.draw(scope, g); } + } catch (final Exception e) { + GAMA.reportAndThrowIfNeeded(scope, GamaRuntimeException.create(e, scope), false); + } finally { + g.endDrawingLayers(); } - } catch (final Exception e) { - GAMA.reportAndThrowIfNeeded(scope, GamaRuntimeException.create(e, scope), false); - } finally { - g.endDrawingLayers(); } } @@ -257,12 +255,17 @@ public void makeItemVisible(final ILayer obj, final boolean b) { } else { obj.disableOn(surface); } - for (final ILayer l : layers) { l.forceRedrawingOnce(); } - surface.layersChanged(); + forceRedrawingLayers(); }); } + @Override + public void forceRedrawingLayers() { + for (final ILayer l : layers) { l.forceRedrawingOnce(); } + surface.layersChanged(); + } + @Override public boolean isProvidingCoordinates() { for (final ILayer i : layers) { if (i.getData().isVisible() && i.isProvidingCoordinates()) return true; } diff --git a/msi.gama.core/src/msi/gaml/statements/draw/DrawingAttributes.java b/msi.gama.core/src/msi/gaml/statements/draw/DrawingAttributes.java index f8f4f0e6e8..fd52bab9f8 100644 --- a/msi.gama.core/src/msi/gaml/statements/draw/DrawingAttributes.java +++ b/msi.gama.core/src/msi/gaml/statements/draw/DrawingAttributes.java @@ -1,9 +1,9 @@ /******************************************************************************************************* * - * msi.gaml.statements.draw.DrawingAttributes.java, in plugin msi.gama.core, is part of the source code of the GAMA - * modeling and simulation platform (v. 1.8.1) + * DrawingAttributes.java, in msi.gama.core, is part of the source code of the GAMA modeling and simulation platform + * (v.1.8.2). * - * (c) 2007-2020 UMI 209 UMMISCO IRD/SU & Partners + * (c) 2007-2021 UMI 209 UMMISCO IRD/SU & Partners (IRIT, MIAT, TLU, CTU) * * Visit https://github.com/gama-platform/gama for license information and contacts. * @@ -24,35 +24,107 @@ import msi.gama.util.GamaMaterial; import msi.gama.util.file.GamaGifFile; import msi.gaml.operators.IUnits; +import ummisco.gama.dev.utils.DEBUG; +/** + * The Class DrawingAttributes. + */ public class DrawingAttributes { + static { + DEBUG.ON(); + } + + /** + * The Enum DrawerType. + */ + public enum DrawerType { + + /** The geometry. */ + GEOMETRY, + /** The string. */ + STRING, + /** The mesh. */ + MESH, + /** The resource. */ + RESOURCE + } + + /** The index. */ private static int INDEX = 0; + + /** The Constant TEXTURED_COLOR. */ public static final GamaColor TEXTURED_COLOR = new GamaColor(Color.white); + + /** The Constant SELECTED_COLOR. */ public static final GamaColor SELECTED_COLOR = new GamaColor(Color.red); + /** The Constant EMPTY. */ public static final int EMPTY = 1; + + /** The Constant SELECTED. */ public static final int SELECTED = 2; + + /** The Constant SYNTHETIC. */ public static final int SYNTHETIC = 4; + + /** The Constant LIGHTING. */ public static final int LIGHTING = 8; + /** The flags. */ int flags = LIGHTING; + /** The unique index. */ private final int uniqueIndex; + + /** The location. */ GamaPoint location; + + /** The size. */ Scaling3D size; + + /** The rotation. */ AxisAngle rotation; + + /** The line width. */ Double depth = null, lineWidth = GamaPreferences.Displays.CORE_LINE_WIDTH.getValue(); + + /** The type. */ public IShape.Type type; + + /** The border. */ GamaColor fill, highlight, border; + + /** The textures. */ List textures; + + /** The material. */ GamaMaterial material; + /** + * Instantiates a new drawing attributes. + */ private DrawingAttributes() { uniqueIndex = INDEX++; } + /** + * Instantiates a new drawing attributes. + * + * @param size + * the size + * @param rotation + * the rotation + * @param location + * the location + * @param color + * the color + * @param border + * the border + * @param lighting + * the lighting + */ public DrawingAttributes(final Scaling3D size, final AxisAngle rotation, final GamaPoint location, final GamaColor color, final GamaColor border, final Boolean lighting) { this(); @@ -64,23 +136,47 @@ public DrawingAttributes(final Scaling3D size, final AxisAngle rotation, final G setLighting(lighting); } - public int getIndex() { - return uniqueIndex; - } + /** + * Gets the index. + * + * @return the index + */ + public int getIndex() { return uniqueIndex; } + /** + * Sets the synthetic. + * + * @param s + * the new synthetic + */ public void setSynthetic(final boolean s) { setFlag(SYNTHETIC, s); } - public boolean isSynthetic() { - return isSet(SYNTHETIC); - } + /** + * Checks if is synthetic. + * + * @return true, if is synthetic + */ + public boolean isSynthetic() { return isSet(SYNTHETIC); } + /** + * Sets the lighting. + * + * @param lighting + * the new lighting + */ public void setLighting(final Boolean lighting) { if (lighting == null) return; setFlag(LIGHTING, lighting); } + /** + * Sets the empty. + * + * @param b + * the new empty + */ public void setEmpty(final Boolean b) { if (b == null || !b) { setFilled(); @@ -89,13 +185,19 @@ public void setEmpty(final Boolean b) { } } - public IAgent getAgentIdentifier() { - return null; - } + /** + * Gets the agent identifier. + * + * @return the agent identifier + */ + public IAgent getAgentIdentifier() { return null; } - public String getSpeciesName() { - return null; - } + /** + * Gets the species name. + * + * @return the species name + */ + public String getSpeciesName() { return null; } /** * Returns the angle of the rotation in degrees (or null if no rotation is defined) @@ -107,6 +209,12 @@ public Double getAngle() { return getRotation().angle; } + /** + * Sets the texture. + * + * @param o + * the new texture + */ public void setTexture(final Object o) { if (o == null) { setTextures(null); @@ -115,26 +223,50 @@ public void setTexture(final Object o) { } } + /** + * Mark selected. + * + * @param pickedIndex + * the picked index + */ public void markSelected(final int pickedIndex) { setSelected(pickedIndex == uniqueIndex); } - public GamaPoint getAnchor() { - return IUnits.bottom_left; - } + /** + * Gets the anchor. + * + * @return the anchor + */ + public GamaPoint getAnchor() { return IUnits.bottom_left; } - public GamaPoint getLocation() { - return location; - } + /** + * Gets the location. + * + * @return the location + */ + public GamaPoint getLocation() { return location; } - public Scaling3D getSize() { - return size; - } + /** + * Gets the size. + * + * @return the size + */ + public Scaling3D getSize() { return size; } - public Double getDepth() { - return depth; - } + /** + * Gets the depth. + * + * @return the depth + */ + public Double getDepth() { return depth; } + /** + * Sets the line width. + * + * @param d + * the new line width + */ public void setLineWidth(final Double d) { if (d == null) { lineWidth = GamaPreferences.Displays.CORE_LINE_WIDTH.getValue(); @@ -143,46 +275,90 @@ public void setLineWidth(final Double d) { } } - public Double getLineWidth() { - return lineWidth; - } + /** + * Gets the line width. + * + * @return the line width + */ + public Double getLineWidth() { return lineWidth; } - public IShape.Type getType() { - return type; - } + /** + * Gets the type. + * + * @return the type + */ + public IShape.Type getType() { return type; } + /** + * Use cache. + * + * @return true, if successful + */ public boolean useCache() { return true; } - public void setType(final IShape.Type type) { - this.type = type; - } + /** + * Sets the type. + * + * @param type + * the new type + */ + public void setType(final IShape.Type type) { this.type = type; } - public AxisAngle getRotation() { - return rotation; - } + /** + * Gets the rotation. + * + * @return the rotation + */ + public AxisAngle getRotation() { return rotation; } - public void setLocation(final GamaPoint loc) { - location = loc; - } + /** + * Sets the location. + * + * @param loc + * the new location + */ + public void setLocation(final GamaPoint loc) { location = loc; } - public void setSize(final Scaling3D size) { - this.size = size; - } + /** + * Sets the size. + * + * @param size + * the new size + */ + public void setSize(final Scaling3D size) { this.size = size; } + /** + * Sets the rotation. + * + * @param rotation + * the new rotation + */ public void setRotation(final AxisAngle rotation) { if (rotation == null) return; this.rotation = rotation; } + /** + * Sets the height. + * + * @param depth + * the new height + */ public void setHeight(final Double depth) { if (depth == null) return; this.depth = depth; } + /** + * Gets the color. + * + * @return the color + */ public GamaColor getColor() { - if (isSet(SELECTED)) return SELECTED_COLOR; + if (isSelected()) // DEBUG.OUT("Selected agent: " + getAgentIdentifier() + " / index : " + uniqueIndex); + return SELECTED_COLOR; if (highlight != null) return highlight; if (isSet(EMPTY)) return null; if (fill == null) { @@ -196,47 +372,90 @@ public GamaColor getColor() { return fill; } + /** + * Gets the border. + * + * @return the border + */ public GamaColor getBorder() { if (isSet(EMPTY) && border == null) return fill; return border; } + /** + * Sets the empty. + */ public void setEmpty() { setFlag(EMPTY, true); } + /** + * Sets the filled. + */ public void setFilled() { setFlag(EMPTY, false); } - public void setFill(final GamaColor color) { - fill = color; - } + /** + * Sets the fill. + * + * @param color + * the new fill + */ + public void setFill(final GamaColor color) { fill = color; } - public void setBorder(final GamaColor border) { - this.border = border; - } + /** + * Sets the border. + * + * @param border + * the new border + */ + public void setBorder(final GamaColor border) { this.border = border; } + /** + * Sets the lighting. + * + * @param lighting + * the new lighting + */ void setLighting(final boolean lighting) { setFlag(LIGHTING, lighting); } + /** + * Sets the no border. + */ public void setNoBorder() { border = null; } - public void setTextures(final List textures) { - this.textures = textures; - } + /** + * Sets the textures. + * + * @param textures + * the new textures + */ + public void setTextures(final List textures) { this.textures = textures; } - public List getTextures() { - return textures; - } + /** + * Gets the textures. + * + * @return the textures + */ + public List getTextures() { return textures; } - public boolean isEmpty() { - return isSet(EMPTY); - } + /** + * Checks if is empty. + * + * @return true, if is empty + */ + public boolean isEmpty() { return isSet(EMPTY); } + /** + * Checks if is animated. + * + * @return true, if is animated + */ public boolean isAnimated() { if (!useCache()) return true; if (textures == null) return false; @@ -245,6 +464,11 @@ public boolean isAnimated() { return true; } + /** + * Gets the frame count. + * + * @return the frame count + */ public int getFrameCount() { if (textures == null) return 1; final Object o = textures.get(0); @@ -253,6 +477,11 @@ public int getFrameCount() { } + /** + * Gets the average delay. + * + * @return the average delay + */ public int getAverageDelay() { if (textures == null) return 0; final Object o = textures.get(0); @@ -261,18 +490,34 @@ public int getAverageDelay() { } - public boolean isLighting() { - return isSet(LIGHTING); - } + /** + * Checks if is lighting. + * + * @return true, if is lighting + */ + public boolean isLighting() { return isSet(LIGHTING); } - public void setHighlighted(final GamaColor color) { - highlight = color; - } + /** + * Sets the highlighted. + * + * @param color + * the new highlighted + */ + public void setHighlighted(final GamaColor color) { highlight = color; } - public boolean isSelected() { - return isSet(SELECTED); - } + /** + * Checks if is selected. + * + * @return true, if is selected + */ + public boolean isSelected() { return isSet(SELECTED); } + /** + * Sets the selected. + * + * @param b + * the new selected + */ public void setSelected(final boolean b) { setFlag(SELECTED, b); } @@ -282,19 +527,38 @@ public void setSelected(final boolean b) { * * @see msi.gaml.statements.draw.DrawingAttributes#getMaterial() */ - public GamaMaterial getMaterial() { - return material; - } + public GamaMaterial getMaterial() { return material; } + /** + * Sets the material. + * + * @param m + * the new material + */ public void setMaterial(final GamaMaterial m) { material = m; } + /** + * Checks if is sets the. + * + * @param value + * the value + * @return true, if is sets the + */ public boolean isSet(final int value) { return (flags & value) == value; } + /** + * Sets the flag. + * + * @param value + * the value + * @param b + * the b + */ public void setFlag(final int value, final boolean b) { flags = b ? flags | value : flags & ~value; } diff --git a/ummisco.gama.opengl/src/ummisco/gama/opengl/OpenGL.java b/ummisco.gama.opengl/src/ummisco/gama/opengl/OpenGL.java index 54832184d8..06445371b1 100644 --- a/ummisco.gama.opengl/src/ummisco/gama/opengl/OpenGL.java +++ b/ummisco.gama.opengl/src/ummisco/gama/opengl/OpenGL.java @@ -52,6 +52,7 @@ import msi.gama.util.file.GamaImageFile; import msi.gaml.operators.Maths; import msi.gaml.statements.draw.DrawingAttributes; +import msi.gaml.statements.draw.DrawingAttributes.DrawerType; import ummisco.gama.dev.utils.DEBUG; import ummisco.gama.opengl.renderer.IOpenGLRenderer; import ummisco.gama.opengl.renderer.caches.GeometryCache; @@ -250,7 +251,7 @@ public OpenGL(final IOpenGLRenderer renderer) { * the type * @return the drawer for */ - public ObjectDrawer> getDrawerFor(final AbstractObject.DrawerType type) { + public ObjectDrawer> getDrawerFor(final DrawerType type) { switch (type) { case STRING: return stringDrawer; @@ -1333,16 +1334,6 @@ public void registerForSelection(final int index) { gl.glLoadName(index); } - /** - * Mark if selected. - * - * @param attributes - * the attributes - */ - public void markIfSelected(final DrawingAttributes attributes) { - pickingState.tryPick(attributes); - } - // LISTS /** @@ -1457,14 +1448,17 @@ public void initializeShapeCache() { * @param object * the object */ - public void beginObject(final AbstractObject object) { + public void beginObject(final AbstractObject object, final boolean isPicking) { // DEBUG.OUT("Object " + object + " begin and is " + (object.getAttributes().isEmpty() ? "empty" : "filled")); - boolean empty = object.getAttributes().isEmpty(); + DrawingAttributes att = object.getAttributes(); + if (isPicking) { registerForSelection(att.getIndex()); } + setLighting(att.isLighting()); + boolean empty = att.isEmpty(); setObjectWireframe(empty); - setLineWidth(object.getAttributes().getLineWidth()); + setLineWidth(att.getLineWidth()); setCurrentTextures(object.getPrimaryTexture(this), object.getAlternateTexture(this)); - setCurrentColor(object.getAttributes().getColor()); - if (!empty && !object.getAttributes().isSynthetic()) { + setCurrentColor(att.getColor()); + if (!empty && !att.isSynthetic()) { gl.glTexEnvi(GL2ES1.GL_TEXTURE_ENV, GL2ES1.GL_TEXTURE_ENV_MODE, GL2ES1.GL_DECAL); } @@ -1476,14 +1470,14 @@ public void beginObject(final AbstractObject object) { * @param object * the object */ - public void endObject(final AbstractObject object) { + public void endObject(final AbstractObject object, final boolean isPicking) { disableTextures(); translateByZIncrement(); if (object.isFilled() && !object.getAttributes().isSynthetic()) { gl.glTexEnvi(GL2ES1.GL_TEXTURE_ENV, GL2ES1.GL_TEXTURE_ENV_MODE, GL2ES1.GL_MODULATE); } - // DEBUG.OUT("Object " + object + " ends and is " + (object.getAttributes().isEmpty() ? "empty" : "filled")); setObjectWireframe(false); + if (isPicking) { pickingState.tryPick(object.getAttributes()); } } /** @@ -1628,9 +1622,7 @@ public void initializeGLStates(final Color bg) { * */ - public void setRotationMode(final boolean b) { - rotationMode = b; - } + public void setRotationMode(final boolean b) { rotationMode = b; } /** * Checks if is in rotation mode. diff --git a/ummisco.gama.opengl/src/ummisco/gama/opengl/renderer/helpers/PickingHelper.java b/ummisco.gama.opengl/src/ummisco/gama/opengl/renderer/helpers/PickingHelper.java index 3e7c699f6f..686386221f 100644 --- a/ummisco.gama.opengl/src/ummisco/gama/opengl/renderer/helpers/PickingHelper.java +++ b/ummisco.gama.opengl/src/ummisco/gama/opengl/renderer/helpers/PickingHelper.java @@ -19,6 +19,7 @@ import com.jogamp.opengl.glu.GLU; import msi.gaml.statements.draw.DrawingAttributes; +import ummisco.gama.dev.utils.DEBUG; import ummisco.gama.opengl.OpenGL; import ummisco.gama.opengl.renderer.IOpenGLRenderer; @@ -27,6 +28,10 @@ */ public class PickingHelper extends AbstractRendererHelper { + static { + DEBUG.ON(); + } + /** The select buffer. */ protected final IntBuffer selectBuffer = Buffers.newDirectIntBuffer(1024); diff --git a/ummisco.gama.opengl/src/ummisco/gama/opengl/renderer/helpers/SceneHelper.java b/ummisco.gama.opengl/src/ummisco/gama/opengl/renderer/helpers/SceneHelper.java index ac242d5fbd..ad48b4de4d 100644 --- a/ummisco.gama.opengl/src/ummisco/gama/opengl/renderer/helpers/SceneHelper.java +++ b/ummisco.gama.opengl/src/ummisco/gama/opengl/renderer/helpers/SceneHelper.java @@ -1,9 +1,9 @@ /******************************************************************************************************* * - * ummisco.gama.opengl.renderer.helpers.SceneHelper.java, in plugin ummisco.gama.opengl, is part of the source code of - * the GAMA modeling and simulation platform (v. 1.8.1) + * SceneHelper.java, in ummisco.gama.opengl, is part of the source code of the GAMA modeling and simulation platform + * (v.1.8.2). * - * (c) 2007-2020 UMI 209 UMMISCO IRD/SU & Partners + * (c) 2007-2021 UMI 209 UMMISCO IRD/SU & Partners (IRIT, MIAT, TLU, CTU) * * Visit https://github.com/gama-platform/gama for license information and contacts. * @@ -31,11 +31,24 @@ */ public class SceneHelper extends AbstractRendererHelper { + /** The back scene. */ volatile ModelScene backScene; + + /** The static scene. */ volatile ModelScene staticScene; + + /** The front scene. */ volatile ModelScene frontScene; + + /** The garbage. */ private final Queue garbage = new ConcurrentLinkedQueue<>(); + /** + * Instantiates a new scene helper. + * + * @param renderer + * the renderer + */ public SceneHelper(final IOpenGLRenderer renderer) { super(renderer); } @@ -43,16 +56,32 @@ public SceneHelper(final IOpenGLRenderer renderer) { @Override public void initialize() {} + /** + * Layer offset changed. + */ public void layerOffsetChanged() { if (getSceneToRender() == null) return; getSceneToRender().layerOffsetChanged(); } + /** + * Begin drawing layer. + * + * @param layer + * the layer + * @param currentLayerAlpha + * the current layer alpha + */ public void beginDrawingLayer(final ILayer layer, final Double currentLayerAlpha) { final ModelScene scene = getSceneToUpdate(); if (scene != null) { scene.beginDrawingLayer(layer, currentLayerAlpha); } } + /** + * Begin updating scene. + * + * @return true, if successful + */ public boolean beginUpdatingScene() { // If we are syncrhonized with the simulation and a backScene exists, we // wait until it has been updated (put to null at the end of @@ -75,12 +104,20 @@ public boolean beginUpdatingScene() { return true; } + /** + * Checks if is not ready to update. + * + * @return true, if is not ready to update + */ public boolean isNotReadyToUpdate() { if (frontScene == null) return false; if (!frontScene.rendered()) return true; return false; } + /** + * End updating scene. + */ public void endUpdatingScene() { // If there is no scene to update, it means it has been cancelled by // another thread (hiding/showing layers, most probably) so we just skip @@ -98,13 +135,12 @@ public void endUpdatingScene() { // If there is another frontScene, we discard it (will be disposed of // later) if (frontScene != null) { - if (frontScene.rendered()) { - garbage.add(frontScene); - } else { + if (!frontScene.rendered()) { garbage.add(backScene); backScene = null; return; } + garbage.add(frontScene); } // We switch the scenes @@ -135,9 +171,7 @@ protected ModelScene createSceneFrom(final ModelScene existing) { * @return */ - public ModelScene getSceneToRender() { - return frontScene; - } + public ModelScene getSceneToRender() { return frontScene; } /** * Returns the scene to update. Can be null @@ -145,9 +179,7 @@ public ModelScene getSceneToRender() { * @return */ - public ModelScene getSceneToUpdate() { - return backScene; - } + public ModelScene getSceneToUpdate() { return backScene; } /** * Performs the management and disposal of discarded scenes @@ -155,7 +187,9 @@ public ModelScene getSceneToUpdate() { * @param gl */ public void garbageCollect(final OpenGL gl) { - final ModelScene[] scenes = garbage.toArray(new ModelScene[garbage.size()]); + int size = garbage.size(); + if (size == 0) return; + final ModelScene[] scenes = garbage.toArray(new ModelScene[size]); garbage.clear(); for (final ModelScene scene : scenes) { scene.wipe(gl); @@ -191,9 +225,12 @@ public void layersChanged() { garbage.add(backScene); backScene = null; } - + frontScene.unlock(); } + /** + * Draw. + */ public void draw() { final OpenGL gl = getOpenGL(); // Do some garbage collecting in model scenes @@ -209,10 +246,21 @@ public void draw() { getSceneToRender().draw(gl); } - public boolean isReady() { - return getSceneToRender() != null; - } + /** + * Checks if is ready. + * + * @return true, if is ready + */ + public boolean isReady() { return getSceneToRender() != null; } + /** + * Reshape. + * + * @param width + * the width + * @param height + * the height + */ public void reshape(final int width, final int height) { if (getSceneToRender() == null) return; getSceneToRender().recomputeLayoutDimensions(this.getOpenGL()); diff --git a/ummisco.gama.opengl/src/ummisco/gama/opengl/scene/AbstractObject.java b/ummisco.gama.opengl/src/ummisco/gama/opengl/scene/AbstractObject.java index 5cb582320c..ba8612b824 100644 --- a/ummisco.gama.opengl/src/ummisco/gama/opengl/scene/AbstractObject.java +++ b/ummisco.gama.opengl/src/ummisco/gama/opengl/scene/AbstractObject.java @@ -1,10 +1,10 @@ /******************************************************************************************************* * - * ummisco.gama.opengl.scene.AbstractObject.java, in plugin ummisco.gama.opengl, is part of the source code of the GAMA - * modeling and simulation platform (v. 1.8.1) + * AbstractObject.java, in ummisco.gama.opengl, is part of the source code of the GAMA modeling and simulation platform + * (v.1.8.2). * - * (c) 2007-2020 UMI 209 UMMISCO IRD/SU & Partners + * (c) 2007-2021 UMI 209 UMMISCO IRD/SU & Partners (IRIT, MIAT, TLU, CTU) * * Visit https://github.com/gama-platform/gama for license information and contacts. * @@ -14,24 +14,45 @@ import java.awt.image.BufferedImage; import java.util.Arrays; -import msi.gama.common.geometry.Envelope3D; import msi.gama.common.interfaces.IDisposable; import msi.gama.metamodel.shape.GamaPoint; import msi.gama.util.file.GamaImageFile; import msi.gaml.statements.draw.DrawingAttributes; +import msi.gaml.statements.draw.DrawingAttributes.DrawerType; import ummisco.gama.opengl.OpenGL; +/** + * The Class AbstractObject. + * + * @param + * the generic type + * @param + * the generic type + */ public abstract class AbstractObject implements IDisposable { - public enum DrawerType { - GEOMETRY, STRING, MESH, RESOURCE - } - + /** The attributes. */ private final ATT attributes; + + /** The textures. */ protected final int[] textures; + + /** The object. */ protected final T object; + + /** The type. */ public final DrawerType type; + /** + * Instantiates a new abstract object. + * + * @param object + * the object + * @param attributes + * the attributes + * @param type + * the type + */ public AbstractObject(final T object, final ATT attributes, final DrawerType type) { this.object = object; this.type = type; @@ -47,9 +68,12 @@ public AbstractObject(final T object, final ATT attributes, final DrawerType typ @Override public void dispose() {} - public T getObject() { - return object; - } + /** + * Gets the object. + * + * @return the object + */ + public T getObject() { return object; } /** * Returns the id of the texture at index 1 @@ -71,8 +95,17 @@ public int getPrimaryTexture(final OpenGL gl) { return getTexture(gl, 0); } + /** + * Gets the texture. + * + * @param gl + * the gl + * @param order + * the order + * @return the texture + */ private int getTexture(final OpenGL gl, final int order) { - if ((textures == null) || order < 0 || order > textures.length - 1) return OpenGL.NO_TEXTURE; + if (textures == null || order < 0 || order > textures.length - 1) return OpenGL.NO_TEXTURE; if (isAnimated() || textures[order] == OpenGL.NO_TEXTURE) { Object obj = null; try { @@ -89,36 +122,41 @@ private int getTexture(final OpenGL gl, final int order) { return textures[order]; } - protected boolean isAnimated() { - return getAttributes().isAnimated(); - } - - public boolean isTextured() { - return textures != null && textures.length > 0; - } - - @SuppressWarnings ("unchecked") - public final > void draw(final OpenGL gl, final ObjectDrawer drawer, - final boolean isPicking) { - if (isPicking) { gl.registerForSelection(getAttributes().getIndex()); } - final var previous = gl.setLighting(getAttributes().isLighting()); - drawer.draw((T) this); - gl.setLighting(previous); - if (isPicking) { gl.markIfSelected(getAttributes()); } - } + /** + * Checks if is animated. + * + * @return true, if is animated + */ + protected boolean isAnimated() { return getAttributes().isAnimated(); } - public boolean isFilled() { - return !getAttributes().isEmpty(); - } + /** + * Checks if is textured. + * + * @return true, if is textured + */ + public boolean isTextured() { return textures != null && textures.length > 0; } - public Envelope3D getEnvelope(final OpenGL gl) { - return gl.getEnvelopeFor(getObject()); - } + /** + * Checks if is filled. + * + * @return true, if is filled + */ + public boolean isFilled() { return !getAttributes().isEmpty(); } - public ATT getAttributes() { - return attributes; - } + /** + * Gets the attributes. + * + * @return the attributes + */ + public ATT getAttributes() { return attributes; } + /** + * Gets the translation into. + * + * @param p + * the p + * @return the translation into + */ public void getTranslationInto(final GamaPoint p) { final var explicitLocation = getAttributes().getLocation(); if (explicitLocation == null) { @@ -128,16 +166,33 @@ public void getTranslationInto(final GamaPoint p) { } } + /** + * Gets the translation for rotation into. + * + * @param p + * the p + * @return the translation for rotation into + */ public void getTranslationForRotationInto(final GamaPoint p) { getTranslationInto(p); } + /** + * Gets the translation for scaling into. + * + * @param p + * the p + * @return the translation for scaling into + */ public void getTranslationForScalingInto(final GamaPoint p) { p.setLocation(0, 0, 0); } - public boolean isBordered() { - return getAttributes().getBorder() != null; - } + /** + * Checks if is bordered. + * + * @return true, if is bordered + */ + public boolean isBordered() { return getAttributes().getBorder() != null; } } diff --git a/ummisco.gama.opengl/src/ummisco/gama/opengl/scene/ModelScene.java b/ummisco.gama.opengl/src/ummisco/gama/opengl/scene/ModelScene.java index 342412424b..269b9ea184 100644 --- a/ummisco.gama.opengl/src/ummisco/gama/opengl/scene/ModelScene.java +++ b/ummisco.gama.opengl/src/ummisco/gama/opengl/scene/ModelScene.java @@ -1,9 +1,9 @@ /******************************************************************************************************* * - * ummisco.gama.opengl.scene.ModelScene.java, in plugin ummisco.gama.opengl, is part of the source code of the GAMA - * modeling and simulation platform (v. 1.8.1) + * ModelScene.java, in ummisco.gama.opengl, is part of the source code of the GAMA modeling and simulation platform + * (v.1.8.2). * - * (c) 2007-2020 UMI 209 UMMISCO IRD/SU & Partners + * (c) 2007-2021 UMI 209 UMMISCO IRD/SU & Partners (IRIT, MIAT, TLU, CTU) * * Visit https://github.com/gama-platform/gama for license information and contacts. * @@ -41,22 +41,49 @@ */ public class ModelScene { + /** The Constant AXES_KEY. */ public static final String AXES_KEY = "__axes__0"; + + /** The Constant FRAME_KEY. */ public static final String FRAME_KEY = "__frame__0"; + /** The layers. */ protected final IMap layers = GamaMapFactory.create(); + + /** The current layer. */ protected LayerObject currentLayer; + + /** The renderer. */ protected final IOpenGLRenderer renderer; + + /** The rendered. */ private volatile boolean rendered = false; + + /** The object number. */ private volatile int objectNumber; + + /** The z increment. */ private double zIncrement; + + /** The current layer trace. */ private int currentLayerTrace; + /** + * Instantiates a new model scene. + * + * @param renderer + * the renderer + * @param withWorld + * the with world + */ public ModelScene(final IOpenGLRenderer renderer, final boolean withWorld) { this.renderer = renderer; if (withWorld) { initWorld(); } } + /** + * Inits the world. + */ protected void initWorld() { if (renderer.getData().isDrawEnv()) { layers.put(FRAME_KEY, new FrameLayerObject(renderer)); @@ -69,14 +96,18 @@ protected void initWorld() { * Called every new iteration when updateDisplay() is called on the surface */ public void wipe(final OpenGL gl) { - layers.forEach((name, obj) -> { - if (obj != null && (!obj.isStatic() || obj.isInvalid())) { obj.clear(gl); } - }); + layers.forEach((name, obj) -> { if (obj != null && (!obj.isStatic() || obj.isInvalid())) { obj.clear(gl); } }); // Wipe the textures. gl.deleteVolatileTextures(); } + /** + * Draw. + * + * @param gl + * the gl + */ public void draw(final OpenGL gl) { gl.push(GLMatrixFunc.GL_MODELVIEW); @@ -85,8 +116,8 @@ public void draw(final OpenGL gl) { layers.forEach((name, layer) -> { if (layer != null && !layer.isInvalid()) { try { - layer.draw(gl); layer.lock(); + layer.draw(gl); } catch (final RuntimeException r) { DEBUG.ERR("Runtime error " + r.getMessage() + " in OpenGL loop"); r.printStackTrace(); @@ -99,6 +130,11 @@ public void draw(final OpenGL gl) { gl.pop(GLMatrixFunc.GL_MODELVIEW); } + /** + * Compute visual Z increment. + * + * @return the double + */ private double computeVisualZIncrement() { if (objectNumber <= 1) return 0d; // The maximum visual z allowance between the object at the bottom and the one at the top @@ -107,62 +143,142 @@ private double computeVisualZIncrement() { return maxZ / objectNumber; } + /** + * Cannot add. + * + * @return true, if successful + */ public boolean cannotAdd() { if (currentLayer == null) return true; return currentLayer.isStatic() && currentLayer.isLocked(); } + /** + * Increment. + * + * @return true, if successful + */ private boolean increment() { if (cannotAdd()) return false; objectNumber += currentLayerTrace; return true; } + /** + * Adds the string. + * + * @param string + * the string + * @param attributes + * the attributes + */ public void addString(final String string, final TextDrawingAttributes attributes) { if (increment()) { currentLayer.addString(string, attributes); } } + /** + * Adds the geometry file. + * + * @param file + * the file + * @param attributes + * the attributes + */ public void addGeometryFile(final GamaGeometryFile file, final DrawingAttributes attributes) { if (increment()) { currentLayer.addFile(file, attributes); } } + /** + * Adds the image. + * + * @param img + * the img + * @param attributes + * the attributes + */ public void addImage(final Object img, final DrawingAttributes attributes) { if (increment()) { currentLayer.addImage(img, attributes); } } + /** + * Adds the geometry. + * + * @param geometry + * the geometry + * @param attributes + * the attributes + */ public void addGeometry(final Geometry geometry, final DrawingAttributes attributes) { if (increment()) { currentLayer.addGeometry(geometry, attributes); } } + /** + * Adds the field. + * + * @param fieldValues + * the field values + * @param attributes + * the attributes + */ public void addField(final IField fieldValues, final MeshDrawingAttributes attributes) { if (increment()) { currentLayer.addField(fieldValues, attributes); } } + /** + * Dispose. + */ public void dispose() { layers.clear(); currentLayer = null; } + /** + * Begin drawing layers. + */ public void beginDrawingLayers() { currentLayerTrace = 0; } + /** + * End drawing layers. + */ public void endDrawingLayers() { zIncrement = computeVisualZIncrement(); } + /** + * Rendered. + * + * @return true, if successful + */ public boolean rendered() { return rendered; } + /** + * Reload. + */ public void reload() { - for (final LayerObject l : layers.values()) { - l.unlock(); - } + unlock(); dispose(); initWorld(); } + /** + * Unlock. + */ + public void unlock() { + for (final LayerObject l : layers.values()) { l.unlock(); } + } + + /** + * Begin drawing layer. + * + * @param layer + * the layer + * @param alpha + * the alpha + */ public void beginDrawingLayer(final ILayer layer, final Double alpha) { final String key = layer.getName() + layer.getDefinition().getOrder(); currentLayer = layers.get(key); @@ -174,6 +290,15 @@ public void beginDrawingLayer(final ILayer layer, final Double alpha) { currentLayerTrace = currentLayer.numberOfTraces(); } + /** + * Creates the regular layer. + * + * @param renderer + * the renderer + * @param layer + * the layer + * @return the layer object + */ protected LayerObject createRegularLayer(final IOpenGLRenderer renderer, final ILayer layer) { boolean overlay = layer != null && layer.isOverlay(); return overlay ? new OverlayLayerObject(renderer, layer) : new LayerObject(renderer, layer); @@ -195,22 +320,25 @@ public ModelScene copyStatic() { * */ public void invalidateLayers() { - layers.forEach((name, layer) -> { - layer.invalidate(); - }); + layers.forEach((name, layer) -> { layer.invalidate(); }); } + /** + * Layer offset changed. + */ public void layerOffsetChanged() { - layers.forEach((name, layer) -> { - if (layer.canSplit()) { layer.computeOffset(); } - }); + layers.forEach((name, layer) -> { if (layer.canSplit()) { layer.computeOffset(); } }); } + /** + * Recompute layout dimensions. + * + * @param gl + * the gl + */ public void recomputeLayoutDimensions(final OpenGL gl) { - layers.forEach((name, layer) -> { - if (layer.isOverlay() || layer.isStatic()) { layer.forceRedraw(gl); } - }); + layers.forEach((name, layer) -> { if (layer.isOverlay() || layer.isStatic()) { layer.forceRedraw(gl); } }); } diff --git a/ummisco.gama.opengl/src/ummisco/gama/opengl/scene/ObjectDrawer.java b/ummisco.gama.opengl/src/ummisco/gama/opengl/scene/ObjectDrawer.java index 0477254f0a..2adf79f762 100644 --- a/ummisco.gama.opengl/src/ummisco/gama/opengl/scene/ObjectDrawer.java +++ b/ummisco.gama.opengl/src/ummisco/gama/opengl/scene/ObjectDrawer.java @@ -1,9 +1,9 @@ /******************************************************************************************************* * - * ummisco.gama.opengl.scene.ObjectDrawer.java, in plugin ummisco.gama.opengl, is part of the source code of the GAMA - * modeling and simulation platform (v. 1.8.1) + * ObjectDrawer.java, in ummisco.gama.opengl, is part of the source code of the GAMA modeling and simulation platform + * (v.1.8.2). * - * (c) 2007-2020 UMI 209 UMMISCO IRD/SU & Partners + * (c) 2007-2021 UMI 209 UMMISCO IRD/SU & Partners (IRIT, MIAT, TLU, CTU) * * Visit https://github.com/gama-platform/gama for license information and contacts. * @@ -16,18 +16,39 @@ import msi.gama.metamodel.shape.GamaPoint; import ummisco.gama.opengl.OpenGL; +/** + * The Class ObjectDrawer. + * + * @param + * the generic type + */ public abstract class ObjectDrawer> { + /** The gl. */ protected final OpenGL gl; + /** + * Instantiates a new object drawer. + * + * @param gl + * the gl + */ public ObjectDrawer(final OpenGL gl) { this.gl = gl; } - final void draw(final T object) { - gl.beginObject(object); - _draw(object); - gl.endObject(object); + /** + * Draw. + * + * @param object + * the object + * @param isPicking + * the is picking + */ + public final void draw(final AbstractObject object, final boolean isPicking) { + gl.beginObject(object, isPicking); + _draw((T) object); + gl.endObject(object, isPicking); } /** @@ -43,7 +64,7 @@ protected boolean applyScaling(final T object) { final Scaling3D size = object.getAttributes().getSize(); if (size != null) { - final Envelope3D env = object.getEnvelope(gl); + final Envelope3D env = gl.getEnvelopeFor(object.getObject()); if (env != null) { // try { final boolean in2D = isDrawing2D(size, env, object); @@ -71,6 +92,7 @@ protected boolean applyScaling(final T object) { } + /** The loc. */ private final GamaPoint loc = new GamaPoint(); /** @@ -86,6 +108,17 @@ protected boolean applyTranslation(final T object) { return true; } + /** + * Checks if is drawing 2 D. + * + * @param size + * the size + * @param env + * the env + * @param object + * the object + * @return true, if is drawing 2 D + */ protected boolean isDrawing2D(final Scaling3D size, final Envelope3D env, final T object) { return env.isFlat() || size.getZ() == 0d; } @@ -110,6 +143,12 @@ protected boolean applyRotation(final T object) { return true; } + /** + * Draw. + * + * @param object + * the object + */ protected abstract void _draw(T object); /** diff --git a/ummisco.gama.opengl/src/ummisco/gama/opengl/scene/geometry/GeometryDrawer.java b/ummisco.gama.opengl/src/ummisco/gama/opengl/scene/geometry/GeometryDrawer.java index 8da2dc4cc9..d06f0e75c6 100644 --- a/ummisco.gama.opengl/src/ummisco/gama/opengl/scene/geometry/GeometryDrawer.java +++ b/ummisco.gama.opengl/src/ummisco/gama/opengl/scene/geometry/GeometryDrawer.java @@ -1,9 +1,9 @@ /******************************************************************************************************* * - * ummisco.gama.opengl.scene.GeometryDrawer.java, in plugin ummisco.gama.opengl, is part of the source code of the GAMA - * modeling and simulation platform (v. 1.8.1) + * GeometryDrawer.java, in ummisco.gama.opengl, is part of the source code of the GAMA modeling and simulation platform + * (v.1.8.2). * - * (c) 2007-2020 UMI 209 UMMISCO IRD/SU & Partners + * (c) 2007-2021 UMI 209 UMMISCO IRD/SU & Partners (IRIT, MIAT, TLU, CTU) * * Visit https://github.com/gama-platform/gama for license information and contacts. * @@ -52,16 +52,36 @@ */ public class GeometryDrawer extends ObjectDrawer { + /** The Constant DEFAULT_BORDER. */ private static final GamaColor DEFAULT_BORDER = new GamaColor(Color.black); + /** The normal. */ final GamaPoint _normal = new GamaPoint(); + + /** The center. */ final GamaPoint _center = new GamaPoint(); + + /** The tangent. */ final GamaPoint _tangent = new GamaPoint(); + + /** The rot. */ final Rotation3D _rot = Rotation3D.identity(); + + /** The scale. */ final Heterogeneous _scale = new Heterogeneous(1, 1, 1); + + /** The quadvertices. */ final ICoordinates _quadvertices = GEOMETRY_FACTORY.COORDINATES_FACTORY.create(5, 3); + + /** The vertices. */ final UnboundedCoordinateSequence _vertices = new UnboundedCoordinateSequence(); + /** + * Instantiates a new geometry drawer. + * + * @param gl + * the gl + */ public GeometryDrawer(final OpenGL gl) { super(gl); } @@ -163,12 +183,20 @@ public void drawGeometry(final Geometry geom, /* final boolean solid, */ final C drawPoint(geom, /* solid, */ gl.getMaxEnvDim() / 800d, border); break; default: - applyToInnerGeometries(geom, g -> { - drawGeometry(g, /* solid, */ border, height, getTypeOf(g)); - }); + applyToInnerGeometries(geom, g -> { drawGeometry(g, /* solid, */ border, height, getTypeOf(g)); }); } } + /** + * Draw polyhedron. + * + * @param polygon + * the polygon + * @param height + * the height + * @param border + * the border + */ private void drawPolyhedron(final Polygon polygon, /* final boolean solid, */final double height, final Color border) { // final boolean hasHoles = getHolesNumber(polygon) > 0; @@ -193,6 +221,18 @@ private void drawPolyhedron(final Polygon polygon, /* final boolean solid, */fin } + /** + * Draw polygon. + * + * @param p + * the p + * @param border + * the border + * @param clockwise + * the clockwise + * @param computeVertices + * the compute vertices + */ private void drawPolygon(final Polygon p, /* final boolean solid, */final Color border, final boolean clockwise, final boolean computeVertices) { if (computeVertices) { _vertices.setToYNegated(getContourCoordinates(p)); } @@ -212,6 +252,16 @@ private void drawPolygon(final Polygon p, /* final boolean solid, */final Color } } + /** + * Draw plan. + * + * @param p + * the p + * @param height + * the height + * @param border + * the border + */ private void drawPlan(final Geometry p, /* final boolean solid, */final double height, final Color border) { _vertices.setToYNegated(getContourCoordinates(p)); if (height != 0) { @@ -225,6 +275,14 @@ private void drawPlan(final Geometry p, /* final boolean solid, */final double h } } + /** + * Draw cached geometry. + * + * @param type + * the type + * @param border + * the border + */ private void drawCachedGeometry(final IShape.Type type, /* final boolean solid, */ final Color border) { gl.pushMatrix(); gl.translateBy(_center); @@ -235,6 +293,16 @@ private void drawCachedGeometry(final IShape.Type type, /* final boolean solid, } + /** + * Draw point. + * + * @param point + * the point + * @param height + * the height + * @param border + * the border + */ private void drawPoint(final Geometry point, /* final boolean solid, */ final double height, final Color border) { _center.setCoordinate(point.getCoordinate()); _center.y *= -1; @@ -243,6 +311,16 @@ private void drawPoint(final Geometry point, /* final boolean solid, */ final do drawCachedGeometry(Type.POINT, /* solid, */ border); } + /** + * Draw cube. + * + * @param p + * the p + * @param height + * the height + * @param border + * the border + */ private void drawCube(final Geometry p, /* final boolean solid, */ final double height, final Color border) { _vertices.setToYNegated(getContourCoordinates(p)); _vertices.getNormal(true, 1, _normal); @@ -252,6 +330,16 @@ private void drawCube(final Geometry p, /* final boolean solid, */ final double drawCachedGeometry(Type.CUBE, /* solid, */ border); } + /** + * Draw pyramid. + * + * @param p + * the p + * @param height + * the height + * @param border + * the border + */ private void drawPyramid(final Geometry p, /* final boolean solid, */final double height, final Color border) { _vertices.setToYNegated(getContourCoordinates(p)); _vertices.getNormal(true, 1, _normal); @@ -261,6 +349,16 @@ private void drawPyramid(final Geometry p, /* final boolean solid, */final doubl drawCachedGeometry(Type.PYRAMID, /* solid, */ border); } + /** + * Draw sphere. + * + * @param p + * the p + * @param height + * the height + * @param border + * the border + */ private void drawSphere(final Geometry p, /* final boolean solid, */ final double height, final Color border) { _vertices.setToYNegated(getContourCoordinates(p)); _vertices.getNormal(true, 1, _normal); @@ -270,6 +368,16 @@ private void drawSphere(final Geometry p, /* final boolean solid, */ final doubl drawCachedGeometry(Type.SPHERE, /* solid, */ border); } + /** + * Draw circle. + * + * @param p + * the p + * @param height + * the height + * @param border + * the border + */ private void drawCircle(final Geometry p, /* final boolean solid, */final double height, final Color border) { _vertices.setToYNegated(getContourCoordinates(p)); _vertices.getNormal(true, 1, _normal); @@ -288,6 +396,16 @@ private void drawCircle(final Geometry p, /* final boolean solid, */final double // drawCachedGeometry(Type.ROUNDED, solid, border); // } + /** + * Draw cylinder. + * + * @param g + * the g + * @param height + * the height + * @param border + * the border + */ private void drawCylinder(final Geometry g, /* final boolean solid, */ final double height, final Color border) { _vertices.setToYNegated(getContourCoordinates(g)); final double radius = g instanceof Polygon ? _vertices.getLength() / (2 * Math.PI) : height; @@ -298,6 +416,16 @@ private void drawCylinder(final Geometry g, /* final boolean solid, */ final dou drawCachedGeometry(Type.CYLINDER, /* solid, */ border); } + /** + * Draw line cylinder. + * + * @param g + * the g + * @param radius + * the radius + * @param border + * the border + */ private void drawLineCylinder(final Geometry g, /* final boolean solid, */ final double radius, final Color border) { _vertices.setToYNegated(getContourCoordinates(g)); @@ -323,6 +451,16 @@ private void drawLineCylinder(final Geometry g, /* final boolean solid, */ final } + /** + * Draw cone 3 D. + * + * @param p + * the p + * @param height + * the height + * @param border + * the border + */ private void drawCone3D(final Geometry p, /* final boolean solid, */final double height, final Color border) { _vertices.setToYNegated(getContourCoordinates(p)); final double radius = p instanceof Polygon ? _vertices.getLength() / (2 * Math.PI) : _vertices.getLength(); @@ -334,6 +472,16 @@ private void drawCone3D(final Geometry p, /* final boolean solid, */final double drawCachedGeometry(Type.CONE, /* solid, */ border); } + /** + * Draw teapot. + * + * @param p + * the p + * @param height + * the height + * @param border + * the border + */ private void drawTeapot(final Geometry p, /* final boolean solid, */final double height, final Color border) { _vertices.setToYNegated(getContourCoordinates(p)); try { diff --git a/ummisco.gama.opengl/src/ummisco/gama/opengl/scene/geometry/GeometryObject.java b/ummisco.gama.opengl/src/ummisco/gama/opengl/scene/geometry/GeometryObject.java index 1e8eb9644d..c5785c43ee 100644 --- a/ummisco.gama.opengl/src/ummisco/gama/opengl/scene/geometry/GeometryObject.java +++ b/ummisco.gama.opengl/src/ummisco/gama/opengl/scene/geometry/GeometryObject.java @@ -1,12 +1,12 @@ /******************************************************************************************************* * - * ummisco.gama.opengl.scene.GeometryObject.java, in plugin ummisco.gama.opengl, is part of the source code of the GAMA - * modeling and simulation platform (v. 1.8.1) + * GeometryObject.java, in ummisco.gama.opengl, is part of the source code of the + * GAMA modeling and simulation platform (v.1.8.2). * - * (c) 2007-2020 UMI 209 UMMISCO IRD/SU & Partners + * (c) 2007-2021 UMI 209 UMMISCO IRD/SU & Partners (IRIT, MIAT, TLU, CTU) * * Visit https://github.com/gama-platform/gama for license information and contacts. - * + * ********************************************************************************************************/ package ummisco.gama.opengl.scene.geometry; @@ -15,11 +15,20 @@ import msi.gama.common.geometry.GeometryUtils; import msi.gama.metamodel.shape.GamaPoint; import msi.gaml.statements.draw.DrawingAttributes; +import msi.gaml.statements.draw.DrawingAttributes.DrawerType; import ummisco.gama.opengl.scene.AbstractObject; -import ummisco.gama.opengl.scene.AbstractObject.DrawerType; +/** + * The Class GeometryObject. + */ public class GeometryObject extends AbstractObject { + /** + * Instantiates a new geometry object. + * + * @param geometry the geometry + * @param attributes the attributes + */ public GeometryObject(final Geometry geometry, final DrawingAttributes attributes) { super(geometry, attributes, DrawerType.GEOMETRY); } diff --git a/ummisco.gama.opengl/src/ummisco/gama/opengl/scene/layers/AxesLayerObject.java b/ummisco.gama.opengl/src/ummisco/gama/opengl/scene/layers/AxesLayerObject.java index da96352f28..30fc727d9b 100644 --- a/ummisco.gama.opengl/src/ummisco/gama/opengl/scene/layers/AxesLayerObject.java +++ b/ummisco.gama.opengl/src/ummisco/gama/opengl/scene/layers/AxesLayerObject.java @@ -23,15 +23,20 @@ import java.util.List; import msi.gama.common.geometry.AxisAngle; +import msi.gama.common.preferences.GamaPreferences; +import msi.gama.metamodel.agent.IAgent; import msi.gama.metamodel.shape.GamaPoint; import msi.gama.metamodel.shape.GamaShape; import msi.gama.metamodel.shape.IShape; import msi.gama.util.GamaColor; import msi.gama.util.GamaFont; +import msi.gaml.statements.draw.DrawingAttributes; +import msi.gaml.statements.draw.ShapeDrawingAttributes; import msi.gaml.statements.draw.TextDrawingAttributes; import ummisco.gama.opengl.OpenGL; import ummisco.gama.opengl.renderer.IOpenGLRenderer; import ummisco.gama.opengl.scene.AbstractObject; +import ummisco.gama.opengl.scene.geometry.GeometryObject; import ummisco.gama.opengl.scene.text.StringObject; /** @@ -129,4 +134,28 @@ public void fillWithObjects(final List> list) { } } + /** + * Adds the synthetic object. + * + * @param list + * the list + * @param shape + * the shape + * @param color + * the color + * @param type + * the type + * @param empty + * the empty + */ + protected void addSyntheticObject(final List> list, final IShape shape, final GamaColor color, + final IShape.Type type, final boolean empty) { + final DrawingAttributes att = new ShapeDrawingAttributes(shape, (IAgent) null, color, color, type, + GamaPreferences.Displays.CORE_LINE_WIDTH.getValue(), null); + att.setEmpty(empty); + att.setHeight(shape.getDepth()); + att.setLighting(false); + list.add(new GeometryObject(shape.getInnerGeometry(), att)); + } + } \ No newline at end of file diff --git a/ummisco.gama.opengl/src/ummisco/gama/opengl/scene/layers/LayerObject.java b/ummisco.gama.opengl/src/ummisco/gama/opengl/scene/layers/LayerObject.java index 25d97f1c18..dd812c7d15 100644 --- a/ummisco.gama.opengl/src/ummisco/gama/opengl/scene/layers/LayerObject.java +++ b/ummisco.gama.opengl/src/ummisco/gama/opengl/scene/layers/LayerObject.java @@ -22,12 +22,8 @@ import msi.gama.common.geometry.Scaling3D; import msi.gama.common.interfaces.IKeyword; import msi.gama.common.interfaces.ILayer; -import msi.gama.common.preferences.GamaPreferences; -import msi.gama.metamodel.agent.IAgent; import msi.gama.metamodel.shape.GamaPoint; -import msi.gama.metamodel.shape.IShape; import msi.gama.runtime.IScope; -import msi.gama.util.GamaColor; import msi.gama.util.file.GamaGeometryFile; import msi.gama.util.matrix.IField; import msi.gaml.expressions.IExpression; @@ -35,7 +31,6 @@ import msi.gaml.operators.Cast; import msi.gaml.statements.draw.DrawingAttributes; import msi.gaml.statements.draw.MeshDrawingAttributes; -import msi.gaml.statements.draw.ShapeDrawingAttributes; import msi.gaml.statements.draw.TextDrawingAttributes; import msi.gaml.types.GamaGeometryType; import ummisco.gama.opengl.OpenGL; @@ -172,7 +167,8 @@ protected void increaseZ() { * @return the list */ protected List newCurrentList() { - return /* Collections.synchronizedList( */new ArrayList()/* ) */; + return new ArrayList(); + // return /* Collections.synchronizedList( */new ArrayList()/* ) */; } /** @@ -190,24 +186,12 @@ protected List newCurrentList() { */ public void draw(final OpenGL gl) { if (isInvalid()) return; - drawWithoutShader(gl); - } - - /** - * Draw without shader. - * - * @param gl - * the gl - */ - private void drawWithoutShader(final OpenGL gl) { prepareDrawing(gl); try { - final boolean picking = renderer.getPickingHelper().isPicking(); - doDrawing(gl, picking); + doDrawing(gl); } finally { stopDrawing(gl); } - } /** @@ -218,18 +202,9 @@ private void drawWithoutShader(final OpenGL gl) { * @param picking * the picking */ - protected void doDrawing(final OpenGL gl, final boolean picking) { - - if (picking) { - if (isPickable()) { - gl.runWithNames(() -> drawAllObjects(gl, true)); - // else if (renderer.getPickingHelper().hasPicked()) { - // // A pickable object from another layer has been picked - // drawAllObjects(gl, false); - // } else { - // // We do not draw the layer during the picking process - // } - } + protected void doDrawing(final OpenGL gl) { + if (renderer.getPickingHelper().isPicking()) { + if (isPickable()) { gl.runWithNames(() -> drawAllObjects(gl, true)); } } else if (isAnimated) { drawAllObjects(gl, false); } else { @@ -300,11 +275,10 @@ protected void drawAllObjects(final OpenGL gl, final boolean picking) { * @param picking * the picking */ - protected void drawObjects(final OpenGL gl, final List> list, final double alpha, + protected final void drawObjects(final OpenGL gl, final List> list, final double alpha, final boolean picking) { gl.setCurrentObjectAlpha(alpha); - AbstractObject[] objects = list.toArray(new AbstractObject[list.size()]); - for (final AbstractObject object : objects) { object.draw(gl, gl.getDrawerFor(object.type), picking); } + for (final AbstractObject object : list) { gl.getDrawerFor(object.type).draw(object, picking); } } /** @@ -405,7 +379,6 @@ public void addImage(final Object o, final DrawingAttributes attributes) { // We build a rectangle that will serve as a "support" for the image (which will become its texture) final Geometry geometry = GamaGeometryType.buildRectangle(size.getX(), size.getY(), new GamaPoint()).getInnerGeometry(); - attributes.setLocation(newLoc); attributes.setTexture(o); attributes.setSynthetic(true); @@ -433,7 +406,7 @@ public void addField(final IField fieldValues, final MeshDrawingAttributes attri * the attributes */ public void addGeometry(final Geometry geometry, final DrawingAttributes attributes) { - isAnimated = attributes.isAnimated(); + isAnimated = /* isAnimated || ?? */attributes.isAnimated(); currentList.add(new GeometryObject(geometry, attributes)); } @@ -466,7 +439,6 @@ protected boolean getFading() { * the gl */ public void clear(final OpenGL gl) { - if (traces != null) { final int sizeLimit = getTrace(); isFading = getFading(); @@ -554,30 +526,6 @@ public boolean canSplit() { return true; } - /** - * Adds the synthetic object. - * - * @param list - * the list - * @param shape - * the shape - * @param color - * the color - * @param type - * the type - * @param empty - * the empty - */ - protected void addSyntheticObject(final List> list, final IShape shape, final GamaColor color, - final IShape.Type type, final boolean empty) { - final DrawingAttributes att = new ShapeDrawingAttributes(shape, (IAgent) null, color, color, type, - GamaPreferences.Displays.CORE_LINE_WIDTH.getValue(), null); - att.setEmpty(empty); - att.setHeight(shape.getDepth()); - att.setLighting(false); - list.add(new GeometryObject(shape.getInnerGeometry(), att)); - } - /** * Force redraw. * @@ -590,7 +538,6 @@ public void forceRedraw(final OpenGL gl) { gl.deleteList(openGLListIndex); openGLListIndex = null; } - // layer.draw(renderer.getSurface().getScope(), renderer); } diff --git a/ummisco.gama.opengl/src/ummisco/gama/opengl/scene/layers/OverlayLayerObject.java b/ummisco.gama.opengl/src/ummisco/gama/opengl/scene/layers/OverlayLayerObject.java index b3f19631b1..92b41220f1 100644 --- a/ummisco.gama.opengl/src/ummisco/gama/opengl/scene/layers/OverlayLayerObject.java +++ b/ummisco.gama.opengl/src/ummisco/gama/opengl/scene/layers/OverlayLayerObject.java @@ -109,10 +109,10 @@ protected void prepareDrawing(final OpenGL gl) { } @Override - protected void doDrawing(final OpenGL gl, final boolean picking) { - if (!picking) { + protected void doDrawing(final OpenGL gl) { + if (!renderer.getPickingHelper().isPicking()) { addFrame(gl); - drawObjects(gl, currentList, alpha, picking); + drawObjects(gl, currentList, alpha, false); } } diff --git a/ummisco.gama.opengl/src/ummisco/gama/opengl/scene/mesh/MeshObject.java b/ummisco.gama.opengl/src/ummisco/gama/opengl/scene/mesh/MeshObject.java index 62efac71d6..7e7e61a128 100644 --- a/ummisco.gama.opengl/src/ummisco/gama/opengl/scene/mesh/MeshObject.java +++ b/ummisco.gama.opengl/src/ummisco/gama/opengl/scene/mesh/MeshObject.java @@ -1,22 +1,31 @@ /******************************************************************************************************* * - * ummisco.gama.opengl.scene.FieldObject.java, in plugin ummisco.gama.opengl, is part of the source code of the GAMA - * modeling and simulation platform (v. 1.8.1) + * MeshObject.java, in ummisco.gama.opengl, is part of the source code of the + * GAMA modeling and simulation platform (v.1.8.2). * - * (c) 2007-2020 UMI 209 UMMISCO IRD/SU & Partners + * (c) 2007-2021 UMI 209 UMMISCO IRD/SU & Partners (IRIT, MIAT, TLU, CTU) * * Visit https://github.com/gama-platform/gama for license information and contacts. - * + * ********************************************************************************************************/ package ummisco.gama.opengl.scene.mesh; import msi.gama.util.matrix.IField; +import msi.gaml.statements.draw.DrawingAttributes.DrawerType; import msi.gaml.statements.draw.MeshDrawingAttributes; import ummisco.gama.opengl.scene.AbstractObject; -import ummisco.gama.opengl.scene.AbstractObject.DrawerType; +/** + * The Class MeshObject. + */ public class MeshObject extends AbstractObject { + /** + * Instantiates a new mesh object. + * + * @param dem the dem + * @param attributes the attributes + */ public MeshObject(final IField dem, final MeshDrawingAttributes attributes) { super(dem, attributes, DrawerType.MESH); } diff --git a/ummisco.gama.opengl/src/ummisco/gama/opengl/scene/resources/ResourceObject.java b/ummisco.gama.opengl/src/ummisco/gama/opengl/scene/resources/ResourceObject.java index ddcef0d7e5..f40810ee70 100644 --- a/ummisco.gama.opengl/src/ummisco/gama/opengl/scene/resources/ResourceObject.java +++ b/ummisco.gama.opengl/src/ummisco/gama/opengl/scene/resources/ResourceObject.java @@ -1,22 +1,31 @@ /******************************************************************************************************* * - * ummisco.gama.opengl.scene.ResourceObject.java, in plugin ummisco.gama.opengl, is part of the source code of the GAMA - * modeling and simulation platform (v. 1.8.1) + * ResourceObject.java, in ummisco.gama.opengl, is part of the source code of the + * GAMA modeling and simulation platform (v.1.8.2). * - * (c) 2007-2020 UMI 209 UMMISCO IRD/SU & Partners + * (c) 2007-2021 UMI 209 UMMISCO IRD/SU & Partners (IRIT, MIAT, TLU, CTU) * * Visit https://github.com/gama-platform/gama for license information and contacts. - * + * ********************************************************************************************************/ package ummisco.gama.opengl.scene.resources; import msi.gama.util.file.GamaGeometryFile; import msi.gaml.statements.draw.DrawingAttributes; +import msi.gaml.statements.draw.DrawingAttributes.DrawerType; import ummisco.gama.opengl.scene.AbstractObject; -import ummisco.gama.opengl.scene.AbstractObject.DrawerType; +/** + * The Class ResourceObject. + */ public class ResourceObject extends AbstractObject { + /** + * Instantiates a new resource object. + * + * @param file the file + * @param attributes the attributes + */ public ResourceObject(final GamaGeometryFile file, final DrawingAttributes attributes) { super(file, attributes, DrawerType.RESOURCE); } diff --git a/ummisco.gama.opengl/src/ummisco/gama/opengl/scene/text/StringObject.java b/ummisco.gama.opengl/src/ummisco/gama/opengl/scene/text/StringObject.java index a3bff9c894..5397f6d824 100644 --- a/ummisco.gama.opengl/src/ummisco/gama/opengl/scene/text/StringObject.java +++ b/ummisco.gama.opengl/src/ummisco/gama/opengl/scene/text/StringObject.java @@ -1,20 +1,30 @@ /******************************************************************************************************* * - * ummisco.gama.opengl.scene.StringObject.java, in plugin ummisco.gama.opengl, is part of the source code of the GAMA - * modeling and simulation platform (v. 1.8.1) + * StringObject.java, in ummisco.gama.opengl, is part of the source code of the + * GAMA modeling and simulation platform (v.1.8.2). * - * (c) 2007-2020 UMI 209 UMMISCO IRD/SU & Partners + * (c) 2007-2021 UMI 209 UMMISCO IRD/SU & Partners (IRIT, MIAT, TLU, CTU) * * Visit https://github.com/gama-platform/gama for license information and contacts. - * + * ********************************************************************************************************/ package ummisco.gama.opengl.scene.text; +import msi.gaml.statements.draw.DrawingAttributes.DrawerType; import msi.gaml.statements.draw.TextDrawingAttributes; import ummisco.gama.opengl.scene.AbstractObject; +/** + * The Class StringObject. + */ public class StringObject extends AbstractObject { + /** + * Instantiates a new string object. + * + * @param string the string + * @param attributes the attributes + */ public StringObject(final String string, final TextDrawingAttributes attributes) { super(string, attributes, DrawerType.STRING); } diff --git a/ummisco.gama.opengl/src/ummisco/gama/opengl/view/SWTOpenGLDisplaySurface.java b/ummisco.gama.opengl/src/ummisco/gama/opengl/view/SWTOpenGLDisplaySurface.java index 38aa66090b..1f7f3a55ad 100644 --- a/ummisco.gama.opengl/src/ummisco/gama/opengl/view/SWTOpenGLDisplaySurface.java +++ b/ummisco.gama.opengl/src/ummisco/gama/opengl/view/SWTOpenGLDisplaySurface.java @@ -576,9 +576,6 @@ public void setPaused(final boolean paused) { } } - /** The cleanup. */ - final Runnable cleanup = () -> WorkbenchHelper.asyncRun(() -> renderer.getPickingHelper().setPicking(false)); - /** * Method selectAgents() * @@ -600,6 +597,13 @@ public void selectAgent(final DrawingAttributes attributes) { ag = attributes.getAgentIdentifier(); } } + /** The cleanup. */ + Runnable cleanup = ag != null ? () -> { renderer.getPickingHelper().setPicking(false); } : () -> { + renderer.getPickingHelper().setPicking(false); + // Necessary to avoir situations like issue #3232. The result is however a bit of flickering + getManager().forceRedrawingLayers(); + updateDisplay(true); + }; if (withHighlight) { menuManager.buildMenu((int) renderer.getCameraHelper().getMousePosition().x, (int) renderer.getCameraHelper().getMousePosition().y, ag, cleanup, @@ -741,7 +745,6 @@ public void setSize(final int x, final int y) {} @Override public void layersChanged() { renderer.getSceneHelper().layersChanged(); - } /** diff --git a/ummisco.gama.ui.experiment/src/ummisco/gama/ui/views/displays/DisplaySurfaceMenu.java b/ummisco.gama.ui.experiment/src/ummisco/gama/ui/views/displays/DisplaySurfaceMenu.java index 3050a2ec55..05fae5d019 100644 --- a/ummisco.gama.ui.experiment/src/ummisco/gama/ui/views/displays/DisplaySurfaceMenu.java +++ b/ummisco.gama.ui.experiment/src/ummisco/gama/ui/views/displays/DisplaySurfaceMenu.java @@ -1,9 +1,9 @@ /******************************************************************************************************* * - * ummisco.gama.ui.views.displays.DisplaySurfaceMenu.java, in plugin ummisco.gama.ui.experiment, is part of the source - * code of the GAMA modeling and simulation platform (v. 1.8.1) + * DisplaySurfaceMenu.java, in ummisco.gama.ui.experiment, is part of the source code of the GAMA modeling and + * simulation platform (v.1.8.2). * - * (c) 2007-2020 UMI 209 UMMISCO IRD/SU & Partners + * (c) 2007-2021 UMI 209 UMMISCO IRD/SU & Partners (IRIT, MIAT, TLU, CTU) * * Visit https://github.com/gama-platform/gama for license information and contacts. * @@ -21,8 +21,8 @@ import org.eclipse.jface.action.MenuManager; import org.eclipse.swt.SWT; +import org.eclipse.swt.events.MenuAdapter; import org.eclipse.swt.events.MenuEvent; -import org.eclipse.swt.events.MenuListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; @@ -50,8 +50,12 @@ import ummisco.gama.ui.resources.IGamaIcons; import ummisco.gama.ui.utils.WorkbenchHelper; +/** + * The Class DisplaySurfaceMenu. + */ public class DisplaySurfaceMenu { + /** The layer images. */ public static Map, Image> layer_images = new LinkedHashMap<>(); static { @@ -63,15 +67,32 @@ public class DisplaySurfaceMenu { layer_images.put(GraphicLayer.class, GamaIcons.create(IGamaIcons.LAYER_GRAPHICS).image()); } + /** The menu. */ Menu menu; + + /** The surface. */ private final IDisplaySurface surface; + + /** The swt control. */ private final Control swtControl; + + /** The presentation menu. */ private final MenuManager presentationMenu; + /** + * The Class FocusOnSelection. + */ private static class FocusOnSelection extends SelectionAdapter { + /** The surface. */ IDisplaySurface surface; + /** + * Instantiates a new focus on selection. + * + * @param surface + * the surface + */ FocusOnSelection(final IDisplaySurface surface) { this.surface = surface; } @@ -80,25 +101,39 @@ private static class FocusOnSelection extends SelectionAdapter { public void widgetSelected(final SelectionEvent e) { final MenuItem mi = (MenuItem) e.widget; final IAgent a = (IAgent) mi.getData("agent"); - if (a != null && !a.dead()) { - surface.runAndUpdate(() -> { - if (!a.dead()) { - surface.focusOn(a); - } - }); - } + if (a != null && !a.dead()) { surface.runAndUpdate(() -> { if (!a.dead()) { surface.focusOn(a); } }); } } } + /** + * Instantiates a new display surface menu. + * + * @param s + * the s + * @param c + * the c + * @param viewMenu + * the view menu + */ public DisplaySurfaceMenu(final IDisplaySurface s, final Control c, final MenuManager viewMenu) { surface = s; swtControl = c; - if (s != null) { - s.setMenuManager(this); - } + if (s != null) { s.setMenuManager(this); } this.presentationMenu = viewMenu; } + /** + * Prepare new menu. + * + * @param c + * the c + * @param x + * the x + * @param y + * the y + * @param withPresentation + * the with presentation + */ public void prepareNewMenu(final Control c, final int x, final int y, final boolean withPresentation) { disposeMenu(); menu = new Menu(c); @@ -109,21 +144,47 @@ public void prepareNewMenu(final Control c, final int x, final int y, final bool } } + /** + * Builds the menu. + * + * @param mousex + * the mousex + * @param mousey + * the mousey + * @param x + * the x + * @param y + * the y + * @param displays + * the displays + */ public void buildMenu(final int mousex, final int mousey, final int x, final int y, final List displays) { - if (displays.isEmpty()) { return; } + if (displays.isEmpty()) return; final Set all = new LinkedHashSet<>(); for (final ILayer display : displays) { if (display.getData().isSelectable()) { final Set agents = display.collectAgentsAt(x, y, surface); - if (agents.isEmpty()) { - continue; - } + if (agents.isEmpty()) { continue; } all.addAll(agents); } } buildMenu(true, mousex, mousey, all, null); } + /** + * Builds the menu. + * + * @param mousex + * the mousex + * @param mousey + * the mousey + * @param agent + * the agent + * @param cleanup + * the cleanup + * @param actions + * the actions + */ public void buildMenu(final int mousex, final int mousey, final IAgent agent, final Runnable cleanup, final MenuAction... actions) { // cleanup is an optional runnable to do whatever is necessary after the @@ -132,6 +193,22 @@ public void buildMenu(final int mousex, final int mousey, final IAgent agent, fi actions); } + /** + * Builds the menu. + * + * @param byLayer + * the by layer + * @param mousex + * the mousex + * @param mousey + * the mousey + * @param agents + * the agents + * @param cleanup + * the cleanup + * @param actions + * the actions + */ private void buildMenu(final boolean byLayer, final int mousex, final int mousey, final Collection agents, final Runnable cleanup, final MenuAction... actions) { WorkbenchHelper.asyncRun(() -> { @@ -142,26 +219,26 @@ private void buildMenu(final boolean byLayer, final int mousex, final int mousey // http://www.eclipse.org/forums/index.php/t/208284/ retryVisible(menu, MAX_RETRIES); if (cleanup != null) { - menu.addMenuListener(new MenuListener() { - - @Override - public void menuShown(final MenuEvent e) { - // DEBUG.LOG("Selection menu has been - // shown"); - } + menu.addMenuListener(new MenuAdapter() { @Override public void menuHidden(final MenuEvent e) { - // DEBUG.LOG("Selection menu has been - // hiden"); - cleanup.run(); menu.removeMenuListener(this); + cleanup.run(); } }); } }); } + /** + * Builds the toolbar menu. + * + * @param trigger + * the trigger + * @param t + * the t + */ public void buildToolbarMenu(final SelectionEvent trigger, final ToolItem t) { prepareNewMenu(t.getParent(), t.getBounds().x + t.getBounds().width, t.getBounds().y + t.getBounds().height, false); @@ -169,10 +246,19 @@ public void buildToolbarMenu(final SelectionEvent trigger, final ToolItem t) { menu.setVisible(true); } + /** The max retries. */ static int MAX_RETRIES = 10; + /** + * Retry visible. + * + * @param menu + * the menu + * @param retriesRemaining + * the retries remaining + */ private void retryVisible(final Menu menu, final int retriesRemaining) { - if (!PlatformHelper.isLinux()) { return; } + if (!PlatformHelper.isLinux()) return; WorkbenchHelper.asyncRun(() -> { if (!menu.isVisible() && retriesRemaining > 0) { menu.setVisible(false); @@ -194,31 +280,41 @@ private void retryVisible(final Menu menu, final int retriesRemaining) { }); } + /** + * Fill. + * + * @param menu + * the menu + * @param index + * the index + * @param withWorld + * the with world + * @param byLayer + * the by layer + * @param filteredList + * the filtered list + * @param actions + * the actions + */ private void fill(final Menu menu, final int index, final boolean withWorld, final boolean byLayer, final Collection filteredList, final MenuAction... actions) { if (withWorld) { AgentsMenu.cascadingAgentMenuItem(menu, surface.getScope().getSimulation(), "World", actions); - if (filteredList != null && !filteredList.isEmpty()) { - GamaMenu.separate(menu); - } else { - return; - } - if (byLayer) { - GamaMenu.separate(menu, "Layers"); - } + if (filteredList == null || filteredList.isEmpty()) return; + GamaMenu.separate(menu); + if (byLayer) { GamaMenu.separate(menu, "Layers"); } } if (!byLayer) { // If the list is null or empty, no need to display anything more - if (filteredList == null || filteredList.isEmpty()) { return; } // If only the world is selected, no need to display anything more - if (filteredList.size() == 1 && filteredList.contains(surface.getScope().getSimulation())) { return; } + if (filteredList == null || filteredList.isEmpty() + || filteredList.size() == 1 && filteredList.contains(surface.getScope().getSimulation())) + return; final FocusOnSelection adapter = new FocusOnSelection(surface); final MenuAction focus = new MenuAction(adapter, GamaIcons.create(IGamaIcons.MENU_FOCUS).image(), "Focus on this display"); final MenuAction[] actions2 = new MenuAction[actions.length + 1]; - for (int i = 0; i < actions.length; i++) { - actions2[i + 1] = actions[i]; - } + for (int i = 0; i < actions.length; i++) { actions2[i + 1] = actions[i]; } actions2[0] = focus; AgentsMenu.fillPopulationSubMenu(menu, filteredList, actions2); } else { @@ -227,26 +323,20 @@ private void fill(final Menu menu, final int index, final boolean withWorld, fin if (layer.getData().isSelectable()) { Collection pop = layer.getAgentsForMenu(surface.getScope()); pop = new ArrayList<>(pop); - if (pop.isEmpty()) { - continue; - } + if (pop.isEmpty()) { continue; } final String layerName = layer.getType() + ": " + layer.getName(); final FocusOnSelection adapter = new FocusOnSelection(surface); final MenuAction focus = new MenuAction(adapter, GamaIcons.create(IGamaIcons.MENU_FOCUS).image(), "Focus on this display"); - final MenuAction[] actions2 = new MenuAction[] { focus }; + final MenuAction[] actions2 = { focus }; // if (layer instanceof GridLayer) { // actions2 = new MenuAction[] { focus }; // } else { // actions2 = new MenuAction[] { focus }; // } - if (filteredList != null) { - pop.retainAll(filteredList); - } - if (pop.isEmpty()) { - continue; - } + if (filteredList != null) { pop.retainAll(filteredList); } + if (pop.isEmpty()) { continue; } final MenuItem layerMenu = new MenuItem(menu, SWT.CASCADE); layerMenu.setText(layerName); layerMenu.setImage(layer_images.get(layer.getClass())); @@ -258,6 +348,21 @@ private void fill(final Menu menu, final int index, final boolean withWorld, fin } } + /** + * Builds the ROI menu. + * + * @param x + * the x + * @param y + * the y + * @param agents + * the agents + * @param actions + * the actions + * @param images + * the images + * @return the menu + */ @SuppressWarnings ("unused") public Menu buildROIMenu(final int x, final int y, final Collection agents, final Map actions, final Map images) { @@ -287,10 +392,11 @@ public void widgetDefaultSelected(final SelectionEvent e) { return menu; } + /** + * Dispose menu. + */ public void disposeMenu() { - if (menu != null && !menu.isDisposed()) { - menu.dispose(); - } + if (menu != null && !menu.isDisposed()) { menu.dispose(); } menu = null; }