package com.jme3.scene.plugins.blender.modifiers; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import com.jme3.effect.ParticleEmitter; import com.jme3.effect.shapes.EmitterMeshVertexShape; import com.jme3.effect.shapes.EmitterShape; import com.jme3.material.Material; import com.jme3.scene.Geometry; import com.jme3.scene.Mesh; import com.jme3.scene.Node; import com.jme3.scene.Spatial; import com.jme3.scene.plugins.blender.BlenderContext; import com.jme3.scene.plugins.blender.file.BlenderFileException; import com.jme3.scene.plugins.blender.file.Pointer; import com.jme3.scene.plugins.blender.file.Structure; import com.jme3.scene.plugins.blender.materials.MaterialHelper; import com.jme3.scene.plugins.blender.meshes.TemporalMesh; import com.jme3.scene.plugins.blender.particles.ParticlesHelper; /** * This modifier allows to add particles to the object. * * @author Marcin Roguski (Kaelthas) */ /* package */class ParticlesModifier extends Modifier { private static final Logger LOGGER = Logger.getLogger(MirrorModifier.class.getName()); /** Loaded particles emitter. */ private ParticleEmitter particleEmitter; /** * This constructor reads the particles system structure and stores it in * order to apply it later to the node. * * @param modifierStructure * the structure of the modifier * @param blenderContext * the blender context * @throws BlenderFileException * an exception is throw wneh there are problems with the * blender file */ public ParticlesModifier(Structure modifierStructure, BlenderContext blenderContext) throws BlenderFileException { if (this.validate(modifierStructure, blenderContext)) { Pointer pParticleSystem = (Pointer) modifierStructure.getFieldValue("psys"); if (pParticleSystem.isNotNull()) { ParticlesHelper particlesHelper = blenderContext.getHelper(ParticlesHelper.class); Structure particleSystem = pParticleSystem.fetchData().get(0); particleEmitter = particlesHelper.toParticleEmitter(particleSystem); } } } @Override public void postMeshCreationApply(Node node, BlenderContext blenderContext) { LOGGER.log(Level.FINE, "Applying particles modifier to: {0}", node); MaterialHelper materialHelper = blenderContext.getHelper(MaterialHelper.class); ParticleEmitter emitter = particleEmitter.clone(); // veryfying the alpha function for particles' texture Integer alphaFunction = MaterialHelper.ALPHA_MASK_HYPERBOLE; char nameSuffix = emitter.getName().charAt(emitter.getName().length() - 1); if (nameSuffix == 'B' || nameSuffix == 'N') { alphaFunction = MaterialHelper.ALPHA_MASK_NONE; } // removing the type suffix from the name emitter.setName(emitter.getName().substring(0, emitter.getName().length() - 1)); // applying emitter shape EmitterShape emitterShape = emitter.getShape(); List<Mesh> meshes = new ArrayList<Mesh>(); for (Spatial spatial : node.getChildren()) { if (spatial instanceof Geometry) { Mesh mesh = ((Geometry) spatial).getMesh(); if (mesh != null) { meshes.add(mesh); Material material = materialHelper.getParticlesMaterial(((Geometry) spatial).getMaterial(), alphaFunction, blenderContext); emitter.setMaterial(material);// TODO: divide into several pieces } } } if (meshes.size() > 0 && emitterShape instanceof EmitterMeshVertexShape) { ((EmitterMeshVertexShape) emitterShape).setMeshes(meshes); } node.attachChild(emitter); } @Override public void apply(Node node, BlenderContext blenderContext) { if (invalid) { LOGGER.log(Level.WARNING, "Particles modifier is invalid! Cannot be applied to: {0}", node.getName()); } else { TemporalMesh temporalMesh = this.getTemporalMesh(node); if(temporalMesh != null) { temporalMesh.applyAfterMeshCreate(this); } else { LOGGER.log(Level.WARNING, "Cannot find temporal mesh for node: {0}. The modifier will NOT be applied!", node); } } } }