1572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams#pragma version(1) 2572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams#pragma rs java_package_name(com.example.android.rs.balls) 3572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 4572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams#include "balls.rsh" 5572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 6572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsfloat2 gGravityVector = {0.f, 9.8f}; 7572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 8572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsfloat2 gMinPos = {0.f, 0.f}; 9572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsfloat2 gMaxPos = {1280.f, 700.f}; 10572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 11572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsstatic float2 touchPos[10]; 12572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsstatic float touchPressure[10]; 13572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsstatic const float gDT = 1.f / 30.f; 14572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 15572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsrs_allocation gGrid; 16572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsrs_allocation gGridCache; 17572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsrs_allocation gBalls; 18572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 19572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsfloat gScale = 1.f; 20572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 21572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsvoid touch(float x, float y, float pressure, int id) { 22572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams if (id >= 10) { 23572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams return; 24572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams } 25572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 26572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams touchPos[id].x = x; 27572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams touchPos[id].y = y; 28572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams touchPressure[id] = pressure; 29572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams} 30572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 31572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsvoid root(Ball_t *ball, uint32_t x) { 32572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams float2 fv = 0; 33572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams float pressure = 0; 34572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams float2 pos = ball->position; 35572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams int2 gridPos[9]; 36572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 37572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams gridPos[0] = convert_int2((ball->position / 100.f) /*- 0.4999f*/); 38572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams gridPos[1] = (int2){gridPos[0].x - 1, gridPos[0].y - 1}; 39572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams gridPos[2] = (int2){gridPos[0].x + 0, gridPos[0].y - 1}; 40572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams gridPos[3] = (int2){gridPos[0].x + 1, gridPos[0].y - 1}; 41572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams gridPos[4] = (int2){gridPos[0].x - 1, gridPos[0].y}; 42572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams gridPos[5] = (int2){gridPos[0].x + 1, gridPos[0].y}; 43572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams gridPos[6] = (int2){gridPos[0].x - 1, gridPos[0].y + 1}; 44572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams gridPos[7] = (int2){gridPos[0].x + 0, gridPos[0].y + 1}; 45572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams gridPos[8] = (int2){gridPos[0].x + 1, gridPos[0].y + 1}; 46572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 47572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams for (int gct=0; gct < 9; gct++) { 48572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams if ((gridPos[gct].x >= rsAllocationGetDimX(gGrid)) || 49572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams (gridPos[gct].x < 0) || 50572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams (gridPos[gct].y >= rsAllocationGetDimY(gGrid)) || 51572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams (gridPos[gct].y < 0)) { 52572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams continue; 53572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams } 54572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams //rsDebug("grid ", gridPos[gct]); 55572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams const BallGrid_t *bg = (const BallGrid_t *)rsGetElementAt(gGrid, gridPos[gct].x, gridPos[gct].y); 56572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 57572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams for (int cidx = 0; cidx < bg->count; cidx++) { 58572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams float2 bcptr = rsGetElementAt_float2(gGridCache, bg->cacheIdx + cidx); 59572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams float2 vec = bcptr - pos; 60572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams float2 vec2 = vec * vec; 61572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams float len2 = vec2.x + vec2.y; 62572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 63811fe009f3db9a7cdc7a8797d31d1a067406860dJason Sams if ((len2 < 10000.f) && (len2 > 0.001f)) { 64811fe009f3db9a7cdc7a8797d31d1a067406860dJason Sams float len = rsqrt(len2 + 4.f); 65811fe009f3db9a7cdc7a8797d31d1a067406860dJason Sams float f = (len * len * len) * 20000.f; 66811fe009f3db9a7cdc7a8797d31d1a067406860dJason Sams fv -= vec * f; 67811fe009f3db9a7cdc7a8797d31d1a067406860dJason Sams pressure += f; 68572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams } 69572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams } 70572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams } 71572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 72572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams //fv /= ball->size * ball->size * ball->size; 73572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams fv -= gGravityVector * 4.f * gScale; 74572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams fv *= gDT; 75572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 76572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams for (int i=0; i < 10; i++) { 77572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams if (touchPressure[i] > 0.1f) { 78572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams float2 vec = touchPos[i] - ball->position; 79572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams float2 vec2 = vec * vec; 80572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams float len2 = max(2.f, vec2.x + vec2.y); 81572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams float2 pfv = (vec / len2) * touchPressure[i] * 500.f * gScale; 82572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams pressure += length(pfv); 83572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams fv -= pfv; 84572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams } 85572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams } 86572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 87572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams ball->delta = (ball->delta * (1.f - 0.008f)) + fv; 88572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams ball->position = ball->position + (ball->delta * gDT); 89572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 90572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams const float wallForce = 400.f * gScale; 91572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams if (ball->position.x > (gMaxPos.x - 20.f)) { 92572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams float d = gMaxPos.x - ball->position.x; 93572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams if (d < 0.f) { 94572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams if (ball->delta.x > 0) { 95572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams ball->delta.x *= -0.7f; 96572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams } 97572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams ball->position.x = gMaxPos.x - 1.f; 98572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams } else { 99572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams ball->delta.x -= min(wallForce / (d * d), 10.f); 100572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams } 101572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams } 102572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 103572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams if (ball->position.x < (gMinPos.x + 20.f)) { 104572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams float d = ball->position.x - gMinPos.x; 105572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams if (d < 0.f) { 106572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams if (ball->delta.x < 0) { 107572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams ball->delta.x *= -0.7f; 108572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams } 109572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams ball->position.x = gMinPos.x + 1.f; 110572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams } else { 111572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams ball->delta.x += min(wallForce / (d * d), 10.f); 112572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams } 113572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams } 114572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 115572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams if (ball->position.y > (gMaxPos.y - 20.f)) { 116572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams float d = gMaxPos.y - ball->position.y; 117572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams if (d < 0.f) { 118572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams if (ball->delta.y > 0) { 119572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams ball->delta.y *= -0.7f; 120572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams } 121572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams ball->position.y = gMaxPos.y - 1.f; 122572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams } else { 123572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams ball->delta.y -= min(wallForce / (d * d), 10.f); 124572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams } 125572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams } 126572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 127572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams if (ball->position.y < (gMinPos.y + 20.f)) { 128572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams float d = ball->position.y - gMinPos.y; 129572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams if (d < 0.f) { 130572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams if (ball->delta.y < 0) { 131572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams ball->delta.y *= -0.7f; 132572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams } 133572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams ball->position.y = gMinPos.y + 1.f; 134572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams } else { 135572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams ball->delta.y += min(wallForce / (d * d * d), 10.f); 136572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams } 137572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams } 138572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 139572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams // low pressure ~500, high ~2500 140811fe009f3db9a7cdc7a8797d31d1a067406860dJason Sams pressure *= 12.f; 141572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams ball->pressure = pressure; 142572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 143572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams //rsDebug("p ", pressure); 144572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 145572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams float4 color = 1.f; 146572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams color.r = pow(pressure, 0.25f) / 12.f; 147572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams color.b = 1.f - color.r; 148572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams color.g = sin(pressure / 1500.f * 3.14f); 149572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams color.rgb = max(color.rgb, (float3)0); 150572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams color.rgb = normalize(color.rgb); 151572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams ball->color = rsPackColorTo8888(color); 152572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 153572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams //rsDebug("physics pos out", ball->position); 154572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams} 155572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 156