1/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#pragma version(1)
18#pragma rs java_package_name(com.example.android.rs.vr.engine)
19#pragma rs_fp_relaxed
20
21#define FLOAT_MAX  3.4028234E30f
22
23float vert[3 * 8];
24int index[3 * 12];
25int width;
26int height;
27
28static float zoff[12];
29static float2 slope[12];
30
31static float2 p1[12];
32static float2 p2[12];
33static float2 p3[12];
34
35      float2 d12[12];
36        float2 d23[12];
37        float2 d31[12];
38static int total;
39
40static void
41triangleSetup(float3 f1, float3 f2, float3 f3) {
42    if (((f1.x - f2.x) * (f3.y - f2.y) - (f1.y - f2.y) * (f3.x - f2.x)) < 0) {
43        float3 tmp = f1;
44        f1 = f2;
45        f2 = tmp;
46    }
47
48    // using maxmima
49    // string(solve([x1*dx+y1*dy+zoff=z1,x2*dx+y2*dy+zoff=z2,x3*dx+y3*dy+zoff=z3],[dx,dy,zoff]));
50    double d = (f1.x * (f3.y - f2.y) - f2.x * f3.y + f3.x * f2.y + (f2.x - f3.x)
51            * f1.y);
52
53    if (d == 0) {
54        return;
55    }
56
57    slope[total].x = (-(f1.y * (f3.z - f2.z) - f2.y * f3.z + f3.y * f2.z + (f2.y - f3.y) * f1.z)
58            / d);
59    slope[total].y = ((f1.x * (f3.z - f2.z) - f2.x * f3.z + f3.x * f2.z + (f2.x - f3.x) * f1.z)
60            / d);
61    zoff[total] = ((f1.x * (f3.y * f2.z - f2.y * f3.z) + f1.y * (f2.x * f3.z - f3.x * f2.z) +
62            (f3.x * f2.y - f2.x * f3.y) * f1.z) / d);
63
64    p1[total] = f1.xy;
65    p2[total] = f2.xy;
66    p3[total] = f3.xy;
67    d12[total] = p1[total] - p2[total];
68    d23[total] = p2[total] - p3[total];
69    d31[total] = p3[total] - p1[total];
70    total++;
71}
72
73void setup_triangles(int w, int h) {
74    width = w;
75    height = h;
76    total = 0;
77    //   rsDebug("RRRRR >>>>>> setup_triangles ", w, h);
78    float3 f1;
79    float3 f2;
80    float3 f3;
81    for (int i = 0; i < 3 * 12; i += 3) {
82        int p1 = index[i];
83        int p2 = index[i + 1];
84        int p3 = index[i + 2];
85        f1.x = vert[p1];
86        f1.y = vert[p1 + 1];
87        f1.z = vert[p1 + 2];
88        f2.x = vert[p2];
89        f2.y = vert[p2 + 1];
90        f2.z = vert[p2 + 2];
91        f3.x = vert[p3];
92        f3.y = vert[p3 + 1];
93        f3.z = vert[p3 + 2];
94        triangleSetup(f1, f2, f3);
95    }
96}
97
98
99float2 __attribute__ ((kernel)) render_z(uint32_t x, uint32_t y) {
100    float2 out = (float2) {FLOAT_MAX,-FLOAT_MAX};
101    float2 loc;
102    loc.x = x;
103    loc.y = y;
104    for (int i = 0; i < total; i++) {
105        float2 d1 = loc - p1[i];
106        float2 d2 = loc - p2[i];
107        float2 d3 = loc - p3[i];
108
109        float test1 = (d12[i].x) * (d1.y) - (d12[i].y) * (d1.x);
110        float test2 = (d23[i].x) * (d2.y) - (d23[i].y) * (d2.x);
111        float test3 = (d31[i].x) * (d3.y) - (d31[i].y) * (d3.x);
112        // float test = edge(0 , test1) * edge(0 , test2)* edge(0 , test3);
113
114        if (test1 >= 0 &&
115                test2 >= 0 &&
116                test3 >= 0) {
117            float2 delta = slope[i] * loc;
118            float z = zoff[i] + delta.x + delta.y;
119
120            out.x = min(z, out.x);
121            out.y = max(z, out.y);
122        }
123    }
124    return out;
125}
126
127
128rs_allocation z_range_buff;
129float min_z = 1500;
130float max_z = 2300;
131
132void getMinMax() {
133
134    float tmp_min = FLOAT_MAX;
135    float tmp_max = -FLOAT_MAX;;
136    for (int y = 0; y < height; y++) {
137        for (int x = 0; x < width; x++) {
138            float2 v = rsGetElementAt_float2(z_range_buff, x, y);
139            if (v.x == FLOAT_MAX) {
140                continue;
141            }
142            tmp_min = min(tmp_min, v.x);
143            tmp_max = max(tmp_max, v.x);
144        }
145    }
146    min_z = tmp_min;
147    max_z = tmp_max;
148    rsDebug("RRRRR >>>>>> getMinMax ", min_z, max_z);
149}
150
151uchar4 __attribute__ ((kernel)) draw_z_buffer(float2 in) {
152
153    if (in.x != FLOAT_MAX) {
154        uchar v = (uchar)(255 * (in.x - min_z) / (max_z - min_z));
155        uchar4 out;
156        out.r = v;
157        out.g = v;
158        out.b = v;
159        out.a = 255;
160        return out;
161    }
162
163    uchar4 out;
164    out.r = 0x44;
165    out.g = 0x44;
166    out.b = 0x99;
167    out.a = 255;
168    return out;
169}