1#pragma version(1) 2#pragma rs java_package_name(com.example.android.rs.balls) 3 4#include "balls.rsh" 5 6float2 gGravityVector = {0.f, 9.8f}; 7 8float2 gMinPos = {0.f, 0.f}; 9float2 gMaxPos = {1280.f, 700.f}; 10 11static float2 touchPos[10]; 12static float touchPressure[10]; 13static const float gDT = 1.f / 30.f; 14 15rs_allocation gGrid; 16rs_allocation gGridCache; 17rs_allocation gBalls; 18 19float gScale = 1.f; 20 21void touch(float x, float y, float pressure, int id) { 22 if (id >= 10) { 23 return; 24 } 25 26 touchPos[id].x = x; 27 touchPos[id].y = y; 28 touchPressure[id] = pressure; 29} 30 31void root(Ball_t *ball, uint32_t x) { 32 float2 fv = 0; 33 float pressure = 0; 34 float2 pos = ball->position; 35 int2 gridPos[9]; 36 37 gridPos[0] = convert_int2((ball->position / 100.f) /*- 0.4999f*/); 38 gridPos[1] = (int2){gridPos[0].x - 1, gridPos[0].y - 1}; 39 gridPos[2] = (int2){gridPos[0].x + 0, gridPos[0].y - 1}; 40 gridPos[3] = (int2){gridPos[0].x + 1, gridPos[0].y - 1}; 41 gridPos[4] = (int2){gridPos[0].x - 1, gridPos[0].y}; 42 gridPos[5] = (int2){gridPos[0].x + 1, gridPos[0].y}; 43 gridPos[6] = (int2){gridPos[0].x - 1, gridPos[0].y + 1}; 44 gridPos[7] = (int2){gridPos[0].x + 0, gridPos[0].y + 1}; 45 gridPos[8] = (int2){gridPos[0].x + 1, gridPos[0].y + 1}; 46 47 for (int gct=0; gct < 9; gct++) { 48 if ((gridPos[gct].x >= rsAllocationGetDimX(gGrid)) || 49 (gridPos[gct].x < 0) || 50 (gridPos[gct].y >= rsAllocationGetDimY(gGrid)) || 51 (gridPos[gct].y < 0)) { 52 continue; 53 } 54 //rsDebug("grid ", gridPos[gct]); 55 const BallGrid_t *bg = (const BallGrid_t *)rsGetElementAt(gGrid, gridPos[gct].x, gridPos[gct].y); 56 57 for (int cidx = 0; cidx < bg->count; cidx++) { 58 float2 bcptr = rsGetElementAt_float2(gGridCache, bg->cacheIdx + cidx); 59 float2 vec = bcptr - pos; 60 float2 vec2 = vec * vec; 61 float len2 = vec2.x + vec2.y; 62 63 if ((len2 < 10000.f) && (len2 > 0.001f)) { 64 float len = rsqrt(len2 + 4.f); 65 float f = (len * len * len) * 20000.f; 66 fv -= vec * f; 67 pressure += f; 68 } 69 } 70 } 71 72 //fv /= ball->size * ball->size * ball->size; 73 fv -= gGravityVector * 4.f * gScale; 74 fv *= gDT; 75 76 for (int i=0; i < 10; i++) { 77 if (touchPressure[i] > 0.1f) { 78 float2 vec = touchPos[i] - ball->position; 79 float2 vec2 = vec * vec; 80 float len2 = max(2.f, vec2.x + vec2.y); 81 float2 pfv = (vec / len2) * touchPressure[i] * 500.f * gScale; 82 pressure += length(pfv); 83 fv -= pfv; 84 } 85 } 86 87 ball->delta = (ball->delta * (1.f - 0.008f)) + fv; 88 ball->position = ball->position + (ball->delta * gDT); 89 90 const float wallForce = 400.f * gScale; 91 if (ball->position.x > (gMaxPos.x - 20.f)) { 92 float d = gMaxPos.x - ball->position.x; 93 if (d < 0.f) { 94 if (ball->delta.x > 0) { 95 ball->delta.x *= -0.7f; 96 } 97 ball->position.x = gMaxPos.x - 1.f; 98 } else { 99 ball->delta.x -= min(wallForce / (d * d), 10.f); 100 } 101 } 102 103 if (ball->position.x < (gMinPos.x + 20.f)) { 104 float d = ball->position.x - gMinPos.x; 105 if (d < 0.f) { 106 if (ball->delta.x < 0) { 107 ball->delta.x *= -0.7f; 108 } 109 ball->position.x = gMinPos.x + 1.f; 110 } else { 111 ball->delta.x += min(wallForce / (d * d), 10.f); 112 } 113 } 114 115 if (ball->position.y > (gMaxPos.y - 20.f)) { 116 float d = gMaxPos.y - ball->position.y; 117 if (d < 0.f) { 118 if (ball->delta.y > 0) { 119 ball->delta.y *= -0.7f; 120 } 121 ball->position.y = gMaxPos.y - 1.f; 122 } else { 123 ball->delta.y -= min(wallForce / (d * d), 10.f); 124 } 125 } 126 127 if (ball->position.y < (gMinPos.y + 20.f)) { 128 float d = ball->position.y - gMinPos.y; 129 if (d < 0.f) { 130 if (ball->delta.y < 0) { 131 ball->delta.y *= -0.7f; 132 } 133 ball->position.y = gMinPos.y + 1.f; 134 } else { 135 ball->delta.y += min(wallForce / (d * d * d), 10.f); 136 } 137 } 138 139 // low pressure ~500, high ~2500 140 pressure *= 12.f; 141 ball->pressure = pressure; 142 143 //rsDebug("p ", pressure); 144 145 float4 color = 1.f; 146 color.r = pow(pressure, 0.25f) / 12.f; 147 color.b = 1.f - color.r; 148 color.g = sin(pressure / 1500.f * 3.14f); 149 color.rgb = max(color.rgb, (float3)0); 150 color.rgb = normalize(color.rgb); 151 ball->color = rsPackColorTo8888(color); 152 153 //rsDebug("physics pos out", ball->position); 154} 155 156