User interface mostly done, except for velocity editing.
[gravitysimulator.git] / src / edu / mit / ezyang / gravity / GravitySimulatorView.java
blob210397eb6936d1e8b0623c47317c4cadeed10455
1 /*
2 * GravitySimulatorView.java
3 */
5 package edu.mit.ezyang.gravity;
7 import edu.mit.ezyang.gravity.j3d.*;
8 import com.sun.j3d.utils.behaviors.keyboard.KeyNavigatorBehavior;
9 import org.jdesktop.application.Action;
10 import org.jdesktop.application.SingleFrameApplication;
11 import org.jdesktop.application.FrameView;
12 import javax.swing.JDialog;
14 import javax.swing.JFrame;
15 import com.sun.j3d.utils.geometry.*;
16 import com.sun.j3d.utils.universe.*;
17 import java.util.*;
18 import javax.media.j3d.*;
19 import javax.swing.JPopupMenu;
20 import javax.vecmath.*;
22 /**
23 * This is the main and only frame of the GravitySimulator application. It
24 * controls the console and the Canvas3D, both of which respond to user
25 * interaction.
26 * @author Edward Z. Yang <ezyang@mit.edu>
28 public class GravitySimulatorView extends FrameView {
30 /**
31 * BranchGroup that objects in the universe should be inserted in. This
32 * itself is inside a rotatable TransformGroup, which allows all objects
33 * in the universe to be rotated.
35 protected BranchGroup universeRoot;
37 /**
38 * TransformGroup corresponding to the rotation universeRoot; this
39 * needs to be registered to all SmartPickTranslateBehavior objects
40 * in order to compensate properly.
42 protected TransformGroup globalRotateGroup;
44 /**
45 * TransformGroup corresponding to the location of the viewpoint; this
46 * can be modified in order to change the viewer's location.
48 protected TransformGroup viewTransformGroup;
50 /**
51 * Canvas being rendered in the UI. Use this to access global properties
52 * including the SimpleUniverse.
54 protected Canvas3D canvas;
56 public GravitySimulatorView(SingleFrameApplication app) {
57 super(app);
59 // make menus heavy, see <http://java3d.j3d.org/faq/swing.html>
60 JPopupMenu.setDefaultLightWeightPopupEnabled(false);
61 initComponents();
63 BoundingSphere bounds = new BoundingSphere(new Point3d(0f,0f,0f), 1000f);
65 canvas = new Canvas3D(SimpleUniverse.getPreferredConfiguration());
66 SimpleUniverse universe = new SimpleUniverse(canvas);
68 BranchGroup root = new BranchGroup();
70 // key navigation
71 TransformGroup vpTrans = universe.getViewingPlatform().getViewPlatformTransform();
72 KeyNavigatorBehavior keyNavBeh = new KeyNavigatorBehavior(vpTrans);
73 keyNavBeh.setSchedulingBounds(bounds);
74 root.addChild(keyNavBeh);
76 universeRoot = new BranchGroup();
77 universeRoot.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE);
78 universeRoot.setCapability(BranchGroup.ALLOW_CHILDREN_EXTEND);
80 globalRotateGroup = new RotateGroup();
82 globalRotateGroup.addChild(universeRoot);
83 root.addChild(globalRotateGroup);
84 universe.addBranchGraph(root);
86 ViewingPlatform platform = universe.getViewingPlatform();
87 platform.setNominalViewingTransform();
88 //platform.getViewers()[0].getView().setFieldOfView(10f);
90 viewTransformGroup = platform.getMultiTransformGroup().getTransformGroup(0);
91 Transform3D viewTransform = new Transform3D();
92 viewTransform.setTranslation(new Vector3f(0.0f,0.0f,10.0f));
93 viewTransformGroup.setTransform(viewTransform);
95 canvasPanel.add(canvas);
97 // Initialize environment with some objects
98 processCommand("add sphere");
99 processCommand("add cube at 0,2,0");
100 processCommand("add cube at 0,-2,0");
101 processCommand("add cube at 2,0,0");
102 processCommand("add cube at -2,0,0");
106 /** Processes a command from the command line box, modifying Universe.
107 * @param command Command line to execute.
109 public void processCommand(String command) {
110 send(command);
111 String[] parts = command.split(" ");
112 if (parts.length == 0 || parts[0].equals("") || parts[0].equals("help")) {
113 send("Commands: add, view, clear");
114 return;
116 if (parts[0].equals("add")) {
117 if (parts.length == 1) {
118 send("Need object to add: sphere, cone, cube or cylinder");
119 return;
122 // initialize default "first class" parameters
123 float scale = 0.4f;
124 Vector3f location = new Vector3f(0f, 0f, 0f);
126 // initialize generic params HashMap; this can be used for
127 // any sort of thing you want
128 HashMap<String, String> params = new HashMap<String, String>();
130 // parse the arguments
131 if (parts.length > 2) {
132 String state = null;
133 for (int i = 2; i < parts.length; i++) {
134 if (state == null) {
135 state = parts[i];
136 } else {
137 if (state.equals("scale")) {
138 scale = new Float(parts[i]);
139 } else if (state.equals("at")) {
140 location = vectorize(parts[i]);
141 } else {
142 params.put(state, parts[i]);
144 state = null;
148 // generate the actual primitive
149 Node object;
150 if (parts[1].equals("sphere")) {
151 Sphere sphere = new Sphere(scale);
152 sphere.getAppearance().getMaterial().setAmbientColor(.8f,.2f,.2f);
153 object = sphere;
154 } else if (parts[1].equals("cube")) {
155 object = new ColorCube(scale);
156 } else if (parts[1].equals("cone")) {
157 object = new Cone(scale * 1f, scale * 2f);
158 } else if (parts[1].equals("cylinder")) {
159 object = new Cylinder(scale * 1f, scale * 2f);
160 } else {
161 send("Unknown primitive: " + parts[1]);
162 return;
164 object.setCapability(Node.ENABLE_PICK_REPORTING);
165 object.setCapability(Node.ALLOW_BOUNDS_READ);
166 object.setCapability(Node.ALLOW_BOUNDS_WRITE);
168 EditableGroup group = new EditableGroup(canvas, globalRotateGroup, location);
169 group.addTransformChild(object);
171 universeRoot.addChild(group);
172 } else if (parts[0].equals("view")) {
173 if (parts.length == 1) {
174 send("Need location parameter x,y,z");
175 return;
177 Transform3D viewTransform = new Transform3D();
178 viewTransform.setTranslation(vectorize(parts[1]));
179 viewTransformGroup.setTransform(viewTransform);
180 } else if (parts[0].equals("zoom")) {
181 if (parts.length == 1) {
182 send("Need zoom value z (view 0,0,z)");
183 return;
185 Transform3D viewTransform = new Transform3D();
186 viewTransform.setTranslation(vectorize("0,0," + parts[1]));
187 viewTransformGroup.setTransform(viewTransform);
188 } else if (parts[0].equals("clear")) {
189 universeRoot.removeAllChildren();
190 } else {
191 send("Unknown command: " + parts[0] + ", type help for options");
192 return;
196 /** Converts string in form x,y,z to Vector3f
197 * @param input vector in form x,y,z
198 * @return Appropriate vector
200 protected Vector3f vectorize(String input) {
201 String[] vectorFields = input.split(",");
202 return new Vector3f(new Float(vectorFields[0]), new Float(vectorFields[1]), new Float(vectorFields[2]));
205 /** Sends a message to display in the terminal.
206 * @param message Message to send
208 protected void send(String message) {
209 terminal.append(message + "\n");
212 /** Displays the about box.
214 @Action
215 public void showAboutBox() {
216 if (aboutBox == null) {
217 JFrame mainFrame = GravitySimulatorApp.getApplication().getMainFrame();
218 aboutBox = new GravitySimulatorAboutBox(mainFrame);
219 aboutBox.setLocationRelativeTo(mainFrame);
221 GravitySimulatorApp.getApplication().show(aboutBox);
224 /** This method is called from within the constructor to
225 * initialize the form.
226 * WARNING: Do NOT modify this code. The content of this method is
227 * always regenerated by the Form Editor.
229 @SuppressWarnings("unchecked")
230 // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
231 private void initComponents() {
233 mainPanel = new javax.swing.JPanel();
234 canvasPanel = new javax.swing.JPanel();
235 console = new javax.swing.JPanel();
236 commandLine = new javax.swing.JTextField();
237 terminalPane = new javax.swing.JScrollPane();
238 terminal = new javax.swing.JTextArea();
239 menuBar = new javax.swing.JMenuBar();
240 javax.swing.JMenu fileMenu = new javax.swing.JMenu();
241 javax.swing.JMenuItem exitMenuItem = new javax.swing.JMenuItem();
242 javax.swing.JMenu helpMenu = new javax.swing.JMenu();
243 javax.swing.JMenuItem aboutMenuItem = new javax.swing.JMenuItem();
245 mainPanel.setName("mainPanel"); // NOI18N
246 mainPanel.setLayout(new java.awt.BorderLayout());
248 org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(edu.mit.ezyang.gravity.GravitySimulatorApp.class).getContext().getResourceMap(GravitySimulatorView.class);
249 canvasPanel.setBackground(resourceMap.getColor("canvasPanel.background")); // NOI18N
250 canvasPanel.setName("canvasPanel"); // NOI18N
251 canvasPanel.setLayout(new java.awt.BorderLayout());
252 mainPanel.add(canvasPanel, java.awt.BorderLayout.CENTER);
254 console.setName("console"); // NOI18N
255 console.setLayout(new java.awt.BorderLayout());
257 commandLine.setText(resourceMap.getString("commandLine.text")); // NOI18N
258 commandLine.setName("commandLine"); // NOI18N
259 commandLine.addActionListener(new java.awt.event.ActionListener() {
260 public void actionPerformed(java.awt.event.ActionEvent evt) {
261 commandLineActionPerformed(evt);
264 console.add(commandLine, java.awt.BorderLayout.CENTER);
266 terminalPane.setName("terminalPane"); // NOI18N
268 terminal.setColumns(20);
269 terminal.setEditable(false);
270 terminal.setFont(resourceMap.getFont("terminal.font")); // NOI18N
271 terminal.setRows(5);
272 terminal.setName("terminal"); // NOI18N
273 terminalPane.setViewportView(terminal);
275 console.add(terminalPane, java.awt.BorderLayout.PAGE_START);
277 mainPanel.add(console, java.awt.BorderLayout.PAGE_END);
279 menuBar.setName("menuBar"); // NOI18N
281 fileMenu.setText(resourceMap.getString("fileMenu.text")); // NOI18N
282 fileMenu.setName("fileMenu"); // NOI18N
284 javax.swing.ActionMap actionMap = org.jdesktop.application.Application.getInstance(edu.mit.ezyang.gravity.GravitySimulatorApp.class).getContext().getActionMap(GravitySimulatorView.class, this);
285 exitMenuItem.setAction(actionMap.get("quit")); // NOI18N
286 exitMenuItem.setName("exitMenuItem"); // NOI18N
287 fileMenu.add(exitMenuItem);
289 menuBar.add(fileMenu);
291 helpMenu.setText(resourceMap.getString("helpMenu.text")); // NOI18N
292 helpMenu.setName("helpMenu"); // NOI18N
294 aboutMenuItem.setAction(actionMap.get("showAboutBox")); // NOI18N
295 aboutMenuItem.setName("aboutMenuItem"); // NOI18N
296 helpMenu.add(aboutMenuItem);
298 menuBar.add(helpMenu);
300 setComponent(mainPanel);
301 setMenuBar(menuBar);
302 }// </editor-fold>//GEN-END:initComponents
304 private void commandLineActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_commandLineActionPerformed
305 processCommand(commandLine.getText());
306 commandLine.setText("");
307 }//GEN-LAST:event_commandLineActionPerformed
309 // Variables declaration - do not modify//GEN-BEGIN:variables
310 private javax.swing.JPanel canvasPanel;
311 private javax.swing.JTextField commandLine;
312 private javax.swing.JPanel console;
313 private javax.swing.JPanel mainPanel;
314 private javax.swing.JMenuBar menuBar;
315 private javax.swing.JTextArea terminal;
316 private javax.swing.JScrollPane terminalPane;
317 // End of variables declaration//GEN-END:variables
319 private JDialog aboutBox;