예제 #1
0
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);
}
예제 #2
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);
}