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);
}
Exemple #3
0
/*!
 * \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);
}