2020-08-16 21:43:28 +03:00
|
|
|
uint findMSB_(uint x)
|
2019-07-21 03:04:35 +03:00
|
|
|
{
|
2019-07-22 08:02:07 +03:00
|
|
|
uint i;
|
|
|
|
uint mask;
|
|
|
|
uint res = -1;
|
|
|
|
|
|
|
|
for (i = 0; i < 32; i++)
|
|
|
|
{
|
|
|
|
mask = 0x80000000 >> i;
|
2019-07-21 03:04:35 +03:00
|
|
|
|
2019-07-22 08:02:07 +03:00
|
|
|
if ((x & mask) != 0)
|
|
|
|
{
|
|
|
|
res = 31 - i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
2019-07-21 03:04:35 +03:00
|
|
|
|
|
|
|
uint parentKey(in uint key)
|
|
|
|
{
|
2019-07-22 08:02:07 +03:00
|
|
|
return (key >> 1u);
|
2019-07-21 03:04:35 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void childrenKeys(in uint key, out uint children[2])
|
|
|
|
{
|
2019-07-22 08:02:07 +03:00
|
|
|
children[0] = (key << 1u) | 0u;
|
|
|
|
children[1] = (key << 1u) | 1u;
|
2019-07-21 03:04:35 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
bool isRootKey(in uint key)
|
|
|
|
{
|
2019-07-22 08:02:07 +03:00
|
|
|
return (key == 1u);
|
2019-07-21 03:04:35 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
bool isLeafKey(in uint key)
|
|
|
|
{
|
2020-08-16 21:43:28 +03:00
|
|
|
return findMSB_(key) == 31;
|
2019-07-21 03:04:35 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
bool isChildZeroKey(in uint key)
|
|
|
|
{
|
2019-07-22 08:02:07 +03:00
|
|
|
return ((key & 1u) == 0u);
|
2019-07-21 03:04:35 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// barycentric interpolation
|
|
|
|
vec3 berp(in vec3 v[3], in vec2 u)
|
|
|
|
{
|
2019-07-22 08:02:07 +03:00
|
|
|
return v[0] + u.x * (v[1] - v[0]) + u.y * (v[2] - v[0]);
|
2019-07-21 03:04:35 +03:00
|
|
|
}
|
2019-07-22 08:02:07 +03:00
|
|
|
|
2019-07-21 03:04:35 +03:00
|
|
|
vec4 berp(in vec4 v[3], in vec2 u)
|
|
|
|
{
|
2019-07-22 08:02:07 +03:00
|
|
|
return v[0] + u.x * (v[1] - v[0]) + u.y * (v[2] - v[0]);
|
2019-07-21 03:04:35 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// get xform from bit value
|
|
|
|
mat3 bitToXform(in uint bit)
|
|
|
|
{
|
2019-07-22 08:02:07 +03:00
|
|
|
float b = float(bit);
|
|
|
|
float c = 1.0f - b;
|
|
|
|
|
|
|
|
vec3 c1 = vec3(0.0f, c , b );
|
|
|
|
vec3 c2 = vec3(0.5f, b , 0.0f);
|
|
|
|
vec3 c3 = vec3(0.5f, 0.0f, c );
|
|
|
|
|
2019-07-21 03:04:35 +03:00
|
|
|
return mtxFromCols(c1, c2, c3);
|
|
|
|
}
|
|
|
|
|
|
|
|
// get xform from key
|
|
|
|
mat3 keyToXform(in uint key)
|
|
|
|
{
|
|
|
|
vec3 c1 = vec3(1.0f, 0.0f, 0.0f);
|
2019-07-22 08:02:07 +03:00
|
|
|
vec3 c2 = vec3(0.0f, 1.0f, 0.0f);
|
|
|
|
vec3 c3 = vec3(0.0f, 0.0f, 1.0f);
|
|
|
|
|
|
|
|
mat3 xf = mtxFromCols(c1, c2, c3);
|
2019-07-21 03:04:35 +03:00
|
|
|
|
2019-07-22 08:02:07 +03:00
|
|
|
while (key > 1u) {
|
|
|
|
xf = mul(xf, bitToXform(key & 1u));
|
|
|
|
key = key >> 1u;
|
|
|
|
}
|
2019-07-21 03:04:35 +03:00
|
|
|
|
2019-07-22 08:02:07 +03:00
|
|
|
return xf;
|
2019-07-21 03:04:35 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// get xform from key as well as xform from parent key
|
|
|
|
mat3 keyToXform(in uint key, out mat3 xfp)
|
|
|
|
{
|
2019-07-22 08:02:07 +03:00
|
|
|
xfp = keyToXform(parentKey(key));
|
|
|
|
return keyToXform(key);
|
2019-07-21 03:04:35 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// subdivision routine (vertex position only)
|
|
|
|
void subd(in uint key, in vec4 v_in[3], out vec4 v_out[3])
|
|
|
|
{
|
2019-07-22 08:02:07 +03:00
|
|
|
mat3 xf = keyToXform(key);
|
|
|
|
|
2019-07-21 03:04:35 +03:00
|
|
|
mat4x3 m = mtxFromRows(v_in[0], v_in[1], v_in[2]);
|
2019-07-22 08:02:07 +03:00
|
|
|
|
|
|
|
mat4x3 v = mul(xf, m);
|
|
|
|
|
2019-07-21 03:04:35 +03:00
|
|
|
v_out[0] = mtxGetRow(v, 0);
|
|
|
|
v_out[1] = mtxGetRow(v, 1);
|
2019-07-22 08:02:07 +03:00
|
|
|
v_out[2] = mtxGetRow(v, 2);
|
2019-07-21 03:04:35 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// subdivision routine (vertex position only)
|
|
|
|
// also computes parent position
|
|
|
|
void subd(in uint key, in vec4 v_in[3], out vec4 v_out[3], out vec4 v_out_p[3])
|
|
|
|
{
|
2019-07-22 08:02:07 +03:00
|
|
|
mat3 xfp; mat3 xf = keyToXform(key, xfp);
|
|
|
|
|
2019-07-21 03:04:35 +03:00
|
|
|
mat4x3 m = mtxFromRows(v_in[0], v_in[1], v_in[2]);
|
2019-07-22 08:02:07 +03:00
|
|
|
|
2019-07-21 03:04:35 +03:00
|
|
|
mat4x3 v = mul(xf, m);
|
2019-07-22 08:02:07 +03:00
|
|
|
mat4x3 vp = mul(xfp, m);
|
|
|
|
|
2019-07-21 03:04:35 +03:00
|
|
|
v_out[0] = mtxGetRow(v, 0);
|
|
|
|
v_out[1] = mtxGetRow(v, 1);
|
|
|
|
v_out[2] = mtxGetRow(v, 2);
|
2019-07-22 08:02:07 +03:00
|
|
|
|
2019-07-21 03:04:35 +03:00
|
|
|
v_out_p[0] = mtxGetRow(vp, 0);
|
|
|
|
v_out_p[1] = mtxGetRow(vp, 1);
|
|
|
|
v_out_p[2] = mtxGetRow(vp, 2);
|
|
|
|
}
|