summaryrefslogtreecommitdiffstats
path: root/libs/rs/scriptc/rs_math.rsh
blob: 8117ca824b183e57c1b2216405e6312c9d67e1b9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/** @file rs_math.rsh
 *  \brief todo-jsams
 *
 *  todo-jsams
 *
 */

#ifndef __RS_MATH_RSH__
#define __RS_MATH_RSH__


/**
 * Return a random value between 0 (or min_value) and max_malue.
 */
extern int __attribute__((overloadable))
    rsRand(int max_value);
/**
 * \overload
 */
extern int __attribute__((overloadable))
    rsRand(int min_value, int max_value);
/**
 * \overload
 */
extern float __attribute__((overloadable))
    rsRand(float max_value);
/**
 * \overload
 */
extern float __attribute__((overloadable))
    rsRand(float min_value, float max_value);

/**
 * Returns the fractional part of a float
 */
extern float __attribute__((overloadable))
    rsFrac(float);


/////////////////////////////////////////////////////
// int ops
/////////////////////////////////////////////////////

/**
 * Clamp the value amount between low and high.
 *
 * @param amount  The value to clamp
 * @param low
 * @param high
 */
_RS_RUNTIME uint __attribute__((overloadable, always_inline)) rsClamp(uint amount, uint low, uint high);

/**
 * \overload
 */
_RS_RUNTIME int __attribute__((overloadable, always_inline)) rsClamp(int amount, int low, int high);
/**
 * \overload
 */
_RS_RUNTIME ushort __attribute__((overloadable, always_inline)) rsClamp(ushort amount, ushort low, ushort high);
/**
 * \overload
 */
_RS_RUNTIME short __attribute__((overloadable, always_inline)) rsClamp(short amount, short low, short high);
/**
 * \overload
 */
_RS_RUNTIME uchar __attribute__((overloadable, always_inline)) rsClamp(uchar amount, uchar low, uchar high);
/**
 * \overload
 */
_RS_RUNTIME char __attribute__((overloadable, always_inline)) rsClamp(char amount, char low, char high);


/**
 * Computes 6 frustum planes from the view projection matrix
 * @param viewProj matrix to extract planes from
 * @param left plane
 * @param right plane
 * @param top plane
 * @param bottom plane
 * @param near plane
 * @param far plane
 */
__inline__ static void __attribute__((overloadable, always_inline))
rsExtractFrustumPlanes(const rs_matrix4x4 *viewProj,
                         float4 *left, float4 *right,
                         float4 *top, float4 *bottom,
                         float4 *near, float4 *far) {
    // x y z w = a b c d in the plane equation
    left->x = viewProj->m[3] + viewProj->m[0];
    left->y = viewProj->m[7] + viewProj->m[4];
    left->z = viewProj->m[11] + viewProj->m[8];
    left->w = viewProj->m[15] + viewProj->m[12];

    right->x = viewProj->m[3] - viewProj->m[0];
    right->y = viewProj->m[7] - viewProj->m[4];
    right->z = viewProj->m[11] - viewProj->m[8];
    right->w = viewProj->m[15] - viewProj->m[12];

    top->x = viewProj->m[3] - viewProj->m[1];
    top->y = viewProj->m[7] - viewProj->m[5];
    top->z = viewProj->m[11] - viewProj->m[9];
    top->w = viewProj->m[15] - viewProj->m[13];

    bottom->x = viewProj->m[3] + viewProj->m[1];
    bottom->y = viewProj->m[7] + viewProj->m[5];
    bottom->z = viewProj->m[11] + viewProj->m[9];
    bottom->w = viewProj->m[15] + viewProj->m[13];

    near->x = viewProj->m[3] + viewProj->m[2];
    near->y = viewProj->m[7] + viewProj->m[6];
    near->z = viewProj->m[11] + viewProj->m[10];
    near->w = viewProj->m[15] + viewProj->m[14];

    far->x = viewProj->m[3] - viewProj->m[2];
    far->y = viewProj->m[7] - viewProj->m[6];
    far->z = viewProj->m[11] - viewProj->m[10];
    far->w = viewProj->m[15] - viewProj->m[14];

    float len = length(left->xyz);
    *left /= len;
    len = length(right->xyz);
    *right /= len;
    len = length(top->xyz);
    *top /= len;
    len = length(bottom->xyz);
    *bottom /= len;
    len = length(near->xyz);
    *near /= len;
    len = length(far->xyz);
    *far /= len;
}

/**
 * Checks if a sphere is withing the 6 frustum planes
 * @param sphere float4 representing the sphere
 * @param left plane
 * @param right plane
 * @param top plane
 * @param bottom plane
 * @param near plane
 * @param far plane
 */
__inline__ static bool __attribute__((overloadable, always_inline))
rsIsSphereInFrustum(float4 *sphere,
                      float4 *left, float4 *right,
                      float4 *top, float4 *bottom,
                      float4 *near, float4 *far) {

    float distToCenter = dot(left->xyz, sphere->xyz) + left->w;
    if (distToCenter < -sphere->w) {
        return false;
    }
    distToCenter = dot(right->xyz, sphere->xyz) + right->w;
    if (distToCenter < -sphere->w) {
        return false;
    }
    distToCenter = dot(top->xyz, sphere->xyz) + top->w;
    if (distToCenter < -sphere->w) {
        return false;
    }
    distToCenter = dot(bottom->xyz, sphere->xyz) + bottom->w;
    if (distToCenter < -sphere->w) {
        return false;
    }
    distToCenter = dot(near->xyz, sphere->xyz) + near->w;
    if (distToCenter < -sphere->w) {
        return false;
    }
    distToCenter = dot(far->xyz, sphere->xyz) + far->w;
    if (distToCenter < -sphere->w) {
        return false;
    }
    return true;
}


/**
 * Pack floating point (0-1) RGB values into a uchar4.  The alpha component is
 * set to 255 (1.0).
 *
 * @param r
 * @param g
 * @param b
 *
 * @return uchar4
 */
_RS_RUNTIME uchar4 __attribute__((overloadable)) rsPackColorTo8888(float r, float g, float b);

/**
 * Pack floating point (0-1) RGBA values into a uchar4.
 *
 * @param r
 * @param g
 * @param b
 * @param a
 *
 * @return uchar4
 */
_RS_RUNTIME uchar4 __attribute__((overloadable)) rsPackColorTo8888(float r, float g, float b, float a);

/**
 * Pack floating point (0-1) RGB values into a uchar4.  The alpha component is
 * set to 255 (1.0).
 *
 * @param color
 *
 * @return uchar4
 */
_RS_RUNTIME uchar4 __attribute__((overloadable)) rsPackColorTo8888(float3 color);

/**
 * Pack floating point (0-1) RGBA values into a uchar4.
 *
 * @param color
 *
 * @return uchar4
 */
_RS_RUNTIME uchar4 __attribute__((overloadable)) rsPackColorTo8888(float4 color);

/**
 * Unpack a uchar4 color to float4.  The resulting float range will be (0-1).
 *
 * @param c
 *
 * @return float4
 */
_RS_RUNTIME float4 rsUnpackColor8888(uchar4 c);


#endif