A way to be preferred over reading the struct - whose memory layout can vary, as you see - as it is and reducing its size could be the way to go.
That said, you can read the file in large blocks and cut the data in the parts you need. Then you read out field for field and put the data into your target array. Something like
float read_float(void ** data) {
float ** fp = data;
float ret = **fp; (*fp)++;
return ret;
}
point read_point(void ** data) {
point ret;
ret.x = read_float(data);
ret.y = read_float(data);
ret.z = read_float(data);
return ret;
}
int16_t read16(void ** data) {
int16_t ** i16p = data;
int16_t ret = **i16p; (*i16p)++;
return ret;
}
point read_triangle(void ** data) {
triangle ret;
ret.normal_vector = read_point(data);
ret.p1 = read_point(data);
ret.p2 = read_point(data);
ret.p3 = read_point(data);
ret.notuse = read_int16(data); // using short int is not portable as well as its size could vary...
return ret;
}
void * scursor = source_array; // which would be a char array
while (scursor < source_array + sizeof(source_array)) {
// make sure that there are enough data present...
target[tcursor++] = read_triangle(&scursor); // the scursor will be advanced by the called function.
}
This way could as well - with certain enhancements - be used to keep e. g. the endianness of your numbers the same - which would be preferrably big endian on files intended to be interchanged between platforms. The changes to read16
would be small, the changes to read_float
a bit bigger, but still doable.