static void
point_array_write(Lib3dsMesh *mesh, Lib3dsIo *io) {
    Lib3dsChunk c;
    int i;

    c.chunk = CHK_POINT_ARRAY;
    c.size = 8 + 12 * mesh->nvertices;
    lib3ds_chunk_write(&c, io);

    lib3ds_io_write_word(io, (uint16_t) mesh->nvertices);

    if (lib3ds_matrix_det(mesh->matrix) >= 0.0f) {
        for (i = 0; i < mesh->nvertices; ++i) {
            lib3ds_io_write_vector(io, mesh->vertices[i]);
        }
    } else {
        /* Flip X coordinate of vertices if mesh matrix
           has negative determinant */
        float inv_matrix[4][4], M[4][4];
        float tmp[3];

        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_io_write_vector(io, tmp);
        }
    }
}
Exemple #2
0
/*!
 * Evaluate an animation node.
 *
 * Recursively sets node and its children to their appropriate values
 * for this point in the animation.
 *
 * \param node Node to be evaluated.
 * \param t time value, between 0. and file->frames
 *
 * \ingroup node
 */
void
lib3ds_node_eval(Lib3dsNode *node, Lib3dsFloat t)
{
  ASSERT(node);
  switch (node->type) {
    case LIB3DS_UNKNOWN_NODE:
      {
        ASSERT(LIB3DS_FALSE);
      }
      break;
    case LIB3DS_AMBIENT_NODE:
      {
        Lib3dsAmbientData *n=&node->data.ambient;
        if (node->parent) {
          lib3ds_matrix_copy(node->matrix, node->parent->matrix);
        }
        else {
          lib3ds_matrix_identity(node->matrix);
        }
        lib3ds_lin3_track_eval(&n->col_track, n->col, t);
      }
      break;
    case LIB3DS_OBJECT_NODE:
      {
        Lib3dsMatrix M;
        Lib3dsObjectData *n=&node->data.object;

        lib3ds_lin3_track_eval(&n->pos_track, n->pos, t);
        lib3ds_quat_track_eval(&n->rot_track, n->rot, t);
        if (n->scl_track.keyL) {
          lib3ds_lin3_track_eval(&n->scl_track, n->scl, t);
        }
        else {
          n->scl[0] = n->scl[1] = n->scl[2] = 1.0f;
        }
        lib3ds_bool_track_eval(&n->hide_track, &n->hide, t);
        lib3ds_morph_track_eval(&n->morph_track, n->morph, t);

        lib3ds_matrix_identity(M);
        lib3ds_matrix_translate(M, n->pos);
        lib3ds_matrix_rotate(M, n->rot);
        lib3ds_matrix_scale(M, n->scl);
        
        if (node->parent) {
          lib3ds_matrix_copy(node->matrix, node->parent->matrix);
          lib3ds_matrix_mult(node->matrix, M);
        }
        else {
          lib3ds_matrix_copy(node->matrix, M);
        }
      }
      break;
    case LIB3DS_CAMERA_NODE:
      {
        Lib3dsCameraData *n=&node->data.camera;
        lib3ds_lin3_track_eval(&n->pos_track, n->pos, t);
        lib3ds_lin1_track_eval(&n->fov_track, &n->fov, t);
        lib3ds_lin1_track_eval(&n->roll_track, &n->roll, t);
        if (node->parent) {
          lib3ds_matrix_copy(node->matrix, node->parent->matrix);
        }
        else {
          lib3ds_matrix_identity(node->matrix);
        }
        lib3ds_matrix_translate(node->matrix, n->pos);
      }
      break;
    case LIB3DS_TARGET_NODE:
      {
        Lib3dsTargetData *n=&node->data.target;
        lib3ds_lin3_track_eval(&n->pos_track, n->pos, t);
        if (node->parent) {
          lib3ds_matrix_copy(node->matrix, node->parent->matrix);
        }
        else {
          lib3ds_matrix_identity(node->matrix);
        }
        lib3ds_matrix_translate(node->matrix, n->pos);
      }
      break;
    case LIB3DS_LIGHT_NODE:
      {
        Lib3dsLightData *n=&node->data.light;
        lib3ds_lin3_track_eval(&n->pos_track, n->pos, t);
        lib3ds_lin3_track_eval(&n->col_track, n->col, t);
        lib3ds_lin1_track_eval(&n->hotspot_track, &n->hotspot, t);
        lib3ds_lin1_track_eval(&n->falloff_track, &n->falloff, t);
        lib3ds_lin1_track_eval(&n->roll_track, &n->roll, t);
        if (node->parent) {
          lib3ds_matrix_copy(node->matrix, node->parent->matrix);
        }
        else {
          lib3ds_matrix_identity(node->matrix);
        }
        lib3ds_matrix_translate(node->matrix, n->pos);
      }
      break;
    case LIB3DS_SPOT_NODE:
      {
        Lib3dsSpotData *n=&node->data.spot;
        lib3ds_lin3_track_eval(&n->pos_track, n->pos, t);
        if (node->parent) {
          lib3ds_matrix_copy(node->matrix, node->parent->matrix);
        }
        else {
          lib3ds_matrix_identity(node->matrix);
        }
        lib3ds_matrix_translate(node->matrix, n->pos);
      }
      break;
  }
  {
    Lib3dsNode *p;

    for (p=node->childs; p!=0; p=p->next) {
      lib3ds_node_eval(p, t);
    }
  }
}
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 #4
0
/*!
 * Evaluate an animation node.
 *
 * Recursively sets node and its children to their appropriate values
 * for this point in the animation.
 *
 * \param node Node to be evaluated.
 * \param t time value, between 0. and file->frames
 */
