86 lines
3.0 KiB
C
86 lines
3.0 KiB
C
|
|
#include "global.h"
|
||
|
|
|
||
|
|
void *plugin;
|
||
|
|
|
||
|
|
void *import_stl(char *path) {
|
||
|
|
buffer_t *b = data_get_blob(path);
|
||
|
|
int pos = 80; // skip header
|
||
|
|
int faces = buffer_get_i32(b, pos);
|
||
|
|
pos += 4;
|
||
|
|
|
||
|
|
f32_array_t *pos_temp = f32_array_create(faces * 9);
|
||
|
|
f32_array_t *nor_temp = f32_array_create(faces * 3);
|
||
|
|
|
||
|
|
for (int i = 0; i < faces; ++i) {
|
||
|
|
int i3 = i * 3;
|
||
|
|
nor_temp->buffer[i3 ] = buffer_get_f32(b, pos); pos += 4;
|
||
|
|
nor_temp->buffer[i3 + 1] = buffer_get_f32(b, pos); pos += 4;
|
||
|
|
nor_temp->buffer[i3 + 2] = buffer_get_f32(b, pos); pos += 4;
|
||
|
|
int i9 = i * 9;
|
||
|
|
pos_temp->buffer[i9 ] = buffer_get_f32(b, pos); pos += 4;
|
||
|
|
pos_temp->buffer[i9 + 1] = buffer_get_f32(b, pos); pos += 4;
|
||
|
|
pos_temp->buffer[i9 + 2] = buffer_get_f32(b, pos); pos += 4;
|
||
|
|
pos_temp->buffer[i9 + 3] = buffer_get_f32(b, pos); pos += 4;
|
||
|
|
pos_temp->buffer[i9 + 4] = buffer_get_f32(b, pos); pos += 4;
|
||
|
|
pos_temp->buffer[i9 + 5] = buffer_get_f32(b, pos); pos += 4;
|
||
|
|
pos_temp->buffer[i9 + 6] = buffer_get_f32(b, pos); pos += 4;
|
||
|
|
pos_temp->buffer[i9 + 7] = buffer_get_f32(b, pos); pos += 4;
|
||
|
|
pos_temp->buffer[i9 + 8] = buffer_get_f32(b, pos); pos += 4;
|
||
|
|
pos += 2; // skip attribute
|
||
|
|
}
|
||
|
|
|
||
|
|
float scale_pos = 0.0;
|
||
|
|
for (int i = 0; i < pos_temp->length; ++i) {
|
||
|
|
float f = pos_temp->buffer[i];
|
||
|
|
if (f < 0.0) f = -f;
|
||
|
|
if (scale_pos < f) scale_pos = f;
|
||
|
|
}
|
||
|
|
float inv = 32767.0 * (1.0 / scale_pos);
|
||
|
|
|
||
|
|
int verts = faces * 3;
|
||
|
|
i16_array_t *posa = i16_array_create(verts * 4);
|
||
|
|
i16_array_t *nora = i16_array_create(verts * 2);
|
||
|
|
u32_array_t *inda = u32_array_create(verts);
|
||
|
|
|
||
|
|
for (int i = 0; i < verts; ++i) {
|
||
|
|
int f = (i / 3) * 3; // face normal base index
|
||
|
|
|
||
|
|
// posa->buffer[i * 4 ] = (int)( pos_temp->buffer[i * 3 ] * inv);
|
||
|
|
// posa->buffer[i * 4 + 1] = (int)(-pos_temp->buffer[i * 3 + 2] * inv);
|
||
|
|
// posa->buffer[i * 4 + 2] = (int)( pos_temp->buffer[i * 3 + 1] * inv);
|
||
|
|
// nora->buffer[i * 2 ] = (int)( nor_temp->buffer[f ] * 32767.0);
|
||
|
|
// nora->buffer[i * 2 + 1] = (int)(-nor_temp->buffer[f + 2] * 32767.0);
|
||
|
|
// posa->buffer[i * 4 + 3] = (int)( nor_temp->buffer[f + 1] * 32767.0);
|
||
|
|
buffer_set_i16(posa, (i * 4) * 2, pos_temp->buffer[i * 3 ] * inv);
|
||
|
|
buffer_set_i16(posa, (i * 4 + 1) * 2, -pos_temp->buffer[i * 3 + 2] * inv);
|
||
|
|
buffer_set_i16(posa, (i * 4 + 2) * 2, pos_temp->buffer[i * 3 + 1] * inv);
|
||
|
|
buffer_set_i16(nora, (i * 2) * 2, nor_temp->buffer[f ] * 32767.0);
|
||
|
|
buffer_set_i16(nora, (i * 2 + 1) * 2, -nor_temp->buffer[f + 2] * 32767.0);
|
||
|
|
buffer_set_i16(posa, (i * 4 + 3) * 2, nor_temp->buffer[f + 1] * 32767.0);
|
||
|
|
|
||
|
|
inda->buffer[i] = i;
|
||
|
|
}
|
||
|
|
|
||
|
|
data_delete_blob(path);
|
||
|
|
|
||
|
|
string_array_t *a = string_split(path, "\\\\");
|
||
|
|
char *s = array_pop(a);
|
||
|
|
a = string_split(s, "/");
|
||
|
|
s = array_pop(a);
|
||
|
|
a = string_split(s, ".");
|
||
|
|
char *name = a->buffer[0];
|
||
|
|
|
||
|
|
return plugin_make_raw_mesh(name, posa, nora, inda, scale_pos);
|
||
|
|
}
|
||
|
|
|
||
|
|
void on_delete() {
|
||
|
|
plugin_unregister_mesh("stl");
|
||
|
|
}
|
||
|
|
|
||
|
|
void main() {
|
||
|
|
plugin = plugin_create();
|
||
|
|
gc_root(plugin);
|
||
|
|
plugin_notify_on_delete(plugin, on_delete);
|
||
|
|
plugin_register_mesh("stl", import_stl);
|
||
|
|
}
|