//---------------------------------------------------- // run the physics for all the particles //---------------------------------------------------- private void simulateParticlesCPU(float deltaTime) { if (_useMultithreading) { if (_parallelForeach == null) { _parallelForeach = new ParallelForeach((a, b) => particleSimulationLogic(a, b, deltaTime)); } _parallelForeach.Dispatch(NUM_PARTICLES); _parallelForeach.Wait(); } else { particleSimulationLogic(0, NUM_PARTICLES, deltaTime); } //---------------------------- // swap back and front buffer //---------------------------- var temp = _backBuffer; _backBuffer = _particles; _particles = temp; }
protected virtual void LateUpdate() { if (_useMultithreading) { using (new ProfilerSample("Wait For Simulation Jobs")) { _integrationForeach.Wait(); _resolveCollisionsForeach.Wait(); } } MaterialPropertyBlock block = new MaterialPropertyBlock(); Matrix4x4 matrix; using (new ProfilerSample("Draw Particles")) { switch (_renderMethod) { case DisplayMethod.DrawMesh: for (int i = 0; i < _aliveParticles; i++) { matrix = Matrix4x4.TRS(_particlesFront[i].position, Quaternion.identity, Vector3.one * PARTICLE_DIAMETER); Graphics.DrawMesh(_particleMesh, matrix, _displayMaterial, 0); } break; case DisplayMethod.DrawMeshInstanced: int remaining = _aliveParticles; int index = 0; int colorIndex = 0; matrix = Matrix4x4.identity; matrix[0, 0] = PARTICLE_DIAMETER; matrix[1, 1] = PARTICLE_DIAMETER; matrix[2, 2] = PARTICLE_DIAMETER; while (remaining > 0) { int toDraw = Mathf.Min(1023, remaining); using (new ProfilerSample("Copy Particle Positions")) { for (int i = 0; i < toDraw; i++) { matrix[0, 3] = _particlesFront[index].position.x; matrix[1, 3] = _particlesFront[index].position.y; matrix[2, 3] = _particlesFront[index].position.z; _instanceMatrices[i] = matrix; _instanceColors[i] = _speciesData[_particlesFront[index].species].color; index++; } remaining -= toDraw; } if (_showInstanceChunks) { block.SetColor("_Color", _randomColors[colorIndex++]); } else { block.SetVectorArray("_Color", _instanceColors); } using (new ProfilerSample("Draw Mesh Instanced")) { Graphics.DrawMeshInstanced(_particleMesh, 0, _displayMaterial, _instanceMatrices, toDraw, block); } } break; } } }