134 lines
2.8 KiB
C
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 */
|