1 #pragma version(1) 2 #pragma rs java_package_name(com.example.android.rs.balls) 3 4 #include "balls.rsh" 5 6 float2 gGravityVector = {0.f, 9.8f}; 7 8 float2 gMinPos = {0.f, 0.f}; 9 float2 gMaxPos = {1280.f, 700.f}; 10 11 static float2 touchPos[10]; 12 static float touchPressure[10]; 13 14 void touch(float x, float y, float pressure, int id) { 15 if (id >= 10) { 16 return; 17 } 18 19 touchPos[id].x = x; 20 touchPos[id].y = y; 21 touchPressure[id] = pressure; 22 } 23 24 void root(const Ball_t *ballIn, Ball_t *ballOut, const BallControl_t *ctl, uint32_t x) { 25 float2 fv = {0, 0}; 26 float2 pos = ballIn->position; 27 28 int arcID = -1; 29 float arcInvStr = 100000; 30 31 const Ball_t * bPtr = rsGetElementAt(ctl->ain, 0); 32 for (uint32_t xin = 0; xin < ctl->dimX; xin++) { 33 float2 vec = bPtr[xin].position - pos; 34 float2 vec2 = vec * vec; 35 float len2 = vec2.x + vec2.y; 36 37 if (len2 < 10000) { 38 //float minDist = ballIn->size + bPtr[xin].size; 39 float forceScale = ballIn->size * bPtr[xin].size; 40 forceScale *= forceScale; 41 42 if (len2 > 16 /* (minDist*minDist)*/) { 43 // Repulsion 44 float len = sqrt(len2); 45 fv -= (vec / (len * len * len)) * 20000.f * forceScale; 46 } else { 47 if (len2 < 1) { 48 if (xin == x) { 49 continue; 50 } 51 ballOut->delta = 0.f; 52 ballOut->position = ballIn->position; 53 if (xin > x) { 54 ballOut->position.x += 1.f; 55 } else { 56 ballOut->position.x -= 1.f; 57 } 58 //ballOut->color.rgb = 1.f; 59 //ballOut->arcID = -1; 60 //ballOut->arcStr = 0; 61 return; 62 } 63 // Collision 64 float2 axis = normalize(vec); 65 float e1 = dot(axis, ballIn->delta); 66 float e2 = dot(axis, bPtr[xin].delta); 67 float e = (e1 - e2) * 0.45f; 68 if (e1 > 0) { 69 fv -= axis * e; 70 } else { 71 fv += axis * e; 72 } 73 } 74 } 75 } 76 77 fv /= ballIn->size * ballIn->size * ballIn->size; 78 fv -= gGravityVector * 4.f; 79 fv *= ctl->dt; 80 81 for (int i=0; i < 10; i++) { 82 if (touchPressure[i] > 0.1f) { 83 float2 vec = touchPos[i] - ballIn->position; 84 float2 vec2 = vec * vec; 85 float len2 = max(2.f, vec2.x + vec2.y); 86 fv -= (vec / len2) * touchPressure[i] * 300.f; 87 } 88 } 89 90 ballOut->delta = (ballIn->delta * (1.f - 0.004f)) + fv; 91 ballOut->position = ballIn->position + (ballOut->delta * ctl->dt); 92 93 const float wallForce = 400.f; 94 if (ballOut->position.x > (gMaxPos.x - 20.f)) { 95 float d = gMaxPos.x - ballOut->position.x; 96 if (d < 0.f) { 97 if (ballOut->delta.x > 0) { 98 ballOut->delta.x *= -0.7; 99 } 100 ballOut->position.x = gMaxPos.x; 101 } else { 102 ballOut->delta.x -= min(wallForce / (d * d), 10.f); 103 } 104 } 105 106 if (ballOut->position.x < (gMinPos.x + 20.f)) { 107 float d = ballOut->position.x - gMinPos.x; 108 if (d < 0.f) { 109 if (ballOut->delta.x < 0) { 110 ballOut->delta.x *= -0.7; 111 } 112 ballOut->position.x = gMinPos.x + 1.f; 113 } else { 114 ballOut->delta.x += min(wallForce / (d * d), 10.f); 115 } 116 } 117 118 if (ballOut->position.y > (gMaxPos.y - 20.f)) { 119 float d = gMaxPos.y - ballOut->position.y; 120 if (d < 0.f) { 121 if (ballOut->delta.y > 0) { 122 ballOut->delta.y *= -0.7; 123 } 124 ballOut->position.y = gMaxPos.y; 125 } else { 126 ballOut->delta.y -= min(wallForce / (d * d), 10.f); 127 } 128 } 129 130 if (ballOut->position.y < (gMinPos.y + 20.f)) { 131 float d = ballOut->position.y - gMinPos.y; 132 if (d < 0.f) { 133 if (ballOut->delta.y < 0) { 134 ballOut->delta.y *= -0.7; 135 } 136 ballOut->position.y = gMinPos.y + 1.f; 137 } else { 138 ballOut->delta.y += min(wallForce / (d * d * d), 10.f); 139 } 140 } 141 142 ballOut->size = ballIn->size; 143 144 //rsDebug("physics pos out", ballOut->position); 145 } 146 147