1 package com.jme3.scene.plugins.blender.modifiers; 2 3 import com.jme3.effect.ParticleEmitter; 4 import com.jme3.effect.shapes.EmitterMeshVertexShape; 5 import com.jme3.effect.shapes.EmitterShape; 6 import com.jme3.material.Material; 7 import com.jme3.scene.Geometry; 8 import com.jme3.scene.Mesh; 9 import com.jme3.scene.Node; 10 import com.jme3.scene.Spatial; 11 import com.jme3.scene.plugins.blender.BlenderContext; 12 import com.jme3.scene.plugins.blender.exceptions.BlenderFileException; 13 import com.jme3.scene.plugins.blender.file.Pointer; 14 import com.jme3.scene.plugins.blender.file.Structure; 15 import com.jme3.scene.plugins.blender.materials.MaterialHelper; 16 import com.jme3.scene.plugins.blender.particles.ParticlesHelper; 17 import java.util.ArrayList; 18 import java.util.List; 19 import java.util.logging.Level; 20 import java.util.logging.Logger; 21 22 /** 23 * This modifier allows to add particles to the object. 24 * 25 * @author Marcin Roguski (Kaelthas) 26 */ 27 /* package */class ParticlesModifier extends Modifier { 28 private static final Logger LOGGER = Logger.getLogger(MirrorModifier.class.getName()); 29 30 /** Loaded particles emitter. */ 31 private ParticleEmitter particleEmitter; 32 33 /** 34 * This constructor reads the particles system structure and stores it in 35 * order to apply it later to the node. 36 * 37 * @param modifierStructure 38 * the structure of the modifier 39 * @param blenderContext 40 * the blender context 41 * @throws BlenderFileException 42 * an exception is throw wneh there are problems with the 43 * blender file 44 */ 45 public ParticlesModifier(Structure modifierStructure, BlenderContext blenderContext) throws BlenderFileException { 46 if(this.validate(modifierStructure, blenderContext)) { 47 Pointer pParticleSystem = (Pointer) modifierStructure.getFieldValue("psys"); 48 if (pParticleSystem.isNotNull()) { 49 ParticlesHelper particlesHelper = blenderContext.getHelper(ParticlesHelper.class); 50 Structure particleSystem = pParticleSystem.fetchData(blenderContext.getInputStream()).get(0); 51 particleEmitter = particlesHelper.toParticleEmitter(particleSystem, blenderContext); 52 } 53 } 54 } 55 56 @Override 57 public Node apply(Node node, BlenderContext blenderContext) { 58 if(invalid) { 59 LOGGER.log(Level.WARNING, "Particles modifier is invalid! Cannot be applied to: {0}", node.getName()); 60 return node; 61 } 62 63 MaterialHelper materialHelper = blenderContext.getHelper(MaterialHelper.class); 64 ParticleEmitter emitter = particleEmitter.clone(); 65 66 // veryfying the alpha function for particles' texture 67 Integer alphaFunction = MaterialHelper.ALPHA_MASK_HYPERBOLE; 68 char nameSuffix = emitter.getName().charAt(emitter.getName().length() - 1); 69 if (nameSuffix == 'B' || nameSuffix == 'N') { 70 alphaFunction = MaterialHelper.ALPHA_MASK_NONE; 71 } 72 // removing the type suffix from the name 73 emitter.setName(emitter.getName().substring(0, emitter.getName().length() - 1)); 74 75 // applying emitter shape 76 EmitterShape emitterShape = emitter.getShape(); 77 List<Mesh> meshes = new ArrayList<Mesh>(); 78 for (Spatial spatial : node.getChildren()) { 79 if (spatial instanceof Geometry) { 80 Mesh mesh = ((Geometry) spatial).getMesh(); 81 if (mesh != null) { 82 meshes.add(mesh); 83 Material material = materialHelper.getParticlesMaterial( 84 ((Geometry) spatial).getMaterial(), alphaFunction, blenderContext); 85 emitter.setMaterial(material);// TODO: divide into several pieces 86 } 87 } 88 } 89 if (meshes.size() > 0 && emitterShape instanceof EmitterMeshVertexShape) { 90 ((EmitterMeshVertexShape) emitterShape).setMeshes(meshes); 91 } 92 93 node.attachChild(emitter); 94 return node; 95 } 96 97 @Override 98 public String getType() { 99 return Modifier.PARTICLE_MODIFIER_DATA; 100 } 101 } 102