init
This commit is contained in:
commit
87bff164f1
416 files changed
+279512
No files matched your search
@@ -0,0 +1,53 @@
|
||||
#version 450
|
||||
#extension GL_GOOGLE_include_directive : require
|
||||
layout(local_size_x = 64) in;
|
||||
#include "rigid_common.glsl"
|
||||
|
||||
// Explosions (from projectiles on the GPU, from props on the host) push the rigid bodies and wake them.
|
||||
layout(std430, set = 0, binding = 37) buffer Xev { ivec4 xhead; vec4 xe[512]; };
|
||||
|
||||
void main() {
|
||||
uint bi = gl_GlobalInvocationID.x;
|
||||
if (int(bi) >= bhdr.x) return;
|
||||
Body B = bodies[bi];
|
||||
if ((B.i.z & B_REMOVED) != 0) return;
|
||||
int s = B.i.x;
|
||||
float mass = shf(s, 7), radius = shf(s, 9);
|
||||
bool touched = false;
|
||||
for (int k = 0; k < min(xhead.x, 512); ++k) {
|
||||
vec4 e = xe[k]; // x, y, radius, power
|
||||
if (e.w < -0.5) { // an explosion with the force of 00657960: this entry and the next one (force min, force max)
|
||||
vec4 f2 = xe[min(k + 1, 511)];
|
||||
++k;
|
||||
const float pixels = float(shi(s, 4) > 0 ? int(shf(s, 7)) : 1);
|
||||
const float massKg = max(pixels * B.q.z * 0.01, 1.0e-4);
|
||||
vec2 O = e.xy, C = B.p.xy;
|
||||
float dist = length(C - O) * 0.1, Ru = e.z * 0.1; // physics units (10 pixels each)
|
||||
if (dist > Ru) continue;
|
||||
// the original needs the angular bin of the explosion to reach this body: approximated by a line of sight through the grid that no solid cell interrupts
|
||||
bool blocked = false;
|
||||
const int steps = int(dist * 10.0);
|
||||
for (int q = 1; q < steps && !blocked; ++q) blocked = solid_at(ivec2(floor(mix(O, C, float(q) / float(steps)))));
|
||||
if (blocked) continue;
|
||||
float t = Ru == 0.0 ? 1.0 : 1.0 - dist / Ru;
|
||||
float A = (f2.y - f2.x) * t + f2.x;
|
||||
vec2 n = dist >= 1.19e-7 ? normalize(C - O) : vec2(0.0);
|
||||
// F = n A (x mass if the body weighs less than 1), x 360 N, dv = F / m / 360 per frame in pixels: = n A min(1, m) / m
|
||||
B.v.xy += n * A * min(1.0, massKg) / massKg;
|
||||
const float inertiaKg = max(shf(s, 8) * B.q.z * 1.0e-4, 1.0e-6);
|
||||
const float tau = float(hash3(bi, uint(xhead.x), 91u) & 0x7FFFu) / 32767.0 * 30.0 - 15.0; // the random torque of the original
|
||||
B.p.w += tau / (3600.0 * inertiaKg);
|
||||
touched = true;
|
||||
continue;
|
||||
}
|
||||
vec2 d = B.p.xy - e.xy - vec2(0.0, 2.0);
|
||||
float dist = length(d);
|
||||
if (dist > e.z + radius) continue;
|
||||
float f = e.w * max(0.0, 1.0 - dist / (e.z + radius)) / sqrt(max(1.0, mass * B.q.z) / 20.0);
|
||||
vec2 n = dist > 1e-3 ? d / dist : vec2(0.0, -1.0);
|
||||
B.v.xy += n * f;
|
||||
B.p.w += (n.x > 0.0 ? 1.0 : -1.0) * f * 0.05;
|
||||
touched = true;
|
||||
}
|
||||
if (touched) { B.i.z &= ~B_ASLEEP; B.i.w = 0; bodies[bi] = B; }
|
||||
}
|
||||
Reference in new issue
Block a user