提交 b15dd6ac 编写于 作者: V Viktor Lidholt

Merge pull request #273 from vlidholt/master

Optimizations for Particle Systems
......@@ -24,13 +24,11 @@ class ColorSequence {
colors = new List<Color>();
colorStops = new List<double>.from(sequence.colorStops);
math.Random rand = new math.Random();
for (Color color in sequence.colors) {
int aDelta = ((rand.nextDouble() * 2.0 - 1.0) * alphaVar).toInt();
int rDelta = ((rand.nextDouble() * 2.0 - 1.0) * redVar).toInt();
int gDelta = ((rand.nextDouble() * 2.0 - 1.0) * greenVar).toInt();
int bDelta = ((rand.nextDouble() * 2.0 - 1.0) * blueVar).toInt();
int aDelta = ((randomDouble() * 2.0 - 1.0) * alphaVar).toInt();
int rDelta = ((randomDouble() * 2.0 - 1.0) * redVar).toInt();
int gDelta = ((randomDouble() * 2.0 - 1.0) * greenVar).toInt();
int bDelta = ((randomDouble() * 2.0 - 1.0) * blueVar).toInt();
int aNew = (color.alpha + aDelta).clamp(0, 255);
int rNew = (color.red + rDelta).clamp(0, 255);
......
......@@ -80,8 +80,6 @@ class ParticleSystem extends Node {
// double _elapsedTime;
int _numEmittedParticles = 0;
math.Random _rand;
ParticleSystem(this.texture,
{this.life: 1.5,
this.lifeVar: 1.0,
......@@ -116,7 +114,6 @@ class ParticleSystem extends Node {
this.numParticlesToEmit: 0,
this.autoRemoveOnFinish: true}) {
_particles = new List<_Particle>();
_rand = new math.Random();
_emitCounter = 0.0;
// _elapsedTime = 0.0;
if (gravity == null) gravity = new Vector2.zero();
......@@ -124,6 +121,8 @@ class ParticleSystem extends Node {
}
void update(double dt) {
// TODO: Fix this (it's a temp fix for low framerates)
if (dt > 0.1) dt = 0.1;
// Create new particles
double rate = 1.0 / emissionRate;
......@@ -196,34 +195,34 @@ class ParticleSystem extends Node {
_Particle particle = new _Particle();
// Time to live
particle.timeToLive = math.max(life + lifeVar * randMinus1To1(), 0.0);
particle.timeToLive = math.max(life + lifeVar * randomSignedDouble(), 0.0);
// Position
Point srcPos = Point.origin;
particle.pos = new Vector2(srcPos.x + posVar.x * randMinus1To1(),
srcPos.y + posVar.y * randMinus1To1());
particle.pos = new Vector2(srcPos.x + posVar.x * randomSignedDouble(),
srcPos.y + posVar.y * randomSignedDouble());
// Size
particle.size = math.max(startSize + startSizeVar * randMinus1To1(), 0.0);
double endSizeFinal = math.max(endSize + endSizeVar * randMinus1To1(), 0.0);
particle.size = math.max(startSize + startSizeVar * randomSignedDouble(), 0.0);
double endSizeFinal = math.max(endSize + endSizeVar * randomSignedDouble(), 0.0);
particle.deltaSize = (endSizeFinal - particle.size) / particle.timeToLive;
// Rotation
particle.rotation = startRotation + startRotationVar * randMinus1To1();
double endRotationFinal = endRotation + endRotationVar * randMinus1To1();
particle.rotation = startRotation + startRotationVar * randomSignedDouble();
double endRotationFinal = endRotation + endRotationVar * randomSignedDouble();
particle.deltaRotation = (endRotationFinal - particle.rotation) / particle.timeToLive;
// Direction
double dirRadians = convertDegrees2Radians(direction + directionVar * randMinus1To1());
double dirRadians = convertDegrees2Radians(direction + directionVar * randomSignedDouble());
Vector2 dirVector = new Vector2(math.cos(dirRadians), math.sin(dirRadians));
double speedFinal = speed + speedVar * randMinus1To1();
double speedFinal = speed + speedVar * randomSignedDouble();
particle.dir = dirVector.scale(speedFinal);
// Radial acceleration
particle.radialAccel = radialAcceleration + radialAccelerationVar * randMinus1To1();
particle.radialAccel = radialAcceleration + radialAccelerationVar * randomSignedDouble();
// Tangential acceleration
particle.tangentialAccel = tangentialAcceleration + tangentialAccelerationVar * randMinus1To1();
particle.tangentialAccel = tangentialAcceleration + tangentialAccelerationVar * randomSignedDouble();
// Color
particle.colorPos = 0.0;
......@@ -248,7 +247,7 @@ class ParticleSystem extends Node {
double scos;
double ssin;
if (rotateToMovement) {
double extraRotation = math.atan2(particle.dir[1], particle.dir[0]);
double extraRotation = GameMath.atan2(particle.dir[1], particle.dir[0]);
scos = math.cos(convertDegrees2Radians(particle.rotation) + extraRotation) * particle.size;
ssin = math.sin(convertDegrees2Radians(particle.rotation) + extraRotation) * particle.size;
} else {
......@@ -275,10 +274,7 @@ class ParticleSystem extends Node {
Paint paint = new Paint()..setTransferMode(transferMode)
..setFilterQuality(FilterQuality.low) // All Skia examples do this.
..isAntiAlias = false; // Antialiasing breaks SkCanvas.drawAtlas?
return canvas.drawAtlas(texture.image, transforms, rects, colors,
canvas.drawAtlas(texture.image, transforms, rects, colors,
TransferMode.modulate, null, paint);
}
double randMinus1To1() => _rand.nextDouble() * 2.0 - 1.0;
}
......@@ -7,6 +7,7 @@ library sprites;
import 'dart:async';
import 'dart:convert';
import 'dart:math' as math;
import 'dart:typed_data';
import 'dart:sky';
import 'package:sky/animation/curves.dart';
......
part of sprites;
math.Random _random = new math.Random();
// Random methods
double randomDouble() {
return _random.nextDouble();
}
double randomSignedDouble() {
return _random.nextDouble() * 2.0 - 1.0;
}
int randomInt(int max) {
return _random.nextInt(max);
}
// atan2
class _Atan2Constants {
_Atan2Constants() {
for (int i = 0; i <= size; i++) {
double f = i.toDouble() / size.toDouble();
ppy[i] = math.atan(f) * stretch / math.PI;
ppx[i] = stretch * 0.5 - ppy[i];
pny[i] = -ppy[i];
pnx[i] = ppy[i] - stretch * 0.5;
npy[i] = stretch - ppy[i];
npx[i] = ppy[i] + stretch * 0.5;
nny[i] = ppy[i] - stretch;
nnx[i] = -stretch * 0.5 - ppy[i];
}
}
static const int size = 1024;
static const double stretch = math.PI;
static const int ezis = -size;
final Float64List ppy = new Float64List(size + 1);
final Float64List ppx = new Float64List(size + 1);
final Float64List pny = new Float64List(size + 1);
final Float64List pnx = new Float64List(size + 1);
final Float64List npy = new Float64List(size + 1);
final Float64List npx = new Float64List(size + 1);
final Float64List nny = new Float64List(size + 1);
final Float64List nnx = new Float64List(size + 1);
}
class GameMath {
static final _Atan2Constants _atan2 = new _Atan2Constants();
static double atan2(double y, double x) {
if (x >= 0) {
if (y >= 0) {
if (x >= y)
return _atan2.ppy[(_Atan2Constants.size * y / x + 0.5).floor()];
else
return _atan2.ppx[(_Atan2Constants.size * x / y + 0.5).floor()];
} else {
if (x >= -y)
return _atan2.pny[(_Atan2Constants.ezis * y / x + 0.5).floor()];
else
return _atan2.pnx[(_Atan2Constants.ezis * x / y + 0.5).floor()];
}
} else {
if (y >= 0) {
if (-x >= y)
return _atan2.npy[(_Atan2Constants.ezis * y / x + 0.5).floor()];
else
return _atan2.npx[(_Atan2Constants.ezis * x / y + 0.5).floor()];
} else {
if (x <= y)
return _atan2.nny[(_Atan2Constants.size * y / x + 0.5).floor()];
else
return _atan2.nnx[(_Atan2Constants.size * x / y + 0.5).floor()];
}
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册