159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapackage com.jme3.scene.plugins.blender.particles; 259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.effect.ParticleEmitter; 459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.effect.ParticleMesh.Type; 559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.effect.influencers.EmptyParticleInfluencer; 659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.effect.influencers.NewtonianParticleInfluencer; 759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.effect.influencers.ParticleInfluencer; 859b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.effect.shapes.EmitterMeshConvexHullShape; 959b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.effect.shapes.EmitterMeshFaceShape; 1059b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.effect.shapes.EmitterMeshVertexShape; 1159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.math.ColorRGBA; 1259b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.plugins.blender.AbstractBlenderHelper; 1359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.plugins.blender.BlenderContext; 1459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.plugins.blender.exceptions.BlenderFileException; 1559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.plugins.blender.file.DynamicArray; 1659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.plugins.blender.file.Pointer; 1759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.plugins.blender.file.Structure; 1859b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.logging.Logger; 1959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 2059b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapublic class ParticlesHelper extends AbstractBlenderHelper { 2159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private static final Logger LOGGER = Logger.getLogger(ParticlesHelper.class.getName()); 2259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 2359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // part->type 2459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static final int PART_EMITTER = 0; 2559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static final int PART_REACTOR = 1; 2659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static final int PART_HAIR = 2; 2759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static final int PART_FLUID = 3; 2859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 2959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // part->flag 3059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static final int PART_REACT_STA_END =1; 3159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static final int PART_REACT_MULTIPLE =2; 3259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static final int PART_LOOP =4; 3359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //public static final int PART_LOOP_INSTANT =8; 3459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static final int PART_HAIR_GEOMETRY =16; 3559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static final int PART_UNBORN =32; //show unborn particles 3659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static final int PART_DIED =64; //show died particles 3759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static final int PART_TRAND =128; 3859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static final int PART_EDISTR =256; // particle/face from face areas 3959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static final int PART_STICKY =512; //collided particles can stick to collider 4059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static final int PART_DIE_ON_COL =1<<12; 4159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static final int PART_SIZE_DEFL =1<<13; // swept sphere deflections 4259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static final int PART_ROT_DYN =1<<14; // dynamic rotation 4359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static final int PART_SIZEMASS =1<<16; 4459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static final int PART_ABS_LENGTH =1<<15; 4559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static final int PART_ABS_TIME =1<<17; 4659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static final int PART_GLOB_TIME =1<<18; 4759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static final int PART_BOIDS_2D =1<<19; 4859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static final int PART_BRANCHING =1<<20; 4959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static final int PART_ANIM_BRANCHING =1<<21; 5059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static final int PART_SELF_EFFECT =1<<22; 5159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static final int PART_SYMM_BRANCHING =1<<24; 5259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static final int PART_HAIR_BSPLINE =1024; 5359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static final int PART_GRID_INVERT =1<<26; 5459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static final int PART_CHILD_EFFECT =1<<27; 5559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static final int PART_CHILD_SEAMS =1<<28; 5659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static final int PART_CHILD_RENDER =1<<29; 5759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static final int PART_CHILD_GUIDE =1<<30; 5859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 5959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // part->from 6059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static final int PART_FROM_VERT =0; 6159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static final int PART_FROM_FACE =1; 6259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static final int PART_FROM_VOLUME =2; 6359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static final int PART_FROM_PARTICLE =3; 6459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static final int PART_FROM_CHILD =4; 6559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 6659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // part->phystype 6759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static final int PART_PHYS_NO = 0; 6859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static final int PART_PHYS_NEWTON= 1; 6959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static final int PART_PHYS_KEYED = 2; 7059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static final int PART_PHYS_BOIDS = 3; 7159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 7259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // part->draw_as 7359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static final int PART_DRAW_NOT = 0; 7459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static final int PART_DRAW_DOT = 1; 7559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static final int PART_DRAW_CIRC = 2; 7659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static final int PART_DRAW_CROSS = 3; 7759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static final int PART_DRAW_AXIS = 4; 7859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static final int PART_DRAW_LINE = 5; 7959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static final int PART_DRAW_PATH = 6; 8059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static final int PART_DRAW_OB = 7; 8159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static final int PART_DRAW_GR = 8; 8259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public static final int PART_DRAW_BB = 9; 8359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 8459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 8559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * This constructor parses the given blender version and stores the result. Some functionalities may differ in 8659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * different blender versions. 8759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param blenderVersion 8859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * the version read from the blend file 8959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param fixUpAxis 9059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * a variable that indicates if the Y asxis is the UP axis or not 9159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 9259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public ParticlesHelper(String blenderVersion, boolean fixUpAxis) { 9359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta super(blenderVersion, fixUpAxis); 9459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 9559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 9659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta @SuppressWarnings("unchecked") 9759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public ParticleEmitter toParticleEmitter(Structure particleSystem, BlenderContext blenderContext) throws BlenderFileException { 9859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta ParticleEmitter result = null; 9959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Pointer pParticleSettings = (Pointer) particleSystem.getFieldValue("part"); 10059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if(pParticleSettings.isNotNull()) { 10159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Structure particleSettings = pParticleSettings.fetchData(blenderContext.getInputStream()).get(0); 10259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 10359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int totPart = ((Number) particleSettings.getFieldValue("totpart")).intValue(); 10459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 10559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //draw type will be stored temporarily in the name (it is used during modifier applying operation) 10659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int drawAs = ((Number)particleSettings.getFieldValue("draw_as")).intValue(); 10759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta char nameSuffix;//P - point, L - line, N - None, B - Bilboard 10859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta switch(drawAs) { 10959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta case PART_DRAW_NOT: 11059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta nameSuffix = 'N'; 11159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta totPart = 0;//no need to generate particles in this case 11259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta break; 11359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta case PART_DRAW_BB: 11459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta nameSuffix = 'B'; 11559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta break; 11659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta case PART_DRAW_OB: 11759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta case PART_DRAW_GR: 11859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta nameSuffix = 'P'; 11959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta LOGGER.warning("Neither object nor group particles supported yet! Using point representation instead!");//TODO: support groups and aobjects 12059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta break; 12159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta case PART_DRAW_LINE: 12259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta nameSuffix = 'L'; 12359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta LOGGER.warning("Lines not yet supported! Using point representation instead!");//TODO: support lines 12459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta default://all others are rendered as points in blender 12559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta nameSuffix = 'P'; 12659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 12759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta result = new ParticleEmitter(particleSettings.getName()+nameSuffix, Type.Triangle, totPart); 12859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if(nameSuffix=='N') { 12959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return result;//no need to set anything else 13059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 13159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 13259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //setting the emitters shape (the shapes meshes will be set later during modifier applying operation) 13359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int from = ((Number)particleSettings.getFieldValue("from")).intValue(); 13459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta switch(from) { 13559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta case PART_FROM_VERT: 13659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta result.setShape(new EmitterMeshVertexShape()); 13759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta break; 13859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta case PART_FROM_FACE: 13959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta result.setShape(new EmitterMeshFaceShape()); 14059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta break; 14159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta case PART_FROM_VOLUME: 14259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta result.setShape(new EmitterMeshConvexHullShape()); 14359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta break; 14459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta default: 14559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta LOGGER.warning("Default shape used! Unknown emitter shape value ('from' parameter: " + from + ')'); 14659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 14759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 14859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //reading acceleration 14959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta DynamicArray<Number> acc = (DynamicArray<Number>) particleSettings.getFieldValue("acc"); 15059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta result.setGravity(-acc.get(0).floatValue(), -acc.get(1).floatValue(), -acc.get(2).floatValue()); 15159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 15259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //setting the colors 15359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta result.setEndColor(new ColorRGBA(1f, 1f, 1f, 1f)); 15459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta result.setStartColor(new ColorRGBA(1f, 1f, 1f, 1f)); 15559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 15659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //reading size 15759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float sizeFactor = nameSuffix=='B' ? 1.0f : 0.3f; 15859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float size = ((Number)particleSettings.getFieldValue("size")).floatValue() * sizeFactor; 15959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta result.setStartSize(size); 16059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta result.setEndSize(size); 16159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 16259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //reading lifetime 16359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int fps = blenderContext.getBlenderKey().getFps(); 16459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float lifetime = ((Number)particleSettings.getFieldValue("lifetime")).floatValue() / fps; 16559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float randlife = ((Number)particleSettings.getFieldValue("randlife")).floatValue() / fps; 16659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta result.setLowLife(lifetime * (1.0f - randlife)); 16759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta result.setHighLife(lifetime); 16859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 16959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta //preparing influencer 17059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta ParticleInfluencer influencer; 17159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int phystype = ((Number)particleSettings.getFieldValue("phystype")).intValue(); 17259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta switch(phystype) { 17359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta case PART_PHYS_NEWTON: 17459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta influencer = new NewtonianParticleInfluencer(); 17559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta ((NewtonianParticleInfluencer)influencer).setNormalVelocity(((Number)particleSettings.getFieldValue("normfac")).floatValue()); 17659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta ((NewtonianParticleInfluencer)influencer).setVelocityVariation(((Number)particleSettings.getFieldValue("randfac")).floatValue()); 17759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta ((NewtonianParticleInfluencer)influencer).setSurfaceTangentFactor(((Number)particleSettings.getFieldValue("tanfac")).floatValue()); 17859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta ((NewtonianParticleInfluencer)influencer).setSurfaceTangentRotation(((Number)particleSettings.getFieldValue("tanphase")).floatValue()); 17959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta break; 18059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta case PART_PHYS_BOIDS: 18159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta case PART_PHYS_KEYED://TODO: support other influencers 18259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta LOGGER.warning("Boids and Keyed particles physic not yet supported! Empty influencer used!"); 18359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta case PART_PHYS_NO: 18459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta default: 18559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta influencer = new EmptyParticleInfluencer(); 18659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 18759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta result.setParticleInfluencer(influencer); 18859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 18959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return result; 19059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 19159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 19259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta @Override 19359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public boolean shouldBeLoaded(Structure structure, BlenderContext blenderContext) { 19459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return true; 19559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 19659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta} 197