1
2
3
4
5
6
7
8
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
171
172
173
174
175
176
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
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
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
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 }