View Javadoc

    1   /*
    2    * @(#) Renderable3D.java May 10, 2004
    3    *
    4    * Copyright (c) 2003 Delft University of Technology Jaffalaan 5, 2628 BX Delft,
    5    * the Netherlands All rights reserved.
    6    *
    7    * This software is proprietary information of Delft University of Technology
    8    * The code is published under the General Public License
    9    */
    10
    11  package nl.tudelft.simulation.dsol.animation.D3;
    12
    13  import java.awt.geom.Point2D;
    14  import java.rmi.RemoteException;
    15  import java.util.Enumeration;
    16
    17  import javax.media.j3d.BranchGroup;
    18  import javax.media.j3d.Group;
    19  import javax.media.j3d.Node;
    20  import javax.media.j3d.Transform3D;
    21  import javax.media.j3d.TransformGroup;
    22  import javax.vecmath.AxisAngle4d;
    23  import javax.vecmath.Vector3d;
    24
    25  import nl.tudelft.simulation.dsol.animation.LocatableInterface;
    26  import nl.tudelft.simulation.dsol.animation.StaticLocation;
    27  import nl.tudelft.simulation.dsol.context.ContextUtil;
    28  import nl.tudelft.simulation.dsol.simulators.SimulatorInterface;
    29  import nl.tudelft.simulation.language.d3.DirectedPoint;
    30  import nl.tudelft.simulation.logger.Logger;
    31
    32  /***
    33   * Renderable3D, a 3d renderable <br>
    34   * (c) copyright 2003 <a href="http://www.simulation.tudelft.nl">Delft
    35   * University of Technology </a>, the Netherlands. <br>
    36   * See for project information <a
    37   * href="http://www.simulation.tudelft.nl">www.simulation.tudelft.nl </a> <br>
    38   * License of use: <a href="http://www.gnu.org/copyleft/gpl.html">General Public
    39   * License (GPL) </a>, no warranty <br>
    40   *
    41   * @version 1.0 10.05.2004 <br>
    42   * @author <a href="http://www.tbm.tudelft.nl/webstaf/royc/index.htm">Roy Chin
    43   *         </a>
    44   */
    45  public abstract class Renderable3D extends BranchGroup implements
    46  		Renderable3DInterface
    47  {
    48  	/*** the source of this animatableObject */
    49  	protected LocatableInterface source = null;
    50
    51  	/*** the simulator */
    52  	protected SimulatorInterface simulator = null;
    53
    54  	/*** Rotation group */
    55  	protected TransformGroup locationGroup = null;
    56
    57  	/*** Type of renderable (world, static or simulated */
    58  	protected int type = Renderable3DInterface.DYNAMIC_OBJECT;
    59
    60  	/***
    61  	 * Scale: temporary solution This scale is used to scale translations and
    62  	 * can also be used to scale the model (shape). This is a temporary solution
    63  	 * as we would actually like to scale the entire content branch, but this is
    64  	 * not possible yet
    65  	 */
    66  	protected double scale = 1.0d;
    67
    68  	/***
    69  	 * translation Used in update; put here to prevent garbage
    70  	 */
    71  	private Transform3D translate = new Transform3D();
    72
    73  	/***
    74  	 * combined rotation angle Used in update; put here to prevent garbage
    75  	 */
    76  	private Transform3D rotate = new Transform3D();
    77
    78  	/***
    79  	 * yaw angle Used in update; put here to prevent garbage
    80  	 */
    81  	private Transform3D yaw = new Transform3D();
    82
    83  	/***
    84  	 * pitch angle Used in update; put here to prevent garbage
    85  	 */
    86  	private Transform3D pitch = new Transform3D();
    87
    88  	/***
    89  	 * roll angle Used in update; put here to prevent garbage
    90  	 */
    91  	private Transform3D roll = new Transform3D();
    92
    93  	/***
    94  	 * @param simulator SimulatorInterface
    95  	 */
    96  	public Renderable3D(final SimulatorInterface simulator)
    97  	{
    98  		if (!LocatableInterface.class.isAssignableFrom(this.getClass()))
    99  		{
    100 			throw new IllegalArgumentException(
    101 					"this class should implement Locatable interface");
    102 		}
    103 		this.source = (LocatableInterface) this;
    104 		this.simulator = simulator;
    105 		this.initialize();
    106 	}
    107
    108 	/***
    109 	 * @param staticLocation Point3d
    110 	 * @param simulator SimulatorInterface
    111 	 */
    112 	public Renderable3D(final DirectedPoint staticLocation,
    113 			final SimulatorInterface simulator)
    114 	{
    115 		super();
    116 		this.source = new StaticLocation(staticLocation, null);
    117 		this.simulator = simulator;
    118 		this.type = Renderable3DInterface.STATIC_OBJECT;
    119 		this.initialize();
    120 	}
    121
    122 	/***
    123 	 * @param staticLocation Point3d
    124 	 * @param branchGroup A branchGroup containing (a part of) the model
    125 	 * @param simulator SimulatorInterface
    126 	 */
    127 	public Renderable3D(final DirectedPoint staticLocation,
    128 			final BranchGroup branchGroup, final SimulatorInterface simulator)
    129 	{
    130 		super();
    131 		this.source = new StaticLocation(staticLocation, null);
    132 		this.simulator = simulator;
    133 		this.type = Renderable3DInterface.STATIC_OBJECT;
    134 		this.initializeTransformGroups();
    135 		this.provideModel(this.locationGroup);
    136 		this.addChild(this.locationGroup);
    137 		this.addChild(branchGroup);
    138 		this.update();
    139 		ContextUtil.bindToContext(this.simulator, "/animation/3D", this);
    140 	}
    141
    142 	/***
    143 	 * @param staticLocation Point2D
    144 	 * @param simulator SimulatorInterface
    145 	 */
    146 	public Renderable3D(final Point2D staticLocation,
    147 			final SimulatorInterface simulator)
    148 	{
    149 		this(new DirectedPoint(staticLocation), simulator);
    150 	}
    151
    152 	/***
    153 	 * @param source LocatableInterface
    154 	 * @param simulator SimulatorInterface
    155 	 */
    156 	public Renderable3D(final LocatableInterface source,
    157 			final SimulatorInterface simulator)
    158 	{
    159 		super();
    160 		this.source = source;
    161 		this.simulator = simulator;
    162 		this.initialize();
    163 	}
    164
    165 	/***
    166 	 * Initialize
    167 	 */
    168 	private void initialize()
    169 	{
    170 		// Note: the order of the lines below does matter!
    171 		// AnimationFrame3D wants to draw as soon as it has
    172 		// got the object from the context, so transforms
    173 		// better be initialized.
    174 		//
    175 		// Note2: RunControl.notify() must create the subcontext:
    176 		// "/animation3d"
    177 		this.initializeTransformGroups();
    178 		this.provideModel(this.locationGroup);
    179 		this.addChild(this.locationGroup);
    180 		this.update();
    181 		ContextUtil.bindToContext(this.simulator, "/animation/3D", this);
    182 	}
    183
    184 	/***
    185 	 * Initialize TransformGroups
    186 	 */
    187 	private void initializeTransformGroups()
    188 	{
    189 		this.setCapability(Group.ALLOW_CHILDREN_READ);
    190 		this.setCapability(Group.ALLOW_CHILDREN_WRITE);
    191 		this.setCapability(Group.ALLOW_CHILDREN_EXTEND);
    192 		this.setCapability(BranchGroup.ALLOW_DETACH);
    193 		this.setCapability(Node.ENABLE_PICK_REPORTING);
    194 		// Determine if this branch group is pickable
    195 		if (this.type == Renderable3DInterface.DYNAMIC_OBJECT)
    196 		{
    197 			this.setPickable(true);
    198 		} else
    199 		{
    200 			this.setPickable(false);
    201 		}
    202
    203 		this.locationGroup = new TransformGroup();
    204
    205 		this.locationGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
    206 		this.locationGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
    207 		this.locationGroup.setCapability(Group.ALLOW_CHILDREN_READ);
    208 		this.locationGroup.setCapability(Group.ALLOW_CHILDREN_WRITE);
    209 		this.locationGroup.setCapability(Group.ALLOW_CHILDREN_EXTEND);
    210 		if (this.type == Renderable3DInterface.DYNAMIC_OBJECT)
    211 		{
    212 			this.locationGroup
    213 					.setCapabilityIsFrequent(TransformGroup.ALLOW_TRANSFORM_READ);
    214 			this.locationGroup
    215 					.setCapabilityIsFrequent(TransformGroup.ALLOW_TRANSFORM_READ);
    216 		}
    217 	}
    218
    219 	/***
    220 	 * Provide the 3D model and add it to the locationGroup
    221 	 *
    222 	 * @param locationGroup The location of the object
    223 	 */
    224 	protected abstract void provideModel(final TransformGroup locationGroup);
    225
    226 	/***
    227 	 * @see nl.tudelft.simulation.dsol.animation.D3.
    228 	 *      Renderable3DInterface#update()
    229 	 */
    230 	public void update()
    231 	{
    232 		try
    233 		{
    234 			this.update(this.getAllChildren());
    235 			DirectedPoint location = this.getSource().getLocation();
    236 			this.translate.set(new Vector3d(location.x * this.scale, location.y
    237 					* this.scale, location.z * this.scale));
    238
    239 			// Hope the order of the rotations is correct ...
    240 			this.yaw.setRotation(new AxisAngle4d(0, 0, 1, location.getRotX()));
    241 			this.pitch.setRotation(new AxisAngle4d(0, 1, 0, location.getRotZ()));
    242 			this.roll.setRotation(new AxisAngle4d(1, 0, 0, location.getRotY()));
    243
    244 			// first translate then rotate
    245 			this.rotate.set(this.translate);
    246 			this.rotate.mul(this.yaw);
    247 			this.rotate.mul(this.pitch);
    248 			this.rotate.mul(this.roll);
    249
    250 			this.locationGroup.setTransform(this.rotate);
    251 		} catch (RemoteException exception)
    252 		{
    253 			this.rotate.set(new Vector3d(0, 0, 0));
    254 			Logger.warning(this, "update", exception);
    255 		}
    256 	}
    257
    258 	/***
    259 	 * Method update.
    260 	 *
    261 	 * @param children the children to update.
    262 	 */
    263 	protected abstract void update(final Enumeration children);
    264
    265 	/***
    266 	 * @return LocatableInterface
    267 	 */
    268 	public LocatableInterface getSource()
    269 	{
    270 		return this.source;
    271 	}
    272
    273 	/***
    274 	 * @see nl.tudelft.simulation.dsol.animation.D3.
    275 	 *      Renderable3DInterface#getType()
    276 	 */
    277 	public int getType()
    278 	{
    279 		return this.type;
    280 	}
    281
    282 	/***
    283 	 * @return scale
    284 	 */
    285 	public double getScale()
    286 	{
    287 		return this.scale;
    288 	}
    289
    290 	/***
    291 	 * @param scale Set the scale of the coordinates
    292 	 */
    293 	public void setScale(final double scale)
    294 	{
    295 		this.scale = scale;
    296 	}
    297 }