• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.badlogic.gdx.tools.flame;
2 
3 import java.awt.Dimension;
4 import java.awt.GridBagConstraints;
5 import java.awt.GridBagLayout;
6 import java.awt.Insets;
7 import java.awt.event.ActionEvent;
8 import java.awt.event.ActionListener;
9 
10 import javax.swing.DefaultComboBoxModel;
11 import javax.swing.JButton;
12 import javax.swing.JComboBox;
13 import javax.swing.JPanel;
14 import javax.swing.JScrollPane;
15 import javax.swing.JTable;
16 import javax.swing.ListSelectionModel;
17 import javax.swing.event.ListSelectionEvent;
18 import javax.swing.event.ListSelectionListener;
19 import javax.swing.event.TableModelEvent;
20 import javax.swing.event.TableModelListener;
21 import javax.swing.table.DefaultTableModel;
22 
23 import com.badlogic.gdx.graphics.g3d.particles.ParticleController;
24 import com.badlogic.gdx.graphics.g3d.particles.influencers.DynamicsInfluencer;
25 import com.badlogic.gdx.graphics.g3d.particles.influencers.DynamicsModifier;
26 import com.badlogic.gdx.graphics.g3d.particles.influencers.DynamicsModifier.BrownianAcceleration;
27 import com.badlogic.gdx.graphics.g3d.particles.influencers.DynamicsModifier.CentripetalAcceleration;
28 import com.badlogic.gdx.graphics.g3d.particles.influencers.DynamicsModifier.FaceDirection;
29 import com.badlogic.gdx.graphics.g3d.particles.influencers.DynamicsModifier.PolarAcceleration;
30 import com.badlogic.gdx.graphics.g3d.particles.influencers.DynamicsModifier.Rotational3D;
31 import com.badlogic.gdx.graphics.g3d.particles.influencers.DynamicsModifier.TangentialAcceleration;
32 import com.badlogic.gdx.tools.flame.FlameMain.ControllerType;
33 import com.badlogic.gdx.utils.Array;
34 
35 /** @author Inferno */
36 public class DynamicsInfluencerPanel extends InfluencerPanel<DynamicsInfluencer> {
37 
38 	private static final String 	VEL_TYPE_ROTATIONAL_2D = "Angular Velocity 2D",
39 															VEL_TYPE_ROTATIONAL_3D = "Angular Velocity 3D",
40 											VEL_TYPE_CENTRIPETAL = "Centripetal",
41 											VEL_TYPE_TANGENTIAL = "Tangential",
42 											VEL_TYPE_POLAR = "Polar",
43 											VEL_TYPE_BROWNIAN = "Brownian",
44 											VEL_TYPE_FACE = "Face";
45 
46 	protected class VelocityWrapper{
47 		public DynamicsModifier velocityValue;
48 		public boolean isActive;
49 
VelocityWrapper(DynamicsModifier value, boolean isActive)50 		public VelocityWrapper(DynamicsModifier value, boolean isActive){
51 			this.velocityValue =  value;
52 			this.isActive = isActive;
53 		}
54 	}
55 
56 	JComboBox velocityBox;
57 	JTable velocityTable;
58 	DefaultTableModel velocityTableModel;
59 	JPanel selectedVelocityPanel;
60 	AngularVelocityPanel angularVelocityPanel;
61 	StrengthVelocityPanel strengthVelocityPanel;
62 	ParticleValuePanel emptyPanel;
63 	Array<VelocityWrapper> velocities;
64 
DynamicsInfluencerPanel(FlameMain editor, DynamicsInfluencer influencer)65 	public DynamicsInfluencerPanel (FlameMain editor, DynamicsInfluencer influencer) {
66 		super(editor, influencer, "Dynamics Influencer",
67 							"Defines how the particles dynamics (acceleration, angular velocity).");
68 		velocities = new Array<VelocityWrapper>();
69 		setValue(value);
70 		set(influencer);
71 	}
72 
set(DynamicsInfluencer influencer)73 	private void set (DynamicsInfluencer influencer) {
74 		//Clear
75 		for (int i = velocityTableModel.getRowCount() - 1; i >= 0; i--) {
76 			velocityTableModel.removeRow(i);
77 		}
78 		velocities.clear();
79 
80 		//Add
81 		for(int i=0, c = influencer.velocities.size; i < c; ++i){
82 			velocities.add(new VelocityWrapper((DynamicsModifier)influencer.velocities.items[i], true));
83 			velocityTableModel.addRow(new Object[] {"Velocity "+i, true});
84 		}
85 
86 		DefaultComboBoxModel model = (DefaultComboBoxModel) velocityBox.getModel();
87 		model.removeAllElements();
88 		for(Object velocityObject : getAvailableVelocities(editor.getControllerType())){
89 			model.addElement(velocityObject);
90 		}
91 	}
92 
getAvailableVelocities(ControllerType type)93 	private Object[] getAvailableVelocities (ControllerType type) {
94 		if(type == ControllerType.Billboard || type == ControllerType.PointSprite) {
95 			return new String[]{	VEL_TYPE_ROTATIONAL_2D, VEL_TYPE_CENTRIPETAL, VEL_TYPE_TANGENTIAL,
96 				VEL_TYPE_POLAR, VEL_TYPE_BROWNIAN};
97 		}
98 		else if(type == ControllerType.ModelInstance|| type == ControllerType.ParticleController) {
99 			return new String[]{	VEL_TYPE_ROTATIONAL_3D, VEL_TYPE_CENTRIPETAL, VEL_TYPE_TANGENTIAL,
100 				VEL_TYPE_POLAR, VEL_TYPE_BROWNIAN, VEL_TYPE_FACE};
101 		}
102 		return null;
103 	}
104 
initializeComponents()105 	protected void initializeComponents () {
106 		super.initializeComponents();
107 		JPanel velocitiesPanel = new JPanel();
108 		velocitiesPanel.setLayout(new GridBagLayout());
109 		{
110 			JPanel sideButtons = new JPanel(new GridBagLayout());
111 			velocitiesPanel.add(sideButtons, new GridBagConstraints(1, 0, 1, 1, 1, 1, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE,
112 				new Insets(0, 0, 0, 0), 0, 0));
113 			{
114 				sideButtons.add(velocityBox = new JComboBox(new DefaultComboBoxModel()),
115 					new GridBagConstraints(0, -1, 1, 1, 0, 0, GridBagConstraints.CENTER,
116 					GridBagConstraints.HORIZONTAL, new Insets(0, 0, 6, 0), 0, 0));
117 			}
118 			{
119 				JButton newButton = new JButton("New");
120 				sideButtons.add(newButton, new GridBagConstraints(0, -1, 1, 1, 0, 0, GridBagConstraints.CENTER,
121 					GridBagConstraints.HORIZONTAL, new Insets(0, 0, 6, 0), 0, 0));
122 				newButton.addActionListener(new ActionListener() {
123 					public void actionPerformed (ActionEvent event) {
124 						createVelocity(velocityBox.getSelectedItem());
125 					}
126 				});
127 			}
128 			{
129 				JButton deleteButton = new JButton("Delete");
130 				sideButtons.add(deleteButton, new GridBagConstraints(0, -1, 1, 1, 0, 0, GridBagConstraints.CENTER,
131 					GridBagConstraints.HORIZONTAL, new Insets(0, 0, 6, 0), 0, 0));
132 				deleteButton.addActionListener(new ActionListener() {
133 					public void actionPerformed (ActionEvent event) {
134 						deleteVelocity();
135 					}
136 				});
137 			}
138 		}
139 		JScrollPane scroll = new JScrollPane();
140 		velocitiesPanel.add(scroll, new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0,
141 			0, 0, 6), 0, 0));
142 		velocityTable = new JTable() {
143 			public Class getColumnClass (int column) {
144 				return column == 1 ? Boolean.class : super.getColumnClass(column);
145 			}
146 
147 			@Override
148 			public Dimension getPreferredScrollableViewportSize () {
149 				Dimension dim = super.getPreferredScrollableViewportSize();
150 				dim.height = getPreferredSize().height;
151 				return dim;
152 			}
153 		};
154 		velocityTable.getTableHeader().setReorderingAllowed(false);
155 		velocityTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
156 		scroll.setViewportView(velocityTable);
157 		velocityTableModel = new DefaultTableModel(new String[0][0], new String[] {"Velocity", "Active"});
158 		velocityTable.setModel(velocityTableModel);
159 		velocityTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
160 			public void valueChanged (ListSelectionEvent event) {
161 				if (event.getValueIsAdjusting()) return;
162 				velocitySelected();
163 			}
164 		});
165 		velocityTableModel.addTableModelListener(new TableModelListener() {
166 			public void tableChanged (TableModelEvent event) {
167 				if (event.getColumn() != 1) return;
168 				velocityChecked(event.getFirstRow(), (Boolean)velocityTable.getValueAt(event.getFirstRow(), 1));
169 			}
170 		});
171 
172 		//Velocity values
173 		emptyPanel = new ParticleValuePanel(editor, "", "",true, false);
174 		strengthVelocityPanel = new StrengthVelocityPanel(editor, null, "Life", "", "");
175 		angularVelocityPanel = new AngularVelocityPanel(editor, null, "Life", "", "");
176 		strengthVelocityPanel.setVisible(false);
177 		angularVelocityPanel.setVisible(false);
178 		emptyPanel.setVisible(false);
179 		strengthVelocityPanel.setIsAlwayShown(true);
180 		angularVelocityPanel.setIsAlwayShown(true);
181 		emptyPanel.setIsAlwayShown(true);
182 		emptyPanel.setValue(null);
183 
184 		//Assemble
185 		int i=0;
186 		addContent(i++, 0, velocitiesPanel);
187 		addContent(i++, 0, strengthVelocityPanel);
188 		addContent(i++, 0, angularVelocityPanel);
189 		addContent(i++, 0, emptyPanel);
190 	}
191 
velocityChecked(int index, boolean isChecked)192 	protected void velocityChecked (int index, boolean isChecked) {
193 		ParticleController controller = editor.getEmitter();
194 		DynamicsInfluencer influencer = (DynamicsInfluencer)controller.findInfluencer(DynamicsInfluencer.class);
195 		influencer.velocities.clear();
196 		velocities.get(index).isActive = isChecked;
197 		for(VelocityWrapper wrapper : velocities){
198 			if(wrapper.isActive)
199 				influencer.velocities.add(wrapper.velocityValue);
200 		}
201 		//Restart the effect and reinit the controller
202 		editor.restart();
203 	}
204 
velocitySelected()205 	protected void velocitySelected () {
206 		//Show the velocity value panel
207 		int index = velocityTable.getSelectedRow();
208 		if(index == -1) return;
209 
210 		DynamicsModifier velocityValue = velocities.get(index).velocityValue;
211 		EditorPanel velocityPanel = getVelocityPanel(velocityValue);
212 
213 		//Show the selected velocity
214 		if(selectedVelocityPanel != null && selectedVelocityPanel != velocityPanel)
215 			selectedVelocityPanel.setVisible(false);
216 		velocityPanel.setVisible(true);
217 		velocityPanel.showContent(true);
218 		selectedVelocityPanel = velocityPanel;
219 	}
220 
getVelocityPanel(DynamicsModifier velocityValue)221 	private EditorPanel getVelocityPanel (DynamicsModifier velocityValue) {
222 		EditorPanel panel = null;
223 		//Billboards
224 		if(velocityValue instanceof DynamicsModifier.Rotational2D ){
225 			strengthVelocityPanel.setValue((DynamicsModifier.Strength) velocityValue);
226 			strengthVelocityPanel.setName("Angular Velocity");
227 			strengthVelocityPanel.setDescription("The angular speed around the billboard facing direction, in degrees/sec .");
228 			panel = strengthVelocityPanel;
229 		}
230 		else if(	velocityValue instanceof CentripetalAcceleration){
231 			strengthVelocityPanel.setValue((DynamicsModifier.CentripetalAcceleration) velocityValue);
232 			strengthVelocityPanel.setName("Centripetal Acceleration");
233 			strengthVelocityPanel.setDescription("A directional acceleration, the direction is towards the origin (global), or towards the emitter position (local), in world units/sec2 .");
234 			panel = strengthVelocityPanel;
235 		}
236 		else if(	velocityValue instanceof TangentialAcceleration){
237 			angularVelocityPanel.setValue((DynamicsModifier.Angular) velocityValue);
238 			angularVelocityPanel.setName("Tangetial Velocity");
239 			angularVelocityPanel.setDescription("A directional acceleration (axis and magnitude), the final direction is the cross product between particle position and the axis, in world units/sec2 .");
240 			panel = angularVelocityPanel;
241 		}
242 		else if(	velocityValue instanceof PolarAcceleration){
243 			angularVelocityPanel.setValue((DynamicsModifier.Angular) velocityValue);
244 			angularVelocityPanel.setName("Polar Velocity");
245 			angularVelocityPanel.setDescription("A directional acceleration (axis and magnitude), in world units/sec2 .");
246 			panel = angularVelocityPanel;
247 		}
248 		else if(	velocityValue instanceof BrownianAcceleration){
249 			strengthVelocityPanel.setValue((DynamicsModifier.Strength) velocityValue);
250 			strengthVelocityPanel.setName("Brownian Velocity");
251 			strengthVelocityPanel.setDescription("A directional acceleration which has random direction at each update, in world units/sec2.");
252 			panel = strengthVelocityPanel;
253 		}
254 		else if(velocityValue instanceof Rotational3D ){
255 			angularVelocityPanel.setValue((DynamicsModifier.Angular) velocityValue);
256 			angularVelocityPanel.setName("Angular Velocity");
257 			angularVelocityPanel.setDescription("An angular velocity (axis and magnitude), in degree/sec2.");
258 			panel = angularVelocityPanel;
259 		}
260 		else if(	velocityValue instanceof FaceDirection){
261 			emptyPanel.setName("Face");
262 			emptyPanel.setDescription("Rotates the model to face its current velocity (Do not add any other angular velocity when using this).");
263 			panel = emptyPanel;
264 		}
265 
266 		return panel;
267 	}
268 
createVelocityValue(Object selectedItem)269 	private DynamicsModifier createVelocityValue (Object selectedItem) {
270 		DynamicsModifier velocityValue = null;
271 		if(selectedItem == VEL_TYPE_ROTATIONAL_2D) velocityValue = new DynamicsModifier.Rotational2D();
272 		else if(selectedItem == VEL_TYPE_ROTATIONAL_3D) velocityValue = new DynamicsModifier.Rotational3D();
273 		else if(selectedItem == VEL_TYPE_CENTRIPETAL) velocityValue = new DynamicsModifier.CentripetalAcceleration();
274 		else if(selectedItem == VEL_TYPE_TANGENTIAL) velocityValue = new DynamicsModifier.TangentialAcceleration();
275 		else if(selectedItem == VEL_TYPE_POLAR) velocityValue = new DynamicsModifier.PolarAcceleration();
276 		else if(selectedItem == VEL_TYPE_BROWNIAN) velocityValue = new DynamicsModifier.BrownianAcceleration();
277 		else if(selectedItem == VEL_TYPE_FACE) velocityValue = new DynamicsModifier.FaceDirection();
278 		return velocityValue;
279 	}
280 
281 
deleteVelocity()282 	protected void deleteVelocity () {
283 		int row = velocityTable.getSelectedRow();
284 		if (row == -1) return;
285 
286 		//Remove the velocity from the table
287 		ParticleController controller = editor.getEmitter();
288 		DynamicsInfluencer influencer = (DynamicsInfluencer)controller.findInfluencer(DynamicsInfluencer.class);
289 		influencer.velocities.removeValue(velocities.removeIndex(row).velocityValue, true);
290 		velocityTableModel.removeRow(row);
291 
292 		//Restart the effect and reinit the controller
293 		editor.restart();
294 
295 		selectedVelocityPanel.setVisible(false);
296 		selectedVelocityPanel = null;
297 	}
298 
createVelocity(Object selectedItem)299 	protected void createVelocity (Object selectedItem) {
300 		//Add the velocity to the table and to the influencer
301 		ParticleController controller = editor.getEmitter();
302 		DynamicsInfluencer influencer = (DynamicsInfluencer)controller.findInfluencer(DynamicsInfluencer.class);
303 		VelocityWrapper wrapper = new VelocityWrapper(createVelocityValue(selectedItem), true);
304 		velocities.add(wrapper);
305 		influencer.velocities.add(wrapper.velocityValue);
306 		int index = velocities.size-1;
307 		velocityTableModel.addRow(new Object[] {"Velocity "+index, true});
308 
309 		//Reinit
310 		editor.restart();
311 
312 		//Select new velocity
313 		velocityTable.getSelectionModel().setSelectionInterval(index, index);
314 		revalidate();
315 		repaint();
316 	}
317 
318 }
319