EffectTrack : fixed control loading issue

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9850 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
3.0
rem..om 12 years ago
parent d6267527e8
commit 479632c06e
  1. 156
      engine/src/core/com/jme3/animation/EffectTrack.java

@ -49,24 +49,26 @@ import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
/** /**
* EffectTrack is a track to add to an existing animation, to emmit particles during animations * EffectTrack is a track to add to an existing animation, to emmit particles
* for example : exhausts, dust raised by foot steps, shock waves, lightnings etc... * during animations for example : exhausts, dust raised by foot steps, shock
* * waves, lightnings etc...
* usage is *
* usage is
* <pre> * <pre>
* AnimControl control model.getControl(AnimControl.class); * AnimControl control model.getControl(AnimControl.class);
* EffectTrack track = new EffectTrack(existingEmmitter, control.getAnim("TheAnim").getLength()); * EffectTrack track = new EffectTrack(existingEmmitter, control.getAnim("TheAnim").getLength());
* control.getAnim("TheAnim").addTrack(track); * control.getAnim("TheAnim").addTrack(track);
* </pre> * </pre>
* *
* if the emitter has emmits 0 particles per seconds emmitAllPArticles will be called on it at time 0 + startOffset. * if the emitter has emmits 0 particles per seconds emmitAllPArticles will be
* if it he it has more it will start emmit normally at time 0 + startOffset. * called on it at time 0 + startOffset. if it he it has more it will start
* * emmit normally at time 0 + startOffset.
*
* *
* @author Nehon * @author Nehon
*/ */
public class EffectTrack implements ClonableTrack { public class EffectTrack implements ClonableTrack {
private static final Logger logger = Logger.getLogger(EffectTrack.class.getName()); private static final Logger logger = Logger.getLogger(EffectTrack.class.getName());
private ParticleEmitter emitter; private ParticleEmitter emitter;
private float startOffset = 0; private float startOffset = 0;
@ -74,20 +76,21 @@ public class EffectTrack implements ClonableTrack {
private float length = 0; private float length = 0;
private boolean emitted = false; private boolean emitted = false;
private boolean initialized = false; private boolean initialized = false;
//control responsible for disable and cull the emitter once all particles are gone //control responsible for disable and cull the emitter once all particles are gone
private KillParticleControl killParticles = new KillParticleControl(); private KillParticleControl killParticles = new KillParticleControl();
public static class KillParticleControl extends AbstractControl {
public static class KillParticleControl extends AbstractControl {
ParticleEmitter emitter; ParticleEmitter emitter;
boolean stopRequested = false; boolean stopRequested = false;
boolean remove = false;
public KillParticleControl() { public KillParticleControl() {
} }
@Override @Override
public void setSpatial(Spatial spatial) { public void setSpatial(Spatial spatial) {
super.setSpatial(spatial); super.setSpatial(spatial);
if (spatial != null) { if (spatial != null) {
if (spatial instanceof ParticleEmitter) { if (spatial instanceof ParticleEmitter) {
emitter = (ParticleEmitter) spatial; emitter = (ParticleEmitter) spatial;
@ -95,13 +98,16 @@ public class EffectTrack implements ClonableTrack {
throw new IllegalArgumentException("KillParticleEmitter can only ba attached to ParticleEmitter"); throw new IllegalArgumentException("KillParticleEmitter can only ba attached to ParticleEmitter");
} }
} }
} }
@Override @Override
protected void controlUpdate(float tpf) { protected void controlUpdate(float tpf) {
if(remove){
emitter.removeControl(this);
return;
}
if (emitter.getNumVisibleParticles() == 0) { if (emitter.getNumVisibleParticles() == 0) {
emitter.setCullHint(CullHint.Always); emitter.setCullHint(CullHint.Always);
emitter.setEnabled(false); emitter.setEnabled(false);
@ -109,24 +115,34 @@ public class EffectTrack implements ClonableTrack {
stopRequested = false; stopRequested = false;
} }
} }
@Override @Override
protected void controlRender(RenderManager rm, ViewPort vp) { protected void controlRender(RenderManager rm, ViewPort vp) {
} }
@Override
public Control cloneForSpatial(Spatial spatial) { public Control cloneForSpatial(Spatial spatial) {
return null;
KillParticleControl c = new KillParticleControl();
//this control should be removed as it shouldn't have been persisted in the first place
//In the quest to find the less hackish solution to achieve this,
//making it remove itself from the spatial in the first update loop when loaded was the less bad.
c.remove = true;
c.setSpatial(spatial);
return c;
} }
}; };
//Anim listener that stops the Emmitter when the animation is finished or changed. //Anim listener that stops the Emmitter when the animation is finished or changed.
private class OnEndListener implements AnimEventListener { private class OnEndListener implements AnimEventListener {
public void onAnimCycleDone(AnimControl control, AnimChannel channel, String animName) { public void onAnimCycleDone(AnimControl control, AnimChannel channel, String animName) {
stop(); stop();
} }
public void onAnimChange(AnimControl control, AnimChannel channel, String animName) { public void onAnimChange(AnimControl control, AnimChannel channel, String animName) {
stop(); stop();
} }
@ -140,8 +156,10 @@ public class EffectTrack implements ClonableTrack {
/** /**
* Creates and EffectTrack * Creates and EffectTrack
*
* @param emitter the emmitter of the track * @param emitter the emmitter of the track
* @param length the length of the track (usually the length of the animation you want to add the track to) * @param length the length of the track (usually the length of the
* animation you want to add the track to)
*/ */
public EffectTrack(ParticleEmitter emitter, float length) { public EffectTrack(ParticleEmitter emitter, float length) {
this.emitter = emitter; this.emitter = emitter;
@ -152,14 +170,17 @@ public class EffectTrack implements ClonableTrack {
this.length = length; this.length = length;
//Marking the emitter with a reference to this track for further use in deserialization. //Marking the emitter with a reference to this track for further use in deserialization.
setUserData(this); setUserData(this);
} }
/** /**
* Creates and EffectTrack * Creates and EffectTrack
*
* @param emitter the emmitter of the track * @param emitter the emmitter of the track
* @param length the length of the track (usually the length of the animation you want to add the track to) * @param length the length of the track (usually the length of the
* @param startOffset the time in second when the emitter will be triggerd after the animation starts (default is 0) * animation you want to add the track to)
* @param startOffset the time in second when the emitter will be triggerd
* after the animation starts (default is 0)
*/ */
public EffectTrack(ParticleEmitter emitter, float length, float startOffset) { public EffectTrack(ParticleEmitter emitter, float length, float startOffset) {
this(emitter, length); this(emitter, length);
@ -168,7 +189,9 @@ public class EffectTrack implements ClonableTrack {
/** /**
* Internal use only * Internal use only
* @see Track#setTime(float, float, com.jme3.animation.AnimControl, com.jme3.animation.AnimChannel, com.jme3.util.TempVars) *
* @see Track#setTime(float, float, com.jme3.animation.AnimControl,
* com.jme3.animation.AnimChannel, com.jme3.util.TempVars)
*/ */
public void setTime(float time, float weight, AnimControl control, AnimChannel channel, TempVars vars) { public void setTime(float time, float weight, AnimControl control, AnimChannel channel, TempVars vars) {
@ -204,13 +227,12 @@ public class EffectTrack implements ClonableTrack {
emitter.addControl(killParticles); emitter.addControl(killParticles);
killParticles.stopRequested = true; killParticles.stopRequested = true;
} }
}
}
/** /**
* Retruns the length of the track * Retruns the length of the track
*
* @return length of the track * @return length of the track
*/ */
public float getLength() { public float getLength() {
@ -219,7 +241,8 @@ public class EffectTrack implements ClonableTrack {
/** /**
* Clone this track * Clone this track
* @return *
* @return
*/ */
@Override @Override
public Track clone() { public Track clone() {
@ -227,8 +250,11 @@ public class EffectTrack implements ClonableTrack {
} }
/** /**
* This method clone the Track and search for the cloned counterpart of the original emmitter in the given cloned spatial. * This method clone the Track and search for the cloned counterpart of the
* The spatial is assumed to be the Spatial holding the AnimControl controling the animation using this Track. * original emmitter in the given cloned spatial. The spatial is assumed to
* be the Spatial holding the AnimControl controling the animation using
* this Track.
*
* @param spatial the Spatial holding the AnimControl * @param spatial the Spatial holding the AnimControl
* @return the cloned Track with proper reference * @return the cloned Track with proper reference
*/ */
@ -245,6 +271,7 @@ public class EffectTrack implements ClonableTrack {
effectTrack.emitter = emitter; effectTrack.emitter = emitter;
} }
removeUserData(this);
//setting user data on the new emmitter and marking it with a reference to the cloned Track. //setting user data on the new emmitter and marking it with a reference to the cloned Track.
setUserData(effectTrack); setUserData(effectTrack);
effectTrack.emitter.setParticlesPerSec(0); effectTrack.emitter.setParticlesPerSec(0);
@ -253,8 +280,9 @@ public class EffectTrack implements ClonableTrack {
/** /**
* recursive function responsible for finding the newly cloned Emitter * recursive function responsible for finding the newly cloned Emitter
*
* @param spat * @param spat
* @return * @return
*/ */
private ParticleEmitter findEmitter(Spatial spat) { private ParticleEmitter findEmitter(Spatial spat) {
if (spat instanceof ParticleEmitter) { if (spat instanceof ParticleEmitter) {
@ -266,7 +294,7 @@ public class EffectTrack implements ClonableTrack {
return em; return em;
} }
return null; return null;
} else if (spat instanceof Node) { } else if (spat instanceof Node) {
for (Spatial child : ((Node) spat).getChildren()) { for (Spatial child : ((Node) spat).getChildren()) {
ParticleEmitter em = findEmitter(child); ParticleEmitter em = findEmitter(child);
@ -277,18 +305,17 @@ public class EffectTrack implements ClonableTrack {
} }
return null; return null;
} }
public void cleanUp() { public void cleanUp() {
TrackInfo t = (TrackInfo) emitter.getUserData("TrackInfo"); TrackInfo t = (TrackInfo) emitter.getUserData("TrackInfo");
t.getTracks().remove(this); t.getTracks().remove(this);
if(!t.getTracks().isEmpty()){ if (t.getTracks().isEmpty()) {
emitter.setUserData("TrackInfo", null); emitter.setUserData("TrackInfo", null);
} }
} }
/** /**
* *
* @return the emitter used by this track * @return the emitter used by this track
*/ */
public ParticleEmitter getEmitter() { public ParticleEmitter getEmitter() {
@ -297,7 +324,8 @@ public class EffectTrack implements ClonableTrack {
/** /**
* Sets the Emitter to use in this track * Sets the Emitter to use in this track
* @param emitter *
* @param emitter
*/ */
public void setEmitter(ParticleEmitter emitter) { public void setEmitter(ParticleEmitter emitter) {
if (this.emitter != null) { if (this.emitter != null) {
@ -305,7 +333,7 @@ public class EffectTrack implements ClonableTrack {
data.getTracks().remove(this); data.getTracks().remove(this);
} }
this.emitter = emitter; this.emitter = emitter;
//saving particles per second value //saving particles per second value
this.particlesPerSeconds = emitter.getParticlesPerSec(); this.particlesPerSeconds = emitter.getParticlesPerSec();
//setting the emmitter to not emmit. //setting the emmitter to not emmit.
this.emitter.setParticlesPerSec(0); this.emitter.setParticlesPerSec(0);
@ -313,7 +341,7 @@ public class EffectTrack implements ClonableTrack {
} }
/** /**
* *
* @return the start offset of the track * @return the start offset of the track
*/ */
public float getStartOffset() { public float getStartOffset() {
@ -322,12 +350,13 @@ public class EffectTrack implements ClonableTrack {
/** /**
* set the start offset of the track * set the start offset of the track
* @param startOffset *
* @param startOffset
*/ */
public void setStartOffset(float startOffset) { public void setStartOffset(float startOffset) {
this.startOffset = startOffset; this.startOffset = startOffset;
} }
private void setUserData(EffectTrack effectTrack) { private void setUserData(EffectTrack effectTrack) {
//fetching the UserData TrackInfo. //fetching the UserData TrackInfo.
TrackInfo data = (TrackInfo) effectTrack.emitter.getUserData("TrackInfo"); TrackInfo data = (TrackInfo) effectTrack.emitter.getUserData("TrackInfo");
@ -340,12 +369,28 @@ public class EffectTrack implements ClonableTrack {
//adding the given Track to the TrackInfo. //adding the given Track to the TrackInfo.
data.addTrack(effectTrack); data.addTrack(effectTrack);
}
private void removeUserData(EffectTrack effectTrack) {
//fetching the UserData TrackInfo.
TrackInfo data = (TrackInfo) effectTrack.emitter.getUserData("TrackInfo");
//if it does not exist, we create it and attach it to the emitter.
if (data == null) {
return;
}
//removing the given Track to the TrackInfo.
data.getTracks().remove(effectTrack);
} }
/** /**
* Internal use only serialization * Internal use only serialization
*
* @param ex exporter * @param ex exporter
* @throws IOException exception * @throws IOException exception
*/ */
@ -363,6 +408,7 @@ public class EffectTrack implements ClonableTrack {
/** /**
* Internal use only serialization * Internal use only serialization
*
* @param im importer * @param im importer
* @throws IOException Exception * @throws IOException Exception
*/ */
@ -374,7 +420,11 @@ public class EffectTrack implements ClonableTrack {
emitter = (ParticleEmitter) in.readSavable("emitter", null); emitter = (ParticleEmitter) in.readSavable("emitter", null);
emitter.setParticlesPerSec(0); emitter.setParticlesPerSec(0);
//if the emitter was saved with a KillParticleControl we remove it. //if the emitter was saved with a KillParticleControl we remove it.
// emitter.removeControl(KillParticleControl.class); // Control c = emitter.getControl(KillParticleControl.class);
// if(c!=null){
// emitter.removeControl(c);
// }
//emitter.removeControl(KillParticleControl.class);
length = in.readFloat("length", length); length = in.readFloat("length", length);
startOffset = in.readFloat("startOffset", 0); startOffset = in.readFloat("startOffset", 0);
} }

Loading…
Cancel
Save