void
lib3ds_node_eval(Lib3dsNode *node, float t) {
    assert(node);
    switch (node->type) {
        case LIB3DS_NODE_AMBIENT_COLOR: {
            Lib3dsAmbientColorNode *n = (Lib3dsAmbientColorNode*)node;
            if (node->parent) {
                lib3ds_matrix_copy(node->matrix, node->parent->matrix);
            } else {
                lib3ds_matrix_identity(node->matrix);
            }
            lib3ds_track_eval_vector(&n->color_track, n->color, t);
            break;
        }

        case LIB3DS_NODE_MESH_INSTANCE: {
            float M[4][4];
            Lib3dsMeshInstanceNode *n = (Lib3dsMeshInstanceNode*)node;

            lib3ds_track_eval_vector(&n->pos_track, n->pos, t);
            lib3ds_track_eval_quat(&n->rot_track, n->rot, t);
            if (n->scl_track.nkeys) {
                lib3ds_track_eval_vector(&n->scl_track, n->scl, t);
            } else {
                n->scl[0] = n->scl[1] = n->scl[2] = 1.0f;
            }
            lib3ds_track_eval_bool(&n->hide_track, &n->hide, t);

            lib3ds_matrix_identity(M);
            lib3ds_matrix_translate(M, n->pos[0], n->pos[1], n->pos[2]);
            lib3ds_matrix_rotate_quat(M, n->rot);
            lib3ds_matrix_scale(M, n->scl[0], n->scl[1], n->scl[2]);

            if (node->parent) {
                lib3ds_matrix_mult(node->matrix, node->parent->matrix, M);
            } else {
                lib3ds_matrix_copy(node->matrix, M);
            }
            break;
        }

        case LIB3DS_NODE_CAMERA: {
            Lib3dsCameraNode *n = (Lib3dsCameraNode*)node;
            lib3ds_track_eval_vector(&n->pos_track, n->pos, t);
            lib3ds_track_eval_float(&n->fov_track, &n->fov, t);
            lib3ds_track_eval_float(&n->roll_track, &n->roll, t);
            if (node->parent) {
                lib3ds_matrix_copy(node->matrix, node->parent->matrix);
            } else {
                lib3ds_matrix_identity(node->matrix);
            }
            lib3ds_matrix_translate(node->matrix, n->pos[0], n->pos[1], n->pos[2]);
            break;
        }

        case LIB3DS_NODE_CAMERA_TARGET: {
            Lib3dsTargetNode *n = (Lib3dsTargetNode*)node;
            lib3ds_track_eval_vector(&n->pos_track, n->pos, t);
            if (node->parent) {
                lib3ds_matrix_copy(node->matrix, node->parent->matrix);
            } else {
                lib3ds_matrix_identity(node->matrix);
            }
            lib3ds_matrix_translate(node->matrix, n->pos[0], n->pos[1], n->pos[2]);
            break;
        }

        case LIB3DS_NODE_OMNILIGHT: {
            Lib3dsOmnilightNode *n = (Lib3dsOmnilightNode*)node;
            lib3ds_track_eval_vector(&n->pos_track, n->pos, t);
            lib3ds_track_eval_vector(&n->color_track, n->color, t);
            if (node->parent) {
                lib3ds_matrix_copy(node->matrix, node->parent->matrix);
            } else {
                lib3ds_matrix_identity(node->matrix);
            }
            lib3ds_matrix_translate(node->matrix, n->pos[0], n->pos[1], n->pos[2]);
            break;
        }

        case LIB3DS_NODE_SPOTLIGHT: {
            Lib3dsSpotlightNode *n = (Lib3dsSpotlightNode*)node;
            lib3ds_track_eval_vector(&n->pos_track, n->pos, t);
            lib3ds_track_eval_vector(&n->color_track, n->color, t);
            lib3ds_track_eval_float(&n->hotspot_track, &n->hotspot, t);
            lib3ds_track_eval_float(&n->falloff_track, &n->falloff, t);
            lib3ds_track_eval_float(&n->roll_track, &n->roll, t);
            if (node->parent) {
                lib3ds_matrix_copy(node->matrix, node->parent->matrix);
            } else {
                lib3ds_matrix_identity(node->matrix);
            }
            lib3ds_matrix_translate(node->matrix, n->pos[0], n->pos[1], n->pos[2]);
            break;
        }

        case LIB3DS_NODE_SPOTLIGHT_TARGET: {
            Lib3dsTargetNode *n = (Lib3dsTargetNode*)node;
            lib3ds_track_eval_vector(&n->pos_track, n->pos, t);
            if (node->parent) {
                lib3ds_matrix_copy(node->matrix, node->parent->matrix);
            } else {
                lib3ds_matrix_identity(node->matrix);
            }
            lib3ds_matrix_translate(node->matrix, n->pos[0], n->pos[1], n->pos[2]);
            break;
        }
    }
    {
        Lib3dsNode *p;
        for (p = node->childs; p != 0; p = p->next) {
            lib3ds_node_eval(p, t);
        }
    }
}