/* Copyright 2008-2010 Gephi Authors : Mathieu Bastian <mathieu.bastian@gephi.org> Website : http://www.gephi.org This file is part of Gephi. Gephi is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Gephi is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Gephi. If not, see <http://www.gnu.org/licenses/>. */ package org.gephi.visualization.opengl.compatibility; import com.sun.opengl.util.BufferUtil; import java.awt.Color; import java.nio.FloatBuffer; import java.nio.IntBuffer; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.concurrent.ConcurrentLinkedQueue; import javax.media.opengl.GL; import javax.media.opengl.glu.GLU; import javax.media.opengl.glu.GLUquadric; import org.gephi.graph.api.EdgeData; import org.gephi.graph.api.Model; import org.gephi.graph.api.NodeData; import org.gephi.visualization.VizController; import org.gephi.visualization.VizModel; import org.gephi.visualization.api.objects.ModelClass; import org.gephi.visualization.opengl.AbstractEngine; import org.gephi.visualization.apiimpl.ModelImpl; import org.gephi.visualization.api.initializer.CompatibilityModeler; import org.gephi.visualization.opengl.octree.Octree; import org.gephi.visualization.apiimpl.Scheduler; import org.gephi.visualization.api.objects.CompatibilityModelClass; import org.gephi.visualization.selection.Cylinder; import org.gephi.visualization.selection.Rectangle; /** * * @author Mathieu Bastian */ public class CompatibilityEngine extends AbstractEngine { private CompatibilityScheduler scheduler; private long markTime = 0; private long markTime2 = 0; //User config protected CompatibilityModelClass[] modelClasses; protected CompatibilityModelClass[] lodClasses; protected CompatibilityModelClass[] selectableClasses; protected CompatibilityModelClass[] clickableClasses; //Selection private ConcurrentLinkedQueue<ModelImpl>[] selectedObjects; private boolean anySelected = false; public CompatibilityEngine() { super(); } @Override public void initArchitecture() { super.initArchitecture(); scheduler = (CompatibilityScheduler) VizController.getInstance().getScheduler(); vizEventManager = VizController.getInstance().getVizEventManager(); //Init octree = new Octree(vizConfig.getOctreeDepth(), vizConfig.getOctreeWidth(), modelClasses.length); octree.initArchitecture(); } public void updateSelection(GL gl, GLU glu) { if (vizConfig.isSelectionEnable() && currentSelectionArea != null && currentSelectionArea.isEnabled()) { VizModel vizModel = VizController.getInstance().getVizModel(); float[] mp = Arrays.copyOf(graphIO.getMousePosition(), 2); float[] cent = currentSelectionArea.getSelectionAreaCenter(); if (cent != null) { mp[0] += cent[0]; mp[1] += cent[1]; } octree.updateSelectedOctant(gl, glu, mp, currentSelectionArea.getSelectionAreaRectancle()); for (int i = 0; i < selectableClasses.length; i++) { CompatibilityModelClass modelClass = selectableClasses[i]; if (modelClass.isEnabled() && modelClass.isGlSelection()) { int objectCount = octree.countSelectedObjects(modelClass.getClassId()); float[] mousePosition = Arrays.copyOf(graphIO.getMousePosition(), 2); float[] pickRectangle = currentSelectionArea.getSelectionAreaRectancle(); float[] center = currentSelectionArea.getSelectionAreaCenter(); if (center != null) { mousePosition[0] += center[0]; mousePosition[1] += center[1]; } int capacity = 1 * 4 * objectCount; //Each object take in maximium : 4 * name stack depth IntBuffer hitsBuffer = BufferUtil.newIntBuffer(capacity); gl.glSelectBuffer(hitsBuffer.capacity(), hitsBuffer); gl.glRenderMode(GL.GL_SELECT); gl.glInitNames(); gl.glPushName(0); gl.glMatrixMode(GL.GL_PROJECTION); gl.glPushMatrix(); gl.glLoadIdentity(); glu.gluPickMatrix(mousePosition[0], mousePosition[1], pickRectangle[0], pickRectangle[1], graphDrawable.getViewport()); gl.glMultMatrixd(graphDrawable.getProjectionMatrix()); gl.glMatrixMode(GL.GL_MODELVIEW); int hitName = 1; ModelImpl[] array = new ModelImpl[objectCount]; for (Iterator<ModelImpl> itr = octree.getSelectedObjectIterator(modelClass.getClassId()); itr.hasNext();) { ModelImpl obj = itr.next(); obj.setAutoSelect(false); array[hitName - 1] = obj; gl.glLoadName(hitName); obj.display(gl, glu, vizModel); hitName++; } //Restoring the original projection matrix gl.glMatrixMode(GL.GL_PROJECTION); gl.glPopMatrix(); gl.glMatrixMode(GL.GL_MODELVIEW); gl.glFlush(); //Returning to normal rendering mode int nbRecords = gl.glRenderMode(GL.GL_RENDER); //Get the hits and put the node under selection in the selectionArray for (int j = 0; j < nbRecords; j++) { int hit = hitsBuffer.get(j * 4 + 3) - 1; //-1 Because of the glPushName(0) ModelImpl obj = array[hit]; obj.setAutoSelect(true); } } } } } @Override public boolean updateWorld() { boolean res = false; boolean changeMode = modeManager.requireModeChange(); boolean newConfig = configChanged; if (changeMode) { modeManager.unload(); } if (newConfig) { dataBridge.reset(); if (!vizConfig.isCustomSelection()) { //Reset model classes for (ModelClass objClass : getModelClasses()) { if (objClass.isEnabled()) { objClass.swapModelers(); resetObjectClass(objClass); } } } initSelection(); } if (dataBridge.requireUpdate() || changeMode || newConfig) { dataBridge.updateWorld(); res = true; } if (changeMode) { modeManager.changeMode(); } if (newConfig) { configChanged = false; } return res; } @Override public void worldUpdated(int cacheMarker) { octree.setCacheMarker(cacheMarker); for (ModelClass objClass : modelClasses) { if (objClass.getCacheMarker() == cacheMarker) { octree.cleanDeletedObjects(objClass.getClassId()); } } } @Override public void beforeDisplay(GL gl, GLU glu) { //Lighten delta if (lightenAnimationDelta != 0) { float factor = vizConfig.getLightenNonSelectedFactor(); factor += lightenAnimationDelta; if (factor >= 0.5f && factor <= 0.98f) { vizConfig.setLightenNonSelectedFactor(factor); } else { lightenAnimationDelta = 0; vizConfig.setLightenNonSelected(anySelected); } } if (backgroundChanged) { Color backgroundColor = vizController.getVizModel().getBackgroundColor(); gl.glClearColor(backgroundColor.getRed() / 255f, backgroundColor.getGreen() / 255f, backgroundColor.getBlue() / 255f, 1f); gl.glClear(GL.GL_COLOR_BUFFER_BIT); backgroundChanged = false; } if (reinit) { VizController.getInstance().refreshWorkspace(); dataBridge.reset(); graphDrawable.initConfig(gl); graphDrawable.setCameraLocation(vizController.getVizModel().getCameraPosition()); graphDrawable.setCameraTarget(vizController.getVizModel().getCameraTarget()); vizConfig.setCustomSelection(false); reinit = false; } } @Override public void display(GL gl, GLU glu) { for (Iterator<ModelImpl> itr = octree.getObjectIterator(AbstractEngine.CLASS_NODE); itr.hasNext();) { //TODO Move this ModelImpl obj = itr.next(); modelClasses[AbstractEngine.CLASS_NODE].getCurrentModeler().chooseModel(obj); setViewportPosition(obj); } markTime++; CompatibilityModelClass edgeClass = modelClasses[AbstractEngine.CLASS_EDGE]; CompatibilityModelClass nodeClass = modelClasses[AbstractEngine.CLASS_NODE]; CompatibilityModelClass arrowClass = modelClasses[AbstractEngine.CLASS_ARROW]; CompatibilityModelClass potatoClass = modelClasses[AbstractEngine.CLASS_POTATO]; VizModel vizModel = VizController.getInstance().getVizModel(); //Potato if (potatoClass.isEnabled()) { potatoClass.beforeDisplay(gl, glu); for (Iterator<ModelImpl> itr = octree.getObjectIterator(AbstractEngine.CLASS_POTATO); itr.hasNext();) { ModelImpl obj = itr.next(); if (obj.markTime != markTime) { obj.display(gl, glu, vizModel); obj.markTime = markTime; } } potatoClass.afterDisplay(gl, glu); } //Edges if (edgeClass.isEnabled()) { edgeClass.beforeDisplay(gl, glu); for (Iterator<ModelImpl> itr = octree.getObjectIterator(AbstractEngine.CLASS_EDGE); itr.hasNext();) { ModelImpl obj = itr.next(); //Renderable renderable = obj.getObj(); if (obj.markTime != markTime) { obj.display(gl, glu, vizModel); obj.markTime = markTime; } } edgeClass.afterDisplay(gl, glu); } //Arrows if (arrowClass.isEnabled()) { arrowClass.beforeDisplay(gl, glu); for (Iterator<ModelImpl> itr = octree.getObjectIterator(AbstractEngine.CLASS_ARROW); itr.hasNext();) { ModelImpl obj = itr.next(); if (obj.markTime != markTime) { obj.display(gl, glu, vizModel); obj.markTime = markTime; } } arrowClass.afterDisplay(gl, glu); } //Nodes if (nodeClass.isEnabled()) { nodeClass.beforeDisplay(gl, glu); for (Iterator<ModelImpl> itr = octree.getObjectIterator(AbstractEngine.CLASS_NODE); itr.hasNext();) { ModelImpl obj = itr.next(); if (obj.markTime != markTime) { obj.display(gl, glu, vizModel); obj.markTime = markTime; } } nodeClass.afterDisplay(gl, glu); } //Labels if (vizModel.getTextModel().isShowNodeLabels() || vizModel.getTextModel().isShowEdgeLabels()) { markTime++; if (nodeClass.isEnabled() && vizModel.getTextModel().isShowNodeLabels()) { textManager.getNodeRenderer().beginRendering(); textManager.defaultNodeColor(); if (textManager.isSelectedOnly()) { for (Iterator<ModelImpl> itr = octree.getObjectIterator(AbstractEngine.CLASS_NODE); itr.hasNext();) { ModelImpl obj = itr.next(); if (obj.markTime != markTime) { if ((obj.isSelected() || obj.isHighlight()) && obj.getObj().getTextData().isVisible()) { textManager.getNodeRenderer().drawTextNode(obj); } obj.markTime = markTime; } } } else { for (Iterator<ModelImpl> itr = octree.getObjectIterator(AbstractEngine.CLASS_NODE); itr.hasNext();) { ModelImpl obj = itr.next(); if (obj.markTime != markTime) { if (obj.getObj().getTextData().isVisible()) { textManager.getNodeRenderer().drawTextNode(obj); } obj.markTime = markTime; } } } textManager.getNodeRenderer().endRendering(); } if (edgeClass.isEnabled() && vizModel.getTextModel().isShowEdgeLabels()) { textManager.getEdgeRenderer().beginRendering(); textManager.defaultEdgeColor(); if (textManager.isSelectedOnly()) { for (Iterator<ModelImpl> itr = octree.getObjectIterator(AbstractEngine.CLASS_EDGE); itr.hasNext();) { ModelImpl obj = itr.next(); if (obj.markTime != markTime) { if ((obj.isSelected() || obj.isHighlight()) && obj.getObj().getTextData().isVisible()) { textManager.getEdgeRenderer().drawTextEdge(obj); } obj.markTime = markTime; } } } else { for (Iterator<ModelImpl> itr = octree.getObjectIterator(AbstractEngine.CLASS_EDGE); itr.hasNext();) { ModelImpl obj = itr.next(); if (obj.markTime != markTime) { if (obj.getObj().getTextData().isVisible()) { textManager.getEdgeRenderer().drawTextEdge(obj); } obj.markTime = markTime; } } } textManager.getEdgeRenderer().endRendering(); } } //octree.displayOctree(gl, glu); } @Override public void afterDisplay(GL gl, GLU glu) { if (vizConfig.isSelectionEnable() && currentSelectionArea != null) { gl.glMatrixMode(GL.GL_PROJECTION); gl.glPushMatrix(); gl.glLoadIdentity(); gl.glOrtho(0, graphDrawable.getViewportWidth(), 0, graphDrawable.getViewportHeight(), -1, 1); gl.glMatrixMode(GL.GL_MODELVIEW); gl.glPushMatrix(); gl.glLoadIdentity(); currentSelectionArea.drawArea(gl, glu); gl.glMatrixMode(GL.GL_PROJECTION); gl.glPopMatrix(); gl.glMatrixMode(GL.GL_MODELVIEW); gl.glPopMatrix(); } graphIO.trigger(); } @Override public void cameraHasBeenMoved(GL gl, GLU glu) { } @Override public void initEngine(final GL gl, final GLU glu) { initDisplayLists(gl, glu); scheduler.cameraMoved.set(true); scheduler.mouseMoved.set(true); lifeCycle.setInited(); } @Override public void initScreenshot(GL gl, GLU glu) { initDisplayLists(gl, glu); textManager.getNodeRenderer().reinitRenderer(); textManager.getEdgeRenderer().reinitRenderer(); scheduler.cameraMoved.set(true); } @Override public void addObject(int classID, ModelImpl obj) { octree.addObject(classID, obj); } @Override public void removeObject(int classID, ModelImpl obj) { octree.removeObject(classID, obj); } @Override public void resetObjectClass(ModelClass object3dClass) { octree.resetObjectClass(object3dClass.getClassId()); } @Override public void mouseClick() { for (ModelClass objClass : clickableClasses) { ModelImpl[] objArray = selectedObjects[objClass.getSelectionId()].toArray(new ModelImpl[0]); if (objArray.length > 0) { eventBridge.mouseClick(objClass, objArray); } } if (vizConfig.isSelectionEnable() && rectangleSelection && !customSelection) { Rectangle rectangle = (Rectangle) currentSelectionArea; //rectangle.setBlocking(false); //Clean opengl picking for (ModelClass objClass : selectableClasses) { if (objClass.isEnabled() && objClass.isGlSelection()) { for (ModelImpl obj : selectedObjects[objClass.getSelectionId()]) { obj.setAutoSelect(false); } } } //Select with click int i = 0; boolean someSelection = false; for (ModelClass objClass : selectableClasses) { markTime2++; for (Iterator<ModelImpl> itr = octree.getSelectedObjectIterator(objClass.getClassId()); itr.hasNext();) { ModelImpl obj = itr.next(); if (isUnderMouse(obj) && currentSelectionArea.select(obj.getObj())) { if (!obj.isSelected()) { //New selected obj.setSelected(true); /*if (vizEventManager.hasSelectionListeners()) { newSelectedObjects.add(obj); }*/ selectedObjects[i].add(obj); } someSelection = true; obj.selectionMark = markTime2; } } if (!(rectangle.isCtrl() && someSelection)) { for (Iterator<ModelImpl> itr = selectedObjects[i].iterator(); itr.hasNext();) { ModelImpl o = itr.next(); if (o.selectionMark != markTime2) { itr.remove(); o.setSelected(false); } } } i++; } rectangle.setBlocking(someSelection); if (vizController.getVizModel().isLightenNonSelectedAuto()) { if (vizConfig.isLightenNonSelectedAnimation()) { if (!anySelected && someSelection) { //Start animation lightenAnimationDelta = 0.07f; } else if (anySelected && !someSelection) { //Stop animation lightenAnimationDelta = -0.07f; } vizConfig.setLightenNonSelected(someSelection || lightenAnimationDelta != 0); } else { vizConfig.setLightenNonSelected(someSelection); } } anySelected = someSelection; scheduler.requireUpdateSelection(); } } @Override public void mouseDrag() { if (vizConfig.isMouseSelectionUpdateWhileDragging()) { mouseMove(); } else { float[] drag = graphIO.getMouseDrag3d(); for (ModelImpl obj : selectedObjects[0]) { float[] mouseDistance = obj.getDragDistanceFromMouse(); obj.getObj().setX(drag[0] + mouseDistance[0]); obj.getObj().setY(drag[1] + mouseDistance[1]); } } } @Override public void mouseMove() { //Selection if (vizConfig.isSelectionEnable() && rectangleSelection) { Rectangle rectangle = (Rectangle) currentSelectionArea; rectangle.setMousePosition(graphIO.getMousePosition()); if (rectangle.isStop()) { return; } } if (customSelection || currentSelectionArea.blockSelection()) { return; } /*List<ModelImpl> newSelectedObjects = null; List<ModelImpl> unSelectedObjects = null; if (vizEventManager.hasSelectionListeners()) { newSelectedObjects = new ArrayList<ModelImpl>(); unSelectedObjects = new ArrayList<ModelImpl>(); }*/ markTime2++; int i = 0; boolean someSelection = false; boolean forceUnselect = false; for (ModelClass objClass : selectableClasses) { forceUnselect = objClass.isAloneSelection() && someSelection; for (Iterator<ModelImpl> itr = octree.getSelectedObjectIterator(objClass.getClassId()); itr.hasNext();) { ModelImpl obj = itr.next(); if (!forceUnselect && isUnderMouse(obj) && currentSelectionArea.select(obj.getObj())) { if (!objClass.isAloneSelection()) { //avoid potatoes to select someSelection = true; } if (!obj.isSelected()) { //New selected obj.setSelected(true); /*if (vizEventManager.hasSelectionListeners()) { newSelectedObjects.add(obj); }*/ selectedObjects[i].add(obj); } obj.selectionMark = markTime2; } else if (currentSelectionArea.unselect(obj.getObj())) { if (forceUnselect) { obj.setAutoSelect(false); } /*else if (vizEventManager.hasSelectionListeners() && obj.isSelected()) { unSelectedObjects.add(obj); }*/ } } for (Iterator<ModelImpl> itr = selectedObjects[i].iterator(); itr.hasNext();) { ModelImpl o = itr.next(); if (o.selectionMark != markTime2) { itr.remove(); o.setSelected(false); } } i++; } if (vizController.getVizModel().isLightenNonSelectedAuto()) { if (vizConfig.isLightenNonSelectedAnimation()) { if (!anySelected && someSelection) { //Start animation lightenAnimationDelta = 0.07f; } else if (anySelected && !someSelection) { //Stop animation lightenAnimationDelta = -0.07f; } vizConfig.setLightenNonSelected(someSelection || lightenAnimationDelta != 0); } else { vizConfig.setLightenNonSelected(someSelection); } } anySelected = someSelection; } @Override public void refreshGraphLimits() { } @Override public void startDrag() { float x = graphIO.getMouseDrag3d()[0]; float y = graphIO.getMouseDrag3d()[1]; for (Iterator<ModelImpl> itr = selectedObjects[0].iterator(); itr.hasNext();) { ModelImpl o = itr.next(); float[] tab = o.getDragDistanceFromMouse(); tab[0] = o.getObj().x() - x; tab[1] = o.getObj().y() - y; } } @Override public void stopDrag() { scheduler.requireUpdatePosition(); //Selection if (vizConfig.isSelectionEnable() && rectangleSelection) { Rectangle rectangle = (Rectangle) currentSelectionArea; rectangle.stop(); scheduler.requireUpdateSelection(); } } @Override public void updateObjectsPosition() { for (ModelClass objClass : modelClasses) { if (objClass.isEnabled()) { octree.updateObjectsPosition(objClass.getClassId()); } } } @Override public ModelImpl[] getSelectedObjects(int modelClass) { return selectedObjects[modelClasses[modelClass].getSelectionId()].toArray(new ModelImpl[0]); } @Override public void selectObject(Model obj) { ModelImpl modl = (ModelImpl) obj; if (!customSelection) { vizConfig.setRectangleSelection(false); customSelection = true; configChanged = true; //Reset for (ModelClass objClass : selectableClasses) { for (Iterator<ModelImpl> itr = selectedObjects[objClass.getSelectionId()].iterator(); itr.hasNext();) { ModelImpl o = itr.next(); itr.remove(); o.setSelected(false); } } anySelected = true; //Force highlight if (vizController.getVizModel().isLightenNonSelectedAuto()) { if (vizConfig.isLightenNonSelectedAnimation()) { //Start animation lightenAnimationDelta = 0.07f; vizConfig.setLightenNonSelected(true); } else { vizConfig.setLightenNonSelected(true); } } } modl.setSelected(true); if (modl.getObj() instanceof NodeData) { selectedObjects[modelClasses[AbstractEngine.CLASS_NODE].getSelectionId()].add(modl); } forceSelectRefresh(modelClasses[AbstractEngine.CLASS_EDGE].getClassId()); } @Override public void selectObject(Model[] objs) { if (!customSelection) { vizConfig.setRectangleSelection(false); customSelection = true; configChanged = true; //Reset for (ModelClass objClass : selectableClasses) { for (Iterator<ModelImpl> itr = selectedObjects[objClass.getSelectionId()].iterator(); itr.hasNext();) { ModelImpl o = itr.next(); itr.remove(); o.setSelected(false); } } anySelected = true; //Force highlight if (vizController.getVizModel().isLightenNonSelectedAuto()) { if (vizConfig.isLightenNonSelectedAnimation()) { //Start animation lightenAnimationDelta = 0.07f; vizConfig.setLightenNonSelected(true); } else { vizConfig.setLightenNonSelected(true); } } } else { //Reset for (ModelClass objClass : selectableClasses) { for (Iterator<ModelImpl> itr = selectedObjects[objClass.getSelectionId()].iterator(); itr.hasNext();) { ModelImpl o = itr.next(); itr.remove(); o.setSelected(false); } } for (Iterator<ModelImpl> itr = octree.getSelectedObjectIterator(modelClasses[AbstractEngine.CLASS_EDGE].getClassId()); itr.hasNext();) { ModelImpl obj = itr.next(); obj.setSelected(false); } } for (Model r : objs) { if (r != null) { ModelImpl mdl = (ModelImpl) r; mdl.setSelected(true); if (mdl.getObj() instanceof NodeData) { selectedObjects[modelClasses[AbstractEngine.CLASS_NODE].getSelectionId()].add(mdl); } else if (mdl.getObj() instanceof EdgeData) { selectedObjects[modelClasses[AbstractEngine.CLASS_EDGE].getSelectionId()].add(mdl); } } } //forceSelectRefresh(modelClasses[AbstractEngine.CLASS_EDGE].getClassId()); } public void forceSelectRefresh(int selectedClass) { for (Iterator<ModelImpl> itr = octree.getSelectedObjectIterator(selectedClass); itr.hasNext();) { ModelImpl obj = itr.next(); if (isUnderMouse(obj)) { if (!obj.isSelected()) { //New selected obj.setSelected(true); /*if (vizEventManager.hasSelectionListeners()) { newSelectedObjects.add(obj); }*/ selectedObjects[selectedClass].add(obj); } } } } @Override public void resetSelection() { customSelection = false; configChanged = true; anySelected = false; for (ModelClass objClass : selectableClasses) { selectedObjects[objClass.getSelectionId()].clear(); } } private void initDisplayLists(GL gl, GLU glu) { //Constants float blancCasse[] = {(float) 213 / 255, (float) 208 / 255, (float) 188 / 255, 1.0f}; float noirCasse[] = {(float) 39 / 255, (float) 25 / 255, (float) 99 / 255, 1.0f}; float noir[] = {(float) 0 / 255, (float) 0 / 255, (float) 0 / 255, 0.0f}; float[] shine_low = {10.0f, 0.0f, 0.0f, 0.0f}; FloatBuffer ambient_metal = FloatBuffer.wrap(noir); FloatBuffer diffuse_metal = FloatBuffer.wrap(noirCasse); FloatBuffer specular_metal = FloatBuffer.wrap(blancCasse); FloatBuffer shininess_metal = FloatBuffer.wrap(shine_low); //End //Quadric for all the glu models GLUquadric quadric = glu.gluNewQuadric(); int ptr = gl.glGenLists(4); // Metal material display list int MATTER_METAL = ptr; gl.glNewList(MATTER_METAL, GL.GL_COMPILE); gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_AMBIENT, ambient_metal); gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_DIFFUSE, diffuse_metal); gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_SPECULAR, specular_metal); gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_SHININESS, shininess_metal); gl.glEndList(); //Fin for (CompatibilityModeler cis : modelClasses[CLASS_NODE].getModelers()) { int newPtr = cis.initDisplayLists(gl, glu, quadric, ptr); ptr = newPtr; } //modelClasses[CLASS_POTATO].getCurrentModeler().initDisplayLists(gl, glu, quadric, ptr); //Fin // Sphere with a texture //SHAPE_BILLBOARD = SHAPE_SPHERE32 + 1; /*gl.glNewList(SHAPE_BILLBOARD,GL.GL_COMPILE); textures[0].bind(); gl.glBegin(GL.GL_TRIANGLE_STRIP); // Map the texture and create the vertices for the particle. gl.glTexCoord2d(1, 1); gl.glVertex3f(0.5f, 0.5f, 0); gl.glTexCoord2d(0, 1); gl.glVertex3f(-0.5f, 0.5f,0); gl.glTexCoord2d(1, 0); gl.glVertex3f(0.5f, -0.5f, 0); gl.glTexCoord2d(0, 0); gl.glVertex3f(-0.5f,-0.5f, 0); gl.glEnd(); gl.glBindTexture(GL.GL_TEXTURE_2D,0); gl.glEndList();*/ //Fin glu.gluDeleteQuadric(quadric); } public void initObject3dClass() { modelClasses = modelClassLibrary.createModelClassesCompatibility(this); lodClasses = new CompatibilityModelClass[0]; selectableClasses = new CompatibilityModelClass[0]; clickableClasses = new CompatibilityModelClass[0]; modelClasses[CLASS_NODE].setEnabled(true); modelClasses[CLASS_EDGE].setEnabled(vizController.getVizModel().isShowEdges()); modelClasses[CLASS_ARROW].setEnabled(vizConfig.isShowArrows()); modelClasses[CLASS_POTATO].setEnabled(vizController.getVizModel().isShowHulls()); //LOD ArrayList<ModelClass> classList = new ArrayList<ModelClass>(); for (ModelClass objClass : modelClasses) { if (objClass.isLod()) { classList.add(objClass); } } lodClasses = classList.toArray(lodClasses); //Selectable classList.clear(); for (ModelClass objClass : modelClasses) { if (objClass.isSelectable()) { classList.add(objClass); } } selectableClasses = classList.toArray(selectableClasses); //Clickable classList.clear(); for (ModelClass objClass : modelClasses) { if (objClass.isClickable()) { classList.add(objClass); } } clickableClasses = classList.toArray(clickableClasses); //Init selection lists selectedObjects = new ConcurrentLinkedQueue[selectableClasses.length]; int i = 0; for (ModelClass objClass : selectableClasses) { objClass.setSelectionId(i); selectedObjects[i] = new ConcurrentLinkedQueue<ModelImpl>(); i++; } } @Override public void initSelection() { if (vizConfig.isCustomSelection()) { //System.out.println("CustomSelection"); rectangleSelection = false; currentSelectionArea = null; } else if (vizConfig.isRectangleSelection()) { currentSelectionArea = new Rectangle(); rectangleSelection = true; customSelection = false; } else { currentSelectionArea = new Cylinder(); rectangleSelection = false; customSelection = false; } } @Override public void startAnimating() { if (!scheduler.isAnimating()) { //System.out.println("start animating"); scheduler.start(); graphIO.startMouseListening(); } } @Override public void stopAnimating() { if (scheduler.isAnimating()) { //System.out.println("stop animating"); scheduler.stop(); graphIO.stopMouseListening(); } } public CompatibilityModelClass[] getModelClasses() { return modelClasses; } public Scheduler getScheduler() { return scheduler; } }