2 * The 3D Studio File Format Library
3 * Copyright (C) 1996-2001 by J.E. Hoffmann <je-h@gmx.net>
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; either version 2.1 of the License, or (at
9 * your option) any later version.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14 * License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 * $Id: node.c,v 1.13 2004/11/16 07:41:44 efalk Exp $
23 #include <lib3ds/node.h>
24 #include <lib3ds/file.h>
25 #include <lib3ds/io.h>
26 #include <lib3ds/chunk.h>
27 #include <lib3ds/matrix.h>
37 * \defgroup node Animation Nodes
39 * \author J.E. Hoffmann <je-h@gmx.net>
44 * Create and return a new ambient node.
46 * The node is returned with an identity matrix. All other fields
54 lib3ds_node_new_ambient()
56 Lib3dsNode *node=(Lib3dsNode*)calloc(sizeof(Lib3dsNode), 1);
57 node->type=LIB3DS_AMBIENT_NODE;
58 lib3ds_matrix_identity(node->matrix);
64 * Create and return a new object node.
66 * The node is returned with an identity matrix. All other fields
74 lib3ds_node_new_object()
76 Lib3dsNode *node=(Lib3dsNode*)calloc(sizeof(Lib3dsNode), 1);
77 node->type=LIB3DS_OBJECT_NODE;
78 lib3ds_matrix_identity(node->matrix);
84 * Create and return a new camera node.
86 * The node is returned with an identity matrix. All other fields
94 lib3ds_node_new_camera()
96 Lib3dsNode *node=(Lib3dsNode*)calloc(sizeof(Lib3dsNode), 1);
97 node->type=LIB3DS_CAMERA_NODE;
98 lib3ds_matrix_identity(node->matrix);
104 * Create and return a new target node.
106 * The node is returned with an identity matrix. All other fields
114 lib3ds_node_new_target()
116 Lib3dsNode *node=(Lib3dsNode*)calloc(sizeof(Lib3dsNode), 1);
117 node->type=LIB3DS_TARGET_NODE;
118 lib3ds_matrix_identity(node->matrix);
124 * Create and return a new light node.
126 * The node is returned with an identity matrix. All other fields
134 lib3ds_node_new_light()
136 Lib3dsNode *node=(Lib3dsNode*)calloc(sizeof(Lib3dsNode), 1);
137 node->type=LIB3DS_LIGHT_NODE;
138 lib3ds_matrix_identity(node->matrix);
144 * Create and return a new spot node.
146 * The node is returned with an identity matrix. All other fields
154 lib3ds_node_new_spot()
156 Lib3dsNode *node=(Lib3dsNode*)calloc(sizeof(Lib3dsNode), 1);
157 node->type=LIB3DS_SPOT_NODE;
158 lib3ds_matrix_identity(node->matrix);
164 free_node_and_childs(Lib3dsNode *node)
167 switch (node->type) {
168 case LIB3DS_UNKNOWN_NODE:
170 case LIB3DS_AMBIENT_NODE:
172 Lib3dsAmbientData *n=&node->data.ambient;
173 lib3ds_lin3_track_free_keys(&n->col_track);
176 case LIB3DS_OBJECT_NODE:
178 Lib3dsObjectData *n=&node->data.object;
180 lib3ds_lin3_track_free_keys(&n->pos_track);
181 lib3ds_quat_track_free_keys(&n->rot_track);
182 lib3ds_lin3_track_free_keys(&n->scl_track);
183 lib3ds_bool_track_free_keys(&n->hide_track);
184 lib3ds_morph_track_free_keys(&n->morph_track);
187 case LIB3DS_CAMERA_NODE:
189 Lib3dsCameraData *n=&node->data.camera;
190 lib3ds_lin3_track_free_keys(&n->pos_track);
191 lib3ds_lin1_track_free_keys(&n->fov_track);
192 lib3ds_lin1_track_free_keys(&n->roll_track);
195 case LIB3DS_TARGET_NODE:
197 Lib3dsTargetData *n=&node->data.target;
198 lib3ds_lin3_track_free_keys(&n->pos_track);
201 case LIB3DS_LIGHT_NODE:
203 Lib3dsLightData *n=&node->data.light;
204 lib3ds_lin3_track_free_keys(&n->pos_track);
205 lib3ds_lin3_track_free_keys(&n->col_track);
206 lib3ds_lin1_track_free_keys(&n->hotspot_track);
207 lib3ds_lin1_track_free_keys(&n->falloff_track);
208 lib3ds_lin1_track_free_keys(&n->roll_track);
211 case LIB3DS_SPOT_NODE:
213 Lib3dsSpotData *n=&node->data.spot;
214 lib3ds_lin3_track_free_keys(&n->pos_track);
220 for (p=node->childs; p; p=q) {
222 free_node_and_childs(p);
225 node->type=LIB3DS_UNKNOWN_NODE;
231 * Free a node and all of its resources.
233 * \param node Lib3dsNode object to be freed.
238 lib3ds_node_free(Lib3dsNode *node)
241 free_node_and_childs(node);
246 * Evaluate an animation node.
248 * Recursively sets node and its children to their appropriate values
249 * for this point in the animation.
251 * \param node Node to be evaluated.
252 * \param t time value, between 0. and file->frames
257 lib3ds_node_eval(Lib3dsNode *node, Lib3dsFloat t)
260 switch (node->type) {
261 case LIB3DS_UNKNOWN_NODE:
263 ASSERT(LIB3DS_FALSE);
266 case LIB3DS_AMBIENT_NODE:
268 Lib3dsAmbientData *n=&node->data.ambient;
270 lib3ds_matrix_copy(node->matrix, node->parent->matrix);
273 lib3ds_matrix_identity(node->matrix);
275 lib3ds_lin3_track_eval(&n->col_track, n->col, t);
278 case LIB3DS_OBJECT_NODE:
281 Lib3dsObjectData *n=&node->data.object;
283 lib3ds_lin3_track_eval(&n->pos_track, n->pos, t);
284 lib3ds_quat_track_eval(&n->rot_track, n->rot, t);
285 lib3ds_lin3_track_eval(&n->scl_track, n->scl, t);
286 lib3ds_bool_track_eval(&n->hide_track, &n->hide, t);
287 lib3ds_morph_track_eval(&n->morph_track, n->morph, t);
289 lib3ds_matrix_identity(M);
290 lib3ds_matrix_translate(M, n->pos);
291 lib3ds_matrix_rotate(M, n->rot);
292 lib3ds_matrix_scale(M, n->scl);
295 lib3ds_matrix_mul(node->matrix, node->parent->matrix, M);
298 lib3ds_matrix_copy(node->matrix, M);
302 case LIB3DS_CAMERA_NODE:
304 Lib3dsCameraData *n=&node->data.camera;
305 lib3ds_lin3_track_eval(&n->pos_track, n->pos, t);
306 lib3ds_lin1_track_eval(&n->fov_track, &n->fov, t);
307 lib3ds_lin1_track_eval(&n->roll_track, &n->roll, t);
309 lib3ds_matrix_copy(node->matrix, node->parent->matrix);
312 lib3ds_matrix_identity(node->matrix);
314 lib3ds_matrix_translate(node->matrix, n->pos);
317 case LIB3DS_TARGET_NODE:
319 Lib3dsTargetData *n=&node->data.target;
320 lib3ds_lin3_track_eval(&n->pos_track, n->pos, t);
322 lib3ds_matrix_copy(node->matrix, node->parent->matrix);
325 lib3ds_matrix_identity(node->matrix);
327 lib3ds_matrix_translate(node->matrix, n->pos);
330 case LIB3DS_LIGHT_NODE:
332 Lib3dsLightData *n=&node->data.light;
333 lib3ds_lin3_track_eval(&n->pos_track, n->pos, t);
334 lib3ds_lin3_track_eval(&n->col_track, n->col, t);
335 lib3ds_lin1_track_eval(&n->hotspot_track, &n->hotspot, t);
336 lib3ds_lin1_track_eval(&n->falloff_track, &n->falloff, t);
337 lib3ds_lin1_track_eval(&n->roll_track, &n->roll, t);
339 lib3ds_matrix_copy(node->matrix, node->parent->matrix);
342 lib3ds_matrix_identity(node->matrix);
344 lib3ds_matrix_translate(node->matrix, n->pos);
347 case LIB3DS_SPOT_NODE:
349 Lib3dsSpotData *n=&node->data.spot;
350 lib3ds_lin3_track_eval(&n->pos_track, n->pos, t);
352 lib3ds_matrix_copy(node->matrix, node->parent->matrix);
355 lib3ds_matrix_identity(node->matrix);
357 lib3ds_matrix_translate(node->matrix, n->pos);
364 for (p=node->childs; p!=0; p=p->next) {
365 lib3ds_node_eval(p, t);
372 * Return a node object by name and type.
374 * This function performs a recursive search for the specified node.
375 * Both name and type must match.
377 * \param node The parent node for the search
378 * \param name The target node name.
379 * \param type The target node type
381 * \return A pointer to the first matching node, or NULL if not found.
386 lib3ds_node_by_name(Lib3dsNode *node, const char* name, Lib3dsNodeTypes type)
390 for (p=node->childs; p!=0; p=p->next) {
391 if ((p->type==type) && (strcmp(p->name, name)==0)) {
394 q=lib3ds_node_by_name(p, name, type);
404 * Return a node object by id.
406 * This function performs a recursive search for the specified node.
408 * \param node The parent node for the search
409 * \param node_id The target node id.
411 * \return A pointer to the first matching node, or NULL if not found.
416 lib3ds_node_by_id(Lib3dsNode *node, Lib3dsWord node_id)
420 for (p=node->childs; p!=0; p=p->next) {
421 if (p->node_id==node_id) {
424 q=lib3ds_node_by_id(p, node_id);
433 static const char* node_names_table[]= {
445 * Dump node and all descendants recursively.
447 * \param node The top-level node to be dumped.
448 * \param level current recursion depth
453 lib3ds_node_dump(Lib3dsNode *node, Lib3dsIntd level)
459 memset(l, ' ', 2*level);
462 if (node->type==LIB3DS_OBJECT_NODE) {
463 printf("%s%s [%s] (%s)\n",
466 node->data.object.instance,
467 node_names_table[node->type]
471 printf("%s%s (%s)\n",
474 node_names_table[node->type]
478 for (p=node->childs; p!=0; p=p->next) {
479 lib3ds_node_dump(p, level+1);
488 lib3ds_node_read(Lib3dsNode *node, Lib3dsFile *file, Lib3dsIo *io)
494 if (!lib3ds_chunk_read_start(&c, 0, io)) {
495 return(LIB3DS_FALSE);
498 case LIB3DS_AMBIENT_NODE_TAG:
499 case LIB3DS_OBJECT_NODE_TAG:
500 case LIB3DS_CAMERA_NODE_TAG:
501 case LIB3DS_TARGET_NODE_TAG:
502 case LIB3DS_LIGHT_NODE_TAG:
503 case LIB3DS_SPOTLIGHT_NODE_TAG:
504 case LIB3DS_L_TARGET_NODE_TAG:
507 return(LIB3DS_FALSE);
510 while ((chunk=lib3ds_chunk_read_next(&c, io))!=0) {
514 node->node_id=lib3ds_io_read_word(io);
515 lib3ds_chunk_dump_info(" ID = %d", (short)node->node_id);
518 case LIB3DS_NODE_HDR:
520 if (!lib3ds_io_read_string(io, node->name, 64)) {
521 return(LIB3DS_FALSE);
523 node->flags1=lib3ds_io_read_word(io);
524 node->flags2=lib3ds_io_read_word(io);
525 node->parent_id=lib3ds_io_read_word(io);
526 lib3ds_chunk_dump_info(" NAME =%s", node->name);
527 lib3ds_chunk_dump_info(" PARENT=%d", (short)node->parent_id);
532 if (node->type==LIB3DS_OBJECT_NODE) {
534 for (i=0; i<3; ++i) {
535 node->data.object.pivot[i]=lib3ds_io_read_float(io);
539 lib3ds_chunk_unknown(chunk);
543 case LIB3DS_INSTANCE_NAME:
545 if (node->type==LIB3DS_OBJECT_NODE) {
546 if (!lib3ds_io_read_string(io, node->data.object.instance, 64)) {
547 return(LIB3DS_FALSE);
551 lib3ds_chunk_unknown(chunk);
555 case LIB3DS_BOUNDBOX:
557 if (node->type==LIB3DS_OBJECT_NODE) {
559 for (i=0; i<3; ++i) {
560 node->data.object.bbox_min[i]=lib3ds_io_read_float(io);
562 for (i=0; i<3; ++i) {
563 node->data.object.bbox_max[i]=lib3ds_io_read_float(io);
567 lib3ds_chunk_unknown(chunk);
571 case LIB3DS_COL_TRACK_TAG:
573 Lib3dsBool result=LIB3DS_TRUE;
575 switch (node->type) {
576 case LIB3DS_AMBIENT_NODE:
577 result=lib3ds_lin3_track_read(&node->data.ambient.col_track, io);
579 case LIB3DS_LIGHT_NODE:
580 result=lib3ds_lin3_track_read(&node->data.light.col_track, io);
583 lib3ds_chunk_unknown(chunk);
586 return(LIB3DS_FALSE);
590 case LIB3DS_POS_TRACK_TAG:
592 Lib3dsBool result=LIB3DS_TRUE;
594 switch (node->type) {
595 case LIB3DS_OBJECT_NODE:
596 result=lib3ds_lin3_track_read(&node->data.object.pos_track, io);
598 case LIB3DS_CAMERA_NODE:
599 result=lib3ds_lin3_track_read(&node->data.camera.pos_track, io);
601 case LIB3DS_TARGET_NODE:
602 result=lib3ds_lin3_track_read(&node->data.target.pos_track, io);
604 case LIB3DS_LIGHT_NODE:
605 result=lib3ds_lin3_track_read(&node->data.light.pos_track, io);
607 case LIB3DS_SPOT_NODE:
608 result=lib3ds_lin3_track_read(&node->data.spot.pos_track, io);
611 lib3ds_chunk_unknown(chunk);
614 return(LIB3DS_FALSE);
618 case LIB3DS_ROT_TRACK_TAG:
620 if (node->type==LIB3DS_OBJECT_NODE) {
621 if (!lib3ds_quat_track_read(&node->data.object.rot_track, io)) {
622 return(LIB3DS_FALSE);
626 lib3ds_chunk_unknown(chunk);
630 case LIB3DS_SCL_TRACK_TAG:
632 if (node->type==LIB3DS_OBJECT_NODE) {
633 if (!lib3ds_lin3_track_read(&node->data.object.scl_track, io)) {
634 return(LIB3DS_FALSE);
638 lib3ds_chunk_unknown(chunk);
642 case LIB3DS_FOV_TRACK_TAG:
644 if (node->type==LIB3DS_CAMERA_NODE) {
645 if (!lib3ds_lin1_track_read(&node->data.camera.fov_track, io)) {
646 return(LIB3DS_FALSE);
650 lib3ds_chunk_unknown(chunk);
654 case LIB3DS_HOT_TRACK_TAG:
656 if (node->type==LIB3DS_LIGHT_NODE) {
657 if (!lib3ds_lin1_track_read(&node->data.light.hotspot_track, io)) {
658 return(LIB3DS_FALSE);
662 lib3ds_chunk_unknown(chunk);
666 case LIB3DS_FALL_TRACK_TAG:
668 if (node->type==LIB3DS_LIGHT_NODE) {
669 if (!lib3ds_lin1_track_read(&node->data.light.falloff_track, io)) {
670 return(LIB3DS_FALSE);
674 lib3ds_chunk_unknown(chunk);
678 case LIB3DS_ROLL_TRACK_TAG:
680 Lib3dsBool result=LIB3DS_TRUE;
682 switch (node->type) {
683 case LIB3DS_CAMERA_NODE:
684 result=lib3ds_lin1_track_read(&node->data.camera.roll_track, io);
686 case LIB3DS_LIGHT_NODE:
687 result=lib3ds_lin1_track_read(&node->data.light.roll_track, io);
690 lib3ds_chunk_unknown(chunk);
693 return(LIB3DS_FALSE);
697 case LIB3DS_HIDE_TRACK_TAG:
699 if (node->type==LIB3DS_OBJECT_NODE) {
700 if (!lib3ds_bool_track_read(&node->data.object.hide_track, io)) {
701 return(LIB3DS_FALSE);
705 lib3ds_chunk_unknown(chunk);
709 case LIB3DS_MORPH_SMOOTH:
711 if (node->type==LIB3DS_OBJECT_NODE) {
712 node->data.object.morph_smooth=lib3ds_io_read_float(io);
715 lib3ds_chunk_unknown(chunk);
719 case LIB3DS_MORPH_TRACK_TAG:
721 if (node->type==LIB3DS_OBJECT_NODE) {
722 if (!lib3ds_morph_track_read(&node->data.object.morph_track, io)) {
723 return(LIB3DS_FALSE);
727 lib3ds_chunk_unknown(chunk);
732 lib3ds_chunk_unknown(chunk);
736 lib3ds_chunk_read_end(&c, io);
745 lib3ds_node_write(Lib3dsNode *node, Lib3dsFile *file, Lib3dsIo *io)
749 switch (node->type) {
750 case LIB3DS_AMBIENT_NODE:
751 c.chunk=LIB3DS_AMBIENT_NODE_TAG;
753 case LIB3DS_OBJECT_NODE:
754 c.chunk=LIB3DS_OBJECT_NODE_TAG;
756 case LIB3DS_CAMERA_NODE:
757 c.chunk=LIB3DS_CAMERA_NODE_TAG;
759 case LIB3DS_TARGET_NODE:
760 c.chunk=LIB3DS_TARGET_NODE_TAG;
762 case LIB3DS_LIGHT_NODE:
763 if (lib3ds_file_node_by_name(file, node->name, LIB3DS_SPOT_NODE)) {
764 c.chunk=LIB3DS_SPOTLIGHT_NODE_TAG;
767 c.chunk=LIB3DS_LIGHT_NODE_TAG;
770 case LIB3DS_SPOT_NODE:
771 c.chunk=LIB3DS_L_TARGET_NODE_TAG;
774 return(LIB3DS_FALSE);
776 if (!lib3ds_chunk_write_start(&c,io)) {
777 return(LIB3DS_FALSE);
780 { /*---- LIB3DS_NODE_ID ----*/
782 c.chunk=LIB3DS_NODE_ID;
784 lib3ds_chunk_write(&c,io);
785 lib3ds_io_write_intw(io, node->node_id);
788 { /*---- LIB3DS_NODE_HDR ----*/
790 c.chunk=LIB3DS_NODE_HDR;
791 c.size=6+ 1+strlen(node->name) +2+2+2;
792 lib3ds_chunk_write(&c,io);
793 lib3ds_io_write_string(io, node->name);
794 lib3ds_io_write_word(io, node->flags1);
795 lib3ds_io_write_word(io, node->flags2);
796 lib3ds_io_write_word(io, node->parent_id);
800 case LIB3DS_AMBIENT_NODE_TAG:
801 { /*---- LIB3DS_COL_TRACK_TAG ----*/
803 c.chunk=LIB3DS_COL_TRACK_TAG;
804 if (!lib3ds_chunk_write_start(&c,io)) {
805 return(LIB3DS_FALSE);
807 if (!lib3ds_lin3_track_write(&node->data.ambient.col_track,io)) {
808 return(LIB3DS_FALSE);
810 if (!lib3ds_chunk_write_end(&c,io)) {
811 return(LIB3DS_FALSE);
815 case LIB3DS_OBJECT_NODE_TAG:
816 { /*---- LIB3DS_PIVOT ----*/
818 c.chunk=LIB3DS_PIVOT;
820 lib3ds_chunk_write(&c,io);
821 lib3ds_io_write_vector(io, node->data.object.pivot);
823 { /*---- LIB3DS_INSTANCE_NAME ----*/
826 if (strlen(node->data.object.instance)) {
827 name=node->data.object.instance;
829 c.chunk=LIB3DS_INSTANCE_NAME;
830 c.size=6+1+strlen(name);
831 lib3ds_chunk_write(&c,io);
832 lib3ds_io_write_string(io, name);
837 for (i=0; i<3; ++i) {
838 if ((fabs(node->data.object.bbox_min[i])>LIB3DS_EPSILON) ||
839 (fabs(node->data.object.bbox_max[i])>LIB3DS_EPSILON)) {
844 if (i<3) { /*---- LIB3DS_BOUNDBOX ----*/
846 c.chunk=LIB3DS_BOUNDBOX;
848 lib3ds_chunk_write(&c,io);
849 lib3ds_io_write_vector(io, node->data.object.bbox_min);
850 lib3ds_io_write_vector(io, node->data.object.bbox_max);
853 { /*---- LIB3DS_POS_TRACK_TAG ----*/
855 c.chunk=LIB3DS_POS_TRACK_TAG;
856 if (!lib3ds_chunk_write_start(&c,io)) {
857 return(LIB3DS_FALSE);
859 if (!lib3ds_lin3_track_write(&node->data.object.pos_track,io)) {
860 return(LIB3DS_FALSE);
862 if (!lib3ds_chunk_write_end(&c,io)) {
863 return(LIB3DS_FALSE);
866 { /*---- LIB3DS_ROT_TRACK_TAG ----*/
868 c.chunk=LIB3DS_ROT_TRACK_TAG;
869 if (!lib3ds_chunk_write_start(&c,io)) {
870 return(LIB3DS_FALSE);
872 if (!lib3ds_quat_track_write(&node->data.object.rot_track,io)) {
873 return(LIB3DS_FALSE);
875 if (!lib3ds_chunk_write_end(&c,io)) {
876 return(LIB3DS_FALSE);
879 { /*---- LIB3DS_SCL_TRACK_TAG ----*/
881 c.chunk=LIB3DS_SCL_TRACK_TAG;
882 if (!lib3ds_chunk_write_start(&c,io)) {
883 return(LIB3DS_FALSE);
885 if (!lib3ds_lin3_track_write(&node->data.object.scl_track,io)) {
886 return(LIB3DS_FALSE);
888 if (!lib3ds_chunk_write_end(&c,io)) {
889 return(LIB3DS_FALSE);
892 if (node->data.object.hide_track.keyL) { /*---- LIB3DS_HIDE_TRACK_TAG ----*/
894 c.chunk=LIB3DS_HIDE_TRACK_TAG;
895 if (!lib3ds_chunk_write_start(&c,io)) {
896 return(LIB3DS_FALSE);
898 if (!lib3ds_bool_track_write(&node->data.object.hide_track,io)) {
899 return(LIB3DS_FALSE);
901 if (!lib3ds_chunk_write_end(&c,io)) {
902 return(LIB3DS_FALSE);
905 if (fabs(node->data.object.morph_smooth)>LIB3DS_EPSILON){ /*---- LIB3DS_MORPH_SMOOTH ----*/
907 c.chunk=LIB3DS_MORPH_SMOOTH;
909 lib3ds_chunk_write(&c,io);
910 lib3ds_io_write_float(io, node->data.object.morph_smooth);
913 case LIB3DS_CAMERA_NODE_TAG:
914 { /*---- LIB3DS_POS_TRACK_TAG ----*/
916 c.chunk=LIB3DS_POS_TRACK_TAG;
917 if (!lib3ds_chunk_write_start(&c,io)) {
918 return(LIB3DS_FALSE);
920 if (!lib3ds_lin3_track_write(&node->data.camera.pos_track,io)) {
921 return(LIB3DS_FALSE);
923 if (!lib3ds_chunk_write_end(&c,io)) {
924 return(LIB3DS_FALSE);
927 { /*---- LIB3DS_FOV_TRACK_TAG ----*/
929 c.chunk=LIB3DS_FOV_TRACK_TAG;
930 if (!lib3ds_chunk_write_start(&c,io)) {
931 return(LIB3DS_FALSE);
933 if (!lib3ds_lin1_track_write(&node->data.camera.fov_track,io)) {
934 return(LIB3DS_FALSE);
936 if (!lib3ds_chunk_write_end(&c,io)) {
937 return(LIB3DS_FALSE);
940 { /*---- LIB3DS_ROLL_TRACK_TAG ----*/
942 c.chunk=LIB3DS_ROLL_TRACK_TAG;
943 if (!lib3ds_chunk_write_start(&c,io)) {
944 return(LIB3DS_FALSE);
946 if (!lib3ds_lin1_track_write(&node->data.camera.roll_track,io)) {
947 return(LIB3DS_FALSE);
949 if (!lib3ds_chunk_write_end(&c,io)) {
950 return(LIB3DS_FALSE);
954 case LIB3DS_TARGET_NODE_TAG:
955 { /*---- LIB3DS_POS_TRACK_TAG ----*/
957 c.chunk=LIB3DS_POS_TRACK_TAG;
958 if (!lib3ds_chunk_write_start(&c,io)) {
959 return(LIB3DS_FALSE);
961 if (!lib3ds_lin3_track_write(&node->data.target.pos_track,io)) {
962 return(LIB3DS_FALSE);
964 if (!lib3ds_chunk_write_end(&c,io)) {
965 return(LIB3DS_FALSE);
969 case LIB3DS_LIGHT_NODE_TAG:
970 { /*---- LIB3DS_POS_TRACK_TAG ----*/
972 c.chunk=LIB3DS_POS_TRACK_TAG;
973 if (!lib3ds_chunk_write_start(&c,io)) {
974 return(LIB3DS_FALSE);
976 if (!lib3ds_lin3_track_write(&node->data.light.pos_track,io)) {
977 return(LIB3DS_FALSE);
979 if (!lib3ds_chunk_write_end(&c,io)) {
980 return(LIB3DS_FALSE);
983 { /*---- LIB3DS_COL_TRACK_TAG ----*/
985 c.chunk=LIB3DS_COL_TRACK_TAG;
986 if (!lib3ds_chunk_write_start(&c,io)) {
987 return(LIB3DS_FALSE);
989 if (!lib3ds_lin3_track_write(&node->data.light.col_track,io)) {
990 return(LIB3DS_FALSE);
992 if (!lib3ds_chunk_write_end(&c,io)) {
993 return(LIB3DS_FALSE);
997 case LIB3DS_SPOTLIGHT_NODE_TAG:
998 { /*---- LIB3DS_POS_TRACK_TAG ----*/
1000 c.chunk=LIB3DS_POS_TRACK_TAG;
1001 if (!lib3ds_chunk_write_start(&c,io)) {
1002 return(LIB3DS_FALSE);
1004 if (!lib3ds_lin3_track_write(&node->data.light.pos_track,io)) {
1005 return(LIB3DS_FALSE);
1007 if (!lib3ds_chunk_write_end(&c,io)) {
1008 return(LIB3DS_FALSE);
1011 { /*---- LIB3DS_COL_TRACK_TAG ----*/
1013 c.chunk=LIB3DS_COL_TRACK_TAG;
1014 if (!lib3ds_chunk_write_start(&c,io)) {
1015 return(LIB3DS_FALSE);
1017 if (!lib3ds_lin3_track_write(&node->data.light.col_track,io)) {
1018 return(LIB3DS_FALSE);
1020 if (!lib3ds_chunk_write_end(&c,io)) {
1021 return(LIB3DS_FALSE);
1024 { /*---- LIB3DS_HOT_TRACK_TAG ----*/
1026 c.chunk=LIB3DS_HOT_TRACK_TAG;
1027 if (!lib3ds_chunk_write_start(&c,io)) {
1028 return(LIB3DS_FALSE);
1030 if (!lib3ds_lin1_track_write(&node->data.light.hotspot_track,io)) {
1031 return(LIB3DS_FALSE);
1033 if (!lib3ds_chunk_write_end(&c,io)) {
1034 return(LIB3DS_FALSE);
1037 { /*---- LIB3DS_FALL_TRACK_TAG ----*/
1039 c.chunk=LIB3DS_FALL_TRACK_TAG;
1040 if (!lib3ds_chunk_write_start(&c,io)) {
1041 return(LIB3DS_FALSE);
1043 if (!lib3ds_lin1_track_write(&node->data.light.falloff_track,io)) {
1044 return(LIB3DS_FALSE);
1046 if (!lib3ds_chunk_write_end(&c,io)) {
1047 return(LIB3DS_FALSE);
1050 { /*---- LIB3DS_ROLL_TRACK_TAG ----*/
1052 c.chunk=LIB3DS_ROLL_TRACK_TAG;
1053 if (!lib3ds_chunk_write_start(&c,io)) {
1054 return(LIB3DS_FALSE);
1056 if (!lib3ds_lin1_track_write(&node->data.light.roll_track,io)) {
1057 return(LIB3DS_FALSE);
1059 if (!lib3ds_chunk_write_end(&c,io)) {
1060 return(LIB3DS_FALSE);
1064 case LIB3DS_L_TARGET_NODE_TAG:
1065 { /*---- LIB3DS_POS_TRACK_TAG ----*/
1067 c.chunk=LIB3DS_POS_TRACK_TAG;
1068 if (!lib3ds_chunk_write_start(&c,io)) {
1069 return(LIB3DS_FALSE);
1071 if (!lib3ds_lin3_track_write(&node->data.spot.pos_track,io)) {
1072 return(LIB3DS_FALSE);
1074 if (!lib3ds_chunk_write_end(&c,io)) {
1075 return(LIB3DS_FALSE);
1080 return(LIB3DS_FALSE);
1083 if (!lib3ds_chunk_write_end(&c,io)) {
1084 return(LIB3DS_FALSE);
1086 return(LIB3DS_TRUE);
1092 \typedef Lib3dsNodeTypes
1098 \enum _Lib3dsNodeTypes
1104 \typedef Lib3dsBoolKey
1111 \typedef Lib3dsBoolTrack
1113 \sa _Lib3dsBoolTrack
1118 \typedef Lib3dsLin1Key
1125 \typedef Lib3dsLin1Track
1127 \sa _Lib3dsLin1Track
1132 \typedef Lib3dsLin3Key
1139 \typedef Lib3dsLin3Track
1141 \sa _Lib3dsLin3Track
1146 \typedef Lib3dsQuatKey
1153 \typedef Lib3dsQuatTrack
1160 \typedef Lib3dsMorphKey
1167 \typedef Lib3dsMorphTrack
1169 \sa _Lib3dsMorphTrack