2.0.2 • Published 4 years ago

neutrinoparticles.js v2.0.2

Weekly downloads
248
License
ISC
Repository
gitlab
Last release
4 years ago

neutrinoparticles.js

The library allows you to load and simulate particle effects exported from NeutrinoParticles Editor.

This is basically a core library which can update particle effect and give you instructions on how to render this effect.

Available integrations

Below is a list of addons for most popular engines/frameworks. These addons provide integrated renderers for neutrinoparticles.js.

neutrinoparticles.pixiFull integration. Supports PIXI.js v4 and v5.
neutrinoparticles.phaserFull integration. Supports Phaser3 only.

Installation

You can install the package with npm:

> npm install neutrinoparticles.js

Or download pre-built package at Releases page. There are UMD packages which you can use in any environment.

Introduction

NeutrinoParticles Editor exports effect to .js file. This file contains a class of the effect with all algorithms and data necessary to simulate it. This class is a model of effect. The model is constant object, and you need only one model to have many instances of this effect in your application.

This library contains shared code which exported effects use. In particular, mathematics, turbulence computations etc.

To use the library in your application, first of all, you need to get access to it. Depending on your environment:

  • HTML
<script src="path/to/neutrinoparticles.js/dist/neutrinoparticles.umd.js"></script>
  • node.js
var Neutrino = require('neutrinoparticles.js')
  • ES6
import * as Neutrino from 'neutrinoparticles.js'

Main Context

Main context is a main interface of the library and a shared object for all effects in the application.

To create it:

let neutrino = new Neutrino.Context();

Loading effect model

Files of effects exported by the Editor has to be evaluated to obtain JS objects that can be used in the application.

You can load effect model using main context. It will use HTTP request to load effect by path. And in this case it will make all evaluating by itself and return you ready to use object:

neutrino.loadEffect('path/to/effect.js', function(effectModel) {
    // on success
  },
  function() {
    // on fail
  });

Or you can somehow load effect file by yourself (or unpack from zip, for example), and when you have a text of the file you can use this simple evaluating function:

function evalEffectModel(effectSource) {
  let wrappedScript =
    "(function(context) {\n" +
	    effectSource +"\n" +
	    "return new NeutrinoEffect(ctx);\n" +
	  "})(neutrino);";
  return eval(wrappedScript);
}

Creating effect instances

When the effect model is loaded, you can create instances of this effect. Each instance is actual entity of effect. It is a state of effect. It has position, rotation and it can be updated (simulated) by time.

Depending on what kind of rendering you want to perform, you can create an instance for:

Canvas rendering:

let effect = effectModel.createCanvas2DInstance(
	position,                   // Array [x, y, z] for starting position of the effect
	rotation,                   // Array [x, y, z, w] for quaternion representing starting rotation
	{                           // options
	  paused: false,            // Effect paused on start?
	  generatorsPaused: false   // Generators of the effect paused on start?
  });

or WebGL rendering:

let effect = effectModel.createWGLInstance(
	position,
	rotation,
	renderBuffer, // Buffer to accept constructed geometry for particles
	options
);

Updating effect

You would probably want to update the effect on each frame of your application. And on each update you can set up new position and rotation of the effect:

effect.update(
	timeInSeconds, // time to simulate
	position,      // (optional) new position, if changed
	rotation       // (optional) new rotation, if changed
);

Rendering effect

Rendering of effect is out of scope of this library. This is because any graphical framework or engine requires custom deep integration and there is no any unified solution.

However, you can find reference renderers in /samples folder of the repository. There are Canvas and WebGL renderers. They are designed for clean HTML5 environment and can be used as standalone renderers on a web site. Or you can refer to them for creating a custom renderer for your graphical framework.

For PIXI.js you can use neutrinoparticles.pixi.js renderer.

Position and Rotation

Effects accept position and rotation on creating and update.

Position vector is represented by 3D array x, y, z.

Rotation is a quaternion represented by 4D array x, y, z, w.

You can make a rotation quaternion by function:

neutrino.axisangle2quat_(
  [x, y, z], // rotation axis
  angle			 // rotation angle in degrees
);

it will make a quaternion by rotating arout an axis.

To react on rotation, effect has to be correcly prepared in the Editor. See "Apply emitter's rotation" switch in Emitter Guide in the Editor.

Using turbulence (or noise)

You need to initialize noise texture before simulating effects which use it. Otherwise, your effects will be without any noise (or turbulence).

