1 /******************************************************************************* 2 * Copyright 2011 See AUTHORS file. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 ******************************************************************************/ 16 17 package com.badlogic.gdx.tools.flame; 18 import java.awt.GridBagConstraints; 19 import java.awt.GridBagLayout; 20 import java.awt.event.ActionEvent; 21 import java.awt.event.ActionListener; 22 23 import javax.swing.DefaultComboBoxModel; 24 import javax.swing.JCheckBox; 25 import javax.swing.JComboBox; 26 import javax.swing.JLabel; 27 import javax.swing.JPanel; 28 import javax.swing.SwingConstants; 29 30 import com.badlogic.gdx.graphics.Mesh; 31 import com.badlogic.gdx.graphics.g3d.Model; 32 import com.badlogic.gdx.graphics.g3d.particles.influencers.SpawnInfluencer; 33 import com.badlogic.gdx.graphics.g3d.particles.values.CylinderSpawnShapeValue; 34 import com.badlogic.gdx.graphics.g3d.particles.values.EllipseSpawnShapeValue; 35 import com.badlogic.gdx.graphics.g3d.particles.values.LineSpawnShapeValue; 36 import com.badlogic.gdx.graphics.g3d.particles.values.PointSpawnShapeValue; 37 import com.badlogic.gdx.graphics.g3d.particles.values.PrimitiveSpawnShapeValue; 38 import com.badlogic.gdx.graphics.g3d.particles.values.PrimitiveSpawnShapeValue.SpawnSide; 39 import com.badlogic.gdx.graphics.g3d.particles.values.RectangleSpawnShapeValue; 40 import com.badlogic.gdx.graphics.g3d.particles.values.SpawnShapeValue; 41 import com.badlogic.gdx.graphics.g3d.particles.values.UnweightedMeshSpawnShapeValue; 42 import com.badlogic.gdx.graphics.g3d.particles.values.WeightMeshSpawnShapeValue; 43 import com.badlogic.gdx.utils.Array; 44 45 /** @author Inferno */ 46 class SpawnInfluencerPanel extends InfluencerPanel<SpawnInfluencer> implements TemplatePickerPanel.Listener<Model> { 47 private static final String SPAWN_SHAPE_POINT = "Point", 48 SPAWN_SHAPE_LINE = "Line", 49 SPAWN_SHAPE_RECTANGLE = "Rectangle", 50 SPAWN_SHAPE_CYLINDER = "Cylinder", 51 SPAWN_SHAPE_ELLIPSE = "Ellipse", 52 SPAWN_SHAPE_MESH = "Unweighted Mesh", 53 SPAWN_SHAPE_WEIGHT_MESH = "Weighted Mesh"; 54 private static String[] spawnShapes = new String[]{ SPAWN_SHAPE_POINT, SPAWN_SHAPE_LINE, SPAWN_SHAPE_RECTANGLE, 55 SPAWN_SHAPE_ELLIPSE, SPAWN_SHAPE_CYLINDER, 56 SPAWN_SHAPE_MESH, SPAWN_SHAPE_WEIGHT_MESH}; 57 JComboBox shapeCombo; 58 JCheckBox edgesCheckbox; 59 JLabel edgesLabel; 60 JComboBox sideCombo; 61 JLabel sideLabel; 62 TemplatePickerPanel<Model> meshPanel; 63 ScaledNumericPanel widthPanel, heightPanel, depthPanel; 64 RangedNumericPanel xPanel, yPanel, zPanel; 65 PointSpawnShapeValue pointSpawnShapeValue; 66 LineSpawnShapeValue lineSpawnShapeValue; 67 RectangleSpawnShapeValue rectangleSpawnShapeValue; 68 EllipseSpawnShapeValue ellipseSpawnShapeValue; 69 CylinderSpawnShapeValue cylinderSpawnShapeValue; 70 UnweightedMeshSpawnShapeValue meshSpawnShapeValue; 71 WeightMeshSpawnShapeValue weightMeshSpawnShapeValue; 72 SpawnInfluencerPanel(final FlameMain editor, SpawnInfluencer influencer)73 public SpawnInfluencerPanel (final FlameMain editor, SpawnInfluencer influencer) { 74 super(editor, influencer, "Spawn Influencer", "Define where the particles are spawned.", true, false); 75 setValue(influencer); 76 setCurrentSpawnData(influencer.spawnShapeValue); 77 shapeCombo.setSelectedItem(spawnShapeToString(influencer.spawnShapeValue)); 78 } 79 setCurrentSpawnData(SpawnShapeValue spawnShapeValue)80 private void setCurrentSpawnData (SpawnShapeValue spawnShapeValue) { 81 SpawnShapeValue local = null; 82 if(spawnShapeValue instanceof PointSpawnShapeValue) 83 local = pointSpawnShapeValue; 84 else if(spawnShapeValue instanceof LineSpawnShapeValue) 85 local = lineSpawnShapeValue; 86 else if(spawnShapeValue instanceof RectangleSpawnShapeValue) 87 local = rectangleSpawnShapeValue; 88 else if(spawnShapeValue instanceof EllipseSpawnShapeValue) 89 local = ellipseSpawnShapeValue; 90 else if(spawnShapeValue instanceof CylinderSpawnShapeValue) 91 local = cylinderSpawnShapeValue; 92 if(spawnShapeValue instanceof UnweightedMeshSpawnShapeValue) 93 local = meshSpawnShapeValue; 94 else if(spawnShapeValue instanceof WeightMeshSpawnShapeValue) 95 local = weightMeshSpawnShapeValue; 96 local.load(spawnShapeValue); 97 } 98 setSpawnShapeValue(SpawnShapeValue spawnShapeValue)99 protected void setSpawnShapeValue(SpawnShapeValue spawnShapeValue){ 100 xPanel.setValue(spawnShapeValue.xOffsetValue); 101 yPanel.setValue(spawnShapeValue.yOffsetValue); 102 zPanel.setValue(spawnShapeValue.zOffsetValue); 103 } 104 setPrimitiveSpawnShape(PrimitiveSpawnShapeValue shape, boolean showEdges, SpawnSide side)105 protected void setPrimitiveSpawnShape (PrimitiveSpawnShapeValue shape, boolean showEdges, SpawnSide side) { 106 setSpawnShapeValue(shape); 107 SpawnInfluencer influencer = (SpawnInfluencer)editor.getEmitter().findInfluencer(SpawnInfluencer.class); 108 influencer.spawnShapeValue = shape; 109 widthPanel.setValue(shape.getSpawnWidth()); 110 heightPanel.setValue(shape.getSpawnHeight()); 111 depthPanel.setValue(shape.getSpawnDepth()); 112 setEdgesVisible(showEdges); 113 if(showEdges) 114 edgesCheckbox.setSelected(shape.isEdges()); 115 if(side != null){ 116 setSidesVisible(true); 117 sideCombo.setSelectedItem(side); 118 } 119 else { 120 setSidesVisible(false); 121 } 122 123 widthPanel.setVisible(true); 124 heightPanel.setVisible(true); 125 depthPanel.setVisible(true); 126 meshPanel.setVisible(false); 127 } 128 setMeshSpawnShape(SpawnShapeValue shape)129 protected void setMeshSpawnShape (SpawnShapeValue shape) { 130 setSpawnShapeValue(shape); 131 value.spawnShapeValue = shape; 132 setEdgesVisible(false); 133 setSidesVisible(false); 134 widthPanel.setVisible(false); 135 heightPanel.setVisible(false); 136 depthPanel.setVisible(false); 137 meshPanel.setVisible(true); 138 } 139 spawnShapeToString(SpawnShapeValue spawnShapeValue)140 private Object spawnShapeToString (SpawnShapeValue spawnShapeValue) { 141 if(spawnShapeValue instanceof PrimitiveSpawnShapeValue){ 142 if(spawnShapeValue instanceof PointSpawnShapeValue) return SPAWN_SHAPE_POINT; 143 else if(spawnShapeValue instanceof LineSpawnShapeValue) return SPAWN_SHAPE_LINE; 144 else if(spawnShapeValue instanceof RectangleSpawnShapeValue) return SPAWN_SHAPE_RECTANGLE; 145 else if(spawnShapeValue instanceof EllipseSpawnShapeValue) return SPAWN_SHAPE_ELLIPSE; 146 else if(spawnShapeValue instanceof CylinderSpawnShapeValue) return SPAWN_SHAPE_CYLINDER; 147 } 148 if(spawnShapeValue instanceof WeightMeshSpawnShapeValue){ 149 return SPAWN_SHAPE_WEIGHT_MESH; 150 } 151 if(spawnShapeValue instanceof UnweightedMeshSpawnShapeValue){ 152 return SPAWN_SHAPE_MESH; 153 } 154 155 return null; 156 } 157 update(FlameMain editor)158 public void update (FlameMain editor) { 159 SpawnInfluencer influencer = (SpawnInfluencer)editor.getEmitter().findInfluencer(SpawnInfluencer.class); 160 shapeCombo.setSelectedItem( spawnShapeToString(influencer.spawnShapeValue)); 161 } 162 setEdgesVisible(boolean visible)163 void setEdgesVisible (boolean visible) 164 { 165 edgesCheckbox.setVisible(visible); 166 edgesLabel.setVisible(visible); 167 } 168 setSidesVisible(boolean visible)169 void setSidesVisible(boolean visible) 170 { 171 sideCombo.setVisible(visible); 172 sideLabel.setVisible(visible); 173 } 174 initializeComponents()175 protected void initializeComponents () { 176 super.initializeComponents(); 177 178 pointSpawnShapeValue = new PointSpawnShapeValue(); 179 lineSpawnShapeValue = new LineSpawnShapeValue(); 180 rectangleSpawnShapeValue = new RectangleSpawnShapeValue(); 181 ellipseSpawnShapeValue = new EllipseSpawnShapeValue(); 182 cylinderSpawnShapeValue = new CylinderSpawnShapeValue(); 183 meshSpawnShapeValue = new UnweightedMeshSpawnShapeValue(); 184 weightMeshSpawnShapeValue = new WeightMeshSpawnShapeValue(); 185 186 lineSpawnShapeValue.setDimensions(6, 6, 6); 187 rectangleSpawnShapeValue.setDimensions(6, 6, 6); 188 ellipseSpawnShapeValue.setDimensions(6, 6, 6); 189 cylinderSpawnShapeValue.setDimensions(6, 6, 6); 190 191 pointSpawnShapeValue.setActive(true); 192 lineSpawnShapeValue.setActive(true); 193 rectangleSpawnShapeValue.setActive(true); 194 ellipseSpawnShapeValue.setActive(true); 195 cylinderSpawnShapeValue.setActive(true); 196 meshSpawnShapeValue.setActive(true); 197 weightMeshSpawnShapeValue.setActive(true); 198 199 Model defaultModel = editor.assetManager.get(FlameMain.DEFAULT_MODEL_PARTICLE); 200 Array<Model> models = new Array<Model>(); 201 models.add(defaultModel); 202 203 int i=0; 204 JPanel panel = new JPanel(new GridBagLayout()); 205 EditorPanel.addContent(panel, i, 0, new JLabel("Shape"), false, GridBagConstraints.WEST, GridBagConstraints.NONE, 0,0); 206 EditorPanel.addContent(panel, i++,1, shapeCombo = new JComboBox(new DefaultComboBoxModel(spawnShapes)), false, GridBagConstraints.WEST, GridBagConstraints.NONE, 1,0); 207 EditorPanel.addContent(panel, i, 0, edgesLabel = new JLabel("Edges"), false, GridBagConstraints.WEST, GridBagConstraints.NONE, 0,0); 208 EditorPanel.addContent(panel, i++, 1, edgesCheckbox = new JCheckBox(), false, GridBagConstraints.WEST, GridBagConstraints.NONE, 0,0); 209 EditorPanel.addContent(panel, i, 0, sideLabel = new JLabel("Side"), false, GridBagConstraints.WEST, GridBagConstraints.NONE, 0,0); 210 EditorPanel.addContent(panel, i++, 1, sideCombo = new JComboBox(new DefaultComboBoxModel(SpawnSide.values())), false, GridBagConstraints.WEST, GridBagConstraints.NONE, 1, 0); 211 edgesCheckbox.setHorizontalTextPosition(SwingConstants.LEFT); 212 213 i=0; 214 addContent(i++, 0, panel, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL); 215 addContent(i++, 0, meshPanel = new TemplatePickerPanel<Model>(editor, models, this, Model.class, new LoaderButton.ModelLoaderButton(editor), true, false) 216 , false, GridBagConstraints.WEST, GridBagConstraints.NONE); 217 addContent(i++, 0, xPanel = new RangedNumericPanel(editor, pointSpawnShapeValue.xOffsetValue, "X Offset", "Amount to offset a particle's starting X location, in world units.", false)); 218 addContent(i++, 0, yPanel = new RangedNumericPanel(editor, pointSpawnShapeValue.yOffsetValue, "Y Offset", "Amount to offset a particle's starting Y location, in world units.", false)); 219 addContent(i++, 0, zPanel = new RangedNumericPanel(editor, pointSpawnShapeValue.zOffsetValue, "Z Offset", "Amount to offset a particle's starting Z location, in world units.", false)); 220 addContent(i++, 0, widthPanel = new ScaledNumericPanel(editor, pointSpawnShapeValue.getSpawnWidth(), "Duration", "Spawn Width", "Width of the spawn shape, in world units.", true)); 221 addContent(i++, 0, heightPanel = new ScaledNumericPanel(editor, pointSpawnShapeValue.getSpawnWidth(), "Duration", "Spawn Height", "Height of the spawn shape, in world units.", true)); 222 addContent(i++, 0, depthPanel = new ScaledNumericPanel(editor, pointSpawnShapeValue.getSpawnWidth(), "Duration", "Spawn Depth", "Depth of the spawn shape, in world units.", true), false); 223 224 meshPanel.setIsAlwayShown(true); 225 onTemplateChecked(defaultModel, true); 226 227 shapeCombo.addActionListener(new ActionListener() { 228 public void actionPerformed (ActionEvent event) { 229 String shape = (String)shapeCombo.getSelectedItem(); 230 if(shape == SPAWN_SHAPE_POINT){ 231 setPrimitiveSpawnShape(pointSpawnShapeValue, false, null); 232 } 233 else if(shape == SPAWN_SHAPE_LINE){ 234 setPrimitiveSpawnShape(lineSpawnShapeValue, false, null); 235 } 236 else if(shape == SPAWN_SHAPE_RECTANGLE){ 237 setPrimitiveSpawnShape(rectangleSpawnShapeValue, true, null); 238 } 239 else if(shape == SPAWN_SHAPE_ELLIPSE){ 240 setPrimitiveSpawnShape(ellipseSpawnShapeValue, true, ellipseSpawnShapeValue.getSide()); 241 } 242 else if(shape == SPAWN_SHAPE_CYLINDER){ 243 setPrimitiveSpawnShape(cylinderSpawnShapeValue, true, null); 244 } 245 else if(shape == SPAWN_SHAPE_MESH){ 246 setMeshSpawnShape(meshSpawnShapeValue); 247 } 248 else if(shape == SPAWN_SHAPE_WEIGHT_MESH){ 249 setMeshSpawnShape(weightMeshSpawnShapeValue); 250 } 251 editor.restart(); 252 } 253 }); 254 255 edgesCheckbox.addActionListener(new ActionListener() { 256 public void actionPerformed (ActionEvent event) { 257 SpawnInfluencer influencer = (SpawnInfluencer)editor.getEmitter().findInfluencer(SpawnInfluencer.class); 258 PrimitiveSpawnShapeValue shapeValue = (PrimitiveSpawnShapeValue)influencer.spawnShapeValue; 259 shapeValue.setEdges(edgesCheckbox.isSelected()); 260 setEdgesVisible(true); 261 } 262 }); 263 264 sideCombo.addActionListener(new ActionListener() { 265 public void actionPerformed (ActionEvent event) { 266 SpawnSide side = (SpawnSide)sideCombo.getSelectedItem(); 267 SpawnInfluencer influencer = (SpawnInfluencer)editor.getEmitter().findInfluencer(SpawnInfluencer.class); 268 EllipseSpawnShapeValue shapeValue = (EllipseSpawnShapeValue)influencer.spawnShapeValue; 269 shapeValue.setSide(side); 270 } 271 }); 272 273 } 274 275 @Override onTemplateChecked(Model model, boolean isChecked)276 public void onTemplateChecked (Model model, boolean isChecked) { 277 //Update the shapes 278 SpawnShapeValue shapeValue = null; 279 Mesh mesh = model.meshes.get(0); 280 weightMeshSpawnShapeValue.setMesh(mesh, model); 281 meshSpawnShapeValue.setMesh(mesh, model); 282 if(shapeCombo.getSelectedItem() == SPAWN_SHAPE_WEIGHT_MESH){ 283 SpawnInfluencer influencer = (SpawnInfluencer)editor.getEmitter().findInfluencer(SpawnInfluencer.class); 284 influencer.spawnShapeValue = weightMeshSpawnShapeValue; 285 } 286 else if(shapeCombo.getSelectedItem() == SPAWN_SHAPE_MESH){ 287 SpawnInfluencer influencer = (SpawnInfluencer)editor.getEmitter().findInfluencer(SpawnInfluencer.class); 288 influencer.spawnShapeValue = meshSpawnShapeValue; 289 } 290 editor.restart(); 291 } 292 293 } 294