diff --git a/engine/src/core/com/jme3/asset/ModelKey.java b/engine/src/core/com/jme3/asset/ModelKey.java index 42f1e0c79..dcf87c3a0 100644 --- a/engine/src/core/com/jme3/asset/ModelKey.java +++ b/engine/src/core/com/jme3/asset/ModelKey.java @@ -48,6 +48,11 @@ public class ModelKey extends AssetKey { super(); } + @Override + public boolean useSmartCache(){ + return true; + } + @Override public Object createClonedInstance(Object asset){ Spatial model = (Spatial) asset; diff --git a/engine/src/core/com/jme3/effect/ParticleEmitter.java b/engine/src/core/com/jme3/effect/ParticleEmitter.java index 9059ab52e..dccd968fc 100644 --- a/engine/src/core/com/jme3/effect/ParticleEmitter.java +++ b/engine/src/core/com/jme3/effect/ParticleEmitter.java @@ -75,7 +75,7 @@ public class ParticleEmitter extends Geometry { private static final EmitterShape DEFAULT_SHAPE = new EmitterPointShape(Vector3f.ZERO); private static final ParticleInfluencer DEFAULT_INFLUENCER = new DefaultParticleInfluencer(); - private ParticleEmitterControl control = new ParticleEmitterControl(); + private ParticleEmitterControl control = new ParticleEmitterControl(this); private EmitterShape shape = DEFAULT_SHAPE; private ParticleMesh particleMesh; private ParticleInfluencer particleInfluencer = DEFAULT_INFLUENCER; @@ -106,29 +106,36 @@ public class ParticleEmitter extends Geometry { //variable that helps with computations private transient Vector3f temp = new Vector3f(); - private class ParticleEmitterControl implements Control { + private static class ParticleEmitterControl implements Control { + private ParticleEmitter parentEmitter; + + public ParticleEmitterControl(ParticleEmitter parentEmitter){ + this.parentEmitter = parentEmitter; + } + public Control cloneForSpatial(Spatial spatial) { - return ((ParticleEmitter) spatial).control; + return this; // WARNING: Sets wrong control on spatial. Will be + // fixed automatically by ParticleEmitter.clone() method. } public void setSpatial(Spatial spatial) { } public void setEnabled(boolean enabled) { - ParticleEmitter.this.setEnabled(enabled); + parentEmitter.setEnabled(enabled); } public boolean isEnabled() { - return ParticleEmitter.this.isEnabled(); + return parentEmitter.isEnabled(); } public void update(float tpf) { - updateFromControl(tpf); + parentEmitter.updateFromControl(tpf); } public void render(RenderManager rm, ViewPort vp) { - renderFromControl(rm, vp); + parentEmitter.renderFromControl(rm, vp); } public void write(JmeExporter ex) throws IOException { @@ -144,12 +151,37 @@ public class ParticleEmitter extends Geometry { public ParticleEmitter clone() { ParticleEmitter clone = (ParticleEmitter) super.clone(); clone.shape = shape.deepClone(); + + // Reinitialize particle list clone.setNumParticles(particles.length); + clone.faceNormal = faceNormal.clone(); clone.startColor = startColor.clone(); clone.endColor = endColor.clone(); clone.particleInfluencer = particleInfluencer.clone(); - clone.controls.add(clone.control); + + // remove wrong control + clone.controls.remove(control); + + // put correct control + clone.controls.add(new ParticleEmitterControl(clone)); + + // Reinitialize particle mesh + switch (meshType) { + case Point: + clone.particleMesh = new ParticlePointMesh(); + clone.setMesh(clone.particleMesh); + break; + case Triangle: + clone.particleMesh = new ParticleTriMesh(); + clone.setMesh(clone.particleMesh); + break; + default: + throw new IllegalStateException("Unrecognized particle type: " + meshType); + } + clone.particleMesh.initParticleData(clone, clone.particles.length); + clone.particleMesh.setImagesXY(clone.imagesX, clone.imagesY); + return clone; } diff --git a/engine/src/core/com/jme3/scene/Spatial.java b/engine/src/core/com/jme3/scene/Spatial.java index 4f2de2d03..7cf76fc1b 100644 --- a/engine/src/core/com/jme3/scene/Spatial.java +++ b/engine/src/core/com/jme3/scene/Spatial.java @@ -31,6 +31,8 @@ */ package com.jme3.scene; +import com.jme3.asset.Asset; +import com.jme3.asset.AssetKey; import com.jme3.bounding.BoundingVolume; import com.jme3.collision.Collidable; import com.jme3.export.JmeExporter; @@ -74,7 +76,7 @@ import java.util.logging.Logger; * @author Joshua Slack * @version $Revision: 4075 $, $Data$ */ -public abstract class Spatial implements Savable, Cloneable, Collidable { +public abstract class Spatial implements Savable, Cloneable, Collidable, Asset { private static final Logger logger = Logger.getLogger(Spatial.class.getName()); @@ -111,20 +113,25 @@ public abstract class Spatial implements Savable, Cloneable, Collidable { protected static final int RF_TRANSFORM = 0x01, // need light resort + combine transforms RF_BOUND = 0x02, RF_LIGHTLIST = 0x04; // changes in light lists + protected CullHint cullHint = CullHint.Inherit; + /** * Spatial's bounding volume relative to the world. */ protected BoundingVolume worldBound; + /** * LightList */ protected LightList localLights; protected transient LightList worldLights; + /** * This spatial's name. */ protected String name; + // scale values protected transient Camera.FrustumIntersect frustrumIntersects = Camera.FrustumIntersect.Intersects; protected RenderQueue.Bucket queueBucket = RenderQueue.Bucket.Inherit; @@ -134,6 +141,14 @@ public abstract class Spatial implements Savable, Cloneable, Collidable { protected Transform worldTransform; protected SafeArrayList controls = new SafeArrayList(Control.class); protected HashMap userData = null; + + /** + * Used for smart asset caching + * + * @see AssetKey#useSmartCache() + */ + protected AssetKey key; + /** * Spatial's parent, or null if it has none. */ @@ -170,6 +185,14 @@ public abstract class Spatial implements Savable, Cloneable, Collidable { this.name = name; } + public void setKey(AssetKey key){ + this.key = key; + } + + public AssetKey getKey(){ + return key; + } + /** * Indicate that the transform of this spatial has changed and that * a refresh is required.