2 * Copyright (c) 2003-2009 jMonkeyEngine
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 package com.jmex.editors.swing.particles;
35 import java.awt.Color;
36 import java.awt.Dimension;
38 import java.awt.GridBagConstraints;
39 import java.awt.GridBagLayout;
40 import java.awt.Insets;
41 import java.awt.event.ActionEvent;
42 import java.awt.event.ActionListener;
43 import java.awt.event.MouseAdapter;
44 import java.awt.event.MouseEvent;
46 import java.net.MalformedURLException;
48 import java.util.ArrayList;
49 import java.util.Iterator;
50 import java.util.concurrent.Callable;
51 import java.util.logging.Level;
52 import java.util.logging.Logger;
53 import java.util.prefs.Preferences;
55 import javax.swing.AbstractAction;
56 import javax.swing.DefaultListModel;
57 import javax.swing.ImageIcon;
58 import javax.swing.JButton;
59 import javax.swing.JCheckBox;
60 import javax.swing.JComboBox;
61 import javax.swing.JFileChooser;
62 import javax.swing.JLabel;
63 import javax.swing.JList;
64 import javax.swing.JPanel;
65 import javax.swing.JScrollPane;
66 import javax.swing.ListSelectionModel;
67 import javax.swing.SwingConstants;
68 import javax.swing.event.ChangeEvent;
69 import javax.swing.event.ChangeListener;
70 import javax.swing.event.ListSelectionEvent;
71 import javax.swing.event.ListSelectionListener;
73 import com.jme.image.Texture;
74 import com.jme.renderer.ColorRGBA;
75 import com.jme.scene.state.BlendState;
76 import com.jme.scene.state.RenderState;
77 import com.jme.scene.state.TextureState;
78 import com.jme.system.DisplaySystem;
79 import com.jme.util.GameTaskQueue;
80 import com.jme.util.GameTaskQueueManager;
81 import com.jme.util.TextureManager;
82 import com.jmex.editors.swing.widget.ValuePanel;
83 import com.jmex.effects.particles.AnimationEntry;
84 import com.jmex.effects.particles.ParticleFactory;
85 import com.jmex.effects.particles.ParticleSystem;
86 import com.jmex.effects.particles.ParticleInfluence;
87 import com.jmex.effects.particles.ParticlePoints;
88 import com.jmex.effects.particles.RampEntry;
89 import com.jmex.effects.particles.ParticleSystem.ParticleType;
91 public abstract class ParticleAppearancePanel extends ParticleEditPanel {
92 private static final Logger logger = Logger
93 .getLogger(ParticleAppearancePanel.class.getName());
95 private static final long serialVersionUID = 1L;
96 private static File newTexture = null;
98 private JCheckBox additiveBlendingBox;
99 private JComboBox geomTypeBox;
100 private JCheckBox velocityAlignedBox;
101 private JLabel imageLabel = new JLabel();
103 private JList rampList = null;
104 private DefaultListModel rampModel = new DefaultListModel();
105 private JButton rampAddButton = makeListButton("Add");
106 private JButton rampRemoveButton = makeListButton("Remove");
107 private JButton rampEditButton = makeListButton("Edit");
108 private JButton rampMoveUpButton = makeListButton("/\\");
109 private JButton rampMoveDownButton = makeListButton("\\/");
111 private JList animList = null;
112 private DefaultListModel animModel = new DefaultListModel();
113 private JButton animAddButton = makeListButton("Add");
114 private JButton animRemoveButton = makeListButton("Remove");
115 private JButton animEditButton = makeListButton("Edit");
116 private JButton animMoveUpButton = makeListButton("/\\");
117 private JButton animMoveDownButton = makeListButton("\\/");
119 private Preferences prefs;
120 private JFileChooser textureChooser = new JFileChooser();
121 private JPanel texturePanel;
123 private ValuePanel texPanel, startTexPanel;
125 public ParticleAppearancePanel(Preferences prefs) {
128 setLayout(new GridBagLayout());
130 initTextureChooser();
133 private JButton makeListButton(String text) {
134 JButton button = new JButton(text);
135 button.setMargin(new Insets(2, 2, 2, 2));
139 private void initPanel() {
141 geomTypeBox = new JComboBox(ParticleType.values());
142 geomTypeBox.addActionListener(new ActionListener() {
143 public void actionPerformed(ActionEvent e) {
144 changeParticleType((ParticleType) geomTypeBox.getSelectedItem());
148 velocityAlignedBox = new JCheckBox(new AbstractAction(
149 "Align with Velocity") {
150 private static final long serialVersionUID = 1L;
151 public void actionPerformed(ActionEvent e) {
152 getEdittedParticles().setVelocityAligned(
153 velocityAlignedBox.isSelected());
156 velocityAlignedBox.setFont(new Font("Arial", Font.BOLD, 13));
158 rampList = new JList(rampModel);
159 rampList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
160 rampList.addListSelectionListener(new ListSelectionListener() {
161 public void valueChanged(ListSelectionEvent e) {
162 int selected = rampList.getSelectedIndex();
163 rampRemoveButton.setEnabled(selected > 0 && selected < rampModel.getSize()-1);
164 rampEditButton.setEnabled(selected != -1);
165 rampMoveUpButton.setEnabled(selected > 1 && selected < rampModel.getSize()-1);
166 rampMoveDownButton.setEnabled(selected < rampModel.getSize()-2 && selected > 0);
169 rampList.addMouseListener(new MouseAdapter() {
171 public void mouseClicked(MouseEvent e) {
172 if (e.getClickCount() > 1) {
173 rampEditButton.doClick();
179 rampAddButton.addActionListener(new ActionListener() {
180 public void actionPerformed(ActionEvent e) {
183 RampEntry entry = new RampEntry();
184 getEdittedParticles().getRamp().addEntry(entry);
185 showEditWindow(entry);
187 rampList.setSelectedValue(entry, true);
193 rampEditButton.addActionListener(new ActionListener() {
194 public void actionPerformed(ActionEvent e) {
197 int index = rampList.getSelectedIndex();
198 RampEntry entry = (RampEntry) rampList
200 showEditWindow(entry);
202 rampList.setSelectedIndex(index);
208 rampRemoveButton.addActionListener(new ActionListener() {
209 public void actionPerformed(ActionEvent e) {
210 RampEntry entry = (RampEntry)rampList.getSelectedValue();
211 getEdittedParticles().getRamp().removeEntry(entry);
216 rampMoveUpButton.addActionListener(new ActionListener() {
217 public void actionPerformed(ActionEvent e) {
218 int index = rampList.getSelectedIndex();
219 RampEntry entry = (RampEntry)rampList.getSelectedValue();
220 getEdittedParticles().getRamp().removeEntry(entry);
221 getEdittedParticles().getRamp().addEntry(index-2, entry);
223 rampList.setSelectedValue(entry, true);
227 rampMoveDownButton.addActionListener(new ActionListener() {
228 public void actionPerformed(ActionEvent e) {
229 int index = rampList.getSelectedIndex();
230 RampEntry entry = (RampEntry)rampList.getSelectedValue();
231 getEdittedParticles().getRamp().removeEntry(entry);
232 getEdittedParticles().getRamp().addEntry(index, entry);
234 rampList.setSelectedValue(entry, true);
238 rampRemoveButton.setEnabled(false);
239 rampEditButton.setEnabled(false);
240 rampMoveUpButton.setEnabled(false);
241 rampMoveDownButton.setEnabled(false);
244 JPanel geomPanel = new JPanel(new GridBagLayout());
245 geomPanel.setBorder(createTitledBorder("PARTICLE GEOMETRY"));
246 geomPanel.add(createBoldLabel("Type:"), new GridBagConstraints(0, 0, 1,
247 1, 0, 0, GridBagConstraints.CENTER, GridBagConstraints.NONE,
248 new Insets(5, 5, 5, 5), 0, 0));
249 geomPanel.add(geomTypeBox, new GridBagConstraints(1, 0, 1, 1, 0, 0,
250 GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL,
251 new Insets(5, 5, 5, 5), 0, 0));
252 geomPanel.add(velocityAlignedBox, new GridBagConstraints(0, 1, 2, 1,
253 1.0, 0, GridBagConstraints.CENTER, GridBagConstraints.NONE,
254 new Insets(5, 5, 5, 5), 0, 0));
256 JPanel rampPanel = new JPanel(new GridBagLayout());
257 rampPanel.setBorder(createTitledBorder("APPEARANCE TIMELINE"));
258 rampPanel.add(new JScrollPane(rampList,
259 JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
260 JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED),
261 new GridBagConstraints(1, 0, 1, 6, 1.0, 1.0,
262 GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH,
263 new Insets(5, 5, 5, 5), 0, 0));
264 rampPanel.add(rampAddButton, new GridBagConstraints(0, 0, 1,
265 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL,
266 new Insets(5, 5, 0, 5), 0, 0));
267 rampPanel.add(rampRemoveButton, new GridBagConstraints(0, 1, 1,
268 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL,
269 new Insets(5, 5, 0, 5), 0, 0));
270 rampPanel.add(rampEditButton, new GridBagConstraints(0, 2, 1,
271 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL,
272 new Insets(5, 5, 0, 5), 0, 0));
273 rampPanel.add(rampMoveUpButton, new GridBagConstraints(0, 3, 1,
274 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL,
275 new Insets(5, 5, 0, 5), 0, 0));
276 rampPanel.add(rampMoveDownButton, new GridBagConstraints(0, 4, 1,
277 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL,
278 new Insets(5, 5, 0, 5), 0, 0));
280 animList = new JList(animModel);
281 animList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
282 animList.addListSelectionListener(new ListSelectionListener() {
283 public void valueChanged(ListSelectionEvent e) {
284 int selected = animList.getSelectedIndex();
285 animRemoveButton.setEnabled(selected != -1);
286 animEditButton.setEnabled(selected != -1);
287 animMoveUpButton.setEnabled(selected > 0);
288 animMoveDownButton.setEnabled(selected != -1 && selected < animModel.getSize()-1);
292 animList.addMouseListener(new MouseAdapter() {
294 public void mouseClicked(MouseEvent e) {
295 if (e.getClickCount() > 1) {
296 animEditButton.doClick();
302 animAddButton.addActionListener(new ActionListener() {
303 public void actionPerformed(ActionEvent e) {
306 AnimationEntry entry = new AnimationEntry();
307 getEdittedParticles().getTexAnimation().addEntry(entry);
308 showEditWindow(entry);
310 animList.setSelectedValue(entry, true);
316 animEditButton.addActionListener(new ActionListener() {
317 public void actionPerformed(ActionEvent e) {
320 int index = animList.getSelectedIndex();
321 AnimationEntry entry = (AnimationEntry) animList
323 showEditWindow(entry);
325 animList.setSelectedIndex(index);
331 animRemoveButton.addActionListener(new ActionListener() {
332 public void actionPerformed(ActionEvent e) {
333 AnimationEntry entry = (AnimationEntry)animList.getSelectedValue();
334 getEdittedParticles().getTexAnimation().removeEntry(entry);
339 animMoveUpButton.addActionListener(new ActionListener() {
340 public void actionPerformed(ActionEvent e) {
341 int index = animList.getSelectedIndex();
342 AnimationEntry entry = (AnimationEntry)animList.getSelectedValue();
343 getEdittedParticles().getTexAnimation().removeEntry(entry);
344 getEdittedParticles().getTexAnimation().addEntry(index-1, entry);
346 animList.setSelectedValue(entry, true);
350 animMoveDownButton.addActionListener(new ActionListener() {
351 public void actionPerformed(ActionEvent e) {
352 int index = animList.getSelectedIndex();
353 AnimationEntry entry = (AnimationEntry)animList.getSelectedValue();
354 getEdittedParticles().getTexAnimation().removeEntry(entry);
355 getEdittedParticles().getTexAnimation().addEntry(index+1, entry);
357 animList.setSelectedValue(entry, true);
361 animRemoveButton.setEnabled(false);
362 animEditButton.setEnabled(false);
363 animMoveUpButton.setEnabled(false);
364 animMoveDownButton.setEnabled(false);
366 JPanel animPanel = new JPanel(new GridBagLayout());
367 animPanel.setBorder(createTitledBorder("ANIMATION TIMELINE"));
368 animPanel.add(new JScrollPane(animList,
369 JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
370 JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED),
371 new GridBagConstraints(1, 0, 1, 6, 1.0, 1.0,
372 GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH,
373 new Insets(5, 5, 5, 5), 0, 0));
374 animPanel.add(animAddButton, new GridBagConstraints(0, 0, 1,
375 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL,
376 new Insets(5, 5, 0, 5), 0, 0));
377 animPanel.add(animRemoveButton, new GridBagConstraints(0, 1, 1,
378 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL,
379 new Insets(5, 5, 0, 5), 0, 0));
380 animPanel.add(animEditButton, new GridBagConstraints(0, 2, 1,
381 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL,
382 new Insets(5, 5, 0, 5), 0, 0));
383 animPanel.add(animMoveUpButton, new GridBagConstraints(0, 3, 1,
384 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL,
385 new Insets(5, 5, 0, 5), 0, 0));
386 animPanel.add(animMoveDownButton, new GridBagConstraints(0, 4, 1,
387 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL,
388 new Insets(5, 5, 0, 5), 0, 0));
391 additiveBlendingBox = new JCheckBox(new AbstractAction(
392 "Additive Blending") {
393 private static final long serialVersionUID = 1L;
395 public void actionPerformed(ActionEvent e) {
396 updateBlendState(additiveBlendingBox.isSelected());
399 additiveBlendingBox.setFont(new Font("Arial", Font.BOLD, 13));
401 JPanel blendPanel = new JPanel(new GridBagLayout());
402 blendPanel.setBorder(createTitledBorder("PARTICLE BLENDING"));
403 blendPanel.add(additiveBlendingBox, new GridBagConstraints(0, 0, 1, 1,
404 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE,
405 new Insets(5, 5, 5, 5), 0, 0));
407 JLabel textureLabel = createBoldLabel("Texture Image:");
408 JButton changeTextureButton = new JButton(new AbstractAction(
410 private static final long serialVersionUID = 1L;
412 public void actionPerformed(ActionEvent e) {
416 changeTextureButton.setFont(new Font("Arial", Font.BOLD, 12));
417 changeTextureButton.setMargin(new Insets(2, 2, 2, 2));
419 JButton clearTextureButton = new JButton(new AbstractAction("Clear") {
420 private static final long serialVersionUID = 1L;
422 public void actionPerformed(ActionEvent e) {
423 ((TextureState) getEdittedParticles().getRenderState(RenderState.StateType.Texture)).setTexture(null);
424 imageLabel.setIcon(null);
427 clearTextureButton.setFont(new Font("Arial", Font.BOLD, 12));
428 clearTextureButton.setMargin(new Insets(2, 2, 2, 2));
430 imageLabel.setBackground(Color.lightGray);
431 imageLabel.setMaximumSize(new Dimension(128, 128));
432 imageLabel.setMinimumSize(new Dimension(0, 0));
433 imageLabel.setHorizontalAlignment(SwingConstants.CENTER);
434 imageLabel.setOpaque(false);
436 texturePanel = new JPanel(new GridBagLayout());
437 texturePanel.setBorder(createTitledBorder("PARTICLE TEXTURE"));
438 texturePanel.add(textureLabel, new GridBagConstraints(0, 0, 1, 1, 0.0,
439 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE,
440 new Insets(5, 5, 5, 5), 0, 0));
441 texturePanel.add(changeTextureButton, new GridBagConstraints(0, 1, 1,
442 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.HORIZONTAL,
443 new Insets(0, 5, 5, 5), 0, 0));
444 texturePanel.add(clearTextureButton, new GridBagConstraints(0, 2, 1, 1,
445 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.HORIZONTAL,
446 new Insets(0, 5, 5, 5), 0, 0));
447 texturePanel.add(imageLabel, new GridBagConstraints(1, 0, 1, 3, 1.0,
448 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE,
449 new Insets(5, 5, 5, 5), 0, 0));
451 texPanel = new ValuePanel("Sub Images: ", "", 1, Integer.MAX_VALUE, 1);
452 texPanel.addChangeListener(new ChangeListener() {
453 public void stateChanged(ChangeEvent e) {
454 getEdittedParticles().setTexQuantity(texPanel.getIntValue());
458 texturePanel.add(texPanel, new GridBagConstraints(0, 3, 2, 1, 1.0, 0.0,
459 GridBagConstraints.NORTHWEST, GridBagConstraints.NONE,
460 new Insets(5, 5, 5, 5), 0, 0));
463 startTexPanel = new ValuePanel("Start Index: ", "", 0, Integer.MAX_VALUE, 1);
464 startTexPanel.addChangeListener(new ChangeListener() {
465 public void stateChanged(ChangeEvent e) {
466 getEdittedParticles().setStartTexIndex(startTexPanel.getIntValue());
470 texturePanel.add(startTexPanel, new GridBagConstraints(0, 4, 2, 1, 1.0, 0.0,
471 GridBagConstraints.NORTHWEST, GridBagConstraints.NONE,
472 new Insets(5, 5, 5, 5), 0, 0));
476 add(geomPanel, new GridBagConstraints(0, 1, 1, 1, 1.0, 0.0,
477 GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL,
478 new Insets(5, 5, 5, 10), 0, 0));
479 add(texturePanel, new GridBagConstraints(0, 2, 1, 1, 1.0, 0.0,
480 GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL,
481 new Insets(5, 10, 5, 10), 0, 0));
482 add(blendPanel, new GridBagConstraints(0, 3, 1, 1, 1.0, 0.0,
483 GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL,
484 new Insets(5, 10, 5, 10), 0, 0));
485 add(rampPanel, new GridBagConstraints(0, 4, 1, 1, 1.0, 1.0,
486 GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL,
487 new Insets(5, 10, 5, 10), 0, 0));
488 add(animPanel, new GridBagConstraints(0, 5, 1, 1, 1.0, 1.0,
489 GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL,
490 new Insets(5, 10, 5, 10), 0, 0));
493 protected void showEditWindow(final RampEntry entry) {
494 RampEntryEditDialog dialog = new RampEntryEditDialog(entry);
495 dialog.setLocationRelativeTo(ParticleAppearancePanel.this);
496 dialog.setModal(true);
497 dialog.setVisible(true);
501 protected void showEditWindow(final AnimationEntry entry) {
502 AnimationEntryEditDialog dialog = new AnimationEntryEditDialog(entry);
503 dialog.setLocationRelativeTo(ParticleAppearancePanel.this);
504 dialog.setModal(true);
505 dialog.setVisible(true);
509 protected void updateRampModel() {
511 rampModel.addElement(new StartRamp(getEdittedParticles()));
512 Iterator<RampEntry> it = getEdittedParticles().getRamp().getEntries();
513 while (it.hasNext()) {
514 RampEntry e = it.next();
515 rampModel.addElement(e);
517 rampModel.addElement(new EndRamp(getEdittedParticles()));
520 protected void updateAnimModel() {
522 Iterator<AnimationEntry> it = getEdittedParticles().getTexAnimation().getEntries();
523 while (it.hasNext()) {
524 AnimationEntry e = it.next();
525 animModel.addElement(e);
529 private void changeParticleType(ParticleType newType) {
530 ParticleType oldType = getEdittedParticles().getParticleType();
531 if (newType == oldType) {
534 ParticleSystem oldGeom = getEdittedParticles(), newGeom;
535 if (newType == ParticleSystem.ParticleType.Point) {
536 ParticlePoints pPoints = ParticleFactory.buildPointParticles(oldGeom.getName(),
537 oldGeom.getNumParticles());
539 pPoints.setPointSize(5);
540 pPoints.setAntialiased(true);
541 } else if (newType == ParticleSystem.ParticleType.Line) {
542 newGeom = ParticleFactory.buildLineParticles(oldGeom.getName(),
543 oldGeom.getNumParticles());
545 newGeom = ParticleFactory.buildParticles(oldGeom.getName(),
546 oldGeom.getNumParticles(), newType);
548 // copy appearance parameters
549 newGeom.setVelocityAligned(oldGeom.isVelocityAligned());
550 newGeom.setStartColor(oldGeom.getStartColor().clone());
551 newGeom.setEndColor(oldGeom.getEndColor().clone());
552 newGeom.setStartTexIndex(oldGeom.getStartTexIndex());
553 newGeom.setStartSize(oldGeom.getStartSize());
554 newGeom.setEndSize(oldGeom.getEndSize());
555 newGeom.setStartMass(oldGeom.getStartMass());
556 newGeom.setEndMass(oldGeom.getEndMass());
557 newGeom.setStartSpin(oldGeom.getStartSpin());
558 newGeom.setEndSpin(oldGeom.getEndSpin());
559 newGeom.setRamp(oldGeom.getRamp());
560 newGeom.setTexQuantity(oldGeom.getTexQuantity());
562 // copy origin parameters
563 newGeom.setLocalTranslation(oldGeom.getLocalTranslation());
564 newGeom.setLocalRotation(oldGeom.getLocalRotation());
565 newGeom.setLocalScale(oldGeom.getLocalScale());
566 newGeom.setOriginOffset(oldGeom.getOriginOffset());
567 newGeom.setGeometry(oldGeom.getLine());
568 newGeom.setGeometry(oldGeom.getRectangle());
569 newGeom.setGeometry(oldGeom.getRing());
570 newGeom.setEmitType(oldGeom.getEmitType());
572 // copy emission parameters
573 newGeom.setRotateWithScene(oldGeom.isRotateWithScene());
574 newGeom.setEmissionDirection(oldGeom.getEmissionDirection());
575 newGeom.setMinimumAngle(oldGeom.getMinimumAngle());
576 newGeom.setMaximumAngle(oldGeom.getMaximumAngle());
577 newGeom.setInitialVelocity(oldGeom.getInitialVelocity());
579 // copy flow parameters
580 newGeom.setControlFlow(oldGeom.getParticleController().isControlFlow());
581 newGeom.setReleaseRate(oldGeom.getReleaseRate());
582 newGeom.setReleaseVariance(oldGeom.getReleaseVariance());
583 newGeom.setRepeatType(oldGeom.getParticleController().getRepeatType());
585 // copy world parameters
586 newGeom.setSpeed(oldGeom.getParticleController().getSpeed());
587 newGeom.setMinimumLifeTime(oldGeom.getMinimumLifeTime());
588 newGeom.setMaximumLifeTime(oldGeom.getMaximumLifeTime());
589 newGeom.getParticleController().setPrecision(
590 oldGeom.getParticleController().getPrecision());
592 // copy influence parameters
593 ArrayList<ParticleInfluence> infs = oldGeom.getInfluences();
595 for (ParticleInfluence inf : infs) {
596 newGeom.addInfluence(inf);
600 // copy render states
601 for (RenderState.StateType type : RenderState.StateType.values()) {
602 RenderState rs = oldGeom.getRenderState(type);
604 newGeom.setRenderState(rs);
608 requestParticleSystemOverwrite(newGeom);
611 protected abstract void requestParticleSystemOverwrite(ParticleSystem newParticles);
613 private void changeTexture() {
615 int result = textureChooser.showOpenDialog(this);
616 if (result == JFileChooser.CANCEL_OPTION) {
619 File textFile = textureChooser.getSelectedFile();
620 prefs.put("texture_dir", textFile.getParent());
622 newTexture = textFile;
624 GameTaskQueueManager.getManager().getQueue(GameTaskQueue.RENDER).enqueue(new Callable<Object>() {
625 public Object call() throws Exception{
631 ImageIcon icon = new ImageIcon(
632 getToolkit().createImage(textFile.getAbsolutePath()));
633 imageLabel.setIcon(icon);
635 } catch (Exception ex) {
636 logger.logp(Level.SEVERE, this.getClass().toString(), "changeTexture()", "Exception",
641 private void initTextureChooser() {
642 String tdir = prefs.get("texture_dir", null);
644 textureChooser.setCurrentDirectory(new File(tdir));
648 private void loadApplyTexture() throws MalformedURLException {
649 TextureState ts = (TextureState)getEdittedParticles().getRenderState(RenderState.StateType.Texture);
650 TextureManager.clearCache();
652 TextureManager.loadTexture(
653 newTexture.toURI().toURL(),
654 Texture.MinificationFilter.BilinearNearestMipMap,
655 Texture.MagnificationFilter.Bilinear));
657 getEdittedParticles().setRenderState(ts);
658 getEdittedParticles().updateRenderState();
662 private void updateBlendState(boolean additive) {
663 BlendState as = (BlendState)getEdittedParticles().getRenderState(RenderState.StateType.Blend);
665 as = DisplaySystem.getDisplaySystem().getRenderer().createBlendState();
666 as.setBlendEnabled(true);
667 as.setSourceFunction(BlendState.SourceFunction.SourceAlpha);
668 as.setTestEnabled(true);
669 as.setTestFunction(BlendState.TestFunction.GreaterThan);
670 getEdittedParticles().setRenderState(as);
671 getEdittedParticles().updateRenderState();
673 as.setDestinationFunction(additive ?
674 BlendState.DestinationFunction.One : BlendState.DestinationFunction.OneMinusSourceAlpha);
678 public void updateWidgets() {
681 ParticleSystem system = getEdittedParticles();
682 geomTypeBox.setSelectedItem(system.getParticleType());
683 velocityAlignedBox.setSelected(system.isVelocityAligned());
684 texPanel.setValue(system.getTexQuantity());
685 startTexPanel.setValue(system.getStartTexIndex());
687 BlendState as = (BlendState)system.getRenderState(RenderState.StateType.Blend);
688 additiveBlendingBox.setSelected(as == null ||
689 as.getDestinationFunctionRGB() == BlendState.DestinationFunction.One);
690 if (getTexturePanel().isVisible()) {
693 tex = ((TextureState)system.getRenderState(RenderState.StateType.Texture)).getTexture();
695 if (tex.getTextureKey() != null && tex.getTextureKey().getLocation() != null)
697 new ImageIcon(tex.getTextureKey().getLocation()));
700 new ImageIcon(new URL(tex.getImageLocation())));
702 imageLabel.setIcon(null);
704 } catch (Exception e) {
705 logger.warning("image: "+tex+" : "+ tex != null ? tex.getImageLocation() : "");
710 public JCheckBox getAdditiveBlendingBox() {
711 return additiveBlendingBox;
714 public JPanel getTexturePanel() {
718 public class StartRamp extends RampEntry {
720 private ParticleSystem particles;
722 public StartRamp(ParticleSystem particles) {
724 this.particles = particles;
725 setColor(particles.getStartColor());
726 setSize(particles.getStartSize());
727 setMass(particles.getStartMass());
728 setSpin(particles.getStartSpin());
732 public String toString() {
733 return "START: "+super.toString();
737 public void setSize(float size) {
739 particles.setStartSize(size);
743 public void setMass(float mass) {
745 particles.setStartMass(mass);
749 public void setSpin(float spin) {
751 particles.setStartSpin(spin);
755 public void setColor(ColorRGBA color) {
756 super.setColor(color);
757 particles.setStartColor(color);
761 public class EndRamp extends RampEntry {
763 private ParticleSystem particles;
765 public EndRamp(ParticleSystem particles) {
767 this.particles = particles;
768 setColor(particles.getEndColor());
769 setSize(particles.getEndSize());
770 setMass(particles.getEndMass());
771 setSpin(particles.getEndSpin());
775 public String toString() {
776 return "END: "+super.toString();
780 public void setSize(float size) {
782 particles.setEndSize(size);
786 public void setMass(float mass) {
788 particles.setEndMass(mass);
792 public void setSpin(float spin) {
794 particles.setEndSpin(spin);
798 public void setColor(ColorRGBA color) {
799 super.setColor(color);
800 particles.setEndColor(color);