FX Builder (I apparently trashed the thread... sorry)

A new place to post questions, issue and fixes. If I missed something from before, as things have been a bit of a blur the last month or so, please do repost it here so I don’t completely miss it!

Bare with me today… just got out of surgery about 30-40 minutes ago and I am all sorts of f’d up atm.

@ghoust Could you repost the fix from the other thread and I won’t quote it this time =)

(just an aside: Is that what’s messing up threads? Code quotes? )

@foxhavendesigns said: (just an aside: Is that what's messing up threads? Code quotes? )

The 3 times it’s happened to me have been after quoting larger posts containing code blocks, yes.

@t0neg0d I had trouble to getting the standard read write support up and running. So I improved it (so I hope).
At least it works for my fire example to save out as a j3o and load as a j3o. Any reason you did not derive Emitter from AbstractControl?

But to get this going I had to set the asset manager for the binary importer, is there a better way of doing this?
[java]
BinaryExporter.getInstance().save(n, new File(“spriteflames.j3o”));
BinaryImporter bim = BinaryImporter.getInstance();
bim.setAssetManager(assetManager);
Node nn = (Node) bim.load(new File(“spriteflames.j3o”));
[/java]

in write Add spatial saving :
[java]
public void write(JmeExporter ex) throws IOException {
OutputCapsule oc = ex.getCapsule(this);
oc.writeSavableArrayList(new ArrayList(influencers), “influencers”, null);

	oc.write(name, "name", null);
	oc.write(spatial, "spatial", null);

[/java]

and here is the working read, reworked to only call setters where needed, not fully optimized (see the lower part with the many if’s), and the crucial spatial.addControl():

[java]
@Override
public void read(JmeImporter im) throws IOException {
InputCapsule ic = im.getCapsule(this);
name = ic.readString(“name”, generateName());
spatial = (Spatial) ic.readSavable(“spatial”, null);
maxParticles = ic.readInt(“maxParticles”, 30);//needed here as initparticles relies on maxParticles

	userDefinedMat = (Material)ic.readSavable("userDefinedMat", null);
	testMat = (Material)ic.readSavable("testMat", null);
	mat = (Material)ic.readSavable("mat", null);
	tex = (Texture) ic.readSavable("tex", null);
	applyLightingTransform = ic.readBoolean("applyLightingTransform", false);
	uniformName = ic.readString("uniformName", null);

	// Emitter animation
	esAnimName = ic.readString("esAnimName", "");
	esAnimSpeed = ic.readFloat("esAnimSpeed", 1);
	esAnimBlendTime = ic.readFloat("esAnimBlendTime", 1);
	Mesh emitterShapeMesh = (Mesh)ic.readSavable("emitterShape", new TriangleEmitterShape(1));
	if(emitterShapeMesh != null){
		emitterShape.setShape(this, emitterShapeMesh);
	}
	esAnimNode = (Node)ic.readSavable("esAnimNode", null);
	esNodeExists = ic.readBoolean("esNodeExists", true);
	esAnimLoopMode = LoopMode.valueOf(ic.readString("esAnimLoopMode", LoopMode.Loop.name()));

	if (esAnimNode != null) {
		setShape(esAnimNode, this.esNodeExists);
		setEmitterAnimation(esAnimName, esAnimSpeed, esAnimBlendTime, esAnimLoopMode);
	} else
		setShape(emitterShape.getMesh());
	
	try {
		particleType = Class.forName(ic.readString("particleType", ParticleDataTriMesh.class.getName()));
	} catch (IOException | ClassNotFoundException ex) {
		particleType = ParticleDataTriMesh.class;
	}
	ptAnimNode = (Node)ic.readSavable("ptAnimNode", null);
	// Particle animation
	ptAnimName = ic.readString("ptAnimName", "");
	ptAnimSpeed = ic.readFloat("ptAnimSpeed", 1);
	ptAnimBlendTime = ic.readFloat("ptAnimBlendTime", 1);
	ptAnimLoopMode = LoopMode.valueOf(ic.readString("ptAnimLoopMode", LoopMode.Loop.name()));
	template = (Mesh)ic.readSavable("template", null);
	if (ptAnimNode != null) {
		setParticleType(particleType, ptAnimNode);
		setParticleAnimation(ptAnimName, ptAnimSpeed, ptAnimBlendTime, ptAnimLoopMode);
	} else
		setParticleType(particleType, template);
	
	String ip = ic.readString("interpolation", null);
	if(ip != null){
		interpolation = Interpolation.getInterpolationByName(ip); 
	} else {
		interpolation = Interpolation.linear;
	}
	
	forceMin = ic.readFloat("forceMin", .15f);
	forceMax = ic.readFloat("forceMax", .5f);
	lifeMin = ic.readFloat("lifeMin", 0.999f);
	lifeMax = ic.readFloat("lifeMax", 0.999f);
	emissionsPerSecond = ic.readInt("emissionsPerSecond", 20);
	setEmissionsPerSecond(emissionsPerSecond);
	particlesPerEmission = ic.readInt("particlesPerEmission", 1);
	setParticlesPerEmission(particlesPerEmission);

	useRandomEmissionPoint = ic.readBoolean("useRandomEmissionPoint", false);
	useSequentialEmissionFace = ic.readBoolean("useSequentialEmissionFace", false);
	useSequentialSkipPattern = ic.readBoolean("useSequentialSkipPattern", false);
	particlesFollowEmitter = ic.readBoolean("particlesFollowEmitter", false);
	useStaticParticles = ic.readBoolean("useStaticParticles", false);
	velocityStretchFactor = ic.readFloat("velocityStretchFactor", 0.35f);
	useVelocityStretching = ic.readBoolean("useVelocityStretching", false);
	stretchAxis = ForcedStretchAxis.valueOf(ic.readString("stretchAxis", ForcedStretchAxis.Y.name()));
	particleEmissionPoint = ParticleEmissionPoint.valueOf(ic.readString("particleEmissionPoint", ParticleEmissionPoint.Particle_Center.name()));
	billboardMode = BillboardMode.valueOf(ic.readString("billboardMode", BillboardMode.Camera.name()));
	directionType = DirectionType.valueOf(ic.readString("directionType", EmitterMesh.DirectionType.Random.name()));
	TEST_EMITTER = ic.readBoolean("TEST_EMITTER", false);
	TEST_PARTICLES = ic.readBoolean("TEST_PARTICLES", false);
	
	influencers = new SafeArrayList<ParticleInfluencer>(ParticleInfluencer.class, ic.readSavableArrayList("influencers", null));

// particleNode.setMaterial(mat);

	initParticles(particleType, template);

// userDefinedMat = (Material)ic.readSavable(“userDefinedMat”, null);
// mat = userDefinedMat;
// applyLightingTransform = ic.readBoolean(“applyLightingTransform”, false);
// uniformName = ic.readString(“uniformName”, null);

	texturePath = ic.readString("texturePath", null);
	spriteWidth = ic.readFloat("spriteWidth", 50);
	spriteHeight = ic.readFloat("spriteHeight", 50);
	spriteCols = ic.readInt("spriteCols", 1);
	spriteRows = ic.readInt("spriteRows", 1);

	mesh.setImagesXY(spriteCols,spriteRows);

// setSprite(texturePath, spriteCols, spriteRows);
enabled = ic.readBoolean(“enabled”, false);

	if (esAnimControl != null) {
		if (!esAnimName.equals("")) {
			esAnimChannel.setAnim(esAnimName, esAnimBlendTime);
			esAnimChannel.setSpeed(esAnimSpeed);
		}
	}

	if (ptAnimControl != null) {
		if (!ptAnimName.equals("")) {
			ptAnimChannel.setAnim(ptAnimName, ptAnimBlendTime);
			ptAnimChannel.setSpeed(ptAnimSpeed);
		}
	}
	
	if (particleNode.getChildren().isEmpty()) {
		Geometry geom = new Geometry();
		geom.setMesh(mesh);
		particleNode.attachChild(geom);
		particleNode.setMaterial(mat);
		particleNode.setQueueBucket(RenderQueue.Bucket.Transparent);
	}
	
	if (emitterTestNode.getChildren().isEmpty()) {
		Geometry testGeom = new Geometry();
		testGeom.setMesh(emitterShape.getMesh());
		emitterTestNode.attachChild(testGeom);
		emitterTestNode.setMaterial(testMat);
	}
	if (particleTestNode.getChildren().isEmpty()) {
		Geometry testPGeom = new Geometry();
		testPGeom.setMesh(mesh);
		particleTestNode.attachChild(testPGeom);
		particleTestNode.setMaterial(testMat);
	}
	emitterInitialized = true;
	if(spatial != null )
		spatial.addControl(this);

// initialize(assetManager);
// setEnabled(enabled);
}
[/java]

2 Likes

I also noticed while loading saved effects that the write method of the Emitter class is lacking the stretch enabling:
[java]
oc.write(useVelocityStretching,“useVelocityStretching”, false);

[/java]
I put it right after oc.write(velocityStretchFactor, “velocityStretchFactor”, 0.35f);

1 Like

And by the way take your time, I will be just sharing what I found out on my way through your code.

The read method was rebuilt from scratch, have not tested it so far if it really works with animations and custom meshes.

The clone method could use a fixup too.

OK,… guess it is wiser to send you the patch file rather than posting bits here and bits there…

@ghoust said: And by the way take your time, I will be just sharing what I found out on my way through your code.

The read method was rebuilt from scratch, have not tested it so far if it really works with animations and custom meshes.

The clone method could use a fixup too.

OK,… guess it is wiser to send you the patch file rather than posting bits here and bits there…

I soooo suck at keeping up with the read/write and clone methods as I am developing something. The big reason the read/write stuff has issues is I have next to no clue what I am doing with these. It’s no surprise I missed the velocity stretching flag >.<

I’m really close to finishing up my first Android project for the 2D framework portion of the gui library (most of the hold up is Google Play Services and Facebook integration which I may just give up on for now and look at it again after releasing the game. I’ve wanted to claw my eyes out several times working on this) Once this is finished up, I’ll be jumping back to this (which means updates for the gui library as well of course) and will get your updates in.

Apparently, before I took a break from working on this, I broke the file preview for rotating/zooming 3D models. I’ll need to fix this as well prior to pushing out an update.

How can i get the code of the effect i built using your FX Builder, do i have to convert from the saved XML to Java language (which is what i already did).

@JacobAmaral said: How can i get the code of the effect i built using your FX Builder, do i have to convert from the saved XML to Java language (which is what i already did).

Atm, this is the case. When I am able to get back to this, I’ll update the output to spit out the Java code for you.

@t0neg0d said: Atm, this is the case. When I am able to get back to this, I'll update the output to spit out the Java code for you.
That would be a cool feature, I know life can get busy.
1 Like