You have two options to make that: to generate or to download it.

Generating noise

Generating noise is iterative process and you can spread it for many application frames (to render some progress bar, for example).

Below is an example function that generates the noise in one loop:

function generateNoise() {
  let noiseGenerator = new neutrino.NoiseGenerator();
  while (!noiseGenerator.step()) { // approx. 5,000 steps
  	// you can use 'noiseGenerator.progress' to get generating progress from 0.0 to 1.0
  }
}

Of course, this function will block execution of the script until finished. So, it's up to you how to make it executed over many frames if necessary.

On modern devices (and mobile as well) above function will be finished in up to 2 seconds.

Please, pay attention to NoiseGenerator object. It has to be out of scope after noise is generated to allow GC to free allocated memory.

Download noise

In case you don't want to generate noise texture for a some reason, you can distribute it pre-computed in a binary file with your application. This file is /bin/neutrinoparticles.noise.bin in the repository.

Then download and initialize with:

neutrino.initializeNoise(
	"/path/to/noise/directory/",  // path to a directory where "neutrinoparticles.noise.bin" is located
	function() {},                // success callback
	function() {},                // fail callback
);

HTTP request will be used to download the file. It's size is 768Kb.

Restart effect

To completely restart the effect:

effect.restart(
	[x, y, z],   // (optional) new position, if changed
	[x, y, z, w] // (optional) new rotation, if changed
);

Instant effect position change (teleporting)

When you move your effect by changing it's position or rotation on each update, the effect is moved linearly. And even if it tightly generates particles, there will be a trail of particles from previous frame position to the new one.

In case, you want to change position instantly (teleport it), you need to reset position:

effect.resetPosition(
  [x, y, z], // new effect's position (pass null if you don't want to reset position)
  [x, y, z, w] // new effect's rotation quaternion (pass null if you don't want to reset rotation)
);

Number of particles

You can request total number of alive particles in topmost emitters (not attached to other emitters):

let numParticles = effect.getNumParticles();

Or request number of particles in a single emitter by name (note underscore before name):

let numEmitterParticles = effect._YourEmitterName.getNumParticles();

Using pause

There are two different kinds of pause for effect:

  1. Pause for whole effect. When all particles freeze and nothing else is generated:

    effect.pauseAllEmitters();
    ...
    let isPaused = effect.areAllEmittersPaused();
    ...
    effect.unpauseAllEmitters();
  2. Generators pause. When already generated particles continue to live but new particles are not generated:

    effect.pauseGeneratorsInAllEmitters();
    ...
    let isGeneratorsPaused = effect.areGeneratorsInAllEmittersPaused();
    ...
    effect.unpauseGeneratorsInAllEmitters();

Changing emitter's properties

You can control exposed emitter properties from your application. Any emitter property added on Emitter Scheme or Emitter Guide in the Editor is exposed in exported effect.

To change properties in a single emitter, you can access them directly from effect instance (note underscores before names):

effect._EmitterName._YourFloatPropertyName = 10;
effect._EmitterName._YourVector2PropertyName = [10, 20];
effect._EmitterName._YourVector3PropertyName = [10, 20, 30];
effect._EmitterName._YourRotationPropertyName = neutrino.axisangle2quat_([0, 1, 0], 45);

To change properties with a given names for all topmost emitters:

effect.setPropertyInAllEmitters("YourFloatPropertyName", 10);
effect.setPropertyInAllEmitters("YourVector2PropertyName", [10, 20]);
effect.setPropertyInAllEmitters("YourVector3PropertyName", [10, 20, 30]);
effect.setPropertyInAllEmitters("YourRotationPropertyName", neutrino.axisangle2quat_([0, 1, 0], 45));

For example, to control particles generating rate from your application: 1. In the Editor, in Emitter Guide window, in Generation section change type of Periodic rate to Emitter property

EmitterProps1

  1. Set up property name to MyParticlesPerSecond

    EmitterProps2

  2. From Emitters window remember emitter name to access your property

    EmitterProps3

  3. Export effect, and after loading in your application you can change the property:

    effect._DefaultEmitter._MyParticlesPerSecond = 100;
2.0.2

4 years ago

2.0.1

4 years ago

2.0.0

4 years ago

1.0.4

5 years ago

1.0.3

5 years ago

1.0.2

5 years ago

1.0.1

5 years ago

1.1.0

5 years ago

1.0.0

6 years ago