1572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams#pragma version(1)
2572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams#pragma rs java_package_name(com.example.android.rs.balls)
3572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams#include "rs_graphics.rsh"
4572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
5572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams#include "balls.rsh"
6572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
7572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsrs_program_fragment gPFPoints;
8572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsrs_mesh partMesh;
9572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
10572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsrs_allocation gGrid;
11572a5031a5d8602db0bec0b253428a034bd4dd59Jason SamsBallGrid_t *unused1;
12572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsfloat2 *gGridCache;
13572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
14572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samstypedef struct __attribute__((packed, aligned(4))) Point {
15572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    float2 position;
16572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    uchar4 color;
17572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams} Point_t;
18572a5031a5d8602db0bec0b253428a034bd4dd59Jason SamsPoint_t *point;
19572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
20572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samstypedef struct VpConsts {
21572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    rs_matrix4x4 MVP;
22572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams} VpConsts_t;
23572a5031a5d8602db0bec0b253428a034bd4dd59Jason SamsVpConsts_t *vpConstants;
24572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
25572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsrs_script physics_script;
26572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
27572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
28572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsvoid initParts(int w, int h)
29572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams{
30572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    uint32_t dimX = rsAllocationGetDimX(rsGetAllocation(balls));
31572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
32572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    for (uint32_t ct=0; ct < dimX; ct++) {
33572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        balls[ct].position.x = rsRand(0.f, (float)w);
34572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        balls[ct].position.y = rsRand(0.f, (float)h);
35572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        balls[ct].delta.x = 0.f;
36572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        balls[ct].delta.y = 0.f;
37572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    }
38572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams}
39572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
40572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsint root() {
41572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    rsgClearColor(0.f, 0.f, 0.f, 1.f);
42572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
43572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    int2 gridDims = (int2){ rsAllocationGetDimX(gGrid),
44572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                            rsAllocationGetDimY(gGrid) };
45572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
46de235208fd6bcaa29c95404d990f7b5e212435f9Jean-Luc Brouillet    rs_allocation aNull = {0};  // Empty rs_allocation, since we don't have an input.
47f29e2cf47c79fdbc3921dccfd78af868fe8ed1cbStephen Hines    rs_allocation aout = rsGetAllocation(balls);
48f29e2cf47c79fdbc3921dccfd78af868fe8ed1cbStephen Hines    int32_t dimX = rsAllocationGetDimX(aout);
49572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
50572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    // Binning
51572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    // Clear the particle list
52572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    for (uint32_t ct=0; ct < dimX; ct++) {
53572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        balls[ct].next = -1;
54572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    }
55572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
56572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    // Clear the grid
57572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    for (uint32_t y=0; y < gridDims.y; y++) {
58572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        for (uint32_t x=0; x < gridDims.x; x++) {
59572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            BallGrid_t *bg = (BallGrid_t *)rsGetElementAt(gGrid, x, y);
60572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            bg->count = 0;
61572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            bg->idx = -1;
62572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        }
63572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    }
64572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
65572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    // Create the particle list per grid
66572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    for (uint32_t ct=0; ct < dimX; ct++) {
67572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        int2 p = convert_int2(balls[ct].position / 100.f);
68572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        p.x = rsClamp(p.x, 0, (int)(gridDims.x-1));
69572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        p.y = rsClamp(p.y, 0, (int)(gridDims.y-1));
70572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        BallGrid_t *bg = (BallGrid_t *)rsGetElementAt(gGrid, p.x, p.y);
71572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        bg->count ++;
72572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        balls[ct].next = bg->idx;
73572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        bg->idx = ct;
74572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    }
75572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
76572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    // Create the sorted grid cache
77572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    uint32_t gridIdx = 0;
78572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    for (uint32_t y=0; y < gridDims.y; y++) {
79572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        for (uint32_t x=0; x < gridDims.x; x++) {
80572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            BallGrid_t *bg = (BallGrid_t *)rsGetElementAt(gGrid, x, y);
81572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            bg->cacheIdx = gridIdx;
82572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
83572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            int idx = bg->idx;
84572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            while (idx >= 0) {
85572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                const Ball_t * bPtr = &balls[idx];
86572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                gGridCache[gridIdx++] = bPtr->position;
87572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                idx = bPtr->next;
88572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            }
89572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        }
90572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    }
91572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
92572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
93f29e2cf47c79fdbc3921dccfd78af868fe8ed1cbStephen Hines    rsForEach(physics_script, aNull, aout);
94572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
95572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    for (uint32_t ct=0; ct < dimX; ct++) {
96572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        point[ct].position = balls[ct].position;
97572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        point[ct].color = balls[ct].color;
98572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    }
99572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
100572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    rsgBindProgramFragment(gPFPoints);
101572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    rsgDrawMesh(partMesh);
102572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    return 1;
103572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams}
104572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
105