Misc offerings for the mainline

I have a few changes to JME3 code that I think might be of general interest. it would certainly be in my interest to not be relying on forked code for too long.

  1. I altered AudioNode so that a single one could be used to play successive assets. The stock implementation does not seem to allow a Node to be loaded with another asset after it finishes playing, which is inefficient for apps like mine that play concatenated speech files a LOT. With very little additional work, the free pool and factory method I am using externally could also be moved into AudioNode. The goal, of course, is to permit the creation of the fewest possible objects and to provide a small savings in 3D calculation. I had to make these changes “in place” due to access restrictions in AudioNode.java and to its intimate relationship to LwjglAudioRenderer.java

  2. I made a wider variety of changes to ParticleEmitter.java, primarily to improve consistency and to help enable more realistic smoke effects in an outdoor environment:
    a. changed default gravity to Vector3f.ZERO
    b. added a wind vector. when non-null, wind will affect this emitter’s particles in concert with …
    c. added float windDrag, which affects how rapidly particles take up the wind’s influence –
    d. added startColor2 and endColor2. When non-null, the end points of a particle’s color transition have a range of values rather than a single one
    e. added boolean chaoticColors. When true, each particle selects independent startColor and endColor pairs within the specified ranges. Else, the starting color value and ending color value will lie at the same proportional but random value within their given range
    f. added floats startSize2 and endSize2. When set to a value other than the default Float.NaN, these permit similar variability in size range for each particle
    g. altered behavior of gravity so it no longer operates BACKWARD (e.g., gravity with a -Y component should mean that they fall down, yes?). I’d make sure that old objects write() and read() into conformity.
    h. added a static method to translate all active particles in the world space by a given offset. I use because I occasionally re-home my top level objects to shove my camera back to the world origin so I can reliably render fine geometry near the camera and also coarse geometry far away without undue Z fighting (my game is a naval sim with a first person perspective-- smoke, handheld devices and ships 30,000m away abound!).

  1. Normen started a rewrite of the audio system, not sure how your changes would fit in there. Normen will have to answer.

  2. Very interesting but that’s a lot of breaking changes…
    a. breaks code relying on the fact that the default is 1.
    b.c. d. e. f. interesting, but we’d really need a generic implementation to influence particles over time. The ParticleInfluencer implementation doesn’t go far enough IMO, because it only gives an impulse to a particle when it’s emitted…It should influence it as long as it’s alive. Users could make their own influencers (they already do btw) and you could add your wind behavior.
    g. Well…gravity is a force applied downward, if you consider this, the current behavior is consistent… But I get your logic. What bothers me is that’s a breaking change.
    h.How does the API looks like for this. This could be included in the actual ParticleEmitter class.

Does all this works on android?

EDIT : do you have a screenshot or a video of what this changes produces on the smoke effect?

Regarding number 1, I wonder why use AudioNode at all. It seems like just a convenience wrapper for a single piece of AudioData. Once you start plugging your own in then I wonder what it’s providing over just using the AudioData and AudioRenderer directly.

I did not understand all the magic of how AudioNode was loading audio data, and I wanted to leverage its presumed handling of things I did not care to break or reinvent.

Essentially, all I needed it to do was have an additional method that would permit me to have an AudioNode (with status == Stopped) set its audio data outside of the constructor. My risk was minimal this way and I retained the 3D positioning of AudioNode.

I actually implemented my cuing of the next files externally in a wrapper class, as I also did the free pool and (not mentioned above) an external framework to implement a finite speed-of-sound to separate logical sound trigger from sound playback – I did not want distant explosions to sound the moment they occurred, but only when their sound had reached the listener’s ear…


Sounds cool. (pun intended) :slight_smile:

I already separated this logic, there is now an “AudioSource”, AudioNode is one too.