static void color_read(float rgb[3], Lib3dsIo *io) { Lib3dsChunk c; uint16_t chunk; int have_lin = FALSE; lib3ds_chunk_read_start(&c, 0, io); while ((chunk = lib3ds_chunk_read_next(&c, io)) != 0) { switch (chunk) { case CHK_LIN_COLOR_24: { int i; for (i = 0; i < 3; ++i) { rgb[i] = 1.0f * lib3ds_io_read_byte(io) / 255.0f; } have_lin = TRUE; break; } case CHK_COLOR_24: { /* gamma corrected color chunk replaced in 3ds R3 by LIN_COLOR_24 */ if (!have_lin) { int i; for (i = 0; i < 3; ++i) { rgb[i] = 1.0f * lib3ds_io_read_byte(io) / 255.0f; } } break; } case CHK_LIN_COLOR_F: { int i; for (i = 0; i < 3; ++i) { rgb[i] = lib3ds_io_read_float(io); } have_lin = TRUE; break; } case CHK_COLOR_F: { if (!have_lin) { int i; for (i = 0; i < 3; ++i) { rgb[i] = lib3ds_io_read_float(io); } } break; } default: lib3ds_chunk_unknown(chunk, io); } } lib3ds_chunk_read_end(&c, io); }
void lib3ds_mesh_read(Lib3dsFile *file, Lib3dsMesh *mesh, Lib3dsIo *io) { Lib3dsChunk c; uint16_t chunk; lib3ds_chunk_read_start(&c, CHK_N_TRI_OBJECT, io); while ((chunk = lib3ds_chunk_read_next(&c, io)) != 0) { switch (chunk) { case CHK_MESH_MATRIX: { int i, j; lib3ds_matrix_identity(mesh->matrix); for (i = 0; i < 4; i++) { for (j = 0; j < 3; j++) { mesh->matrix[i][j] = lib3ds_io_read_float(io); } } break; } case CHK_MESH_COLOR: { mesh->color = lib3ds_io_read_byte(io); break; } case CHK_POINT_ARRAY: { int i; uint16_t nvertices = lib3ds_io_read_word(io); lib3ds_mesh_resize_vertices(mesh, nvertices, mesh->texcos != NULL, mesh->vflags != NULL); for (i = 0; i < mesh->nvertices; ++i) { lib3ds_io_read_vector(io, mesh->vertices[i]); } break; } case CHK_POINT_FLAG_ARRAY: { int i; uint16_t nflags = lib3ds_io_read_word(io); uint16_t nvertices = (mesh->nvertices >= nflags)? mesh->nvertices : nflags; lib3ds_mesh_resize_vertices(mesh, nvertices, mesh->texcos != NULL, 1); for (i = 0; i < nflags; ++i) { mesh->vflags[i] = lib3ds_io_read_word(io); } break; } case CHK_FACE_ARRAY: { lib3ds_chunk_read_reset(&c, io); face_array_read(file, mesh, io); break; } case CHK_MESH_TEXTURE_INFO: { int i, j; //FIXME: mesh->map_type = lib3ds_io_read_word(io); for (i = 0; i < 2; ++i) { mesh->map_tile[i] = lib3ds_io_read_float(io); } for (i = 0; i < 3; ++i) { mesh->map_pos[i] = lib3ds_io_read_float(io); } mesh->map_scale = lib3ds_io_read_float(io); lib3ds_matrix_identity(mesh->map_matrix); for (i = 0; i < 4; i++) { for (j = 0; j < 3; j++) { mesh->map_matrix[i][j] = lib3ds_io_read_float(io); } } for (i = 0; i < 2; ++i) { mesh->map_planar_size[i] = lib3ds_io_read_float(io); } mesh->map_cylinder_height = lib3ds_io_read_float(io); break; } case CHK_TEX_VERTS: { int i; uint16_t ntexcos = lib3ds_io_read_word(io); uint16_t nvertices = (mesh->nvertices >= ntexcos)? mesh->nvertices : ntexcos;; if (!mesh->texcos) { lib3ds_mesh_resize_vertices(mesh, nvertices, 1, mesh->vflags != NULL); } for (i = 0; i < ntexcos; ++i) { mesh->texcos[i][0] = lib3ds_io_read_float(io); mesh->texcos[i][1] = lib3ds_io_read_float(io); } break; } default: lib3ds_chunk_unknown(chunk, io); } } if (lib3ds_matrix_det(mesh->matrix) < 0.0) { /* Flip X coordinate of vertices if mesh matrix has negative determinant */ float inv_matrix[4][4], M[4][4]; float tmp[3]; int i; lib3ds_matrix_copy(inv_matrix, mesh->matrix); lib3ds_matrix_inv(inv_matrix); lib3ds_matrix_copy(M, mesh->matrix); lib3ds_matrix_scale(M, -1.0f, 1.0f, 1.0f); lib3ds_matrix_mult(M, M, inv_matrix); for (i = 0; i < mesh->nvertices; ++i) { lib3ds_vector_transform(tmp, M, mesh->vertices[i]); lib3ds_vector_copy(mesh->vertices[i], tmp); } } lib3ds_chunk_read_end(&c, io); }
/*! * \ingroup mesh */ Lib3dsBool lib3ds_mesh_read(Lib3dsMesh *mesh, Lib3dsIo *io) { Lib3dsChunk c; Lib3dsWord chunk; if (!lib3ds_chunk_read_start(&c, LIB3DS_N_TRI_OBJECT, io)) { return(LIB3DS_FALSE); } while ((chunk=lib3ds_chunk_read_next(&c, io))!=0) { switch (chunk) { case LIB3DS_MESH_MATRIX: { int i,j; lib3ds_matrix_identity(mesh->matrix); for (i=0; i<4; i++) { for (j=0; j<3; j++) { mesh->matrix[i][j]=lib3ds_io_read_float(io); } } } break; case LIB3DS_MESH_COLOR: { mesh->color=lib3ds_io_read_byte(io); } break; case LIB3DS_POINT_ARRAY: { unsigned i,j; unsigned points; lib3ds_mesh_free_point_list(mesh); points=lib3ds_io_read_word(io); if (points) { if (!lib3ds_mesh_new_point_list(mesh, points)) { LIB3DS_ERROR_LOG; return(LIB3DS_FALSE); } for (i=0; i<mesh->points; ++i) { for (j=0; j<3; ++j) { mesh->pointL[i].pos[j]=lib3ds_io_read_float(io); } } ASSERT((!mesh->flags) || (mesh->points==mesh->flags)); ASSERT((!mesh->texels) || (mesh->points==mesh->texels)); } } break; case LIB3DS_POINT_FLAG_ARRAY: { unsigned i; unsigned flags; lib3ds_mesh_free_flag_list(mesh); flags=lib3ds_io_read_word(io); if (flags) { if (!lib3ds_mesh_new_flag_list(mesh, flags)) { LIB3DS_ERROR_LOG; return(LIB3DS_FALSE); } for (i=0; i<mesh->flags; ++i) { mesh->flagL[i]=lib3ds_io_read_word(io); } ASSERT((!mesh->points) || (mesh->flags==mesh->points)); ASSERT((!mesh->texels) || (mesh->flags==mesh->texels)); } } break; case LIB3DS_FACE_ARRAY: { lib3ds_chunk_read_reset(&c, io); if (!face_array_read(mesh, io)) { return(LIB3DS_FALSE); } } break; case LIB3DS_MESH_TEXTURE_INFO: { int i,j; for (i=0; i<2; ++i) { mesh->map_data.tile[i]=lib3ds_io_read_float(io); } for (i=0; i<3; ++i) { mesh->map_data.pos[i]=lib3ds_io_read_float(io); } mesh->map_data.scale=lib3ds_io_read_float(io); lib3ds_matrix_identity(mesh->map_data.matrix); for (i=0; i<4; i++) { for (j=0; j<3; j++) { mesh->map_data.matrix[i][j]=lib3ds_io_read_float(io); } } for (i=0; i<2; ++i) { mesh->map_data.planar_size[i]=lib3ds_io_read_float(io); } mesh->map_data.cylinder_height=lib3ds_io_read_float(io); } break; case LIB3DS_TEX_VERTS: { unsigned i; unsigned texels; lib3ds_mesh_free_texel_list(mesh); texels=lib3ds_io_read_word(io); if (texels) { if (!lib3ds_mesh_new_texel_list(mesh, texels)) { LIB3DS_ERROR_LOG; return(LIB3DS_FALSE); } for (i=0; i<mesh->texels; ++i) { mesh->texelL[i][0]=lib3ds_io_read_float(io); mesh->texelL[i][1]=lib3ds_io_read_float(io); } ASSERT((!mesh->points) || (mesh->texels==mesh->points)); ASSERT((!mesh->flags) || (mesh->texels==mesh->flags)); } } break; default: lib3ds_chunk_unknown(chunk); } } { unsigned j; for (j=0; j<mesh->faces; ++j) { ASSERT(mesh->faceL[j].points[0]<mesh->points); ASSERT(mesh->faceL[j].points[1]<mesh->points); ASSERT(mesh->faceL[j].points[2]<mesh->points); lib3ds_vector_normal( mesh->faceL[j].normal, mesh->pointL[mesh->faceL[j].points[0]].pos, mesh->pointL[mesh->faceL[j].points[1]].pos, mesh->pointL[mesh->faceL[j].points[2]].pos ); } } if (lib3ds_matrix_det(mesh->matrix) < 0.0) { /* Flip X coordinate of vertices if mesh matrix has negative determinant */ Lib3dsMatrix inv_matrix, M; Lib3dsVector tmp; unsigned i; lib3ds_matrix_copy(inv_matrix, mesh->matrix); lib3ds_matrix_inv(inv_matrix); lib3ds_matrix_copy(M, mesh->matrix); lib3ds_matrix_scale_xyz(M, -1.0f, 1.0f, 1.0f); lib3ds_matrix_mult(M, inv_matrix); for (i=0; i<mesh->points; ++i) { lib3ds_vector_transform(tmp, M, mesh->pointL[i].pos); lib3ds_vector_copy(mesh->pointL[i].pos, tmp); } } lib3ds_chunk_read_end(&c, io); return(LIB3DS_TRUE); }
static void texture_map_read(Lib3dsTextureMap *map, Lib3dsIo *io) { Lib3dsChunk c; uint16_t chunk; lib3ds_chunk_read_start(&c, 0, io); while ((chunk = lib3ds_chunk_read_next(&c, io)) != 0) { switch (chunk) { case CHK_INT_PERCENTAGE: { map->percent = 1.0f * lib3ds_io_read_intw(io) / 100.0f; break; } case CHK_MAT_MAPNAME: { lib3ds_io_read_string(io, map->name, 64); lib3ds_io_log(io, LIB3DS_LOG_INFO, " NAME=%s", map->name); break; } case CHK_MAT_MAP_TILING: { map->flags = lib3ds_io_read_word(io); break; } case CHK_MAT_MAP_TEXBLUR: map->blur = lib3ds_io_read_float(io); break; case CHK_MAT_MAP_USCALE: map->scale[0] = lib3ds_io_read_float(io); break; case CHK_MAT_MAP_VSCALE: { map->scale[1] = lib3ds_io_read_float(io); break; } case CHK_MAT_MAP_UOFFSET: { map->offset[0] = lib3ds_io_read_float(io); break; } case CHK_MAT_MAP_VOFFSET: { map->offset[1] = lib3ds_io_read_float(io); break; } case CHK_MAT_MAP_ANG: { map->rotation = lib3ds_io_read_float(io); break; } case CHK_MAT_MAP_COL1: { map->tint_1[0] = 1.0f * lib3ds_io_read_byte(io) / 255.0f; map->tint_1[1] = 1.0f * lib3ds_io_read_byte(io) / 255.0f; map->tint_1[2] = 1.0f * lib3ds_io_read_byte(io) / 255.0f; break; } case CHK_MAT_MAP_COL2: { map->tint_2[0] = 1.0f * lib3ds_io_read_byte(io) / 255.0f; map->tint_2[1] = 1.0f * lib3ds_io_read_byte(io) / 255.0f; map->tint_2[2] = 1.0f * lib3ds_io_read_byte(io) / 255.0f; break; } case CHK_MAT_MAP_RCOL: { map->tint_r[0] = 1.0f * lib3ds_io_read_byte(io) / 255.0f; map->tint_r[1] = 1.0f * lib3ds_io_read_byte(io) / 255.0f; map->tint_r[2] = 1.0f * lib3ds_io_read_byte(io) / 255.0f; break; } case CHK_MAT_MAP_GCOL: { map->tint_g[0] = 1.0f * lib3ds_io_read_byte(io) / 255.0f; map->tint_g[1] = 1.0f * lib3ds_io_read_byte(io) / 255.0f; map->tint_g[2] = 1.0f * lib3ds_io_read_byte(io) / 255.0f; break; } case CHK_MAT_MAP_BCOL: { map->tint_b[0] = 1.0f * lib3ds_io_read_byte(io) / 255.0f; map->tint_b[1] = 1.0f * lib3ds_io_read_byte(io) / 255.0f; map->tint_b[2] = 1.0f * lib3ds_io_read_byte(io) / 255.0f; break; } default: lib3ds_chunk_unknown(chunk,io); } } lib3ds_chunk_read_end(&c, io); }
static Lib3dsBool texture_map_read(Lib3dsTextureMap *map, Lib3dsIo *io) { Lib3dsChunk c; Lib3dsWord chunk; if (!lib3ds_chunk_read_start(&c, 0, io)) { return(LIB3DS_FALSE); } while ((chunk=lib3ds_chunk_read_next(&c, io))!=0) { switch (chunk) { case LIB3DS_INT_PERCENTAGE: { map->percent=1.0f*lib3ds_io_read_intw(io)/100.0f; } break; case LIB3DS_MAT_MAPNAME: { if (!lib3ds_io_read_string(io, map->name, 64)) { return(LIB3DS_FALSE); } lib3ds_chunk_dump_info(" NAME=%s", map->name); } break; case LIB3DS_MAT_MAP_TILING: { map->flags=lib3ds_io_read_word(io); } break; case LIB3DS_MAT_MAP_TEXBLUR: { map->blur=lib3ds_io_read_float(io); } break; case LIB3DS_MAT_MAP_USCALE: { map->scale[0]=lib3ds_io_read_float(io); } break; case LIB3DS_MAT_MAP_VSCALE: { map->scale[1]=lib3ds_io_read_float(io); } break; case LIB3DS_MAT_MAP_UOFFSET: { map->offset[0]=lib3ds_io_read_float(io); } break; case LIB3DS_MAT_MAP_VOFFSET: { map->offset[1]=lib3ds_io_read_float(io); } break; case LIB3DS_MAT_MAP_ANG: { map->rotation=lib3ds_io_read_float(io); } break; case LIB3DS_MAT_MAP_COL1: { map->tint_1[0]=1.0f*lib3ds_io_read_byte(io)/255.0f; map->tint_1[1]=1.0f*lib3ds_io_read_byte(io)/255.0f; map->tint_1[2]=1.0f*lib3ds_io_read_byte(io)/255.0f; } break; case LIB3DS_MAT_MAP_COL2: { map->tint_2[0]=1.0f*lib3ds_io_read_byte(io)/255.0f; map->tint_2[1]=1.0f*lib3ds_io_read_byte(io)/255.0f; map->tint_2[2]=1.0f*lib3ds_io_read_byte(io)/255.0f; } break; case LIB3DS_MAT_MAP_RCOL: { map->tint_r[0]=1.0f*lib3ds_io_read_byte(io)/255.0f; map->tint_r[1]=1.0f*lib3ds_io_read_byte(io)/255.0f; map->tint_r[2]=1.0f*lib3ds_io_read_byte(io)/255.0f; } break; case LIB3DS_MAT_MAP_GCOL: { map->tint_g[0]=1.0f*lib3ds_io_read_byte(io)/255.0f; map->tint_g[1]=1.0f*lib3ds_io_read_byte(io)/255.0f; map->tint_g[2]=1.0f*lib3ds_io_read_byte(io)/255.0f; } break; case LIB3DS_MAT_MAP_BCOL: { map->tint_b[0]=1.0f*lib3ds_io_read_byte(io)/255.0f; map->tint_b[1]=1.0f*lib3ds_io_read_byte(io)/255.0f; map->tint_b[2]=1.0f*lib3ds_io_read_byte(io)/255.0f; } break; default: lib3ds_chunk_unknown(chunk); } } lib3ds_chunk_read_end(&c, io); return(LIB3DS_TRUE); }
static Lib3dsBool color_read(Lib3dsRgba rgb, Lib3dsIo *io) { Lib3dsChunk c; Lib3dsWord chunk; Lib3dsBool have_lin=LIB3DS_FALSE; if (!lib3ds_chunk_read_start(&c, 0, io)) { return(LIB3DS_FALSE); } while ((chunk=lib3ds_chunk_read_next(&c, io))!=0) { switch (chunk) { case LIB3DS_LIN_COLOR_24: { int i; for (i=0; i<3; ++i) { rgb[i]=1.0f*lib3ds_io_read_byte(io)/255.0f; } rgb[3]=1.0f; } have_lin=LIB3DS_TRUE; break; case LIB3DS_COLOR_24: /* gamma corrected color chunk replaced in 3ds R3 by LIN_COLOR_24 */ if (!have_lin) { int i; for (i=0; i<3; ++i) { rgb[i]=1.0f*lib3ds_io_read_byte(io)/255.0f; } rgb[3]=1.0f; } break; case LIB3DS_LIN_COLOR_F: { int i; for (i=0; i<3; ++i) { rgb[i]=lib3ds_io_read_float(io); } rgb[3]=1.0f; } have_lin=LIB3DS_TRUE; break; case LIB3DS_COLOR_F: if (!have_lin) { int i; for (i=0; i<3; ++i) { rgb[i]=lib3ds_io_read_float(io); } rgb[3]=1.0f; } break; default: lib3ds_chunk_unknown(chunk); } } lib3ds_chunk_read_end(&c, io); return(LIB3DS_TRUE); }