Add keyboard navigation.
[gravitysimulator.git] / src / edu / mit / ezyang / gravity / GravitySimulatorView.java
blob0bfb2a92ed918936ef952af1bf9170f2165c8a82
1 /*
2 * GravitySimulatorView.java
3 */
5 package edu.mit.ezyang.gravity;
7 import com.sun.j3d.utils.behaviors.keyboard.KeyNavigatorBehavior;
8 import org.jdesktop.application.Action;
9 import org.jdesktop.application.SingleFrameApplication;
10 import org.jdesktop.application.FrameView;
11 import javax.swing.JDialog;
13 import javax.swing.JFrame;
14 import com.sun.j3d.utils.behaviors.mouse.*;
15 import com.sun.j3d.utils.geometry.*;
16 import com.sun.j3d.utils.universe.*;
17 import java.util.HashMap;
18 import javax.media.j3d.*;
19 import javax.swing.JPopupMenu;
20 import javax.vecmath.*;
22 /**
23 * The application's main frame.
25 public class GravitySimulatorView extends FrameView {
27 /**
28 * SimpleUniverse controlling everything
30 protected SimpleUniverse universe;
32 /**
33 * Root group node that new elements should be added to.
35 protected BranchGroup universeRoot;
37 /**
38 * 3D transform controlling viewpoint.
40 protected Transform3D viewTransform;
42 protected TransformGroup viewTransformGroup;
44 public GravitySimulatorView(SingleFrameApplication app) {
45 super(app);
47 // make menus heavy
48 JPopupMenu.setDefaultLightWeightPopupEnabled(false);
49 initComponents();
51 // 3D canvas initialization
52 Canvas3D canvas = new Canvas3D(SimpleUniverse.getPreferredConfiguration());
53 universe = new SimpleUniverse(canvas);
55 BranchGroup root = new BranchGroup();
56 BoundingSphere bounding = new BoundingSphere(new Point3d(0f,0f,0f), 1000.0f);
58 // key navigation
59 TransformGroup vpTrans = universe.getViewingPlatform().getViewPlatformTransform();
60 KeyNavigatorBehavior keyNavBeh = new KeyNavigatorBehavior(vpTrans);
61 keyNavBeh.setSchedulingBounds(new BoundingSphere(new Point3d(), 1000.0));
62 root.addChild(keyNavBeh);
64 universeRoot = new BranchGroup();
65 universeRoot.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE);
66 universeRoot.setCapability(BranchGroup.ALLOW_CHILDREN_EXTEND);
68 TransformGroup rotateGroup = new TransformGroup();
69 rotateGroup.addChild(universeRoot);
70 rotateGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
71 rotateGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
73 DirectionalLight light = new DirectionalLight(new Color3f(1.8f, 0.2f, 0.2f), new Vector3f(4.0f, -7.0f, 7.0f));
74 light.setInfluencingBounds(bounding);
75 rotateGroup.addChild(light);
77 AmbientLight ambLight = new AmbientLight(new Color3f(.6f, .6f, .6f));
78 ambLight.setInfluencingBounds(bounding);
79 rotateGroup.addChild(ambLight);
81 Transform3D yAxis = new Transform3D();
82 Alpha rotationAlpha = new Alpha(-1, 4000);
83 RotationInterpolator rotator = new RotationInterpolator(
84 rotationAlpha, rotateGroup, yAxis,
85 0.0f, (float) Math.PI*2.0f);
86 BoundingSphere bounds =
87 new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
88 rotator.setSchedulingBounds(bounds);
89 rotateGroup.addChild(rotator);
91 TransformGroup controlGroup = new TransformGroup();
92 controlGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
93 controlGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
94 MouseRotate behavior = new MouseRotate();
95 behavior.setTransformGroup(controlGroup);
96 behavior.setSchedulingBounds(new BoundingSphere());
97 controlGroup.addChild(behavior);
99 controlGroup.addChild(rotateGroup);
100 root.addChild(controlGroup);
101 universe.addBranchGraph(root);
103 ViewingPlatform platform = universe.getViewingPlatform();
104 platform.setNominalViewingTransform();
106 viewTransformGroup = platform.getMultiTransformGroup().getTransformGroup(0);
107 viewTransform = new Transform3D();
108 viewTransform.setTranslation(new Vector3f(0.0f,0.0f,10.0f));
109 viewTransformGroup.setTransform(viewTransform);
111 canvasPanel.add(canvas);
113 processCommand("add cube");
118 * Processes a command from the command line box, modifying Universe.
119 * @param command Command line to execute.
121 public void processCommand(String command) {
122 send(command);
123 String[] parts = command.split(" ");
124 if (parts.length == 0 || parts[0].equals("") || parts[0].equals("help")) {
125 send("Commands: add, view, clear");
126 return;
128 if (parts[0].equals("add")) {
129 if (parts.length == 1) {
130 send("Need object to add: sphere, cone, cube or cylinder");
131 return;
133 BranchGroup group = new BranchGroup();
134 group.setCapability(BranchGroup.ALLOW_DETACH);
136 // initialize default "first class" parameters
137 float scale = 0.4f;
138 Vector3f location = new Vector3f(0f, 0f, 0f);
140 // initialize generic params HashMap; this can be used for
141 // any sort of thing you want
142 HashMap<String, String> params = new HashMap<String, String>();
144 // parse the arguments
145 if (parts.length > 2) {
146 String state = null;
147 for (int i = 2; i < parts.length; i++) {
148 if (state == null) {
149 state = parts[i];
150 } else {
151 if (state.equals("scale")) {
152 scale = new Float(parts[i]);
153 } else if (state.equals("at")) {
154 location = vectorize(parts[i]);
155 } else {
156 params.put(state, parts[i]);
158 state = null;
162 // generate the actual primitive
163 Node object;
164 if (parts[1].equals("sphere")) {
165 Sphere sphere = new Sphere(scale);
166 sphere.getAppearance().getMaterial().setAmbientColor(.8f,.2f,.2f);
167 object = sphere;
168 } else if (parts[1].equals("cube")) {
169 object = new ColorCube(scale);
170 } else if (parts[1].equals("cone")) {
171 object = new Cone(scale * 1f, scale * 2f);
172 } else if (parts[1].equals("cylinder")) {
173 object = new Cylinder(scale * 1f, scale * 2f);
174 } else {
175 send("Unknown primitive: " + parts[1]);
176 return;
178 // generate the transform (we do this even if we don't position them
179 // anywhere interesting)
180 Transform3D transform = new Transform3D();
181 TransformGroup transformGroup = new TransformGroup();
182 transform.setTranslation(location);
183 transformGroup.setTransform(transform);
185 transformGroup.addChild(object);
186 group.addChild(transformGroup);
187 universeRoot.addChild(group);
188 } else if (parts[0].equals("view")) {
189 if (parts.length == 1) {
190 send("Need location parameter x,y,z");
191 return;
193 viewTransform.setTranslation(vectorize(parts[1]));
194 viewTransformGroup.setTransform(viewTransform);
195 } else if (parts[0].equals("zoom")) {
196 if (parts.length == 1) {
197 send("Need zoom value z (view 0,0,z)");
198 return;
200 viewTransform.setTranslation(vectorize("0,0," + parts[1]));
201 viewTransformGroup.setTransform(viewTransform);
202 } else if (parts[0].equals("clear")) {
203 universeRoot.removeAllChildren();
204 } else {
205 send("Unknown command: " + parts[0] + ", type help for options");
206 return;
211 * Converts string in form x,y,z to Vector3f
212 * @param input vector in form x,y,z
213 * @return
215 protected Vector3f vectorize(String input) {
216 String[] vectorFields = input.split(",");
217 return new Vector3f(new Float(vectorFields[0]), new Float(vectorFields[1]), new Float(vectorFields[2]));
220 protected void send(String message) {
221 terminal.append(message + "\n");
224 @Action
225 public void showAboutBox() {
226 if (aboutBox == null) {
227 JFrame mainFrame = GravitySimulatorApp.getApplication().getMainFrame();
228 aboutBox = new GravitySimulatorAboutBox(mainFrame);
229 aboutBox.setLocationRelativeTo(mainFrame);
231 GravitySimulatorApp.getApplication().show(aboutBox);
234 /** This method is called from within the constructor to
235 * initialize the form.
236 * WARNING: Do NOT modify this code. The content of this method is
237 * always regenerated by the Form Editor.
239 @SuppressWarnings("unchecked")
240 // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
241 private void initComponents() {
243 mainPanel = new javax.swing.JPanel();
244 canvasPanel = new javax.swing.JPanel();
245 console = new javax.swing.JPanel();
246 commandLine = new javax.swing.JTextField();
247 terminalPane = new javax.swing.JScrollPane();
248 terminal = new javax.swing.JTextArea();
249 menuBar = new javax.swing.JMenuBar();
250 javax.swing.JMenu fileMenu = new javax.swing.JMenu();
251 javax.swing.JMenuItem exitMenuItem = new javax.swing.JMenuItem();
252 javax.swing.JMenu helpMenu = new javax.swing.JMenu();
253 javax.swing.JMenuItem aboutMenuItem = new javax.swing.JMenuItem();
255 mainPanel.setName("mainPanel"); // NOI18N
256 mainPanel.setLayout(new java.awt.BorderLayout());
258 org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(edu.mit.ezyang.gravity.GravitySimulatorApp.class).getContext().getResourceMap(GravitySimulatorView.class);
259 canvasPanel.setBackground(resourceMap.getColor("canvasPanel.background")); // NOI18N
260 canvasPanel.setName("canvasPanel"); // NOI18N
261 canvasPanel.setLayout(new java.awt.BorderLayout());
262 mainPanel.add(canvasPanel, java.awt.BorderLayout.CENTER);
264 console.setName("console"); // NOI18N
265 console.setLayout(new java.awt.BorderLayout());
267 commandLine.setText(resourceMap.getString("commandLine.text")); // NOI18N
268 commandLine.setName("commandLine"); // NOI18N
269 commandLine.addActionListener(new java.awt.event.ActionListener() {
270 public void actionPerformed(java.awt.event.ActionEvent evt) {
271 commandLineActionPerformed(evt);
274 console.add(commandLine, java.awt.BorderLayout.CENTER);
276 terminalPane.setName("terminalPane"); // NOI18N
278 terminal.setColumns(20);
279 terminal.setEditable(false);
280 terminal.setFont(resourceMap.getFont("terminal.font")); // NOI18N
281 terminal.setRows(5);
282 terminal.setName("terminal"); // NOI18N
283 terminalPane.setViewportView(terminal);
285 console.add(terminalPane, java.awt.BorderLayout.PAGE_START);
287 mainPanel.add(console, java.awt.BorderLayout.PAGE_END);
289 menuBar.setName("menuBar"); // NOI18N
291 fileMenu.setText(resourceMap.getString("fileMenu.text")); // NOI18N
292 fileMenu.setName("fileMenu"); // NOI18N
294 javax.swing.ActionMap actionMap = org.jdesktop.application.Application.getInstance(edu.mit.ezyang.gravity.GravitySimulatorApp.class).getContext().getActionMap(GravitySimulatorView.class, this);
295 exitMenuItem.setAction(actionMap.get("quit")); // NOI18N
296 exitMenuItem.setName("exitMenuItem"); // NOI18N
297 fileMenu.add(exitMenuItem);
299 menuBar.add(fileMenu);
301 helpMenu.setText(resourceMap.getString("helpMenu.text")); // NOI18N
302 helpMenu.setName("helpMenu"); // NOI18N
304 aboutMenuItem.setAction(actionMap.get("showAboutBox")); // NOI18N
305 aboutMenuItem.setName("aboutMenuItem"); // NOI18N
306 helpMenu.add(aboutMenuItem);
308 menuBar.add(helpMenu);
310 setComponent(mainPanel);
311 setMenuBar(menuBar);
312 }// </editor-fold>//GEN-END:initComponents
314 private void commandLineActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_commandLineActionPerformed
315 processCommand(commandLine.getText());
316 commandLine.setText("");
317 }//GEN-LAST:event_commandLineActionPerformed
319 // Variables declaration - do not modify//GEN-BEGIN:variables
320 private javax.swing.JPanel canvasPanel;
321 private javax.swing.JTextField commandLine;
322 private javax.swing.JPanel console;
323 private javax.swing.JPanel mainPanel;
324 private javax.swing.JMenuBar menuBar;
325 private javax.swing.JTextArea terminal;
326 private javax.swing.JScrollPane terminalPane;
327 // End of variables declaration//GEN-END:variables
329 private JDialog aboutBox;