static Lib3dsBool kfdata_read(Lib3dsFile *file, FILE *f) { Lib3dsChunk c; Lib3dsWord chunk; if (!lib3ds_chunk_read_start(&c, LIB3DS_KFDATA, f)) { return(LIB3DS_FALSE); } while ((chunk=lib3ds_chunk_read_next(&c, f))!=0) { switch (chunk) { case LIB3DS_KFHDR: { file->keyf_revision=lib3ds_word_read(f); if (!lib3ds_string_read(file->name, 12+1, f)) { return(LIB3DS_FALSE); } file->frames=lib3ds_intd_read(f); } break; case LIB3DS_KFSEG: { file->segment_from=lib3ds_intd_read(f); file->segment_to=lib3ds_intd_read(f); } break; case LIB3DS_KFCURTIME: { file->current_frame=lib3ds_intd_read(f); } break; case LIB3DS_VIEWPORT_LAYOUT: case LIB3DS_DEFAULT_VIEW: { lib3ds_chunk_read_reset(&c, f); if (!lib3ds_viewport_read(&file->viewport_keyf, f)) { return(LIB3DS_FALSE); } } break; case LIB3DS_AMBIENT_NODE_TAG: { Lib3dsNode *node; node=lib3ds_node_new_ambient(); if (!node) { return(LIB3DS_FALSE); } lib3ds_chunk_read_reset(&c, f); if (!lib3ds_node_read(node, file, f)) { return(LIB3DS_FALSE); } lib3ds_file_insert_node(file, node); } break; case LIB3DS_OBJECT_NODE_TAG: { Lib3dsNode *node; node=lib3ds_node_new_object(); if (!node) { return(LIB3DS_FALSE); } lib3ds_chunk_read_reset(&c, f); if (!lib3ds_node_read(node, file, f)) { return(LIB3DS_FALSE); } lib3ds_file_insert_node(file, node); } break; case LIB3DS_CAMERA_NODE_TAG: { Lib3dsNode *node; node=lib3ds_node_new_camera(); if (!node) { return(LIB3DS_FALSE); } lib3ds_chunk_read_reset(&c, f); if (!lib3ds_node_read(node, file, f)) { return(LIB3DS_FALSE); } lib3ds_file_insert_node(file, node); } break; case LIB3DS_TARGET_NODE_TAG: { Lib3dsNode *node; node=lib3ds_node_new_target(); if (!node) { return(LIB3DS_FALSE); } lib3ds_chunk_read_reset(&c, f); if (!lib3ds_node_read(node, file, f)) { return(LIB3DS_FALSE); } lib3ds_file_insert_node(file, node); } break; case LIB3DS_LIGHT_NODE_TAG: case LIB3DS_SPOTLIGHT_NODE_TAG: { Lib3dsNode *node; node=lib3ds_node_new_light(); if (!node) { return(LIB3DS_FALSE); } lib3ds_chunk_read_reset(&c, f); if (!lib3ds_node_read(node, file, f)) { return(LIB3DS_FALSE); } lib3ds_file_insert_node(file, node); } break; case LIB3DS_L_TARGET_NODE_TAG: { Lib3dsNode *node; node=lib3ds_node_new_spot(); if (!node) { return(LIB3DS_FALSE); } lib3ds_chunk_read_reset(&c, f); if (!lib3ds_node_read(node, file, f)) { return(LIB3DS_FALSE); } lib3ds_file_insert_node(file, node); } break; default: lib3ds_chunk_unknown(chunk); } } lib3ds_chunk_read_end(&c, f); return(LIB3DS_TRUE); }
static void kfdata_read(Lib3dsFile *file, Lib3dsIo *io) { Lib3dsChunk c; uint16_t chunk; unsigned num_nodes = 0; Lib3dsNode *last = NULL; lib3ds_chunk_read_start(&c, CHK_KFDATA, io); while ((chunk = lib3ds_chunk_read_next(&c, io)) != 0) { switch (chunk) { case CHK_KFHDR: { file->keyf_revision = lib3ds_io_read_word(io); lib3ds_io_read_string(io, file->name, 12 + 1); file->frames = lib3ds_io_read_intd(io); break; } case CHK_KFSEG: { file->segment_from = lib3ds_io_read_intd(io); file->segment_to = lib3ds_io_read_intd(io); break; } case CHK_KFCURTIME: { file->current_frame = lib3ds_io_read_intd(io); break; } case CHK_VIEWPORT_LAYOUT: case CHK_DEFAULT_VIEW: { lib3ds_chunk_read_reset(&c, io); lib3ds_viewport_read(&file->viewport_keyf, io); break; } case CHK_AMBIENT_NODE_TAG: case CHK_OBJECT_NODE_TAG: case CHK_CAMERA_NODE_TAG: case CHK_TARGET_NODE_TAG: case CHK_LIGHT_NODE_TAG: case CHK_SPOTLIGHT_NODE_TAG: case CHK_L_TARGET_NODE_TAG: { Lib3dsNodeType type = (Lib3dsNodeType)0; Lib3dsNode *node; switch (chunk) { case CHK_AMBIENT_NODE_TAG: type = LIB3DS_NODE_AMBIENT_COLOR; break; case CHK_OBJECT_NODE_TAG: type = LIB3DS_NODE_MESH_INSTANCE; break; case CHK_CAMERA_NODE_TAG: type = LIB3DS_NODE_CAMERA; break; case CHK_TARGET_NODE_TAG: type = LIB3DS_NODE_CAMERA_TARGET; break; case CHK_LIGHT_NODE_TAG: type = LIB3DS_NODE_OMNILIGHT; break; case CHK_SPOTLIGHT_NODE_TAG: type = LIB3DS_NODE_SPOTLIGHT; break; case CHK_L_TARGET_NODE_TAG: type = LIB3DS_NODE_SPOTLIGHT_TARGET; break; } node = lib3ds_node_new(type); node->node_id = (unsigned short)(num_nodes++); if (last) { last->next = node; } else { file->nodes = node; } node->user_ptr = last; last = node; lib3ds_chunk_read_reset(&c, io); lib3ds_node_read(node, io); break; } default: lib3ds_chunk_unknown(chunk, io); } } { Lib3dsNode **nodes = (Lib3dsNode**)malloc(num_nodes * sizeof(Lib3dsNode*)); unsigned i; Lib3dsNode *p, *q, *parent; p = file->nodes; for (i = 0; i < num_nodes; ++i) { nodes[i] = p; p = p->next; } qsort(nodes, num_nodes, sizeof(Lib3dsNode*), compare_node_id); p = last; while (p) { q = (Lib3dsNode*)p->user_ptr; if (p->user_id != 65535) { parent = *(Lib3dsNode**)bsearch(&p->user_id, nodes, num_nodes, sizeof(Lib3dsNode*), compare_node_id2); if (parent) { q->next = p->next; p->next = parent->childs; p->parent = parent; parent->childs = p; } else { /* TODO: warning */ } } p->user_id = 0; p->user_ptr = NULL; p = q; } free(nodes); } lib3ds_chunk_read_end(&c, io); }