rbdlsim/src/sconvcol.h

134 lines
2.8 KiB
C

#ifndef SCONVCOL_H
#define SCONVCOL_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdbool.h>
#include <assert.h>
#include "vectorial/simd4x4f.h"
typedef struct sch_edge sch_edge;
typedef struct sch_vert sch_vert;
typedef struct sch_face sch_face;
typedef struct sch_hull sch_hull;
typedef struct sch_plane sch_plane;
struct sch_edge {
sch_vert* vert;
sch_edge* twin;
sch_face* face;
sch_edge* next;
};
struct sch_vert {
simd4f p;
sch_edge* edge;
};
struct sch_face {
sch_edge* edge;
};
struct sch_hull {
int num_faces;
sch_face* faces;
};
struct sch_plane {
simd4f p;
simd4f n;
};
float sch_plane_distance (sch_plane* plane, simd4f* v);
void sch_edge_get_dir (sch_edge* edge, simd4f* dir);
void sch_hull_get_plane (sch_hull* hull, int index, sch_plane *out_plane);
void sch_hull_get_support (sch_hull* hull, simd4f n, simd4f* out_vert);
void sch_create_face (int num_vert, simd4f* vertices, sch_face* out_face);
void sch_create_hull (int num_faces, sch_face* faces,
sch_hull* out_hull);
//
// srender Implementation
//
#ifdef SCONVCOL_IMPLEMENTATION
float sch_plane_distance (sch_plane* plane, simd4f* v) {
return simd4f_dot3_scalar(simd4f_sub (*v, plane->p), plane->n);
}
void sch_create_face (int num_vert, simd4f* vertices, sch_face* out_face) {
assert(out_face != NULL);
assert(out_face->edge == NULL);
int i = 0;
sch_edge* f_edges = malloc(sizeof(sch_edge) * num_vert);
sch_vert* f_verts = malloc(sizeof(sch_vert) * num_vert);
while (i < num_vert) {
sch_vert* vert = &f_verts[i];
sch_edge* edge = &f_edges[i];
edge->twin = NULL;
edge->vert = vert;
edge->face = out_face;
edge->next = &f_edges[(i + 1) % num_vert];
vert->edge = edge;
vert->p = vertices[i];
i++;
}
out_face->edge = &f_edges[0];
}
void sch_edge_get_dir (sch_edge* edge, simd4f* out_dir) {
*out_dir = simd4f_sub (edge->next->vert->p, edge->vert->p);
float recip_len = 1. / sqrt(simd4f_dot3_scalar (*out_dir, *out_dir));
*out_dir = simd4f_mul (*out_dir, simd4f_splat(recip_len));
}
void sch_create_hull (int num_faces, sch_face* faces,
sch_hull* out_hull) {
assert (out_hull != NULL);
assert (out_hull->num_faces == NULL);
out_hull->num_faces = num_faces;
out_hull->faces = faces;
}
void sch_hull_get_plane (sch_hull* hull, int index, sch_plane* out_plane) {
assert (hull != NULL);
assert (index >= 0 && index < hull->num_faces);
assert (out_plane != NULL);
// TODO move plane calculation to create hull?
sch_face* face = &hull->faces[index];
sch_edge* edge0 = face->edge;
sch_edge* edge1 = edge0->next;
simd4f dir0;
simd4f dir1;
sch_edge_get_dir(edge0, &dir0);
sch_edge_get_dir(edge1, &dir1);
out_plane->p = edge0->vert->p;
out_plane->n = simd4f_cross3 (dir0, dir1);
}
#endif /* SCONVCOL_IMPLEMENTATION */
#ifdef __cplusplus
}
#endif
#endif /* SCONVCOL_H */