Package jsynoptic.plugins.java3d

Source Code of jsynoptic.plugins.java3d.Universe$Listener

/* ========================
* JSynoptic : a free Synoptic editor
* ========================
*
* Project Info:  http://jsynoptic.sourceforge.net/index.html
*
* This program is free software; you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Foundation;
* either version 2.1 of the License, or (at your option) any later version.
*
* This program 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*
* (C) Copyright 2001-2007, by :
*     Corporate:
*         EADS Astrium
*     Individual:
*         Claude Cazenave
*
* $Id: Universe.java,v 1.9 2008/12/17 22:37:53 cazenave Exp $
*
* Changes
* -------
* 4 janv. 08  : Initial public release
*
*/
package jsynoptic.plugins.java3d;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;

import javax.media.j3d.BranchGroup;
import javax.media.j3d.Canvas3D;
import javax.media.j3d.Group;
import javax.media.j3d.Locale;
import javax.media.j3d.Node;
import javax.media.j3d.SceneGraphObject;
import javax.media.j3d.View;
import javax.media.j3d.VirtualUniverse;

import simtools.data.EndNotificationListener;
import simtools.util.ListenerManager;

import com.sun.j3d.utils.geometry.Primitive;
import com.sun.j3d.utils.scenegraph.io.SceneGraphFileReader;
import com.sun.j3d.utils.scenegraph.io.SceneGraphFileWriter;
import com.sun.j3d.utils.scenegraph.io.UnsupportedUniverseException;
import com.sun.j3d.utils.universe.Viewer;
import com.sun.j3d.utils.universe.ViewingPlatform;

public class Universe extends VirtualUniverse implements EndNotificationListener {
    /** One locale is enough but easy to extend if needed */
    Locale _rootLocale;

    /** a map with all the viewers for each canvas */
    HashMap<Canvas3D, Viewer> _viewers;

    /** a list of listener */
    ArrayList<Listener> _listeners;

    /** An array of DisplayListener objects */
    ListenerManager _displayListeners = new ListenerManager();

    /**
     * An array of Dirty nodes to update before calling listeners
     * The dirty nodes are then automatically removed from this array, as they're supposed to be cleaned up
     */
    ListenerManager _dirtyNodes = new ListenerManager();

    /**
     * True when the user has changed the period for refreshing the scene>
     */
    boolean _refreshPeriodChanged = false;
   
    static public int REFRESH_PERIOD = 100;
   
    long _refreshPeriod = REFRESH_PERIOD;
       
    /**
     * This timer is used to gather notify events and send them at a reasonable rate to 3D motors.
     */
    Timer _timer;
   
    Universe() {
        _rootLocale = new Locale(this);
        _viewers = new HashMap<Canvas3D, Viewer>();
        _listeners = new ArrayList<Listener>();
    }

    public Locale getLocale() {
        return _rootLocale;
    }

    public File getFile() {
        return UniversePool.getGlobal().getFile(this);
    }

    public String getName() {
        String name = getFile().getName();
        int k = name.lastIndexOf(UniversePool.JAVA_3D_FILE_EXT);
        if (k > 0) {
            name = name.substring(0, k);
        }
        return name;
    }

    public void addBranchGraph(BranchGroup bg) {
        bg.setCapability(BranchGroup.ALLOW_DETACH);
        _rootLocale.addBranchGraph(bg);
    }

    public void addView(NodeSelector selector) {
        new Java3dFrame(getName(), -1, -1, -1, -1, this, selector);
    }

    ViewingPlatform getViewingPlatform(Canvas3D canvas) {
        Viewer v = _viewers.get(canvas);
        if (v != null) {
            return v.getViewingPlatform();
        }
        return null;
    }

    Viewer getViewer(Canvas3D canvas) {
        return _viewers.get(canvas);
    }

    public Set<Canvas3D> getCanvas() {
        return _viewers.keySet();
    }

