From a0b0e139db4cfa13664b3fd06e52e6c8a9e16a21 Mon Sep 17 00:00:00 2001 From: Viktor Lidholt Date: Thu, 6 Aug 2015 13:24:29 -0700 Subject: [PATCH] Adds test for measuring computation speed in game like conditions --- .../game/test_performance_computation.dart | 309 ++++++++++++++++++ 1 file changed, 309 insertions(+) create mode 100644 packages/flutter/example/game/test_performance_computation.dart diff --git a/packages/flutter/example/game/test_performance_computation.dart b/packages/flutter/example/game/test_performance_computation.dart new file mode 100644 index 0000000000..ff6c99ecb3 --- /dev/null +++ b/packages/flutter/example/game/test_performance_computation.dart @@ -0,0 +1,309 @@ +import 'dart:math' as math; +import 'dart:typed_data'; + +import 'package:vector_math/vector_math.dart'; + +main() { + runTest(); +} + +const int numSystems = 1000; +const int numFrames = 100; + +void runTest() { + int timeStart; + timeStart = new DateTime.now().millisecondsSinceEpoch; + + // Create systems + List systems = []; + for (int i = 0; i < numSystems; i++) { + systems.add(new TestParticleSystem()); + } + + int timeAfterCreate = new DateTime.now().millisecondsSinceEpoch; + print("TIME creation ${(timeAfterCreate - timeStart) / 1000.0}"); + timeStart = new DateTime.now().millisecondsSinceEpoch; + + // Update systems + for (int frame = 0; frame < numFrames; frame++) { + for (int i = 0; i < numSystems; i++) { + systems[i].update(1.0 / 60.0); + } + } + + int timeAfterUpdates = new DateTime.now().millisecondsSinceEpoch; + print("TIME updates ${(timeAfterUpdates - timeStart) / 1000.0}"); + timeStart = new DateTime.now().millisecondsSinceEpoch; + + // Calculate matrices + for (int frame = 0; frame < numFrames; frame++) { + for (int i = 0; i < numSystems; i++) { + systems[i].paint(); + } + } + + int timeAfterMatrices = new DateTime.now().millisecondsSinceEpoch; + print("TIME matrices ${(timeAfterMatrices - timeStart) / 1000.0}"); +} + +class TestParticle { + Vector2 pos; + Vector2 startPos; + + double colorPos; + double deltaColorPos; + + double size; + double deltaSize; + + double rotation; + double deltaRotation; + + double timeToLive; + + Vector2 dir; + + double radialAccel; + double tangentialAccel; + + Float64List simpleColorSequence; + + Matrix4 transform; +} + +class TestParticleSystem { + double life; + double lifeVar; + + Vector2 posVar; + + double startSize; + double startSizeVar; + + double endSize; + double endSizeVar; + + double startRotation; + double startRotationVar; + + double endRotation; + double endRotationVar; + + double direction; + double directionVar; + + double speed; + double speedVar; + + double radialAcceleration; + double radialAccelerationVar; + + double tangentialAcceleration; + double tangentialAccelerationVar; + + Vector2 gravity; + + int maxParticles; + int numParticlesToEmit; + double emissionRate; + + List _particles; + + double _emitCounter; + int _numEmittedParticles = 0; + + TestParticleSystem({this.life: 1.5, + this.lifeVar: 0.0, + this.startSize: 2.5, + this.startSizeVar: 0.5, + this.endSize: 0.0, + this.endSizeVar: 0.0, + this.startRotation: 0.0, + this.startRotationVar: 0.0, + this.endRotation: 0.0, + this.endRotationVar: 0.0, + this.direction: 0.0, + this.directionVar: 360.0, + this.speed: 100.0, + this.speedVar: 50.0, + this.radialAcceleration: 0.0, + this.radialAccelerationVar: 0.0, + this.tangentialAcceleration: 0.0, + this.tangentialAccelerationVar: 0.0, + this.gravity, + this.maxParticles: 100, + this.emissionRate: 50.0, + this.numParticlesToEmit: 0}) { + posVar = new Vector2.zero(); + _particles = new List(); + _emitCounter = 0.0; + gravity = new Vector2.zero(); + } + + void update(double dt) { + // Create new particles + double rate = 1.0 / emissionRate; + + if (_particles.length < maxParticles) { + _emitCounter += dt; + } + + while(_particles.length < maxParticles + && _emitCounter > rate + && (numParticlesToEmit == 0 || _numEmittedParticles < numParticlesToEmit)) { + // Add a new particle + _addParticle(); + _emitCounter -= rate; + } + + // Iterate over all particles + for (int i = _particles.length -1; i >= 0; i--) { + TestParticle particle = _particles[i]; + + // Manage life time + particle.timeToLive -= dt; + if (particle.timeToLive <= 0) { + _particles.removeAt(i); + continue; + } + + // Update the particle + + // Radial acceleration + Vector2 radial; + if (particle.pos[0] != 0 || particle.pos[1] != 0) { + radial = new Vector2.copy(particle.pos).normalize(); + } else { + radial = new Vector2.zero(); + } + Vector2 tangential = new Vector2.copy(radial); + radial.scale(particle.radialAccel); + + // Tangential acceleration + double newY = tangential.x; + tangential.x = -tangential.y; + tangential.y = newY; + tangential.scale(particle.tangentialAccel); + + // (gravity + radial + tangential) * dt + Vector2 accel = (gravity + radial + tangential).scale(dt); + particle.dir += accel; + + // Update particle position + particle.pos[0] += particle.dir[0] * dt; + particle.pos[1] += particle.dir[1] * dt; + + // Size + particle.size = math.max(particle.size + particle.deltaSize * dt, 0.0); + + // Angle + particle.rotation += particle.deltaRotation * dt; + + // Color + if (particle.simpleColorSequence != null) { + for (int i = 0; i < 4; i++) { + particle.simpleColorSequence[i] += particle.simpleColorSequence[i + 4] * dt; + } + } else { + particle.colorPos = math.min(particle.colorPos + particle.deltaColorPos * dt, 1.0); + } + } + } + + void _addParticle() { + + TestParticle particle = new TestParticle(); + + // Time to live + particle.timeToLive = math.max(life + lifeVar * randomSignedDouble(), 0.0); + + // Position + Vector2 srcPos = new Vector2.zero(); + particle.pos = new Vector2(srcPos.x + posVar.x * randomSignedDouble(), + srcPos.y + posVar.y * randomSignedDouble()); + + // Size + 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 * randomSignedDouble(); + double endRotationFinal = endRotation + endRotationVar * randomSignedDouble(); + particle.deltaRotation = (endRotationFinal - particle.rotation) / particle.timeToLive; + + // Direction + double dirRadians = radians(direction + directionVar * randomSignedDouble()); + Vector2 dirVector = new Vector2(math.cos(dirRadians), math.sin(dirRadians)); + double speedFinal = speed + speedVar * randomSignedDouble(); + particle.dir = dirVector.scale(speedFinal); + + // Radial acceleration + particle.radialAccel = radialAcceleration + radialAccelerationVar * randomSignedDouble(); + + // Tangential acceleration + particle.tangentialAccel = tangentialAcceleration + tangentialAccelerationVar * randomSignedDouble(); + + // Colors + particle.simpleColorSequence = new Float64List(8); + particle.simpleColorSequence[0] = 255.0; + particle.simpleColorSequence[1] = 255.0; + particle.simpleColorSequence[2] = 255.0; + particle.simpleColorSequence[3] = 255.0; + + particle.simpleColorSequence[4] = 255.0; + particle.simpleColorSequence[5] = 0.0; + particle.simpleColorSequence[6] = 0.0; + particle.simpleColorSequence[7] = 0.0; + + // Transform + particle.transform = new Matrix4.identity(); + + // Add particle + _particles.add(particle); + _numEmittedParticles++; + } + + + void paint() { + + if (!printed) { + printed = true; + } + + for (int i = _particles.length -1; i >= 0; i--) { + TestParticle particle = _particles[i]; + particle.rotation + randomSignedDouble(); + + // Transform + double c = math.cos(radians(particle.rotation)); + double s = math.sin(radians(particle.rotation)); + + // Create transformation matrix for scale, position and rotation + Matrix4 matrix = new Matrix4(c * particle.size, s * particle.size, 0.0, 0.0, + -s * particle.size, c * particle.size, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + particle.pos.x, particle.pos.y, 0.0, 1.0); + + particle.transform.multiply(matrix); + } + } +} + +math.Random _random = new math.Random(); + +bool printed = false; + +// Random methods + +double randomDouble() { + return _random.nextDouble(); +} + +double randomSignedDouble() { + return _random.nextDouble() * 2.0 - 1.0; +} + +int randomInt(int max) { + return _random.nextInt(max); +}