unsafe int RunCPUBenchmark(peUpdateRoutine r, bool mt, string text) { IntPtr ctx = peCreateContext(BenchmarkParticleCount); peParams p = default(peParams); p.pressure_stiffness = m_pressure_stiffness; p.wall_stiffness = m_wall_stiffness; p.particle_size = m_particle_size; p.update_velocity = Update_Velocity; p.update_position = Update_Position; p.routine = r; p.multi_threading = mt; peSetParams(ctx, ref p); float elapsed_total = 0.0f; int num_try = 0; while (elapsed_total < BenchmarkTimeout) { float t = Time.realtimeSinceStartup; peUpdate(ctx, BenchmarkDeltaTime); elapsed_total += Time.realtimeSinceStartup - t; ++num_try; } peDestroyContext(ctx); m_output.text = m_output.text + text + (elapsed_total / num_try * 1000.0f).ToString("0.0") + "ms\n"; return(0); }
unsafe void Update() { if (Input.GetKeyDown(KeyCode.R)) { ResetParticles(); } if (Input.GetKeyDown(KeyCode.P)) { m_pause = !m_pause; } if (m_pause) { return; } float t = Time.realtimeSinceStartup; if (m_routine == peUpdateRoutine.ComputeShader) { Update_ComputeShader(Time.deltaTime); } else { peParams p = default(peParams); p.routine = m_routine; p.multi_threading = m_multi_threading; p.pressure_stiffness = m_pressure_stiffness; p.wall_stiffness = m_wall_stiffness; p.particle_size = m_particle_size; p.update_velocity = Update_Velocity; p.update_position = Update_Position; peSetParams(m_ctx, ref p); peUpdate(m_ctx, Time.deltaTime); } m_update_time = Time.realtimeSinceStartup - t; }
[DllImport("ParticleEngine")] public static extern void peSetParams(IntPtr ctx, ref peParams v);
public static extern void peSetParams(IntPtr ctx, ref peParams v);
static unsafe void Update_Velocity(peParams* p, float dt, int begin, int end) { peParticle* particles = p->particles; float particle_size2 = p->particle_size * 2.0f; float rcp_particle_size2 = 1.0f / (p->particle_size * 2.0f); // パーティクル同士の押し返し for (int i = begin; i < end; ++i) { Vector3 pos1 = particles[i].position; Vector3 accel = Vector3.zero; for (int j = 0; j < p->particles_count; ++j) { Vector3 pos2 = particles[j].position; Vector3 diff = pos2 - pos1; Vector3 dir = diff * rcp_particle_size2; float dist = diff.magnitude; if (dist > 0.0f) { Vector3 a = dir * (Mathf.Min(0.0f, dist - particle_size2) * p->pressure_stiffness); accel = accel + a; } } Vector3 vel = particles[i].velocity; vel = vel + accel * dt; particles[i].velocity = vel; } // 床との衝突 Vector3 floor_normal = new Vector3(0.0f, 1.0f, 0.0f); float floor_distance = -p->particle_size; for (int i = begin; i < end; ++i) { Vector3 pos = particles[i].position; float d = Vector3.Dot(pos, floor_normal) + floor_distance; Vector3 accel = floor_normal * (-Mathf.Min(0.0f, d) * p->wall_stiffness); Vector3 vel = particles[i].velocity; vel = vel + accel * dt; particles[i].velocity = vel; } // 重力加速 Vector3 gravity_direction = new Vector3(0.0f, -1.0f, 0.0f); float gravity_strength = 5.0f; for (int i = begin; i < end; ++i) { Vector3 accel = gravity_direction * gravity_strength; Vector3 vel = particles[i].velocity; vel = vel + accel * dt; particles[i].velocity = vel; } }
static unsafe void Update_Position(peParams* p, float dt, int begin, int end) { peParticle* particles = p->particles; for (int i = begin; i < end; ++i) { Vector3 pos = particles[i].position; Vector3 vel = particles[i].velocity; pos = pos + (vel * dt); particles[i].position = pos; } }