summaryrefslogtreecommitdiff
path: root/tests/java_api/Balls/src/com/example/android/rs/balls/ball_physics.rscript
diff options
context:
space:
mode:
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.rscript155
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);
+}
+