• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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