    void addCanvas(Canvas3D canvas) {
        // check if one exists
        if (_viewers.containsKey(canvas)) {
            throw new IllegalArgumentException("canvas already exists");
        }
        Viewer viewer = new Viewer(canvas);
        viewer.getView().setMinimumFrameCycleTime(30);
        ViewingPlatform viewingPlatform = new ViewingPlatform(1);
        viewingPlatform.setNominalViewingTransform();
        _rootLocale.addBranchGraph(viewingPlatform);
        viewer.setViewingPlatform(viewingPlatform);
        _viewers.put(canvas, viewer);
        for (Listener l : _listeners) {
            l.notifyChange();
        }
    }

    void removeCanvas(Canvas3D canvas) {
        Viewer v = _viewers.get(canvas);
        // check if one exists
        if (v == null) {
            return;
        }
        cleanupViewer(v);
        _viewers.remove(canvas);
        for (Listener l : _listeners) {
            l.notifyChange();
        }
    }

    private void cleanupViewer(Viewer v) {
        // Get view associated with this SimpleUniverse
        View view = v.getView();
        // cleanup all off-screen canvases
        for (int i = view.numCanvas3Ds() - 1; i >= 0; i--) {
            Canvas3D c = view.getCanvas3D(i);
            if (c.isOffScreen()) {
                c.setOffScreenBuffer(null);
            }
        }
        // Remove all canvases from view; remove the viewing platform from
        // this viewer; remove all locales to cleanup the scene graph
        view.removeAllCanvas3Ds();
        _rootLocale.removeBranchGraph(v.getViewingPlatform());
        v.setViewingPlatform(null);
    }

    public ArrayList<BranchGroup> getSceneGraphs() {
        Enumeration<?> e = _rootLocale.getAllBranchGraphs();
        ArrayList<BranchGroup> res = new ArrayList<BranchGroup>();
        while (e.hasMoreElements()) {
            BranchGroup bg = (BranchGroup) e.nextElement();
            if (!(bg instanceof ViewingPlatform)) {
                res.add(bg);
            }
        }
        return res;
    }

    /**
     * Register the universe as the unique listener for animators data events in the whole scene graph.
     * This way, all events coming from the same source are fusionned into a single event
     * for the scene
     */
    public void notificationEnd(Object referer) {
        notifyChange();
    }

    /**
     * Notify listeners that this scene has changed.
     * For performance purposes, all notification changes are coalesced into a single event
     * no more than the scene period notification delay.
     * @see simtools.data.EndNotificationListener#notificationEnd(java.lang.Object)
     */
   
    protected class SceneTimerTask extends TimerTask{
        public void run() {
            synchronized(Universe.this) {
                updateDirtyNodes();
            }
        }
    }
   
    protected synchronized void notifyChange() {
         // if there is a timer and no change about the refreshperiod, let it do its job
        if (_refreshPeriodChanged || _timer == null){
            _refreshPeriodChanged = false;
            if (_timer!=null)
                _timer.cancel();
            _timer = new Timer(true); // do not block the application on exit
            _timer.schedule(new SceneTimerTask(),0,_refreshPeriod);
        }
    }

    // Dirty Nodes handling. Idem
    public void addDirtyNode(DirtyNode node) {
        _dirtyNodes.add(node);
    }

    public void removeDirtyNode(DirtyNode node) {
        _dirtyNodes.remove(node);
    }

    /** Call this when the scene changed */
    public void updateDirtyNodes() {
        if (_dirtyNodes.size()>0) {
            synchronized(_dirtyNodes) {
                int n = _dirtyNodes.size(); // only one call outside loop
                for (int i=0; i<n; ++i) {
                    DirtyNode dn = (DirtyNode)_dirtyNodes.get(i);
                    if (dn!=null) dn.cleanup();
                }
                // Nodes are clean now.
                _dirtyNodes.clear();
            }
        }
    }
   
    void read(File f) throws IOException {
        SceneGraphFileReader r = new SceneGraphFileReader(f);
        BranchGroup[] bgs = r.readAllBranchGraphs();
        for (BranchGroup bg : bgs) {
            _rootLocale.addBranchGraph(bg);
        }
    }

