Home | History | Annotate | Download | only in modifiers
      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