bevy/test-data/generate-test-data.c
alteous dc8fe97715 Add closures interface
Former-commit-id: 76f4a864fa3b1fbde9d5ac2eab7c5d0639d147ef
2017-08-29 19:16:39 +01:00

246 lines
5.9 KiB
C

#include <assert.h>
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include "mikktspace.h"
struct tangent {
// Vector.
float v[3];
// Sign.
float s;
};
struct vertex {
// Borrows from `input.positions`.
float (*position)[3];
// Borrows from `input.positions`.
float (*normal)[3];
// Borrows from `input.positions`.
float (*tex_coord)[2];
};
struct face {
// Borrows from `positions`, `normals`, and `tex_coords`.
struct vertex vertices[3];
};
struct input {
// Owned.
float (*positions)[3];
// Owned.
float (*normals)[3];
// Owned.
float (*tex_coords)[2];
// Borrows from `positions`, `normals`, and `tex_coords`.
struct face *faces;
// Number of entries in `positions`, `normals`, and `tex_coords`.
size_t nr_vertices;
// Number of entries in `faces`.
size_t nr_faces;
} input;
struct output {
// Borrows from `positions`, `normals`, and `tex_coords`.
struct vertex *vertices;
// Owned.
struct tangent *tangents;
// Number of entries in `vertices` and `tangents`.
// Equal to `3 * input.nr_faces`.
size_t nr_vertices;
} output;
void print_vec2(float (*t)[2]) {
printf("[%f, %f]", (*t)[0], (*t)[1]);
}
void print_vec3(float (*t)[3]) {
printf("[%f, %f, %f]", (*t)[0], (*t)[1], (*t)[2]);
}
void print_tangent(const struct tangent *t) {
printf("[%f, %f, %f, %f]", t->v[0], t->v[1], t->v[2], t->s);
}
int get_num_faces(const SMikkTSpaceContext *x) {
return input.nr_faces;
}
int get_num_vertices_of_face(const SMikkTSpaceContext *x, int f) {
return 3;
}
void get_position(const SMikkTSpaceContext *x, float *dst, int f, int v) {
float (*src)[3] = input.faces[f].vertices[v].position;
memcpy(dst, src, sizeof(*src));
}
void get_normal(const SMikkTSpaceContext *x, float *dst, int f, int v) {
float (*src)[3] = input.faces[f].vertices[v].normal;
memcpy(dst, src, sizeof(*src));
}
void get_tex_coord(const SMikkTSpaceContext *x, float *dst, int f, int v) {
float (*src)[2] = input.faces[f].vertices[v].tex_coord;
memcpy(dst, src, sizeof(*src));
}
void set_tspace_basic(
const SMikkTSpaceContext *x,
const float *t,
float s,
int f,
int v
) {
// The index of the last output (vertex, tangent) pair.
static int i = 0;
struct vertex *in = &input.faces[f].vertices[v];
output.vertices[i].position = in->position;
output.vertices[i].normal = in->normal;
output.vertices[i].tex_coord = in->tex_coord;
memcpy(output.tangents[i].v, t, 3 * sizeof(float));
output.tangents[i].s = s;
++i;
}
void set_tspace(
const SMikkTSpaceContext *x,
const float *t,
const float *b,
float mag_s,
float mag_t,
tbool op,
int f,
int v
) {
assert(!"unreachable");
}
int main() {
input.nr_vertices = 406;
input.nr_faces = 682;
output.nr_vertices = 3 * input.nr_faces;
input.positions = calloc(input.nr_vertices, sizeof(*input.positions));
input.normals = calloc(input.nr_vertices, sizeof(*input.normals));
input.tex_coords = calloc(input.nr_vertices, sizeof(*input.tex_coords));
input.faces = calloc(input.nr_faces, sizeof(*input.faces));
output.vertices = calloc(output.nr_vertices, sizeof(*output.vertices));
output.tangents = calloc(output.nr_vertices, sizeof(*output.tangents));
FILE *fi = fopen("Avocado.obj", "rb");
assert(fi);
char buffer[1024];
for (size_t i = 0; i < input.nr_vertices; ++i) {
fgets(buffer, sizeof(buffer), fi);
sscanf(
buffer,
"v %f %f %f",
&input.positions[i][0],
&input.positions[i][1],
&input.positions[i][2]
);
}
for (size_t i = 0; i < input.nr_vertices; ++i) {
fgets(buffer, sizeof(buffer), fi);
sscanf(
buffer,
"vn %f %f %f",
&input.normals[i][0],
&input.normals[i][1],
&input.normals[i][2]
);
}
for (size_t i = 0; i < input.nr_vertices; ++i) {
fgets(buffer, sizeof(buffer), fi);
sscanf(
buffer,
"vt %f %f",
&input.tex_coords[i][0],
&input.tex_coords[i][1]
);
}
for (size_t i = 0; i < input.nr_faces; ++i) {
fgets(buffer, sizeof(buffer), fi);
int v[3];
sscanf(
buffer,
"f %d/%d/%d %d/%d/%d %d/%d/%d",
&v[0], &v[0], &v[0],
&v[1], &v[1], &v[1],
&v[2], &v[2], &v[2]
);
for (size_t j = 0; j < 3; ++j) {
input.faces[i].vertices[j].position = &input.positions[v[j] - 1];
input.faces[i].vertices[j].normal = &input.normals[v[j] - 1];
input.faces[i].vertices[j].tex_coord = &input.tex_coords[v[j] - 1];
}
}
SMikkTSpaceInterface interface = {
.m_getNumFaces = get_num_faces,
.m_getNumVerticesOfFace = get_num_vertices_of_face,
.m_getPosition = get_position,
.m_getNormal = get_normal,
.m_getTexCoord = get_tex_coord,
.m_setTSpaceBasic = set_tspace_basic,
.m_setTSpace = NULL,
};
SMikkTSpaceContext context = {
.m_pInterface = &interface,
.m_pUserData = NULL,
};
genTangSpaceDefault(&context);
printf("{\n \"vlist\": [\n");
for (size_t i = 0; i < output.nr_vertices; ++i) {
printf(" {\"v\": ");
print_vec3(output.vertices[i].position);
printf(", \"vn\": ");
print_vec3(output.vertices[i].normal);
printf(", \"vt\": ");
print_vec2(output.vertices[i].tex_coord);
printf(", \"vx\": ");
print_tangent(&output.tangents[i]);
if (i == output.nr_vertices - 1) {
printf("}\n");
} else {
printf("},\n");
}
}
printf(" ]\n}");
fclose(fi);
free(input.positions);
free(input.normals);
free(input.tex_coords);
free(input.faces);
free(output.vertices);
free(output.tangents);
return 0;
}