QuelSolaarHxA/hxa_util_normals.h
2020-05-03 14:16:33 +02:00

163 lines
4.3 KiB
C

/* Do not include or call anything defined in this .h file. It is exclusivly for the use of hxa_util_normals.c */
#ifdef NORMAL_FACE
HXATYPE *hxa_util_normal_face_macro(HXANode *node)
{
HXATYPE v1[3], v2[3], f, *normals, *n, *vertex, *a, *b, *c;
unsigned int i, j, count;
int *ref;
ref = node->content.geometry.corner_stack.layers[HXA_CONVENTION_HARD_BASE_CORNER_LAYER_ID].data.int32_data;
vertex = node->content.geometry.vertex_stack.layers[HXA_CONVENTION_HARD_BASE_VERTEX_LAYER_ID].data.HXATYPE_DATA;
n = normals = malloc((sizeof *normals) * node->content.geometry.face_count * 3);
for(i = 0; i < node->content.geometry.edge_corner_count;)
{
if(ref[i + 2] < 0) /* Triangle */
{
a = &vertex[hxa_ref(ref, i) * 3];
b = &vertex[hxa_ref(ref, i + 1) * 3];
c = &vertex[hxa_ref(ref, i + 2) * 3];
v1[0] = a[0] - c[0];
v1[1] = a[1] - c[1];
v1[2] = a[2] - c[2];
v2[0] = b[0] - c[0];
v2[1] = b[1] - c[1];
v2[2] = b[2] - c[2];
n[0] = v1[2] * v2[1] - v1[1] * v2[2];
n[1] = v1[0] * v2[2] - v1[2] * v2[0];
n[2] = v1[1] * v2[0] - v1[0] * v2[1];
i += 3;
}else
{
count = node->content.geometry.edge_corner_count - i;
n[0] = n[1] = n[2] = 0;
for(j = 0; j < count; j++)
{
if(ref[i + j + 2] < 0)
count = j + 2;
a = &vertex[hxa_ref(ref, (i + j)) * 3];
b = &vertex[hxa_ref(ref, (i + (j + 1) % count)) * 3];
c = &vertex[hxa_ref(ref, (i + (j + 2) % count)) * 3];
v1[0] = a[0] - c[0];
v1[1] = a[1] - c[1];
v1[2] = a[2] - c[2];
v2[0] = b[0] - c[0];
v2[1] = b[1] - c[1];
v2[2] = b[2] - c[2];
n[0] += v1[2] * v2[1] - v1[1] * v2[2];
n[1] += v1[0] * v2[2] - v1[2] * v2[0];
n[2] += v1[1] * v2[0] - v1[0] * v2[1];
}
i += count + 1;
}
f = sqrtf(n[0] * n[0] + n[1] * n[1] + n[2] * n[2]);
n[0] /= f;
n[1] /= f;
n[2] /= f;
n += 3;
}
return normals;
}
#endif
#ifdef NORMAL_CORNER
HXATYPE *hxa_util_normal_corner_macro(HXANode *node,
unsigned int *neighburs,
#ifdef HXA_CREASE_TYPE
HXA_CREASE_TYPE *creases,
#endif
HXATYPE *face_normals,
unsigned int *faces)
{
HXATYPE *corner_normals, *n, tmp[3], f;
unsigned int i, r;
int * ref;
ref = node->content.geometry.corner_stack.layers[HXA_CONVENTION_HARD_BASE_CORNER_LAYER_ID].data.int32_data;
corner_normals = malloc((sizeof *corner_normals) * node->content.geometry.edge_corner_count * 3);
for(i = 0; i < node->content.geometry.edge_corner_count * 3; i++)
corner_normals[i] = 0;
for(i = 0; i < node->content.geometry.edge_corner_count; i++)
{
if(corner_normals[i * 3] == 0 && corner_normals[i * 3 + 1] == 0 && corner_normals[i * 3 + 2] == 0)
{
r = i;
tmp[0] = tmp[1] = tmp[2] = 0;
n = &face_normals[faces[r] * 3];
tmp[0] += n[0];
tmp[1] += n[1];
tmp[2] += n[2];
r = i;
while(r = neighburs[hxa_corner_get_previous(ref, r)] != -1 && r != i
#ifdef HXA_CREASE_TYPE
&& !creases[r]
#endif
)
{
n = &face_normals[faces[r] * 3];
tmp[0] += n[0];
tmp[1] += n[1];
tmp[2] += n[2];
}
if(i != r)
{
r = i;
while(
#ifdef HXA_CREASE_TYPE
!creases[r] &&
#endif
(r = neighburs[r]) != -1 && (r = hxa_corner_get_next(ref, r)) != i)
{
n = &face_normals[faces[r] * 3];
tmp[0] += n[0];
tmp[1] += n[1];
tmp[2] += n[2];
}
}
f = sqrt(tmp[0] * tmp[0] + tmp[1] * tmp[1] + tmp[2] * tmp[2]);
tmp[0] /= f;
tmp[1] /= f;
tmp[2] /= f;
corner_normals[i * 3] = tmp[0];
corner_normals[i * 3 + 1] = tmp[1];
corner_normals[i * 3 + 2] = tmp[2];
r = i;
while(r = neighburs[hxa_corner_get_previous(ref, r)] != -1 && r != i
#ifdef HXA_CREASE_TYPE
&& !creases[r]
#endif
)
{
corner_normals[r * 3] = tmp[0];
corner_normals[r * 3 + 1] = tmp[1];
corner_normals[r * 3 + 2] = tmp[2];
}
if(i != r)
{
r = i;
while(
#ifdef HXA_CREASE_TYPE
!creases[r] &&
#endif
(r = neighburs[r]) != -1 && (r = hxa_corner_get_next(ref, r)) != i)
{
corner_normals[r * 3] = tmp[0];
corner_normals[r * 3 + 1] = tmp[1];
corner_normals[r * 3 + 2] = tmp[2];
}
}
}
}
return corner_normals;
}
#endif