00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "lib3ds_impl.h"
00019
00020
00029 Lib3dsNode*
00030 lib3ds_node_new(Lib3dsNodeType type) {
00031 Lib3dsNode *node;
00032 switch (type) {
00033 case LIB3DS_NODE_AMBIENT_COLOR: {
00034 Lib3dsAmbientColorNode *n = calloc(sizeof(Lib3dsAmbientColorNode), 1);
00035 node = (Lib3dsNode*)n;
00036 strcpy(node->name, "$AMBIENT$");
00037 n->color_track.type = LIB3DS_TRACK_VECTOR;
00038 break;
00039 }
00040
00041 case LIB3DS_NODE_MESH_INSTANCE: {
00042 Lib3dsMeshInstanceNode *n = calloc(sizeof(Lib3dsMeshInstanceNode), 1);
00043 node = (Lib3dsNode*)n;
00044 strcpy(node->name, "$$$DUMMY");
00045 n->pos_track.type = LIB3DS_TRACK_VECTOR;
00046 n->scl_track.type = LIB3DS_TRACK_VECTOR;
00047 n->rot_track.type = LIB3DS_TRACK_QUAT;
00048 n->hide_track.type = LIB3DS_TRACK_BOOL;
00049 break;
00050 }
00051
00052 case LIB3DS_NODE_CAMERA: {
00053 Lib3dsCameraNode *n = calloc(sizeof(Lib3dsCameraNode), 1);
00054 node = (Lib3dsNode*)n;
00055 n->pos_track.type = LIB3DS_TRACK_VECTOR;
00056 n->fov_track.type = LIB3DS_TRACK_FLOAT;
00057 n->roll_track.type = LIB3DS_TRACK_FLOAT;
00058 break;
00059 }
00060
00061 case LIB3DS_NODE_CAMERA_TARGET: {
00062 Lib3dsTargetNode *n = calloc(sizeof(Lib3dsTargetNode), 1);
00063 node = (Lib3dsNode*)n;
00064 n->pos_track.type = LIB3DS_TRACK_VECTOR;
00065 break;
00066 }
00067
00068 case LIB3DS_NODE_OMNILIGHT: {
00069 Lib3dsOmnilightNode *n = calloc(sizeof(Lib3dsOmnilightNode), 1);
00070 node = (Lib3dsNode*)n;
00071 n->pos_track.type = LIB3DS_TRACK_VECTOR;
00072 n->color_track.type = LIB3DS_TRACK_VECTOR;
00073 break;
00074 }
00075
00076 case LIB3DS_NODE_SPOTLIGHT: {
00077 Lib3dsSpotlightNode *n = calloc(sizeof(Lib3dsSpotlightNode), 1);
00078 node = (Lib3dsNode*)n;
00079 n->pos_track.type = LIB3DS_TRACK_VECTOR;
00080 n->color_track.type = LIB3DS_TRACK_VECTOR;
00081 n->hotspot_track.type = LIB3DS_TRACK_FLOAT;
00082 n->falloff_track.type = LIB3DS_TRACK_FLOAT;
00083 n->roll_track.type = LIB3DS_TRACK_FLOAT;
00084 break;
00085 }
00086
00087 case LIB3DS_NODE_SPOTLIGHT_TARGET: {
00088 Lib3dsTargetNode *n = calloc(sizeof(Lib3dsTargetNode), 1);
00089 node = (Lib3dsNode*)n;
00090 n->pos_track.type = LIB3DS_TRACK_VECTOR;
00091 break;
00092 }
00093
00094 default:
00095 assert(0);
00096 return NULL;
00097 }
00098
00099 node->type = type;
00100 node->node_id = 65535;
00101 node->user_id = 65535;
00102 lib3ds_matrix_identity(node->matrix);
00103 return node;
00104 }
00105
00106
00107 Lib3dsAmbientColorNode*
00108 lib3ds_node_new_ambient_color(float color0[3]) {
00109 Lib3dsNode *node;
00110 Lib3dsAmbientColorNode *n;
00111
00112 node = lib3ds_node_new(LIB3DS_NODE_AMBIENT_COLOR);
00113
00114 n = (Lib3dsAmbientColorNode*)node;
00115 lib3ds_track_resize(&n->color_track, 1);
00116 if (color0) {
00117 lib3ds_vector_copy(n->color_track.keys[0].value, color0);
00118 } else {
00119 lib3ds_vector_zero(n->color_track.keys[0].value);
00120 }
00121
00122 return n;
00123 }
00124
00125
00126 Lib3dsMeshInstanceNode*
00127 lib3ds_node_new_mesh_instance(Lib3dsMesh *mesh, const char *instance_name, float pos0[3], float scl0[3], float rot0[4]) {
00128 Lib3dsNode *node;
00129 Lib3dsMeshInstanceNode *n;
00130 int i;
00131
00132 node = lib3ds_node_new(LIB3DS_NODE_MESH_INSTANCE);
00133 if (mesh) {
00134 strcpy(node->name, mesh->name);
00135 } else {
00136 strcpy(node->name, "$$$DUMMY");
00137 }
00138
00139 n = (Lib3dsMeshInstanceNode*)node;
00140 if (instance_name) {
00141 strcpy(n->instance_name, instance_name);
00142 }
00143
00144 lib3ds_track_resize(&n->pos_track, 1);
00145 if (pos0) {
00146 lib3ds_vector_copy(n->pos_track.keys[0].value, pos0);
00147 }
00148
00149 lib3ds_track_resize(&n->scl_track, 1);
00150 if (scl0) {
00151 lib3ds_vector_copy(n->scl_track.keys[0].value, scl0);
00152 } else {
00153 lib3ds_vector_make(n->scl_track.keys[0].value, 1, 1, 1);
00154 }
00155
00156 lib3ds_track_resize(&n->rot_track, 1);
00157 if (rot0) {
00158 for (i = 0; i < 4; ++i) n->rot_track.keys[0].value[i] = rot0[i];
00159 } else {
00160 for (i = 0; i < 4; ++i) n->rot_track.keys[0].value[i] = 0;
00161 }
00162
00163 return n;
00164 }
00165
00166
00167 Lib3dsCameraNode*
00168 lib3ds_node_new_camera(Lib3dsCamera *camera) {
00169 Lib3dsNode *node = lib3ds_node_new(LIB3DS_NODE_CAMERA);
00170 Lib3dsCameraNode *n;
00171
00172 assert(camera);
00173 node = lib3ds_node_new(LIB3DS_NODE_CAMERA);
00174 strcpy(node->name, camera->name);
00175
00176 n = (Lib3dsCameraNode*)node;
00177 lib3ds_track_resize(&n->pos_track, 1);
00178 lib3ds_vector_copy(n->pos_track.keys[0].value, camera->position);
00179
00180 lib3ds_track_resize(&n->fov_track, 1);
00181 n->fov_track.keys[0].value[0] = camera->fov;
00182
00183 lib3ds_track_resize(&n->roll_track, 1);
00184 n->roll_track.keys[0].value[0] = camera->roll;
00185
00186 return n;
00187 }
00188
00189
00190 Lib3dsTargetNode*
00191 lib3ds_node_new_camera_target(Lib3dsCamera *camera) {
00192 Lib3dsNode *node;
00193 Lib3dsTargetNode *n;
00194
00195 assert(camera);
00196 node = lib3ds_node_new(LIB3DS_NODE_CAMERA_TARGET);
00197 strcpy(node->name, camera->name);
00198
00199 n = (Lib3dsTargetNode*)node;
00200 lib3ds_track_resize(&n->pos_track, 1);
00201 lib3ds_vector_copy(n->pos_track.keys[0].value, camera->target);
00202
00203 return n;
00204 }
00205
00206
00207 Lib3dsOmnilightNode*
00208 lib3ds_node_new_omnilight(Lib3dsLight *light) {
00209 Lib3dsNode *node;
00210 Lib3dsOmnilightNode *n;
00211
00212 assert(light);
00213 node = lib3ds_node_new(LIB3DS_NODE_OMNILIGHT);
00214 strcpy(node->name, light->name);
00215
00216 n = (Lib3dsOmnilightNode*)node;
00217 lib3ds_track_resize(&n->pos_track, 1);
00218 lib3ds_vector_copy(n->pos_track.keys[0].value, light->position);
00219
00220 lib3ds_track_resize(&n->color_track, 1);
00221 lib3ds_vector_copy(n->color_track.keys[0].value, light->color);
00222
00223 return n;
00224 }
00225
00226
00227 Lib3dsSpotlightNode*
00228 lib3ds_node_new_spotlight(Lib3dsLight *light) {
00229 Lib3dsNode *node;
00230 Lib3dsSpotlightNode *n;
00231
00232 assert(light);
00233 node = lib3ds_node_new(LIB3DS_NODE_SPOTLIGHT);
00234 strcpy(node->name, light->name);
00235
00236 n = (Lib3dsSpotlightNode*)node;
00237 lib3ds_track_resize(&n->pos_track, 1);
00238 lib3ds_vector_copy(n->pos_track.keys[0].value, light->position);
00239
00240 lib3ds_track_resize(&n->color_track, 1);
00241 lib3ds_vector_copy(n->color_track.keys[0].value, light->color);
00242
00243 lib3ds_track_resize(&n->hotspot_track, 1);
00244 n->hotspot_track.keys[0].value[0] = light->hotspot;
00245
00246 lib3ds_track_resize(&n->falloff_track, 1);
00247 n->falloff_track.keys[0].value[0] = light->falloff;
00248
00249 lib3ds_track_resize(&n->roll_track, 1);
00250 n->roll_track.keys[0].value[0] = light->roll;
00251
00252 return n;
00253 }
00254
00255
00256 Lib3dsTargetNode*
00257 lib3ds_node_new_spotligf_target(Lib3dsLight *light) {
00258 Lib3dsNode *node;
00259 Lib3dsTargetNode *n;
00260
00261 assert(light);
00262 node = lib3ds_node_new(LIB3DS_NODE_SPOTLIGHT_TARGET);
00263 strcpy(node->name, light->name);
00264
00265 n = (Lib3dsTargetNode*)node;
00266 lib3ds_track_resize(&n->pos_track, 1);
00267 lib3ds_vector_copy(n->pos_track.keys[0].value, light->target);
00268
00269 return n;
00270 }
00271
00272
00273 static void
00274 free_node_and_childs(Lib3dsNode *node) {
00275 assert(node);
00276 switch (node->type) {
00277 case LIB3DS_NODE_AMBIENT_COLOR: {
00278 Lib3dsAmbientColorNode *n = (Lib3dsAmbientColorNode*)node;
00279 lib3ds_track_resize(&n->color_track, 0);
00280 break;
00281 }
00282
00283 case LIB3DS_NODE_MESH_INSTANCE: {
00284 Lib3dsMeshInstanceNode *n = (Lib3dsMeshInstanceNode*)node;
00285 lib3ds_track_resize(&n->pos_track, 0);
00286 lib3ds_track_resize(&n->rot_track, 0);
00287 lib3ds_track_resize(&n->scl_track, 0);
00288 lib3ds_track_resize(&n->hide_track, 0);
00289 break;
00290 }
00291
00292 case LIB3DS_NODE_CAMERA: {
00293 Lib3dsCameraNode *n = (Lib3dsCameraNode*)node;
00294 lib3ds_track_resize(&n->pos_track, 0);
00295 lib3ds_track_resize(&n->fov_track, 0);
00296 lib3ds_track_resize(&n->roll_track, 0);
00297 break;
00298 }
00299
00300 case LIB3DS_NODE_CAMERA_TARGET: {
00301 Lib3dsTargetNode *n = (Lib3dsTargetNode*)node;
00302 lib3ds_track_resize(&n->pos_track, 0);
00303 break;
00304 }
00305
00306 case LIB3DS_NODE_OMNILIGHT: {
00307 Lib3dsOmnilightNode *n = (Lib3dsOmnilightNode*)node;
00308 lib3ds_track_resize(&n->pos_track, 0);
00309 lib3ds_track_resize(&n->color_track, 0);
00310 break;
00311 }
00312
00313 case LIB3DS_NODE_SPOTLIGHT: {
00314 Lib3dsSpotlightNode *n = (Lib3dsSpotlightNode*)node;
00315 lib3ds_track_resize(&n->pos_track, 0);
00316 lib3ds_track_resize(&n->color_track, 0);
00317 lib3ds_track_resize(&n->hotspot_track, 0);
00318 lib3ds_track_resize(&n->falloff_track, 0);
00319 lib3ds_track_resize(&n->roll_track, 0);
00320 break;
00321 }
00322
00323 case LIB3DS_NODE_SPOTLIGHT_TARGET: {
00324 Lib3dsTargetNode *n = (Lib3dsTargetNode*)node;
00325 lib3ds_track_resize(&n->pos_track, 0);
00326 break;
00327 }
00328 }
00329 {
00330 Lib3dsNode *p, *q;
00331 for (p = node->childs; p; p = q) {
00332 q = p->next;
00333 free_node_and_childs(p);
00334 }
00335 }
00336 free(node);
00337 }
00338
00339
00345 void
00346 lib3ds_node_free(Lib3dsNode *node) {
00347 assert(node);
00348 free_node_and_childs(node);
00349 }
00350
00351
00361 void
00362 lib3ds_node_eval(Lib3dsNode *node, float t) {
00363 assert(node);
00364 switch (node->type) {
00365 case LIB3DS_NODE_AMBIENT_COLOR: {
00366 Lib3dsAmbientColorNode *n = (Lib3dsAmbientColorNode*)node;
00367 if (node->parent) {
00368 lib3ds_matrix_copy(node->matrix, node->parent->matrix);
00369 } else {
00370 lib3ds_matrix_identity(node->matrix);
00371 }
00372 lib3ds_track_eval_vector(&n->color_track, n->color, t);
00373 break;
00374 }
00375
00376 case LIB3DS_NODE_MESH_INSTANCE: {
00377 float M[4][4];
00378 Lib3dsMeshInstanceNode *n = (Lib3dsMeshInstanceNode*)node;
00379
00380 lib3ds_track_eval_vector(&n->pos_track, n->pos, t);
00381 lib3ds_track_eval_quat(&n->rot_track, n->rot, t);
00382 if (n->scl_track.nkeys) {
00383 lib3ds_track_eval_vector(&n->scl_track, n->scl, t);
00384 } else {
00385 n->scl[0] = n->scl[1] = n->scl[2] = 1.0f;
00386 }
00387 lib3ds_track_eval_bool(&n->hide_track, &n->hide, t);
00388
00389 lib3ds_matrix_identity(M);
00390 lib3ds_matrix_translate(M, n->pos[0], n->pos[1], n->pos[2]);
00391 lib3ds_matrix_rotate_quat(M, n->rot);
00392 lib3ds_matrix_scale(M, n->scl[0], n->scl[1], n->scl[2]);
00393
00394 if (node->parent) {
00395 lib3ds_matrix_mult(node->matrix, node->parent->matrix, M);
00396 } else {
00397 lib3ds_matrix_copy(node->matrix, M);
00398 }
00399 break;
00400 }
00401
00402 case LIB3DS_NODE_CAMERA: {
00403 Lib3dsCameraNode *n = (Lib3dsCameraNode*)node;
00404 lib3ds_track_eval_vector(&n->pos_track, n->pos, t);
00405 lib3ds_track_eval_float(&n->fov_track, &n->fov, t);
00406 lib3ds_track_eval_float(&n->roll_track, &n->roll, t);
00407 if (node->parent) {
00408 lib3ds_matrix_copy(node->matrix, node->parent->matrix);
00409 } else {
00410 lib3ds_matrix_identity(node->matrix);
00411 }
00412 lib3ds_matrix_translate(node->matrix, n->pos[0], n->pos[1], n->pos[2]);
00413 break;
00414 }
00415
00416 case LIB3DS_NODE_CAMERA_TARGET: {
00417 Lib3dsTargetNode *n = (Lib3dsTargetNode*)node;
00418 lib3ds_track_eval_vector(&n->pos_track, n->pos, t);
00419 if (node->parent) {
00420 lib3ds_matrix_copy(node->matrix, node->parent->matrix);
00421 } else {
00422 lib3ds_matrix_identity(node->matrix);
00423 }
00424 lib3ds_matrix_translate(node->matrix, n->pos[0], n->pos[1], n->pos[2]);
00425 break;
00426 }
00427
00428 case LIB3DS_NODE_OMNILIGHT: {
00429 Lib3dsOmnilightNode *n = (Lib3dsOmnilightNode*)node;
00430 lib3ds_track_eval_vector(&n->pos_track, n->pos, t);
00431 lib3ds_track_eval_vector(&n->color_track, n->color, t);
00432 if (node->parent) {
00433 lib3ds_matrix_copy(node->matrix, node->parent->matrix);
00434 } else {
00435 lib3ds_matrix_identity(node->matrix);
00436 }
00437 lib3ds_matrix_translate(node->matrix, n->pos[0], n->pos[1], n->pos[2]);
00438 break;
00439 }
00440
00441 case LIB3DS_NODE_SPOTLIGHT: {
00442 Lib3dsSpotlightNode *n = (Lib3dsSpotlightNode*)node;
00443 lib3ds_track_eval_vector(&n->pos_track, n->pos, t);
00444 lib3ds_track_eval_vector(&n->color_track, n->color, t);
00445 lib3ds_track_eval_float(&n->hotspot_track, &n->hotspot, t);
00446 lib3ds_track_eval_float(&n->falloff_track, &n->falloff, t);
00447 lib3ds_track_eval_float(&n->roll_track, &n->roll, t);
00448 if (node->parent) {
00449 lib3ds_matrix_copy(node->matrix, node->parent->matrix);
00450 } else {
00451 lib3ds_matrix_identity(node->matrix);
00452 }
00453 lib3ds_matrix_translate(node->matrix, n->pos[0], n->pos[1], n->pos[2]);
00454 break;
00455 }
00456
00457 case LIB3DS_NODE_SPOTLIGHT_TARGET: {
00458 Lib3dsTargetNode *n = (Lib3dsTargetNode*)node;
00459 lib3ds_track_eval_vector(&n->pos_track, n->pos, t);
00460 if (node->parent) {
00461 lib3ds_matrix_copy(node->matrix, node->parent->matrix);
00462 } else {
00463 lib3ds_matrix_identity(node->matrix);
00464 }
00465 lib3ds_matrix_translate(node->matrix, n->pos[0], n->pos[1], n->pos[2]);
00466 break;
00467 }
00468 }
00469 {
00470 Lib3dsNode *p;
00471 for (p = node->childs; p != 0; p = p->next) {
00472 lib3ds_node_eval(p, t);
00473 }
00474 }
00475 }
00476
00477
00490 Lib3dsNode*
00491 lib3ds_node_by_name(Lib3dsNode *node, const char* name, Lib3dsNodeType type) {
00492 Lib3dsNode *p, *q;
00493
00494 for (p = node->childs; p != 0; p = p->next) {
00495 if ((p->type == type) && (strcmp(p->name, name) == 0)) {
00496 return(p);
00497 }
00498 q = lib3ds_node_by_name(p, name, type);
00499 if (q) {
00500 return(q);
00501 }
00502 }
00503 return(0);
00504 }
00505
00506
00517 Lib3dsNode*
00518 lib3ds_node_by_id(Lib3dsNode *node, uint16_t node_id) {
00519 Lib3dsNode *p, *q;
00520
00521 for (p = node->childs; p != 0; p = p->next) {
00522 if (p->node_id == node_id) {
00523 return(p);
00524 }
00525 q = lib3ds_node_by_id(p, node_id);
00526 if (q) {
00527 return(q);
00528 }
00529 }
00530 return(0);
00531 }
00532
00533
00534 void
00535 lib3ds_node_read(Lib3dsNode *node, Lib3dsIo *io) {
00536 Lib3dsChunk c;
00537 uint16_t chunk;
00538
00539 assert(node);
00540 lib3ds_chunk_read_start(&c, 0, io);
00541
00542 switch (c.chunk) {
00543 case CHK_AMBIENT_NODE_TAG:
00544 case CHK_OBJECT_NODE_TAG:
00545 case CHK_CAMERA_NODE_TAG:
00546 case CHK_TARGET_NODE_TAG:
00547 case CHK_LIGHT_NODE_TAG:
00548 case CHK_SPOTLIGHT_NODE_TAG:
00549 case CHK_L_TARGET_NODE_TAG:
00550 break;
00551 default:
00552 return;
00553 }
00554
00555 while ((chunk = lib3ds_chunk_read_next(&c, io)) != 0) {
00556 switch (chunk) {
00557 case CHK_NODE_ID: {
00558 node->node_id = lib3ds_io_read_word(io);
00559 lib3ds_io_log_indent(io, 1);
00560 lib3ds_io_log(io, LIB3DS_LOG_INFO, "ID=%d", (short)node->node_id);
00561 lib3ds_io_log_indent(io, -1);
00562 break;
00563 }
00564
00565 case CHK_NODE_HDR: {
00566 lib3ds_io_read_string(io, node->name, 64);
00567 node->flags = lib3ds_io_read_word(io);
00568 node->flags |= ((uint32_t)lib3ds_io_read_word(io)) << 16;
00569 node->user_id = lib3ds_io_read_word(io);
00570
00571 lib3ds_io_log_indent(io, 1);
00572 lib3ds_io_log(io, LIB3DS_LOG_INFO, "NAME=%s", node->name);
00573 lib3ds_io_log(io, LIB3DS_LOG_INFO, "PARENT=%d", (short)node->user_id);
00574 lib3ds_io_log_indent(io, -1);
00575 break;
00576 }
00577
00578 case CHK_PIVOT: {
00579 if (node->type == LIB3DS_NODE_MESH_INSTANCE) {
00580 Lib3dsMeshInstanceNode *n = (Lib3dsMeshInstanceNode*)node;
00581 lib3ds_io_read_vector(io, n->pivot);
00582 } else {
00583 lib3ds_chunk_unknown(chunk, io);
00584 }
00585 break;
00586 }
00587
00588 case CHK_INSTANCE_NAME: {
00589 if (node->type == LIB3DS_NODE_MESH_INSTANCE) {
00590 Lib3dsMeshInstanceNode *n = (Lib3dsMeshInstanceNode*)node;
00591 lib3ds_io_read_string(io, n->instance_name, 64);
00592 } else {
00593 lib3ds_chunk_unknown(chunk, io);
00594 }
00595 break;
00596 }
00597
00598 case CHK_BOUNDBOX: {
00599 if (node->type == LIB3DS_NODE_MESH_INSTANCE) {
00600 Lib3dsMeshInstanceNode *n = (Lib3dsMeshInstanceNode*)node;
00601 lib3ds_io_read_vector(io, n->bbox_min);
00602 lib3ds_io_read_vector(io, n->bbox_max);
00603 } else {
00604 lib3ds_chunk_unknown(chunk, io);
00605 }
00606 break;
00607 }
00608
00609 case CHK_COL_TRACK_TAG: {
00610 Lib3dsTrack *track = 0;
00611 switch (node->type) {
00612 case LIB3DS_NODE_AMBIENT_COLOR: {
00613 Lib3dsAmbientColorNode *n = (Lib3dsAmbientColorNode*)node;
00614 track = &n->color_track;
00615 break;
00616 }
00617 case LIB3DS_NODE_OMNILIGHT: {
00618 Lib3dsOmnilightNode *n = (Lib3dsOmnilightNode*)node;
00619 track = &n->color_track;
00620 break;
00621 }
00622 case LIB3DS_NODE_SPOTLIGHT: {
00623 Lib3dsSpotlightNode *n = (Lib3dsSpotlightNode*)node;
00624 track = &n->color_track;
00625 break;
00626 }
00627 default:
00628 lib3ds_chunk_unknown(chunk, io);
00629 }
00630 if (track) {
00631 lib3ds_track_read(track, io);
00632 }
00633 break;
00634 }
00635
00636 case CHK_POS_TRACK_TAG: {
00637 Lib3dsTrack *track = 0;
00638 switch (node->type) {
00639 case LIB3DS_NODE_MESH_INSTANCE: {
00640 Lib3dsMeshInstanceNode *n = (Lib3dsMeshInstanceNode*)node;
00641 track = &n->pos_track;
00642 break;
00643 }
00644 case LIB3DS_NODE_CAMERA: {
00645 Lib3dsCameraNode *n = (Lib3dsCameraNode*)node;
00646 track = &n->pos_track;
00647 break;
00648 }
00649 case LIB3DS_NODE_CAMERA_TARGET: {
00650 Lib3dsTargetNode *n = (Lib3dsTargetNode*)node;
00651 track = &n->pos_track;
00652 break;
00653 }
00654 case LIB3DS_NODE_OMNILIGHT: {
00655 Lib3dsOmnilightNode *n = (Lib3dsOmnilightNode*)node;
00656 track = &n->pos_track;
00657 break;
00658 }
00659 case LIB3DS_NODE_SPOTLIGHT: {
00660 Lib3dsSpotlightNode *n = (Lib3dsSpotlightNode*)node;
00661 track = &n->pos_track;
00662 break;
00663 }
00664 case LIB3DS_NODE_SPOTLIGHT_TARGET: {
00665 Lib3dsTargetNode *n = (Lib3dsTargetNode*)node;
00666 track = &n->pos_track;
00667 break;
00668 }
00669 default:
00670 lib3ds_chunk_unknown(chunk, io);
00671 }
00672 if (track) {
00673 lib3ds_track_read(track, io);
00674 }
00675 break;
00676 }
00677
00678 case CHK_ROT_TRACK_TAG: {
00679 if (node->type == LIB3DS_NODE_MESH_INSTANCE) {
00680 Lib3dsMeshInstanceNode *n = (Lib3dsMeshInstanceNode*)node;
00681 n->rot_track.type = LIB3DS_TRACK_QUAT;
00682 lib3ds_track_read(&n->rot_track, io);
00683 } else {
00684 lib3ds_chunk_unknown(chunk, io);
00685 }
00686 break;
00687 }
00688
00689 case CHK_SCL_TRACK_TAG: {
00690 if (node->type == LIB3DS_NODE_MESH_INSTANCE) {
00691 Lib3dsMeshInstanceNode *n = (Lib3dsMeshInstanceNode*)node;
00692 n->scl_track.type = LIB3DS_TRACK_VECTOR;
00693 lib3ds_track_read(&n->scl_track, io);
00694 } else {
00695 lib3ds_chunk_unknown(chunk, io);
00696 }
00697 break;
00698 }
00699
00700 case CHK_FOV_TRACK_TAG: {
00701 if (node->type == LIB3DS_NODE_CAMERA) {
00702 Lib3dsCameraNode *n = (Lib3dsCameraNode*)node;
00703 n->fov_track.type = LIB3DS_TRACK_FLOAT;
00704 lib3ds_track_read(&n->fov_track, io);
00705 } else {
00706 lib3ds_chunk_unknown(chunk, io);
00707 }
00708 break;
00709 }
00710
00711 case CHK_HOT_TRACK_TAG: {
00712 if (node->type == LIB3DS_NODE_SPOTLIGHT) {
00713 Lib3dsSpotlightNode *n = (Lib3dsSpotlightNode*)node;
00714 n->hotspot_track.type = LIB3DS_TRACK_FLOAT;
00715 lib3ds_track_read(&n->hotspot_track, io);
00716 } else {
00717 lib3ds_chunk_unknown(chunk, io);
00718 }
00719 break;
00720 }
00721
00722 case CHK_FALL_TRACK_TAG: {
00723 if (node->type == LIB3DS_NODE_SPOTLIGHT) {
00724 Lib3dsSpotlightNode *n = (Lib3dsSpotlightNode*)node;
00725 n->falloff_track.type= LIB3DS_TRACK_FLOAT;
00726 lib3ds_track_read(&n->falloff_track, io);
00727 } else {
00728 lib3ds_chunk_unknown(chunk, io);
00729 }
00730 break;
00731 }
00732
00733 case CHK_ROLL_TRACK_TAG: {
00734 switch (node->type) {
00735 case LIB3DS_NODE_CAMERA: {
00736 Lib3dsCameraNode *n = (Lib3dsCameraNode*)node;
00737 n->roll_track.type = LIB3DS_TRACK_FLOAT;
00738 lib3ds_track_read(&n->roll_track, io);
00739 break;
00740 }
00741 case LIB3DS_NODE_SPOTLIGHT: {
00742 Lib3dsSpotlightNode *n = (Lib3dsSpotlightNode*)node;
00743 n->roll_track.type = LIB3DS_TRACK_FLOAT;
00744 lib3ds_track_read(&n->roll_track, io);
00745 break;
00746 }
00747 default:
00748 lib3ds_chunk_unknown(chunk, io);
00749 }
00750 break;
00751 }
00752
00753 case CHK_HIDE_TRACK_TAG: {
00754 if (node->type == LIB3DS_NODE_MESH_INSTANCE) {
00755 Lib3dsMeshInstanceNode *n = (Lib3dsMeshInstanceNode*)node;
00756 n->hide_track.type = LIB3DS_TRACK_BOOL;
00757 lib3ds_track_read(&n->hide_track, io);
00758 } else {
00759 lib3ds_chunk_unknown(chunk, io);
00760 }
00761 break;
00762 }
00763
00764 case CHK_MORPH_SMOOTH: {
00765 if (node->type == LIB3DS_NODE_MESH_INSTANCE) {
00766 Lib3dsMeshInstanceNode *n = (Lib3dsMeshInstanceNode*)node;
00767 n->morph_smooth = lib3ds_io_read_float(io);
00768 } else {
00769 lib3ds_chunk_unknown(chunk, io);
00770 }
00771 }
00772 break;
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787 default:
00788 lib3ds_chunk_unknown(chunk, io);
00789 }
00790 }
00791
00792 lib3ds_chunk_read_end(&c, io);
00793 }
00794
00795
00796 void
00797 lib3ds_node_write(Lib3dsNode *node, uint16_t node_id, uint16_t parent_id, Lib3dsIo *io) {
00798 Lib3dsChunk c;
00799
00800 switch (node->type) {
00801 case LIB3DS_NODE_AMBIENT_COLOR:
00802 c.chunk = CHK_AMBIENT_NODE_TAG;
00803 break;
00804
00805 case LIB3DS_NODE_MESH_INSTANCE:
00806 c.chunk = CHK_OBJECT_NODE_TAG;
00807 break;
00808
00809 case LIB3DS_NODE_CAMERA:
00810 c.chunk = CHK_CAMERA_NODE_TAG;
00811 break;
00812
00813 case LIB3DS_NODE_CAMERA_TARGET:
00814 c.chunk = CHK_TARGET_NODE_TAG;
00815 break;
00816
00817 case LIB3DS_NODE_OMNILIGHT:
00818 c.chunk = CHK_LIGHT_NODE_TAG;
00819 break;
00820
00821 case LIB3DS_NODE_SPOTLIGHT:
00822 c.chunk = CHK_SPOTLIGHT_NODE_TAG;
00823 break;
00824
00825 case LIB3DS_NODE_SPOTLIGHT_TARGET:
00826 c.chunk = CHK_L_TARGET_NODE_TAG;
00827 break;
00828
00829 default:
00830 assert(0);
00831 return;
00832 }
00833
00834 lib3ds_chunk_write_start(&c, io);
00835
00836 {
00837 Lib3dsChunk c;
00838 c.chunk = CHK_NODE_ID;
00839 c.size = 8;
00840 lib3ds_chunk_write(&c, io);
00841 lib3ds_io_write_intw(io, node_id);
00842 }
00843
00844 {
00845 Lib3dsChunk c;
00846 c.chunk = CHK_NODE_HDR;
00847 c.size = 6 + 1 + (uint32_t)strlen(node->name) + 2 + 2 + 2;
00848 lib3ds_chunk_write(&c, io);
00849 lib3ds_io_write_string(io, node->name);
00850 lib3ds_io_write_word(io, node->flags & 0xffff);
00851 lib3ds_io_write_word(io, (node->flags >> 16) & 0xffff);
00852 lib3ds_io_write_word(io, parent_id);
00853 }
00854
00855 switch (c.chunk) {
00856 case CHK_AMBIENT_NODE_TAG: {
00857 Lib3dsAmbientColorNode *n = (Lib3dsAmbientColorNode*)node;
00858 if (n->color_track.nkeys) {
00859 Lib3dsChunk c;
00860 c.chunk = CHK_COL_TRACK_TAG;
00861 lib3ds_chunk_write_start(&c, io);
00862 lib3ds_track_write(&n->color_track, io);
00863 lib3ds_chunk_write_end(&c, io);
00864 }
00865 break;
00866 }
00867
00868 case CHK_OBJECT_NODE_TAG: {
00869 Lib3dsMeshInstanceNode *n = (Lib3dsMeshInstanceNode*)node;
00870 {
00871 Lib3dsChunk c;
00872 c.chunk = CHK_PIVOT;
00873 c.size = 18;
00874 lib3ds_chunk_write(&c, io);
00875 lib3ds_io_write_vector(io, n->pivot);
00876 }
00877
00878 {
00879 Lib3dsChunk c;
00880 const char *name;
00881 if (strlen(n->instance_name)) {
00882 name = n->instance_name;
00883
00884 c.chunk = CHK_INSTANCE_NAME;
00885 c.size = 6 + 1 + (uint32_t)strlen(name);
00886 lib3ds_chunk_write(&c, io);
00887 lib3ds_io_write_string(io, name);
00888 }
00889 }
00890 {
00891 int i;
00892 for (i = 0; i < 3; ++i) {
00893 if ((fabs(n->bbox_min[i]) > LIB3DS_EPSILON) ||
00894 (fabs(n->bbox_max[i]) > LIB3DS_EPSILON)) {
00895 break;
00896 }
00897 }
00898
00899 if (i < 3) {
00900 Lib3dsChunk c;
00901 c.chunk = CHK_BOUNDBOX;
00902 c.size = 30;
00903 lib3ds_chunk_write(&c, io);
00904 lib3ds_io_write_vector(io, n->bbox_min);
00905 lib3ds_io_write_vector(io, n->bbox_max);
00906 }
00907 }
00908
00909 if (n->pos_track.nkeys) {
00910 Lib3dsChunk c;
00911 c.chunk = CHK_POS_TRACK_TAG;
00912 lib3ds_chunk_write_start(&c, io);
00913 lib3ds_track_write(&n->pos_track, io);
00914 lib3ds_chunk_write_end(&c, io);
00915 }
00916 if (n->rot_track.nkeys) {
00917 Lib3dsChunk c;
00918 c.chunk = CHK_ROT_TRACK_TAG;
00919 lib3ds_chunk_write_start(&c, io);
00920 lib3ds_track_write(&n->rot_track, io);
00921 lib3ds_chunk_write_end(&c, io);
00922 }
00923 if (n->scl_track.nkeys) {
00924 Lib3dsChunk c;
00925 c.chunk = CHK_SCL_TRACK_TAG;
00926 lib3ds_chunk_write_start(&c, io);
00927 lib3ds_track_write(&n->scl_track, io);
00928 lib3ds_chunk_write_end(&c, io);
00929 }
00930 if (n->hide_track.nkeys) {
00931 Lib3dsChunk c;
00932 c.chunk = CHK_HIDE_TRACK_TAG;
00933 lib3ds_chunk_write_start(&c, io);
00934 lib3ds_track_write(&n->hide_track, io);
00935 lib3ds_chunk_write_end(&c, io);
00936 }
00937 if (fabs(n->morph_smooth) > LIB3DS_EPSILON) {
00938 Lib3dsChunk c;
00939 c.chunk = CHK_MORPH_SMOOTH;
00940 c.size = 10;
00941 lib3ds_chunk_write(&c, io);
00942 lib3ds_io_write_float(io, n->morph_smooth);
00943 }
00944 break;
00945 }
00946
00947 case CHK_CAMERA_NODE_TAG: {
00948 Lib3dsCameraNode *n = (Lib3dsCameraNode*)node;
00949 if (n->pos_track.nkeys) {
00950 Lib3dsChunk c;
00951 c.chunk = CHK_POS_TRACK_TAG;
00952 lib3ds_chunk_write_start(&c, io);
00953 lib3ds_track_write(&n->pos_track, io);
00954 lib3ds_chunk_write_end(&c, io);
00955 }
00956 if (n->fov_track.nkeys) {
00957 Lib3dsChunk c;
00958 c.chunk = CHK_FOV_TRACK_TAG;
00959 lib3ds_chunk_write_start(&c, io);
00960 lib3ds_track_write(&n->fov_track, io);
00961 lib3ds_chunk_write_end(&c, io);
00962 }
00963 if (n->roll_track.nkeys) {
00964 Lib3dsChunk c;
00965 c.chunk = CHK_ROLL_TRACK_TAG;
00966 lib3ds_chunk_write_start(&c, io);
00967 lib3ds_track_write(&n->roll_track, io);
00968 lib3ds_chunk_write_end(&c, io);
00969 }
00970 break;
00971 }
00972
00973 case CHK_TARGET_NODE_TAG: {
00974 Lib3dsTargetNode *n = (Lib3dsTargetNode*)node;
00975 if (n->pos_track.nkeys) {
00976 Lib3dsChunk c;
00977 c.chunk = CHK_POS_TRACK_TAG;
00978 lib3ds_chunk_write_start(&c, io);
00979 lib3ds_track_write(&n->pos_track, io);
00980 lib3ds_chunk_write_end(&c, io);
00981 }
00982 break;
00983 }
00984
00985 case CHK_LIGHT_NODE_TAG: {
00986 Lib3dsOmnilightNode *n = (Lib3dsOmnilightNode*)node;
00987 if (n->pos_track.nkeys) {
00988 Lib3dsChunk c;
00989 c.chunk = CHK_POS_TRACK_TAG;
00990 lib3ds_chunk_write_start(&c, io);
00991 lib3ds_track_write(&n->pos_track, io);
00992 lib3ds_chunk_write_end(&c, io);
00993 }
00994 if (n->color_track.nkeys) {
00995 Lib3dsChunk c;
00996 c.chunk = CHK_COL_TRACK_TAG;
00997 lib3ds_chunk_write_start(&c, io);
00998 lib3ds_track_write(&n->color_track, io);
00999 lib3ds_chunk_write_end(&c, io);
01000 }
01001 break;
01002 }
01003
01004 case CHK_SPOTLIGHT_NODE_TAG: {
01005 Lib3dsSpotlightNode *n = (Lib3dsSpotlightNode*)node;
01006 if (n->pos_track.nkeys) {
01007 Lib3dsChunk c;
01008 c.chunk = CHK_POS_TRACK_TAG;
01009 lib3ds_chunk_write_start(&c, io);
01010 lib3ds_track_write(&n->pos_track, io);
01011 lib3ds_chunk_write_end(&c, io);
01012 }
01013 if (n->color_track.nkeys) {
01014 Lib3dsChunk c;
01015 c.chunk = CHK_COL_TRACK_TAG;
01016 lib3ds_chunk_write_start(&c, io);
01017 lib3ds_track_write(&n->color_track, io);
01018 lib3ds_chunk_write_end(&c, io);
01019 }
01020 if (n->hotspot_track.nkeys) {
01021 Lib3dsChunk c;
01022 c.chunk = CHK_HOT_TRACK_TAG;
01023 lib3ds_chunk_write_start(&c, io);
01024 lib3ds_track_write(&n->hotspot_track, io);
01025 lib3ds_chunk_write_end(&c, io);
01026 }
01027 if (n->falloff_track.nkeys) {
01028 Lib3dsChunk c;
01029 c.chunk = CHK_FALL_TRACK_TAG;
01030 lib3ds_chunk_write_start(&c, io);
01031 lib3ds_track_write(&n->falloff_track, io);
01032 lib3ds_chunk_write_end(&c, io);
01033 }
01034 if (n->roll_track.nkeys) {
01035 Lib3dsChunk c;
01036 c.chunk = CHK_ROLL_TRACK_TAG;
01037 lib3ds_chunk_write_start(&c, io);
01038 lib3ds_track_write(&n->roll_track, io);
01039 lib3ds_chunk_write_end(&c, io);
01040 }
01041 break;
01042 }
01043
01044 case CHK_L_TARGET_NODE_TAG: {
01045 Lib3dsTargetNode *n = (Lib3dsTargetNode*)node;
01046 if (n->pos_track.nkeys) {
01047 Lib3dsChunk c;
01048 c.chunk = CHK_POS_TRACK_TAG;
01049 lib3ds_chunk_write_start(&c, io);
01050 lib3ds_track_write(&n->pos_track, io);
01051 lib3ds_chunk_write_end(&c, io);
01052 }
01053 break;
01054 }
01055
01056 default:
01057 break;
01058 }
01059
01060 lib3ds_chunk_write_end(&c, io);
01061 }
01062