diff --git a/src/libstl/stl_global.h b/src/libstl/stl_global.h index 72b00b3..53d815b 100644 --- a/src/libstl/stl_global.h +++ b/src/libstl/stl_global.h @@ -16,6 +16,5 @@ /* STLB */ #define FOUG_STLB_HEADER_SIZE 80 #define FOUG_STLB_MIN_CONTENTS_SIZE 284 -#define FOUG_STLB_TRIANGLE_SIZE 50 /* 12 * sizeof(foug_real32_t) + sizeof(uint16_t) */ #endif /* FOUG_DATAX_C_LIBSTL_STLB_GLOBAL_H */ diff --git a/src/libstl/stl_triangle.h b/src/libstl/stl_triangle.h index d8fb12b..14f8b01 100644 --- a/src/libstl/stl_triangle.h +++ b/src/libstl/stl_triangle.h @@ -9,6 +9,7 @@ typedef struct foug_stl_coords foug_real32_t y; foug_real32_t z; } foug_stl_coords_t; +#define FOUG_STL_COORDS_RAWSIZE (3 * sizeof(foug_real32_t)) typedef struct foug_stl_triangle { @@ -17,5 +18,6 @@ typedef struct foug_stl_triangle foug_stl_coords_t v2; foug_stl_coords_t v3; } foug_stl_triangle_t; +#define FOUG_STL_TRIANGLE_RAWSIZE (4 * FOUG_STL_COORDS_RAWSIZE) #endif /* FOUG_DATAX_C_LIBSTL_TRIANGLE_H */ diff --git a/src/libstl/stlb_read.c b/src/libstl/stlb_read.c index 483d3c5..fc1cf5d 100644 --- a/src/libstl/stlb_read.c +++ b/src/libstl/stlb_read.c @@ -1,8 +1,31 @@ #include "stlb_read.h" +#include "../convert.h" #include "../error.h" #include "../endian.h" +#include + +static void read_triangle_memcpy(const uint8_t* buffer, foug_stlb_triangle_t* triangle) +{ + /* *triangle = *((foug_stlb_triangle_t*)(buffer)); */ + memcpy(triangle, buffer, FOUG_STLB_TRIANGLE_RAWSIZE); +} + +static void read_coords_alignsafe(const uint8_t* buffer, foug_stl_coords_t* coords) +{ + memcpy(coords, buffer, FOUG_STL_COORDS_RAWSIZE); +} + +static void read_triangle_alignsafe(const uint8_t* buffer, foug_stlb_triangle_t* triangle) +{ + read_coords_alignsafe(buffer, &triangle->data.normal); + read_coords_alignsafe(buffer + 1*FOUG_STL_COORDS_RAWSIZE, &triangle->data.v1); + read_coords_alignsafe(buffer + 2*FOUG_STL_COORDS_RAWSIZE, &triangle->data.v2); + read_coords_alignsafe(buffer + 3*FOUG_STL_COORDS_RAWSIZE, &triangle->data.v3); + memcpy(&triangle->attribute_byte_count, buffer + 4*FOUG_STL_COORDS_RAWSIZE, sizeof(uint16_t)); +} + static void foug_stlb_read_facets(foug_stlb_geom_input_t* geom, uint8_t* buffer, uint32_t facet_count) @@ -17,8 +40,12 @@ static void foug_stlb_read_facets(foug_stlb_geom_input_t* geom, buffer_offset = 0; for (i_facet = 0; i_facet < facet_count; ++i_facet) { /* Decode data */ - triangle = *((foug_stlb_triangle_t*)(buffer + buffer_offset)); - buffer_offset += FOUG_STLB_TRIANGLE_SIZE; +#ifdef FOUG_STLB_READWRITE_ALIGNSAFE + read_triangle_alignsafe(buffer + buffer_offset, &triangle); +#else + read_triangle_memcpy(buffer + buffer_offset, &triangle); +#endif + buffer_offset += FOUG_STLB_TRIANGLE_RAWSIZE; /* Declare triangle */ geom->process_next_triangle_func(geom, &triangle); @@ -66,8 +93,8 @@ int foug_stlb_read(foug_stlb_geom_input_t* geom, while (foug_datax_no_error(error) && accum_facet_count_read < total_facet_count) { const size_t facet_count_read = foug_stream_read(&trsf->stream, trsf->buffer, - FOUG_STLB_TRIANGLE_SIZE, - trsf->buffer_size / FOUG_STLB_TRIANGLE_SIZE); + FOUG_STLB_TRIANGLE_RAWSIZE, + trsf->buffer_size / FOUG_STLB_TRIANGLE_RAWSIZE); if (foug_stream_error(&trsf->stream) != 0) error = FOUG_DATAX_STREAM_ERROR; else if (facet_count_read > 0) diff --git a/src/libstl/stlb_triangle.h b/src/libstl/stlb_triangle.h index 6375357..500db37 100644 --- a/src/libstl/stlb_triangle.h +++ b/src/libstl/stlb_triangle.h @@ -8,5 +8,6 @@ typedef struct foug_stlb_triangle foug_stl_triangle_t data; uint16_t attribute_byte_count; } foug_stlb_triangle_t; +#define FOUG_STLB_TRIANGLE_RAWSIZE (FOUG_STL_TRIANGLE_RAWSIZE + sizeof(uint16_t)) #endif /* FOUG_DATAX_C_LIBSTL_STLB_TRIANGLE_H */ diff --git a/src/libstl/stlb_write.c b/src/libstl/stlb_write.c index 369a26b..f4ef18e 100644 --- a/src/libstl/stlb_write.c +++ b/src/libstl/stlb_write.c @@ -4,6 +4,25 @@ #include "../error.h" #include +static void write_triangle_memcpy(const foug_stlb_triangle_t* triangle, uint8_t* buffer) +{ + memcpy(buffer, triangle, FOUG_STLB_TRIANGLE_RAWSIZE); +} + +static void write_coords_alignsafe(const foug_stl_coords_t* coords, uint8_t* buffer) +{ + memcpy(buffer, coords, FOUG_STL_COORDS_RAWSIZE); +} + +static void write_triangle_alignsafe(const foug_stlb_triangle_t* triangle, uint8_t* buffer) +{ + write_coords_alignsafe(&triangle->data.normal, buffer); + write_coords_alignsafe(&triangle->data.v1, buffer + 1*FOUG_STL_COORDS_RAWSIZE); + write_coords_alignsafe(&triangle->data.v2, buffer + 2*FOUG_STL_COORDS_RAWSIZE); + write_coords_alignsafe(&triangle->data.v3, buffer + 3*FOUG_STL_COORDS_RAWSIZE); + memcpy(buffer + 4*FOUG_STL_COORDS_RAWSIZE, &triangle->attribute_byte_count, sizeof(uint16_t)); +} + static void foug_stlb_write_facets(const foug_stlb_geom_output_t* geom, uint8_t* buffer, uint32_t ifacet_start, @@ -20,8 +39,13 @@ static void foug_stlb_write_facets(const foug_stlb_geom_output_t* geom, for (i_facet = ifacet_start; i_facet < (ifacet_start + facet_count); ++i_facet) { geom->get_triangle_func(geom, i_facet, &triangle); - memcpy(buffer + buffer_offset, &triangle, FOUG_STLB_TRIANGLE_SIZE); - buffer_offset += FOUG_STLB_TRIANGLE_SIZE; +#ifdef FOUG_STLB_READWRITE_ALIGNSAFE + write_triangle_alignsafe(&triangle, buffer + buffer_offset); +#else + write_triangle_memcpy(&triangle, buffer + buffer_offset); +#endif + + buffer_offset += FOUG_STLB_TRIANGLE_RAWSIZE; } /* end for */ } @@ -70,7 +94,7 @@ int foug_stlb_write(const foug_stlb_geom_output_t* geom, /* Write triangles */ error = FOUG_DATAX_NO_ERROR; - buffer_facet_count = trsf->buffer_size / FOUG_STLB_TRIANGLE_SIZE; + buffer_facet_count = trsf->buffer_size / FOUG_STLB_TRIANGLE_RAWSIZE; ifacet_start = 0; for (i_facet = 0; i_facet < facet_count && foug_datax_no_error(error); @@ -83,7 +107,7 @@ int foug_stlb_write(const foug_stlb_geom_output_t* geom, ifacet_start += buffer_facet_count; /* Write buffer to stream */ - if (foug_stream_write(&trsf->stream, trsf->buffer, FOUG_STLB_TRIANGLE_SIZE, buffer_facet_count) + if (foug_stream_write(&trsf->stream, trsf->buffer, FOUG_STLB_TRIANGLE_RAWSIZE, buffer_facet_count) != buffer_facet_count) { error = FOUG_DATAX_STREAM_ERROR;