Home | History | Annotate | Download | only in include
      1 #ifndef __RS_CORE_RSH__
      2 #define __RS_CORE_RSH__
      3 
      4 #define _RS_RUNTIME extern
      5 
      6 /**
      7  * Debug function.  Prints a string and value to the log.
      8  */
      9 extern void __attribute__((overloadable))
     10     rsDebug(const char *, float);
     11 /**
     12  * Debug function.  Prints a string and value to the log.
     13  */
     14 extern void __attribute__((overloadable))
     15     rsDebug(const char *, float, float);
     16 /**
     17  * Debug function.  Prints a string and value to the log.
     18  */
     19 extern void __attribute__((overloadable))
     20     rsDebug(const char *, float, float, float);
     21 /**
     22  * Debug function.  Prints a string and value to the log.
     23  */
     24 extern void __attribute__((overloadable))
     25     rsDebug(const char *, float, float, float, float);
     26 /**
     27  * Debug function.  Prints a string and value to the log.
     28  */
     29 extern void __attribute__((overloadable))
     30     rsDebug(const char *, double);
     31 /**
     32  * Debug function.  Prints a string and value to the log.
     33  */
     34 extern void __attribute__((overloadable))
     35     rsDebug(const char *, const rs_matrix4x4 *);
     36 /**
     37  * Debug function.  Prints a string and value to the log.
     38  */
     39 extern void __attribute__((overloadable))
     40     rsDebug(const char *, const rs_matrix3x3 *);
     41 /**
     42  * Debug function.  Prints a string and value to the log.
     43  */
     44 extern void __attribute__((overloadable))
     45     rsDebug(const char *, const rs_matrix2x2 *);
     46 /**
     47  * Debug function.  Prints a string and value to the log.
     48  */
     49 extern void __attribute__((overloadable))
     50     rsDebug(const char *, int);
     51 /**
     52  * Debug function.  Prints a string and value to the log.
     53  */
     54 extern void __attribute__((overloadable))
     55     rsDebug(const char *, uint);
     56 /**
     57  * Debug function.  Prints a string and value to the log.
     58  */
     59 extern void __attribute__((overloadable))
     60     rsDebug(const char *, long);
     61 /**
     62  * Debug function.  Prints a string and value to the log.
     63  */
     64 extern void __attribute__((overloadable))
     65     rsDebug(const char *, unsigned long);
     66 /**
     67  * Debug function.  Prints a string and value to the log.
     68  */
     69 extern void __attribute__((overloadable))
     70     rsDebug(const char *, long long);
     71 /**
     72  * Debug function.  Prints a string and value to the log.
     73  */
     74 extern void __attribute__((overloadable))
     75     rsDebug(const char *, unsigned long long);
     76 /**
     77  * Debug function.  Prints a string and value to the log.
     78  */
     79 extern void __attribute__((overloadable))
     80     rsDebug(const char *, const void *);
     81 #define RS_DEBUG(a) rsDebug(#a, a)
     82 #define RS_DEBUG_MARKER rsDebug(__FILE__, __LINE__)
     83 
     84 
     85 /**
     86  * Debug function.  Prints a string and value to the log.
     87  */
     88 _RS_RUNTIME void __attribute__((overloadable)) rsDebug(const char *s, float2 v);
     89 /**
     90  * Debug function.  Prints a string and value to the log.
     91  */
     92 _RS_RUNTIME void __attribute__((overloadable)) rsDebug(const char *s, float3 v);
     93 /**
     94  * Debug function.  Prints a string and value to the log.
     95  */
     96 _RS_RUNTIME void __attribute__((overloadable)) rsDebug(const char *s, float4 v);
     97 
     98 
     99 /**
    100  * Pack floating point (0-1) RGB values into a uchar4.  The alpha component is
    101  * set to 255 (1.0).
    102  *
    103  * @param r
    104  * @param g
    105  * @param b
    106  *
    107  * @return uchar4
    108  */
    109 _RS_RUNTIME uchar4 __attribute__((overloadable)) rsPackColorTo8888(float r, float g, float b);
    110 
    111 /**
    112  * Pack floating point (0-1) RGBA values into a uchar4.
    113  *
    114  * @param r
    115  * @param g
    116  * @param b
    117  * @param a
    118  *
    119  * @return uchar4
    120  */
    121 _RS_RUNTIME uchar4 __attribute__((overloadable)) rsPackColorTo8888(float r, float g, float b, float a);
    122 
    123 /**
    124  * Pack floating point (0-1) RGB values into a uchar4.  The alpha component is
    125  * set to 255 (1.0).
    126  *
    127  * @param color
    128  *
    129  * @return uchar4
    130  */
    131 _RS_RUNTIME uchar4 __attribute__((overloadable)) rsPackColorTo8888(float3 color);
    132 
    133 /**
    134  * Pack floating point (0-1) RGBA values into a uchar4.
    135  *
    136  * @param color
    137  *
    138  * @return uchar4
    139  */
    140 _RS_RUNTIME uchar4 __attribute__((overloadable)) rsPackColorTo8888(float4 color);
    141 
    142 /**
    143  * Unpack a uchar4 color to float4.  The resulting float range will be (0-1).
    144  *
    145  * @param c
    146  *
    147  * @return float4
    148  */
    149 _RS_RUNTIME float4 rsUnpackColor8888(uchar4 c);
    150 
    151 
    152 /////////////////////////////////////////////////////
    153 // Matrix ops
    154 /////////////////////////////////////////////////////
    155 
    156 /**
    157  * Set one element of a matrix.
    158  *
    159  * @param m The matrix to be set
    160  * @param row
    161  * @param col
    162  * @param v
    163  *
    164  * @return void
    165  */
    166 _RS_RUNTIME void __attribute__((overloadable))
    167 rsMatrixSet(rs_matrix4x4 *m, uint32_t row, uint32_t col, float v);
    168 _RS_RUNTIME void __attribute__((overloadable))
    169 rsMatrixSet(rs_matrix3x3 *m, uint32_t row, uint32_t col, float v);
    170 _RS_RUNTIME void __attribute__((overloadable))
    171 rsMatrixSet(rs_matrix2x2 *m, uint32_t row, uint32_t col, float v);
    172 
    173 /**
    174  * Get one element of a matrix.
    175  *
    176  * @param m The matrix to read from
    177  * @param row
    178  * @param col
    179  *
    180  * @return float
    181  */
    182 _RS_RUNTIME float __attribute__((overloadable))
    183 rsMatrixGet(const rs_matrix4x4 *m, uint32_t row, uint32_t col);
    184 _RS_RUNTIME float __attribute__((overloadable))
    185 rsMatrixGet(const rs_matrix3x3 *m, uint32_t row, uint32_t col);
    186 _RS_RUNTIME float __attribute__((overloadable))
    187 rsMatrixGet(const rs_matrix2x2 *m, uint32_t row, uint32_t col);
    188 
    189 /**
    190  * Set the elements of a matrix to the identity matrix.
    191  *
    192  * @param m
    193  */
    194 extern void __attribute__((overloadable)) rsMatrixLoadIdentity(rs_matrix4x4 *m);
    195 extern void __attribute__((overloadable)) rsMatrixLoadIdentity(rs_matrix3x3 *m);
    196 extern void __attribute__((overloadable)) rsMatrixLoadIdentity(rs_matrix2x2 *m);
    197 
    198 /**
    199  * Set the elements of a matrix from an array of floats.
    200  *
    201  * @param m
    202  */
    203 extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix4x4 *m, const float *v);
    204 extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix3x3 *m, const float *v);
    205 extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix2x2 *m, const float *v);
    206 
    207 /**
    208  * Set the elements of a matrix from another matrix.
    209  *
    210  * @param m
    211  */
    212 extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix4x4 *m, const rs_matrix4x4 *v);
    213 extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix4x4 *m, const rs_matrix3x3 *v);
    214 extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix4x4 *m, const rs_matrix2x2 *v);
    215 extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix3x3 *m, const rs_matrix3x3 *v);
    216 extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix2x2 *m, const rs_matrix2x2 *v);
    217 
    218 /**
    219  * Load a rotation matrix.
    220  *
    221  * @param m
    222  * @param rot
    223  * @param x
    224  * @param y
    225  * @param z
    226  */
    227 extern void __attribute__((overloadable))
    228 rsMatrixLoadRotate(rs_matrix4x4 *m, float rot, float x, float y, float z);
    229 
    230 extern void __attribute__((overloadable))
    231 rsMatrixLoadScale(rs_matrix4x4 *m, float x, float y, float z);
    232 
    233 extern void __attribute__((overloadable))
    234 rsMatrixLoadTranslate(rs_matrix4x4 *m, float x, float y, float z);
    235 
    236 extern void __attribute__((overloadable))
    237 rsMatrixLoadMultiply(rs_matrix4x4 *m, const rs_matrix4x4 *lhs, const rs_matrix4x4 *rhs);
    238 
    239 extern void __attribute__((overloadable))
    240 rsMatrixMultiply(rs_matrix4x4 *m, const rs_matrix4x4 *rhs);
    241 
    242 extern void __attribute__((overloadable))
    243 rsMatrixLoadMultiply(rs_matrix3x3 *m, const rs_matrix3x3 *lhs, const rs_matrix3x3 *rhs);
    244 
    245 extern void __attribute__((overloadable))
    246 rsMatrixMultiply(rs_matrix3x3 *m, const rs_matrix3x3 *rhs);
    247 
    248 extern void __attribute__((overloadable))
    249 rsMatrixLoadMultiply(rs_matrix2x2 *m, const rs_matrix2x2 *lhs, const rs_matrix2x2 *rhs);
    250 
    251 extern void __attribute__((overloadable))
    252 rsMatrixMultiply(rs_matrix2x2 *m, const rs_matrix2x2 *rhs);
    253 
    254 extern void __attribute__((overloadable))
    255 rsMatrixRotate(rs_matrix4x4 *m, float rot, float x, float y, float z);
    256 
    257 extern void __attribute__((overloadable))
    258 rsMatrixScale(rs_matrix4x4 *m, float x, float y, float z);
    259 
    260 extern void __attribute__((overloadable))
    261 rsMatrixTranslate(rs_matrix4x4 *m, float x, float y, float z);
    262 
    263 extern void __attribute__((overloadable))
    264 rsMatrixLoadOrtho(rs_matrix4x4 *m, float left, float right, float bottom, float top, float near, float far);
    265 
    266 extern void __attribute__((overloadable))
    267 rsMatrixLoadFrustum(rs_matrix4x4 *m, float left, float right, float bottom, float top, float near, float far);
    268 
    269 extern void __attribute__((overloadable))
    270 rsMatrixLoadPerspective(rs_matrix4x4* m, float fovy, float aspect, float near, float far);
    271 
    272 _RS_RUNTIME float4 __attribute__((overloadable))
    273 rsMatrixMultiply(rs_matrix4x4 *m, float4 in);
    274 
    275 _RS_RUNTIME float4 __attribute__((overloadable))
    276 rsMatrixMultiply(rs_matrix4x4 *m, float3 in);
    277 
    278 _RS_RUNTIME float4 __attribute__((overloadable))
    279 rsMatrixMultiply(rs_matrix4x4 *m, float2 in);
    280 
    281 _RS_RUNTIME float3 __attribute__((overloadable))
    282 rsMatrixMultiply(rs_matrix3x3 *m, float3 in);
    283 
    284 _RS_RUNTIME float3 __attribute__((overloadable))
    285 rsMatrixMultiply(rs_matrix3x3 *m, float2 in);
    286 
    287 _RS_RUNTIME float2 __attribute__((overloadable))
    288 rsMatrixMultiply(rs_matrix2x2 *m, float2 in);
    289 
    290 // Returns true if the matrix was successfully inversed
    291 extern bool __attribute__((overloadable)) rsMatrixInverse(rs_matrix4x4 *m);
    292 extern bool __attribute__((overloadable)) rsMatrixInverseTranspose(rs_matrix4x4 *m);
    293 extern void __attribute__((overloadable)) rsMatrixTranspose(rs_matrix4x4 *m);
    294 extern void __attribute__((overloadable)) rsMatrixTranspose(rs_matrix3x3 *m);
    295 extern void __attribute__((overloadable)) rsMatrixTranspose(rs_matrix2x2 *m);
    296 
    297 /////////////////////////////////////////////////////
    298 // quaternion ops
    299 /////////////////////////////////////////////////////
    300 
    301 static void __attribute__((overloadable))
    302 rsQuaternionSet(rs_quaternion *q, float w, float x, float y, float z) {
    303     q->w = w;
    304     q->x = x;
    305     q->y = y;
    306     q->z = z;
    307 }
    308 
    309 static void __attribute__((overloadable))
    310 rsQuaternionSet(rs_quaternion *q, const rs_quaternion *rhs) {
    311     q->w = rhs->w;
    312     q->x = rhs->x;
    313     q->y = rhs->y;
    314     q->z = rhs->z;
    315 }
    316 
    317 static void __attribute__((overloadable))
    318 rsQuaternionMultiply(rs_quaternion *q, float s) {
    319     q->w *= s;
    320     q->x *= s;
    321     q->y *= s;
    322     q->z *= s;
    323 }
    324 
    325 static void __attribute__((overloadable))
    326 rsQuaternionMultiply(rs_quaternion *q, const rs_quaternion *rhs) {
    327     q->w = -q->x*rhs->x - q->y*rhs->y - q->z*rhs->z + q->w*rhs->w;
    328     q->x =  q->x*rhs->w + q->y*rhs->z - q->z*rhs->y + q->w*rhs->x;
    329     q->y = -q->x*rhs->z + q->y*rhs->w + q->z*rhs->x + q->w*rhs->y;
    330     q->z =  q->x*rhs->y - q->y*rhs->x + q->z*rhs->w + q->w*rhs->z;
    331 }
    332 
    333 static void
    334 rsQuaternionAdd(rs_quaternion *q, const rs_quaternion *rhs) {
    335     q->w *= rhs->w;
    336     q->x *= rhs->x;
    337     q->y *= rhs->y;
    338     q->z *= rhs->z;
    339 }
    340 
    341 static void
    342 rsQuaternionLoadRotateUnit(rs_quaternion *q, float rot, float x, float y, float z) {
    343     rot *= (float)(M_PI / 180.0f) * 0.5f;
    344     float c = cos(rot);
    345     float s = sin(rot);
    346 
    347     q->w = c;
    348     q->x = x * s;
    349     q->y = y * s;
    350     q->z = z * s;
    351 }
    352 
    353 static void
    354 rsQuaternionLoadRotate(rs_quaternion *q, float rot, float x, float y, float z) {
    355     const float len = x*x + y*y + z*z;
    356     if (len != 1) {
    357         const float recipLen = 1.f / sqrt(len);
    358         x *= recipLen;
    359         y *= recipLen;
    360         z *= recipLen;
    361     }
    362     rsQuaternionLoadRotateUnit(q, rot, x, y, z);
    363 }
    364 
    365 static void
    366 rsQuaternionConjugate(rs_quaternion *q) {
    367     q->x = -q->x;
    368     q->y = -q->y;
    369     q->z = -q->z;
    370 }
    371 
    372 static float
    373 rsQuaternionDot(const rs_quaternion *q0, const rs_quaternion *q1) {
    374     return q0->w*q1->w + q0->x*q1->x + q0->y*q1->y + q0->z*q1->z;
    375 }
    376 
    377 static void
    378 rsQuaternionNormalize(rs_quaternion *q) {
    379     const float len = rsQuaternionDot(q, q);
    380     if (len != 1) {
    381         const float recipLen = 1.f / sqrt(len);
    382         rsQuaternionMultiply(q, recipLen);
    383     }
    384 }
    385 
    386 static void
    387 rsQuaternionSlerp(rs_quaternion *q, const rs_quaternion *q0, const rs_quaternion *q1, float t) {
    388     if (t <= 0.0f) {
    389         rsQuaternionSet(q, q0);
    390         return;
    391     }
    392     if (t >= 1.0f) {
    393         rsQuaternionSet(q, q1);
    394         return;
    395     }
    396 
    397     rs_quaternion tempq0, tempq1;
    398     rsQuaternionSet(&tempq0, q0);
    399     rsQuaternionSet(&tempq1, q1);
    400 
    401     float angle = rsQuaternionDot(q0, q1);
    402     if (angle < 0) {
    403         rsQuaternionMultiply(&tempq0, -1.0f);
    404         angle *= -1.0f;
    405     }
    406 
    407     float scale, invScale;
    408     if (angle + 1.0f > 0.05f) {
    409         if (1.0f - angle >= 0.05f) {
    410             float theta = acos(angle);
    411             float invSinTheta = 1.0f / sin(theta);
    412             scale = sin(theta * (1.0f - t)) * invSinTheta;
    413             invScale = sin(theta * t) * invSinTheta;
    414         } else {
    415             scale = 1.0f - t;
    416             invScale = t;
    417         }
    418     } else {
    419         rsQuaternionSet(&tempq1, tempq0.z, -tempq0.y, tempq0.x, -tempq0.w);
    420         scale = sin(M_PI * (0.5f - t));
    421         invScale = sin(M_PI * t);
    422     }
    423 
    424     rsQuaternionSet(q, tempq0.w*scale + tempq1.w*invScale, tempq0.x*scale + tempq1.x*invScale,
    425                         tempq0.y*scale + tempq1.y*invScale, tempq0.z*scale + tempq1.z*invScale);
    426 }
    427 
    428 static void rsQuaternionGetMatrixUnit(rs_matrix4x4 *m, const rs_quaternion *q) {
    429     float x2 = 2.0f * q->x * q->x;
    430     float y2 = 2.0f * q->y * q->y;
    431     float z2 = 2.0f * q->z * q->z;
    432     float xy = 2.0f * q->x * q->y;
    433     float wz = 2.0f * q->w * q->z;
    434     float xz = 2.0f * q->x * q->z;
    435     float wy = 2.0f * q->w * q->y;
    436     float wx = 2.0f * q->w * q->x;
    437     float yz = 2.0f * q->y * q->z;
    438 
    439     m->m[0] = 1.0f - y2 - z2;
    440     m->m[1] = xy - wz;
    441     m->m[2] = xz + wy;
    442     m->m[3] = 0.0f;
    443 
    444     m->m[4] = xy + wz;
    445     m->m[5] = 1.0f - x2 - z2;
    446     m->m[6] = yz - wx;
    447     m->m[7] = 0.0f;
    448 
    449     m->m[8] = xz - wy;
    450     m->m[9] = yz - wx;
    451     m->m[10] = 1.0f - x2 - y2;
    452     m->m[11] = 0.0f;
    453 
    454     m->m[12] = 0.0f;
    455     m->m[13] = 0.0f;
    456     m->m[14] = 0.0f;
    457     m->m[15] = 1.0f;
    458 }
    459 
    460 /////////////////////////////////////////////////////
    461 // utility funcs
    462 /////////////////////////////////////////////////////
    463 __inline__ static void __attribute__((overloadable, always_inline))
    464 rsExtractFrustumPlanes(const rs_matrix4x4 *modelViewProj,
    465                          float4 *left, float4 *right,
    466                          float4 *top, float4 *bottom,
    467                          float4 *near, float4 *far) {
    468     // x y z w = a b c d in the plane equation
    469     left->x = modelViewProj->m[3] + modelViewProj->m[0];
    470     left->y = modelViewProj->m[7] + modelViewProj->m[4];
    471     left->z = modelViewProj->m[11] + modelViewProj->m[8];
    472     left->w = modelViewProj->m[15] + modelViewProj->m[12];
    473 
    474     right->x = modelViewProj->m[3] - modelViewProj->m[0];
    475     right->y = modelViewProj->m[7] - modelViewProj->m[4];
    476     right->z = modelViewProj->m[11] - modelViewProj->m[8];
    477     right->w = modelViewProj->m[15] - modelViewProj->m[12];
    478 
    479     top->x = modelViewProj->m[3] - modelViewProj->m[1];
    480     top->y = modelViewProj->m[7] - modelViewProj->m[5];
    481     top->z = modelViewProj->m[11] - modelViewProj->m[9];
    482     top->w = modelViewProj->m[15] - modelViewProj->m[13];
    483 
    484     bottom->x = modelViewProj->m[3] + modelViewProj->m[1];
    485     bottom->y = modelViewProj->m[7] + modelViewProj->m[5];
    486     bottom->z = modelViewProj->m[11] + modelViewProj->m[9];
    487     bottom->w = modelViewProj->m[15] + modelViewProj->m[13];
    488 
    489     near->x = modelViewProj->m[3] + modelViewProj->m[2];
    490     near->y = modelViewProj->m[7] + modelViewProj->m[6];
    491     near->z = modelViewProj->m[11] + modelViewProj->m[10];
    492     near->w = modelViewProj->m[15] + modelViewProj->m[14];
    493 
    494     far->x = modelViewProj->m[3] - modelViewProj->m[2];
    495     far->y = modelViewProj->m[7] - modelViewProj->m[6];
    496     far->z = modelViewProj->m[11] - modelViewProj->m[10];
    497     far->w = modelViewProj->m[15] - modelViewProj->m[14];
    498 
    499     float len = length(left->xyz);
    500     *left /= len;
    501     len = length(right->xyz);
    502     *right /= len;
    503     len = length(top->xyz);
    504     *top /= len;
    505     len = length(bottom->xyz);
    506     *bottom /= len;
    507     len = length(near->xyz);
    508     *near /= len;
    509     len = length(far->xyz);
    510     *far /= len;
    511 }
    512 
    513 __inline__ static bool __attribute__((overloadable, always_inline))
    514 rsIsSphereInFrustum(float4 *sphere,
    515                       float4 *left, float4 *right,
    516                       float4 *top, float4 *bottom,
    517                       float4 *near, float4 *far) {
    518 
    519     float distToCenter = dot(left->xyz, sphere->xyz) + left->w;
    520     if (distToCenter < -sphere->w) {
    521         return false;
    522     }
    523     distToCenter = dot(right->xyz, sphere->xyz) + right->w;
    524     if (distToCenter < -sphere->w) {
    525         return false;
    526     }
    527     distToCenter = dot(top->xyz, sphere->xyz) + top->w;
    528     if (distToCenter < -sphere->w) {
    529         return false;
    530     }
    531     distToCenter = dot(bottom->xyz, sphere->xyz) + bottom->w;
    532     if (distToCenter < -sphere->w) {
    533         return false;
    534     }
    535     distToCenter = dot(near->xyz, sphere->xyz) + near->w;
    536     if (distToCenter < -sphere->w) {
    537         return false;
    538     }
    539     distToCenter = dot(far->xyz, sphere->xyz) + far->w;
    540     if (distToCenter < -sphere->w) {
    541         return false;
    542     }
    543     return true;
    544 }
    545 
    546 
    547 /////////////////////////////////////////////////////
    548 // int ops
    549 /////////////////////////////////////////////////////
    550 
    551 _RS_RUNTIME uint __attribute__((overloadable, always_inline)) rsClamp(uint amount, uint low, uint high);
    552 _RS_RUNTIME int __attribute__((overloadable, always_inline)) rsClamp(int amount, int low, int high);
    553 _RS_RUNTIME ushort __attribute__((overloadable, always_inline)) rsClamp(ushort amount, ushort low, ushort high);
    554 _RS_RUNTIME short __attribute__((overloadable, always_inline)) rsClamp(short amount, short low, short high);
    555 _RS_RUNTIME uchar __attribute__((overloadable, always_inline)) rsClamp(uchar amount, uchar low, uchar high);
    556 _RS_RUNTIME char __attribute__((overloadable, always_inline)) rsClamp(char amount, char low, char high);
    557 
    558 #undef _RS_RUNTIME
    559 
    560 #endif
    561