View Javadoc

    1   /*
    2    * @(#) Animation3DCanvas.java May 10, 2004
    3    *
    4    * Copyright (c) 2002-2005 Delft University of Technology Jaffalaan 5, 2628 BX
    5    * Delft, the Netherlands. All rights reserved.
    6    *
    7    * This software is proprietary information of Delft University of Technology
    8    * The code is published under the Lesser General Public License
    9    */
    10  package nl.tudelft.simulation.dsol.gui.animation3D;
    11
    12  import java.rmi.RemoteException;
    13
    14  import javax.media.j3d.BoundingSphere;
    15  import javax.media.j3d.BranchGroup;
    16  import javax.media.j3d.Canvas3D;
    17  import javax.media.j3d.Locale;
    18  import javax.media.j3d.VirtualUniverse;
    19  import javax.naming.Binding;
    20  import javax.naming.NamingEnumeration;
    21  import javax.naming.event.EventContext;
    22  import javax.naming.event.NamespaceChangeListener;
    23  import javax.naming.event.NamingEvent;
    24  import javax.naming.event.NamingExceptionEvent;
    25
    26  import nl.tudelft.simulation.dsol.animation.D3.Renderable3DInterface;
    27  import nl.tudelft.simulation.dsol.experiment.Experiment;
    28  import nl.tudelft.simulation.dsol.gui.DSOLApplicationInterface;
    29  import nl.tudelft.simulation.dsol.gui.animation3D.mouse.PickObjectMouseBehavior;
    30  import nl.tudelft.simulation.dsol.simulators.AnimatorInterface;
    31  import nl.tudelft.simulation.dsol.simulators.SimulatorInterface;
    32  import nl.tudelft.simulation.event.Event;
    33  import nl.tudelft.simulation.event.EventInterface;
    34  import nl.tudelft.simulation.event.EventListenerInterface;
    35  import nl.tudelft.simulation.logger.Logger;
    36  import nl.tudelft.simulation.naming.InitialEventContext;
    37
    38  import com.sun.j3d.utils.universe.SimpleUniverse;
    39
    40  /***
    41   * Animation3DCanvas, a canvas for 3d animation <br>
    42   * (c) copyright 2002-2005 <a href="http://www.simulation.tudelft.nl">Delft
    43   * University of Technology </a>, the Netherlands. <br>
    44   * See for project information <a
    45   * href="http://www.simulation.tudelft.nl">www.simulation.tudelft.nl </a> <br>
    46   * License of use: <a href="http://www.gnu.org/copyleft/lesser.html">Lesser
    47   * General Public License (LGPL) </a>, no warranty.
    48   *
    49   * @version $Revision$ $Date$
    50   * @author <a href="http://www.tbm.tudelft.nl/webstaf/royc/index.htm">Roy Chin
    51   *         </a>
    52   */
    53  public class Animation3DCanvas extends Canvas3D implements
    54  		EventListenerInterface, NamespaceChangeListener
    55  {
    56
    57  	/*** the application */
    58  	private DSOLApplicationInterface application = null;
    59
    60  	/*** the eventContext */
    61  	private EventContext context = null;
    62
    63  	/*** View branch */
    64  	private ViewBranch viewBranch = null;
    65
    66  	/*** Content branch */
    67  	private ContentBranch contentBranch = null;
    68
    69  	/***
    70  	 * Constructs a new panel
    71  	 *
    72  	 * @param application DSOLApplicationInterface
    73  	 */
    74  	public Animation3DCanvas(final DSOLApplicationInterface application)
    75  	{
    76  		super(SimpleUniverse.getPreferredConfiguration());
    77  		this.application = application;
    78  		initializePanel();
    79  		initializeSubscription();
    80  	}
    81
    82  	/***
    83  	 * Initializes the panel
    84  	 */
    85  	public void initializePanel()
    86  	{
    87  		// ----------------
    88  		// Configure canvas
    89  		this.setFocusable(true);
    90
    91  		// ------------------------------------
    92  		// Create a default universe and locale
    93  		VirtualUniverse universe = new VirtualUniverse();
    94  		Locale locale = new Locale(universe);
    95
    96  		// ---------------------
    97  		// Build the scene graph
    98  		this.viewBranch = new ViewBranch(this);
    99  		this.contentBranch = new ContentBranch();
    100
    101 		// --------------
    102 		// Enable picking
    103 		new PickObjectMouseBehavior(this, this.contentBranch,
    104 				new BoundingSphere());
    105
    106 		locale.addBranchGraph(this.viewBranch);
    107 		locale.addBranchGraph(this.contentBranch);
    108 	}
    109
    110 	/***
    111 	 * initializes the panel subscription
    112 	 */
    113 	private void initializeSubscription()
    114 	{
    115 		try
    116 		{
    117 			this.application.addListener(this,
    118 					DSOLApplicationInterface.EXPERIMENT_CHANGED_EVENT);
    119 			this.notify(new Event(
    120 					DSOLApplicationInterface.EXPERIMENT_CHANGED_EVENT,
    121 					this.application, this.application.getExperiment()));
    122 		} catch (RemoteException exception)
    123 		{
    124 			Logger.warning(this, "initialize", exception);
    125 		}
    126 	}
    127
    128 	/***
    129 	 * @see nl.tudelft.simulation.event.EventListenerInterface#notify
    130 	 *      (nl.tudelft.simulation.event.EventInterface)
    131 	 */
    132 	public void notify(final EventInterface event) throws RemoteException
    133 	{
    134 		// UPDATE_ANIMATION_EVENT
    135 		if (event.getSource() instanceof AnimatorInterface
    136 				&& event.getType().equals(
    137 						AnimatorInterface.UPDATE_ANIMATION_EVENT))
    138 		{
    139 			if (this.getWidth() > 0 || this.getHeight() > 0)
    140 			{
    141 				this.updateElements();
    142 				// this.repaint();
    143 			}
    144 			return;
    145 		}
    146 		// START_REPLICATION_EVENT
    147 		if (event.getSource() instanceof AnimatorInterface
    148 				&& event.getType().equals(
    149 						SimulatorInterface.START_REPLICATION_EVENT))
    150 		{
    151 			this.contentBranch.getDynamicObjectBranch().removeAllChildren();
    152 			this.contentBranch.getStaticObjectBranch().removeAllChildren();
    153 			AnimatorInterface simulator = (AnimatorInterface) event.getSource();
    154 			String contextName = this.application.getExperiment().getRun()
    155 					+ "/treatment("
    156 					+ simulator.getReplication().getRunControl().getTreatment()
    157 							.getNumber() + ")/replication("
    158 					+ simulator.getReplication().getNumber() + ")/animation/3D";
    159 			try
    160 			{
    161 				if (this.context != null)
    162 				{
    163 					this.context.removeNamingListener(this);
    164 				}
    165 				this.context = (EventContext) new InitialEventContext()
    166 						.lookup(contextName);
    167 				this.context.addNamingListener("", EventContext.SUBTREE_SCOPE,
    168 						this);
    169 				NamingEnumeration list = this.context.listBindings("");
    170 				while (list.hasMore())
    171 				{
    172 					Binding binding = (Binding) list.next();
    173 					this.objectAdded(new NamingEvent(this.context, -1, binding,
    174 							binding, null));
    175 				}
    176 				this.updateElements();
    177 				// this.repaint();
    178 			} catch (Exception exception)
    179 			{
    180 				Logger.warning(this, "notify", exception);
    181 			}
    182 		}
    183 		// SIMULATOR_CHANGED_EVENT
    184 		if (event.getSource() instanceof Experiment
    185 				&& event.getType().equals(Experiment.SIMULATOR_CHANGED_EVENT))
    186 		{
    187 			// System.out.println("SIMULATOR_CHANGED_EVENT");
    188 			this.contentBranch.getDynamicObjectBranch().removeAllChildren();
    189 			this.contentBranch.getStaticObjectBranch().removeAllChildren();
    190 			this.updateElements();
    191 			// this.repaint();
    192 			if (event.getContent() instanceof AnimatorInterface
    193 					&& event.getContent() != null)
    194 			{
    195 				AnimatorInterface simulator = (AnimatorInterface) event
    196 						.getContent();
    197 				simulator.addListener(this,
    198 						AnimatorInterface.UPDATE_ANIMATION_EVENT);
    199 				if (simulator.getReplication() != null)
    200 				{
    201 					this.notify(new Event(
    202 							SimulatorInterface.START_REPLICATION_EVENT,
    203 							simulator, simulator));
    204 				} else
    205 				{
    206 					simulator.addListener(this,
    207 							SimulatorInterface.START_REPLICATION_EVENT);
    208 				}
    209 			}
    210 		}
    211 		// EXPERIMENT_CHANGED_EVENT
    212 		if (event.getSource().equals(this.application)
    213 				&& event.getType().equals(
    214 						DSOLApplicationInterface.EXPERIMENT_CHANGED_EVENT))
    215 		{
    216 			// System.out.println("EXPERIMENT_CHANGED_EVENT");
    217 			this.contentBranch.getDynamicObjectBranch().removeAllChildren();
    218 			this.contentBranch.getStaticObjectBranch().removeAllChildren();
    219 			this.updateElements();
    220 			// this.repaint();
    221 			if (event.getContent() != null)
    222 			{
    223 				Experiment experiment = (Experiment) event.getContent();
    224 				experiment
    225 						.addListener(this, Experiment.SIMULATOR_CHANGED_EVENT);
    226 				this.notify(new Event(Experiment.SIMULATOR_CHANGED_EVENT,
    227 						experiment, experiment.getSimulator()));
    228 			}
    229 			return;
    230 		}
    231
    232 	}
    233
    234 	/***
    235 	 * @see javax.naming.event.NamespaceChangeListener#objectAdded
    236 	 *      (javax.naming.event.NamingEvent)
    237 	 */
    238 	public void objectAdded(final NamingEvent namingEvent)
    239 	{
    240 		Renderable3DInterface element = (Renderable3DInterface) namingEvent
    241 				.getNewBinding().getObject();
    242 		// Add the element's model to the content branch
    243 		BranchGroup model = (BranchGroup) element;
    244 		if (model != null)
    245 		{
    246 			if (element.getType() != Renderable3DInterface.DYNAMIC_OBJECT)
    247 			{
    248 				this.contentBranch.getStaticObjectBranch().addChild(model);
    249 			} else
    250 			{
    251 				this.contentBranch.getDynamicObjectBranch().addChild(model);
    252 			}
    253 		}
    254 	}
    255
    256 	/***
    257 	 * @see javax.naming.event.NamespaceChangeListener#objectRemoved
    258 	 *      (javax.naming.event.NamingEvent)
    259 	 */
    260 	public void objectRemoved(final NamingEvent namingEvent)
    261 	{
    262 		System.out.println("Animation3d: Object removed");
    263 		Renderable3DInterface element = (Renderable3DInterface) namingEvent
    264 				.getOldBinding().getObject();
    265
    266 		// Remove element's model from the branch graph
    267 		this.contentBranch.getDynamicObjectBranch().removeChild(
    268 				(BranchGroup) element);
    269 	}
    270
    271 	/***
    272 	 * @see javax.naming.event.NamespaceChangeListener#objectRenamed
    273 	 *      (javax.naming.event.NamingEvent)
    274 	 */
    275 	public void objectRenamed(final NamingEvent namingEvent)
    276 	{
    277 		this.objectRemoved(namingEvent);
    278 		this.objectAdded(namingEvent);
    279 	}
    280
    281 	/***
    282 	 * @see javax.naming.event.NamingListener#namingExceptionThrown
    283 	 *      (javax.naming.event.NamingExceptionEvent)
    284 	 */
    285 	public void namingExceptionThrown(final NamingExceptionEvent namingEvent)
    286 	{
    287 		Logger.warning(this, "namingExceptionThrown", namingEvent
    288 				.getException());
    289 	}
    290
    291 	/***
    292 	 * Update all elements
    293 	 */
    294 	public void updateElements()
    295 	{
    296 		BranchGroup dynamicObjectBranch = this.contentBranch
    297 				.getDynamicObjectBranch();
    298 		// Synchronize is meant to prevent shaky animation
    299 		// when updating lots of objects. Seems to work.
    300 		synchronized (this)
    301 		{
    302 			for (int i = 0; i < dynamicObjectBranch.numChildren(); i++)
    303 			{
    304 				Renderable3DInterface element = (Renderable3DInterface) dynamicObjectBranch
    305 						.getChild(i);
    306 				element.update();
    307 			}
    308 		}
    309 	}
    310
    311 	/***
    312 	 * @return ContentBranch
    313 	 */
    314 	public ContentBranch getContentBranch()
    315 	{
    316 		return this.contentBranch;
    317 	}
    318
    319 	/***
    320 	 * @return ViewBranch
    321 	 */
    322 	public ViewBranch getViewBranch()
    323 	{
    324 		return this.viewBranch;
    325 	}
    326
    327 }