system_emitter library
TODO lot of test (unit, ...) TODO benchmark, profiling, optimisation
Functions
Vector3GenInto cone({Vector3 apex, Vector3 axis, double angle: 0.0, double height: 10.0, double truncatedHeight: 0.0}) #
Vector3GenInto cone({Vector3 apex, Vector3 axis, double angle : 0.0, double height : 10.0, double truncatedHeight : 0.0} ){
apex = (apex == null) ? new Vector3.zero() : apex;
axis = (axis == null)? VY_AXIS : axis;
var _perp1 = perpendicular(axis);
var _perp2 = axis.cross( _perp1 ).normalize();
return (v, dt){
var h = _random.nextDouble();
h = truncatedHeight + ( 1 - h * h ) * ( height - truncatedHeight );
var r = _random.nextDouble();
var radiusAtHeight = math.tan( angle / 2 ) * h;
r = ( 1 - r * r ) * ( h ) * radiusAtHeight;
var a = _random.nextDouble() * 2 * math.PI;
var p1 = _perp1.clone();
p1.scale( r * math.cos( a ) );
var p2 = _perp2.clone();
p2.scale( r * math.sin( a ) );
return v.setFrom(axis)
.scale( h )
.add(p1)
.add(p2)
.add(apex)
;
};
}
Vector3 perpendicular(Vector3 v) #
Vector3 perpendicular(Vector3 v) {
if( v.x == 0 ) {
return new Vector3( 1.0, 0.0, 0.0 );
} else {
return new Vector3( v.y, -v.x, 0.0 ).normalize();
}
}
Vector3GenInto line(Vector3 start, Vector3 end, Ease easing) #
Vector3GenInto line(Vector3 start, Vector3 end, ease.Ease easing){
var length = end - start;
var acc = 0.0;
return (v, dt){
v.setFrom(length).scale(easing(acc, 1.0, 0)).add(start);
acc += dt;
return v;
};
}
Vector3GenInto box(Vector3 center, Vector3 offsets) #
Vector3GenInto box(Vector3 center, Vector3 offsets) => (v, dt){
v.setFrom(center);
v.x += (_random.nextDouble() - 0.5) * 2 * offsets.x;
v.y += (_random.nextDouble() - 0.5) * 2 * offsets.y;
v.z += (_random.nextDouble() - 0.5) * 2 * offsets.z;
return v;
};
Vector3GenInto constant(Vector3 x) #
always return a clone of x.
Vector3GenInto constant(Vector3 x) => (v, dt) => v.setFrom(x);
IntGen easingOverTime(Ease easing, num change, num baseValue) #
IntGen easingOverTime(ease.Ease easing, num change, num baseValue){
num _acc = 0.0;
return (dt){
_acc += dt;
return easing(_acc, change, baseValue).toInt();
};
}
IntGen steady(int rate) #
rate The number of particles to emit per second. TODO manage case where rate * dt < 1000
IntGen steady(int rate) {
num _acc = 0;
num _rateInv = (rate > 0)? 1000/rate : 0;
return (dt){
_acc += dt;
var b = ((rate * _acc) / 1000).round();
//print("${b * 1000/_acc} ---- ${b} --- ${_acc}");
_acc -= b * _rateInv;
return b;
};
}
Initializer particlesAddComponents(List<Function> fs) #
Initializer particlesAddComponents(List<Function> fs) => (dt, Entity emitter, List<Entity> es) {
es.forEach((e){
var ps = e.getComponent(Particles.CT) as Particles;
if (ps != null) {
fs.forEach((f) => e.addComponent(f(ps.length)));
}
});
};
Initializer addComponents(List<Function> fs) #
Initializer addComponents(List<Function> fs) => (dt, Entity emitter, List<Entity> es) {
es.forEach((e){
fs.forEach((f) => e.addComponent(f()));
});
};
Initializer particlesStartPositionPrevious(Vector3GenInto gen, bool fromEmitter) #
used to define a initial velocity if Verlet Simulator, also add Constraints Component should add after a Initializer that set position3d of particules
Initializer particlesStartPositionPrevious(Vector3GenInto gen, bool fromEmitter) => (dt, Entity emitter, List<Entity> es) {
var m4 = new Matrix4.identity();
if (fromEmitter) {
var tf = emitter.getComponent(Transform.CT) as Transform;
m4.rotateX(tf.rotation3d.x);
m4.rotateY(tf.rotation3d.y);
m4.rotateZ(tf.rotation3d.z);
}
processParticules(es, (ps, i) {
var v = gen(ps.position3dPrevious[i], dt);
v = m4.rotate3(v);
v.add(ps.position3d[i]);
});
};
Initializer particlesStartPosition(Vector3GenInto gen, bool fromEmitter) #
Initializer particlesStartPosition(Vector3GenInto gen, bool fromEmitter) => (dt, Entity emitter, List<Entity> es) {
var tf = emitter.getComponent(Transform.CT) as Transform;
var pos = tf.position3d;
processParticules(es, (ps, i) {
gen(ps.position3d[i], dt);
//print(p.position3d);
if (fromEmitter) ps.position3d[i].add(pos);
});
};
dynamic processParticules(List<Entity> es, f(Particules, i)) #
processParticules(List<Entity> es, f(Particules, i)) {
es.forEach((e) {
var ps = e.getComponent(Particles.CT) as Particles;
if (ps != null) {
//print("init on ${ps.l.length} particles");
for(var i = 0; i < ps.length; i++) {
f(ps, i);
}
}
});
}