1#pragma version(1)
2#pragma rs java_package_name(com.example.android.rs.balls)
3#include "rs_graphics.rsh"
4
5#include "balls.rsh"
6
7rs_program_fragment gPFPoints;
8rs_mesh partMesh;
9
10rs_allocation gGrid;
11BallGrid_t *unused1;
12float2 *gGridCache;
13
14typedef struct __attribute__((packed, aligned(4))) Point {
15    float2 position;
16    uchar4 color;
17} Point_t;
18Point_t *point;
19
20typedef struct VpConsts {
21    rs_matrix4x4 MVP;
22} VpConsts_t;
23VpConsts_t *vpConstants;
24
25rs_script physics_script;
26
27
28void initParts(int w, int h)
29{
30    uint32_t dimX = rsAllocationGetDimX(rsGetAllocation(balls));
31
32    for (uint32_t ct=0; ct < dimX; ct++) {
33        balls[ct].position.x = rsRand(0.f, (float)w);
34        balls[ct].position.y = rsRand(0.f, (float)h);
35        balls[ct].delta.x = 0.f;
36        balls[ct].delta.y = 0.f;
37    }
38}
39
40int root() {
41    rsgClearColor(0.f, 0.f, 0.f, 1.f);
42
43    int2 gridDims = (int2){ rsAllocationGetDimX(gGrid),
44                            rsAllocationGetDimY(gGrid) };
45
46    rs_allocation aNull = {0};  // Empty rs_allocation, since we don't have an input.
47    rs_allocation aout = rsGetAllocation(balls);
48    int32_t dimX = rsAllocationGetDimX(aout);
49
50    // Binning
51    // Clear the particle list
52    for (uint32_t ct=0; ct < dimX; ct++) {
53        balls[ct].next = -1;
54    }
55
56    // Clear the grid
57    for (uint32_t y=0; y < gridDims.y; y++) {
58        for (uint32_t x=0; x < gridDims.x; x++) {
59            BallGrid_t *bg = (BallGrid_t *)rsGetElementAt(gGrid, x, y);
60            bg->count = 0;
61            bg->idx = -1;
62        }
63    }
64
65    // Create the particle list per grid
66    for (uint32_t ct=0; ct < dimX; ct++) {
67        int2 p = convert_int2(balls[ct].position / 100.f);
68        p.x = rsClamp(p.x, 0, (int)(gridDims.x-1));
69        p.y = rsClamp(p.y, 0, (int)(gridDims.y-1));
70        BallGrid_t *bg = (BallGrid_t *)rsGetElementAt(gGrid, p.x, p.y);
71        bg->count ++;
72        balls[ct].next = bg->idx;
73        bg->idx = ct;
74    }
75
76    // Create the sorted grid cache
77    uint32_t gridIdx = 0;
78    for (uint32_t y=0; y < gridDims.y; y++) {
79        for (uint32_t x=0; x < gridDims.x; x++) {
80            BallGrid_t *bg = (BallGrid_t *)rsGetElementAt(gGrid, x, y);
81            bg->cacheIdx = gridIdx;
82
83            int idx = bg->idx;
84            while (idx >= 0) {
85                const Ball_t * bPtr = &balls[idx];
86                gGridCache[gridIdx++] = bPtr->position;
87                idx = bPtr->next;
88            }
89        }
90    }
91
92
93    rsForEach(physics_script, aNull, aout);
94
95    for (uint32_t ct=0; ct < dimX; ct++) {
96        point[ct].position = balls[ct].position;
97        point[ct].color = balls[ct].color;
98    }
99
100    rsgBindProgramFragment(gPFPoints);
101    rsgDrawMesh(partMesh);
102    return 1;
103}
104
105