diff options
Diffstat (limited to 'tests/java_api/Balls/src/com/example/android/rs/balls/ball_physics.rscript')
-rw-r--r-- | tests/java_api/Balls/src/com/example/android/rs/balls/ball_physics.rscript | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/tests/java_api/Balls/src/com/example/android/rs/balls/ball_physics.rscript b/tests/java_api/Balls/src/com/example/android/rs/balls/ball_physics.rscript new file mode 100644 index 00000000..a8c781d2 --- /dev/null +++ b/tests/java_api/Balls/src/com/example/android/rs/balls/ball_physics.rscript @@ -0,0 +1,155 @@ +#pragma version(1) +#pragma rs java_package_name(com.example.android.rs.balls) + +#include "balls.rsh" + +float2 gGravityVector = {0.f, 9.8f}; + +float2 gMinPos = {0.f, 0.f}; +float2 gMaxPos = {1280.f, 700.f}; + +static float2 touchPos[10]; +static float touchPressure[10]; +static const float gDT = 1.f / 30.f; + +rs_allocation gGrid; +rs_allocation gGridCache; +rs_allocation gBalls; + +float gScale = 1.f; + +void touch(float x, float y, float pressure, int id) { + if (id >= 10) { + return; + } + + touchPos[id].x = x; + touchPos[id].y = y; + touchPressure[id] = pressure; +} + +void root(Ball_t *ball, uint32_t x) { + float2 fv = 0; + float pressure = 0; + float2 pos = ball->position; + int2 gridPos[9]; + + gridPos[0] = convert_int2((ball->position / 100.f) /*- 0.4999f*/); + gridPos[1] = (int2){gridPos[0].x - 1, gridPos[0].y - 1}; + gridPos[2] = (int2){gridPos[0].x + 0, gridPos[0].y - 1}; + gridPos[3] = (int2){gridPos[0].x + 1, gridPos[0].y - 1}; + gridPos[4] = (int2){gridPos[0].x - 1, gridPos[0].y}; + gridPos[5] = (int2){gridPos[0].x + 1, gridPos[0].y}; + gridPos[6] = (int2){gridPos[0].x - 1, gridPos[0].y + 1}; + gridPos[7] = (int2){gridPos[0].x + 0, gridPos[0].y + 1}; + gridPos[8] = (int2){gridPos[0].x + 1, gridPos[0].y + 1}; + + for (int gct=0; gct < 9; gct++) { + if ((gridPos[gct].x >= rsAllocationGetDimX(gGrid)) || + (gridPos[gct].x < 0) || + (gridPos[gct].y >= rsAllocationGetDimY(gGrid)) || + (gridPos[gct].y < 0)) { + continue; + } + //rsDebug("grid ", gridPos[gct]); + const BallGrid_t *bg = (const BallGrid_t *)rsGetElementAt(gGrid, gridPos[gct].x, gridPos[gct].y); + + for (int cidx = 0; cidx < bg->count; cidx++) { + float2 bcptr = rsGetElementAt_float2(gGridCache, bg->cacheIdx + cidx); + float2 vec = bcptr - pos; + float2 vec2 = vec * vec; + float len2 = vec2.x + vec2.y; + + if ((len2 < 10000.f) && (len2 > 0.001f)) { + float len = rsqrt(len2 + 4.f); + float f = (len * len * len) * 20000.f; + fv -= vec * f; + pressure += f; + } + } + } + + //fv /= ball->size * ball->size * ball->size; + fv -= gGravityVector * 4.f * gScale; + fv *= gDT; + + for (int i=0; i < 10; i++) { + if (touchPressure[i] > 0.1f) { + float2 vec = touchPos[i] - ball->position; + float2 vec2 = vec * vec; + float len2 = max(2.f, vec2.x + vec2.y); + float2 pfv = (vec / len2) * touchPressure[i] * 500.f * gScale; + pressure += length(pfv); + fv -= pfv; + } + } + + ball->delta = (ball->delta * (1.f - 0.008f)) + fv; + ball->position = ball->position + (ball->delta * gDT); + + const float wallForce = 400.f * gScale; + if (ball->position.x > (gMaxPos.x - 20.f)) { + float d = gMaxPos.x - ball->position.x; + if (d < 0.f) { + if (ball->delta.x > 0) { + ball->delta.x *= -0.7f; + } + ball->position.x = gMaxPos.x - 1.f; + } else { + ball->delta.x -= min(wallForce / (d * d), 10.f); + } + } + + if (ball->position.x < (gMinPos.x + 20.f)) { + float d = ball->position.x - gMinPos.x; + if (d < 0.f) { + if (ball->delta.x < 0) { + ball->delta.x *= -0.7f; + } + ball->position.x = gMinPos.x + 1.f; + } else { + ball->delta.x += min(wallForce / (d * d), 10.f); + } + } + + if (ball->position.y > (gMaxPos.y - 20.f)) { + float d = gMaxPos.y - ball->position.y; + if (d < 0.f) { + if (ball->delta.y > 0) { + ball->delta.y *= -0.7f; + } + ball->position.y = gMaxPos.y - 1.f; + } else { + ball->delta.y -= min(wallForce / (d * d), 10.f); + } + } + + if (ball->position.y < (gMinPos.y + 20.f)) { + float d = ball->position.y - gMinPos.y; + if (d < 0.f) { + if (ball->delta.y < 0) { + ball->delta.y *= -0.7f; + } + ball->position.y = gMinPos.y + 1.f; + } else { + ball->delta.y += min(wallForce / (d * d * d), 10.f); + } + } + + // low pressure ~500, high ~2500 + pressure *= 12.f; + ball->pressure = pressure; + + //rsDebug("p ", pressure); + + float4 color = 1.f; + color.r = pow(pressure, 0.25f) / 12.f; + color.b = 1.f - color.r; + color.g = sin(pressure / 1500.f * 3.14f); + color.rgb = max(color.rgb, (float3)0); + color.rgb = normalize(color.rgb); + ball->color = rsPackColorTo8888(color); + + //rsDebug("physics pos out", ball->position); +} + |