    void write(File f) throws IOException {
        try {
            SceneGraphFileWriter w = new SceneGraphFileWriter(f, null, false,
                    "TBDuinverseName", null);
            Enumeration<?> e = _rootLocale.getAllBranchGraphs();
            while (e.hasMoreElements()) {
                BranchGroup bg = (BranchGroup) e.nextElement();
                if (!(bg instanceof ViewingPlatform)) {
                    // TODO serialize a name ???
                    w.writeBranchGraph(bg, null);
                }
            }
            w.close();
        } catch (UnsupportedUniverseException e) {
            // will not be thrown but in case
            throw new IOException(e.getMessage());
        }
    }

    /**
     * Cleanup memory use and reference by SimpleUniverse. Typically it should
     * be invoked by the applet's destroy method.
     */
    public void cleanup() {
        for (Viewer v : _viewers.values()) {
            cleanupViewer(v);
        }
        removeAllLocales();
        // viewerMap cleanup here to prevent memory leak problem.
        Viewer.clearViewerMap();
        Primitive.clearGeometryCache();
    }

    public ArrayList<Node> getNodes(Class<? extends Node> nodeClass){
        ArrayList<Node> res=new ArrayList<Node>();
        Enumeration<?> e=getAllLocales();
        while(e.hasMoreElements()){
            Locale l=(Locale)e.nextElement();
            Enumeration<?> el=l.getAllBranchGraphs();
            while(el.hasMoreElements()){
                BranchGroup bg=(BranchGroup)el.nextElement();
                if(nodeClass.isAssignableFrom(bg.getClass())){
                    res.add(bg);
                }
                getNodes(res, nodeClass, bg);
            }
        }
        return res;
    }
   
    private static void getNodes(ArrayList<Node> res, Class<? extends Node> nodeClass, Group g){
        Enumeration<?> e=g.getAllChildren();
        while(e.hasMoreElements()){
            Node n=(Node)e.nextElement();
            if(nodeClass.isAssignableFrom(n.getClass())){
                res.add(n);
            }
            if(n instanceof Group){
                getNodes(res,nodeClass, (Group)n);
            }
        }
    }

    public void addListner(Listener l) {
        _listeners.add(l);
    }

    public void removeListner(Listener l) {
        _listeners.remove(l);
    }

    public interface Listener {
        public void notifyChange();
    }
   
    public static SceneGraphObjectHolder findHolder(SceneGraphObjectHolder start, SceneGraphObject object){
        ArrayList<SceneGraphObjectHolder> roots=new ArrayList<SceneGraphObjectHolder>();
        start.getRootHolders(roots);
        return findHolder(roots, object);
    }

    private static SceneGraphObjectHolder findHolder(ArrayList<SceneGraphObjectHolder> list, SceneGraphObject object){
        for(SceneGraphObjectHolder s : list){
            if(s.getSceneGraphObject()==object){
                return s;
            }
            ArrayList<SceneGraphObjectHolder> c=new ArrayList<SceneGraphObjectHolder>();
            s.getChildrenHolders(c);
            SceneGraphObjectHolder h=findHolder(c, object);
            if(h!=null){
                return h;
            }      
        }
        return null;
    }

    public static Universe getGraphPath(Node n, SceneGraphObject o,
            ArrayList<SceneGraphObject> path) {
        if(n==null){
            if(o instanceof Node){
                n=(Node)o;
            }
            else{
                path.add(o);
                return null;
            }
        }
        if(o!=null && o!=n){
            path.add(n);
        }

        Node np = n.getParent();
        while (np != null) {
            path.add(np);
            np = np.getParent();
        }
        if (n.getLocale() == null) {
            return null; // detached
        }
        return (Universe) (n.getLocale().getVirtualUniverse());
    }
}
TOP

Related Classes of jsynoptic.plugins.java3d.Universe$Listener

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.