root/OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_node.c @ 10853

Revision 10853, 35.9 kB (checked in by robert, 5 years ago)

From Sukender,
"Here is our freshly baked 3DS reader/writer (named 'v0.5' to differentiate from previous one). Changes are against trunk rev. 10819.
Short changelog (from rev 10819):
- Added 3DS writer
- Sync'd with latest lib3DS
- Added options, especially "flattenMatrixTransforms" to get the "old" behaviour (else the reader correctly maps to OSG the transforms from the 3DS file).

What should be done:
- Check with pivot points, with and without "flattenMatrixTransforms" option.
- We ran tests on it, but we can never be 100% sure there is no bug. Testing from the community would of course be helpful."

RevLine 
[10853]1/*
2    Copyright (C) 1996-2008 by Jan Eric Kyprianidis <www.kyprianidis.com>
3    All rights reserved.
4   
5    This program is free  software: you can redistribute it and/or modify
6    it under the terms of the GNU Lesser General Public License as published
7    by the Free Software Foundation, either version 2.1 of the License, or
8    (at your option) any later version.
9
10    Thisprogram  is  distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13    GNU Lesser General Public License for more details.
14   
15    You should  have received a copy of the GNU Lesser General Public License
16    along with  this program; If not, see <http://www.gnu.org/licenses/>.
17*/
18#include "lib3ds_impl.h"
19
20
21/*!
22 * Create and return a new node object.
23 *
24 * The node is returned with an identity matrix. All other fields
25 * are zero.
26 *
27 * \return Lib3dsNode
28 */
29Lib3dsNode*
30lib3ds_node_new(Lib3dsNodeType type) {
31    Lib3dsNode *node;
32    switch (type) {
33        case LIB3DS_NODE_AMBIENT_COLOR: {
34            Lib3dsAmbientColorNode *n = (Lib3dsAmbientColorNode*)calloc(sizeof(Lib3dsAmbientColorNode), 1);
35            node = (Lib3dsNode*)n;
36            strcpy(node->name, "$AMBIENT$");
37            n->color_track.type = LIB3DS_TRACK_VECTOR;
38            break;
39        }
40
41        case LIB3DS_NODE_MESH_INSTANCE: {
42            Lib3dsMeshInstanceNode *n = (Lib3dsMeshInstanceNode*)calloc(sizeof(Lib3dsMeshInstanceNode), 1);
43            node = (Lib3dsNode*)n;
44            strcpy(node->name, "$$$DUMMY");
45            n->pos_track.type = LIB3DS_TRACK_VECTOR;
46            n->scl_track.type = LIB3DS_TRACK_VECTOR;
47            n->rot_track.type = LIB3DS_TRACK_QUAT;
48            n->hide_track.type = LIB3DS_TRACK_BOOL;
49            break;
50        }
51
52        case LIB3DS_NODE_CAMERA: {
53            Lib3dsCameraNode *n = (Lib3dsCameraNode*)calloc(sizeof(Lib3dsCameraNode), 1);
54            node = (Lib3dsNode*)n;
55            n->pos_track.type = LIB3DS_TRACK_VECTOR;
56            n->fov_track.type = LIB3DS_TRACK_FLOAT;
57            n->roll_track.type = LIB3DS_TRACK_FLOAT;
58            break;
59        }
60
61        case LIB3DS_NODE_CAMERA_TARGET: {
62            Lib3dsTargetNode *n = (Lib3dsTargetNode*)calloc(sizeof(Lib3dsTargetNode), 1);
63            node = (Lib3dsNode*)n;
64            n->pos_track.type = LIB3DS_TRACK_VECTOR;
65            break;
66        }
67
68        case LIB3DS_NODE_OMNILIGHT: {
69            Lib3dsOmnilightNode *n = (Lib3dsOmnilightNode*)calloc(sizeof(Lib3dsOmnilightNode), 1);
70            node = (Lib3dsNode*)n;
71            n->pos_track.type = LIB3DS_TRACK_VECTOR;
72            n->color_track.type = LIB3DS_TRACK_VECTOR;
73            break;
74        }
75
76        case LIB3DS_NODE_SPOTLIGHT: {
77            Lib3dsSpotlightNode *n = (Lib3dsSpotlightNode*)calloc(sizeof(Lib3dsSpotlightNode), 1);
78            node = (Lib3dsNode*)n;
79            n->pos_track.type = LIB3DS_TRACK_VECTOR;
80            n->color_track.type = LIB3DS_TRACK_VECTOR;
81            n->hotspot_track.type = LIB3DS_TRACK_FLOAT;
82            n->falloff_track.type = LIB3DS_TRACK_FLOAT;
83            n->roll_track.type = LIB3DS_TRACK_FLOAT;
84            break;
85        }
86
87        case LIB3DS_NODE_SPOTLIGHT_TARGET: {
88            Lib3dsTargetNode *n = (Lib3dsTargetNode*)calloc(sizeof(Lib3dsTargetNode), 1);
89            node = (Lib3dsNode*)n;
90            n->pos_track.type = LIB3DS_TRACK_VECTOR;
91            break;
92        }
93
94        default:
95            assert(0);
96            return NULL;
97    }
98
99    node->type = type;
100    node->node_id = 65535;
101    node->user_id = 65535;
102    lib3ds_matrix_identity(node->matrix);
103    return node;
104}
105
106
107Lib3dsAmbientColorNode*
108lib3ds_node_new_ambient_color(float color0[3]) {
109    Lib3dsNode *node;
110    Lib3dsAmbientColorNode *n;
111
112    node = lib3ds_node_new(LIB3DS_NODE_AMBIENT_COLOR);
113
114    n = (Lib3dsAmbientColorNode*)node;
115    lib3ds_track_resize(&n->color_track, 1);
116    if (color0) {
117        lib3ds_vector_copy(n->color_track.keys[0].value, color0);
118    } else {
119        lib3ds_vector_zero(n->color_track.keys[0].value);
120    }
121
122    return n;
123}
124
125
126Lib3dsMeshInstanceNode*
127lib3ds_node_new_mesh_instance(Lib3dsMesh *mesh, const char *instance_name, float pos0[3], float scl0[3], float rot0[4]) {
128    Lib3dsNode *node;
129    Lib3dsMeshInstanceNode *n;
130    int i;
131
132    node = lib3ds_node_new(LIB3DS_NODE_MESH_INSTANCE);
133    if (mesh) {
134        strcpy(node->name, mesh->name);
135    } else {
136        strcpy(node->name, "$$$DUMMY");
137    }
138
139    n = (Lib3dsMeshInstanceNode*)node;
140    if (instance_name) {
141        strcpy(n->instance_name, instance_name);
142    }
143
144    lib3ds_track_resize(&n->pos_track, 1);
145    if (pos0) {
146        lib3ds_vector_copy(n->pos_track.keys[0].value, pos0);
147    }
148
149    lib3ds_track_resize(&n->scl_track, 1);
150    if (scl0) {
151        lib3ds_vector_copy(n->scl_track.keys[0].value, scl0);
152    } else {
153        lib3ds_vector_make(n->scl_track.keys[0].value, 1, 1, 1);
154    }
155
156    lib3ds_track_resize(&n->rot_track, 1);
157    if (rot0) {
158        for (i = 0; i < 4; ++i) n->rot_track.keys[0].value[i] = rot0[i];
159    } else {
160        for (i = 0; i < 4; ++i) n->rot_track.keys[0].value[i] = 0;
161    }
162
163    return n;
164}
165
166
167Lib3dsCameraNode*
168lib3ds_node_new_camera(Lib3dsCamera *camera) {
169    Lib3dsNode *node = lib3ds_node_new(LIB3DS_NODE_CAMERA);
170    Lib3dsCameraNode *n;
171   
172    assert(camera);
173    node = lib3ds_node_new(LIB3DS_NODE_CAMERA);
174    strcpy(node->name, camera->name);
175
176    n = (Lib3dsCameraNode*)node;
177    lib3ds_track_resize(&n->pos_track, 1);
178    lib3ds_vector_copy(n->pos_track.keys[0].value, camera->position);
179
180    lib3ds_track_resize(&n->fov_track, 1);
181    n->fov_track.keys[0].value[0] = camera->fov;
182
183    lib3ds_track_resize(&n->roll_track, 1);
184    n->roll_track.keys[0].value[0] = camera->roll;
185
186    return n;
187}
188
189
190Lib3dsTargetNode*
191lib3ds_node_new_camera_target(Lib3dsCamera *camera) {
192    Lib3dsNode *node;
193    Lib3dsTargetNode *n;
194   
195    assert(camera);
196    node = lib3ds_node_new(LIB3DS_NODE_CAMERA_TARGET);
197    strcpy(node->name, camera->name);
198
199    n = (Lib3dsTargetNode*)node;
200    lib3ds_track_resize(&n->pos_track, 1);
201    lib3ds_vector_copy(n->pos_track.keys[0].value, camera->target);
202
203    return n;
204}
205
206
207Lib3dsOmnilightNode*
208lib3ds_node_new_omnilight(Lib3dsLight *light) {
209    Lib3dsNode *node;
210    Lib3dsOmnilightNode *n;
211
212    assert(light);
213    node = lib3ds_node_new(LIB3DS_NODE_OMNILIGHT);
214    strcpy(node->name, light->name);
215
216    n = (Lib3dsOmnilightNode*)node;
217    lib3ds_track_resize(&n->pos_track, 1);
218    lib3ds_vector_copy(n->pos_track.keys[0].value, light->position);
219
220    lib3ds_track_resize(&n->color_track, 1);
221    lib3ds_vector_copy(n->color_track.keys[0].value, light->color);
222
223    return n;
224}
225
226
227Lib3dsSpotlightNode*
228lib3ds_node_new_spotlight(Lib3dsLight *light) {
229    Lib3dsNode *node;
230    Lib3dsSpotlightNode *n;
231
232    assert(light);
233    node = lib3ds_node_new(LIB3DS_NODE_SPOTLIGHT);
234    strcpy(node->name, light->name);
235
236    n = (Lib3dsSpotlightNode*)node;
237    lib3ds_track_resize(&n->pos_track, 1);
238    lib3ds_vector_copy(n->pos_track.keys[0].value, light->position);
239
240    lib3ds_track_resize(&n->color_track, 1);
241    lib3ds_vector_copy(n->color_track.keys[0].value, light->color);
242
243    lib3ds_track_resize(&n->hotspot_track, 1);
244    n->hotspot_track.keys[0].value[0] = light->hotspot;
245
246    lib3ds_track_resize(&n->falloff_track, 1);
247    n->falloff_track.keys[0].value[0] = light->falloff;
248
249    lib3ds_track_resize(&n->roll_track, 1);
250    n->roll_track.keys[0].value[0] = light->roll;
251
252    return n;
253}
254
255
256Lib3dsTargetNode*
257lib3ds_node_new_spotligf_target(Lib3dsLight *light) {
258    Lib3dsNode *node;
259    Lib3dsTargetNode *n;
260   
261    assert(light);
262    node = lib3ds_node_new(LIB3DS_NODE_SPOTLIGHT_TARGET);
263    strcpy(node->name, light->name);
264
265    n = (Lib3dsTargetNode*)node;
266    lib3ds_track_resize(&n->pos_track, 1);
267    lib3ds_vector_copy(n->pos_track.keys[0].value, light->target);
268
269    return n;
270}
271
272
273static void
274free_node_and_childs(Lib3dsNode *node) {
275    assert(node);
276    switch (node->type) {
277        case LIB3DS_NODE_AMBIENT_COLOR: {
278            Lib3dsAmbientColorNode *n = (Lib3dsAmbientColorNode*)node;
279            lib3ds_track_resize(&n->color_track, 0);
280            break;
281        }
282
283        case LIB3DS_NODE_MESH_INSTANCE: {
284            Lib3dsMeshInstanceNode *n = (Lib3dsMeshInstanceNode*)node;
285            lib3ds_track_resize(&n->pos_track, 0);
286            lib3ds_track_resize(&n->rot_track, 0);
287            lib3ds_track_resize(&n->scl_track, 0);
288            lib3ds_track_resize(&n->hide_track, 0);
289            break;
290        }
291
292        case LIB3DS_NODE_CAMERA: {
293            Lib3dsCameraNode *n = (Lib3dsCameraNode*)node;
294            lib3ds_track_resize(&n->pos_track, 0);
295            lib3ds_track_resize(&n->fov_track, 0);
296            lib3ds_track_resize(&n->roll_track, 0);
297            break;
298        }
299
300        case LIB3DS_NODE_CAMERA_TARGET: {
301            Lib3dsTargetNode *n = (Lib3dsTargetNode*)node;
302            lib3ds_track_resize(&n->pos_track, 0);
303            break;
304        }
305
306        case LIB3DS_NODE_OMNILIGHT: {
307            Lib3dsOmnilightNode *n = (Lib3dsOmnilightNode*)node;
308            lib3ds_track_resize(&n->pos_track, 0);
309            lib3ds_track_resize(&n->color_track, 0);
310            break;
311        }
312
313        case LIB3DS_NODE_SPOTLIGHT: {
314            Lib3dsSpotlightNode *n = (Lib3dsSpotlightNode*)node;
315            lib3ds_track_resize(&n->pos_track, 0);
316            lib3ds_track_resize(&n->color_track, 0);
317            lib3ds_track_resize(&n->hotspot_track, 0);
318            lib3ds_track_resize(&n->falloff_track, 0);
319            lib3ds_track_resize(&n->roll_track, 0);
320            break;
321        }
322
323        case LIB3DS_NODE_SPOTLIGHT_TARGET: {
324            Lib3dsTargetNode *n = (Lib3dsTargetNode*)node;
325            lib3ds_track_resize(&n->pos_track, 0);
326            break;
327        }
328    }
329    {
330        Lib3dsNode *p, *q;
331        for (p = node->childs; p; p = q) {
332            q = p->next;
333            free_node_and_childs(p);
334        }
335    }
336    free(node);
337}
338
339
340/*!
341 * Free a node and all of its resources.
342 *
343 * \param node Lib3dsNode object to be freed.
344 */
345void
346lib3ds_node_free(Lib3dsNode *node) {
347    assert(node);
348    free_node_and_childs(node);
349}
350
351
352/*!
353 * Evaluate an animation node.
354 *
355 * Recursively sets node and its children to their appropriate values
356 * for this point in the animation.
357 *
358 * \param node Node to be evaluated.
359 * \param t time value, between 0. and file->frames
360 */
361void
362lib3ds_node_eval(Lib3dsNode *node, float t) {
363    assert(node);
364    switch (node->type) {
365        case LIB3DS_NODE_AMBIENT_COLOR: {
366            Lib3dsAmbientColorNode *n = (Lib3dsAmbientColorNode*)node;
367            if (node->parent) {
368                lib3ds_matrix_copy(node->matrix, node->parent->matrix);
369            } else {
370                lib3ds_matrix_identity(node->matrix);
371            }
372            lib3ds_track_eval_vector(&n->color_track, n->color, t);
373            break;
374        }
375
376        case LIB3DS_NODE_MESH_INSTANCE: {
377            float M[4][4];
378            Lib3dsMeshInstanceNode *n = (Lib3dsMeshInstanceNode*)node;
379
380            lib3ds_track_eval_vector(&n->pos_track, n->pos, t);
381            lib3ds_track_eval_quat(&n->rot_track, n->rot, t);
382            if (n->scl_track.nkeys) {
383                lib3ds_track_eval_vector(&n->scl_track, n->scl, t);
384            } else {
385                n->scl[0] = n->scl[1] = n->scl[2] = 1.0f;
386            }
387            lib3ds_track_eval_bool(&n->hide_track, &n->hide, t);
388
389            lib3ds_matrix_identity(M);
390            lib3ds_matrix_translate(M, n->pos[0], n->pos[1], n->pos[2]);
391            lib3ds_matrix_rotate_quat(M, n->rot);
392            lib3ds_matrix_scale(M, n->scl[0], n->scl[1], n->scl[2]);
393
394            if (node->parent) {
395                lib3ds_matrix_mult(node->matrix, node->parent->matrix, M);
396            } else {
397                lib3ds_matrix_copy(node->matrix, M);
398            }
399            break;
400        }
401
402        case LIB3DS_NODE_CAMERA: {
403            Lib3dsCameraNode *n = (Lib3dsCameraNode*)node;
404            lib3ds_track_eval_vector(&n->pos_track, n->pos, t);
405            lib3ds_track_eval_float(&n->fov_track, &n->fov, t);
406            lib3ds_track_eval_float(&n->roll_track, &n->roll, t);
407            if (node->parent) {
408                lib3ds_matrix_copy(node->matrix, node->parent->matrix);
409            } else {
410                lib3ds_matrix_identity(node->matrix);
411            }
412            lib3ds_matrix_translate(node->matrix, n->pos[0], n->pos[1], n->pos[2]);
413            break;
414        }
415
416        case LIB3DS_NODE_CAMERA_TARGET: {
417            Lib3dsTargetNode *n = (Lib3dsTargetNode*)node;
418            lib3ds_track_eval_vector(&n->pos_track, n->pos, t);
419            if (node->parent) {
420                lib3ds_matrix_copy(node->matrix, node->parent->matrix);
421            } else {
422                lib3ds_matrix_identity(node->matrix);
423            }
424            lib3ds_matrix_translate(node->matrix, n->pos[0], n->pos[1], n->pos[2]);
425            break;
426        }
427
428        case LIB3DS_NODE_OMNILIGHT: {
429            Lib3dsOmnilightNode *n = (Lib3dsOmnilightNode*)node;
430            lib3ds_track_eval_vector(&n->pos_track, n->pos, t);
431            lib3ds_track_eval_vector(&n->color_track, n->color, t);
432            if (node->parent) {
433                lib3ds_matrix_copy(node->matrix, node->parent->matrix);
434            } else {
435                lib3ds_matrix_identity(node->matrix);
436            }
437            lib3ds_matrix_translate(node->matrix, n->pos[0], n->pos[1], n->pos[2]);
438            break;
439        }
440
441        case LIB3DS_NODE_SPOTLIGHT: {
442            Lib3dsSpotlightNode *n = (Lib3dsSpotlightNode*)node;
443            lib3ds_track_eval_vector(&n->pos_track, n->pos, t);
444            lib3ds_track_eval_vector(&n->color_track, n->color, t);
445            lib3ds_track_eval_float(&n->hotspot_track, &n->hotspot, t);
446            lib3ds_track_eval_float(&n->falloff_track, &n->falloff, t);
447            lib3ds_track_eval_float(&n->roll_track, &n->roll, t);
448            if (node->parent) {
449                lib3ds_matrix_copy(node->matrix, node->parent->matrix);
450            } else {
451                lib3ds_matrix_identity(node->matrix);
452            }
453            lib3ds_matrix_translate(node->matrix, n->pos[0], n->pos[1], n->pos[2]);
454            break;
455        }
456
457        case LIB3DS_NODE_SPOTLIGHT_TARGET: {
458            Lib3dsTargetNode *n = (Lib3dsTargetNode*)node;
459            lib3ds_track_eval_vector(&n->pos_track, n->pos, t);
460            if (node->parent) {
461                lib3ds_matrix_copy(node->matrix, node->parent->matrix);
462            } else {
463                lib3ds_matrix_identity(node->matrix);
464            }
465            lib3ds_matrix_translate(node->matrix, n->pos[0], n->pos[1], n->pos[2]);
466            break;
467        }
468    }
469    {
470        Lib3dsNode *p;
471        for (p = node->childs; p != 0; p = p->next) {
472            lib3ds_node_eval(p, t);
473        }
474    }
475}
476
477
478/*!
479 * Return a node object by name and type.
480 *
481 * This function performs a recursive search for the specified node.
482 * Both name and type must match.
483 *
484 * \param node The parent node for the search
485 * \param name The target node name.
486 * \param type The target node type
487 *
488 * \return A pointer to the first matching node, or NULL if not found.
489 */
490Lib3dsNode*
491lib3ds_node_by_name(Lib3dsNode *node, const char* name, Lib3dsNodeType type) {
492    Lib3dsNode *p, *q;
493
494    for (p = node->childs; p != 0; p = p->next) {
495        if ((p->type == type) && (strcmp(p->name, name) == 0)) {
496            return(p);
497        }
498        q = lib3ds_node_by_name(p, name, type);
499        if (q) {
500            return(q);
501        }
502    }
503    return(0);
504}
505
506
507/*!
508 * Return a node object by id.
509 *
510 * This function performs a recursive search for the specified node.
511 *
512 * \param node The parent node for the search
513 * \param node_id The target node id.
514 *
515 * \return A pointer to the first matching node, or NULL if not found.
516 */
517Lib3dsNode*
518lib3ds_node_by_id(Lib3dsNode *node, uint16_t node_id) {
519    Lib3dsNode *p, *q;
520
521    for (p = node->childs; p != 0; p = p->next) {
522        if (p->node_id == node_id) {
523            return(p);
524        }
525        q = lib3ds_node_by_id(p, node_id);
526        if (q) {
527            return(q);
528        }
529    }
530    return(0);
531}
532
533
534void
535lib3ds_node_read(Lib3dsNode *node, Lib3dsIo *io) {
536    Lib3dsChunk c;
537    uint16_t chunk;
538
539    assert(node);
540    lib3ds_chunk_read_start(&c, 0, io);
541
542    switch (c.chunk) {
543        case CHK_AMBIENT_NODE_TAG:
544        case CHK_OBJECT_NODE_TAG:
545        case CHK_CAMERA_NODE_TAG:
546        case CHK_TARGET_NODE_TAG:
547        case CHK_LIGHT_NODE_TAG:
548        case CHK_SPOTLIGHT_NODE_TAG:
549        case CHK_L_TARGET_NODE_TAG:
550            break;
551        default:
552            return;
553    }
554
555    while ((chunk = lib3ds_chunk_read_next(&c, io)) != 0)  {
556        switch (chunk) {
557            case CHK_NODE_ID: {
558                node->node_id = lib3ds_io_read_word(io);
559                lib3ds_io_log_indent(io, 1);
560                lib3ds_io_log(io, LIB3DS_LOG_INFO, "ID=%d", (short)node->node_id);
561                lib3ds_io_log_indent(io, -1);
562                break;
563            }
564
565            case CHK_NODE_HDR: {
566                lib3ds_io_read_string(io, node->name, 64);
567                node->flags = lib3ds_io_read_word(io);
568                node->flags |= ((uint32_t)lib3ds_io_read_word(io)) << 16;
569                node->user_id = lib3ds_io_read_word(io);
570
571                lib3ds_io_log_indent(io, 1);
572                lib3ds_io_log(io, LIB3DS_LOG_INFO, "NAME=%s", node->name);
573                lib3ds_io_log(io, LIB3DS_LOG_INFO, "PARENT=%d", (short)node->user_id);
574                lib3ds_io_log_indent(io, -1);
575                break;
576            }
577
578            case CHK_PIVOT: {
579                if (node->type == LIB3DS_NODE_MESH_INSTANCE) {
580                    Lib3dsMeshInstanceNode *n = (Lib3dsMeshInstanceNode*)node;
581                    lib3ds_io_read_vector(io, n->pivot);
582                } else {
583                    lib3ds_chunk_unknown(chunk, io);
584                }
585                break;
586            }
587
588            case CHK_INSTANCE_NAME: {
589                if (node->type == LIB3DS_NODE_MESH_INSTANCE) {
590                    Lib3dsMeshInstanceNode *n = (Lib3dsMeshInstanceNode*)node;
591                    lib3ds_io_read_string(io, n->instance_name, 64);
592                } else {
593                    lib3ds_chunk_unknown(chunk, io);
594                }
595                break;
596            }
597
598            case CHK_BOUNDBOX: {
599                if (node->type == LIB3DS_NODE_MESH_INSTANCE) {
600                    Lib3dsMeshInstanceNode *n = (Lib3dsMeshInstanceNode*)node;
601                    lib3ds_io_read_vector(io, n->bbox_min);
602                    lib3ds_io_read_vector(io, n->bbox_max);
603                } else {
604                    lib3ds_chunk_unknown(chunk, io);
605                }
606                break;
607            }
608
609            case CHK_COL_TRACK_TAG: {
610                Lib3dsTrack *track = 0;
611                switch (node->type) {
612                    case LIB3DS_NODE_AMBIENT_COLOR: {
613                        Lib3dsAmbientColorNode *n = (Lib3dsAmbientColorNode*)node;
614                        track = &n->color_track;
615                        break;
616                    }             
617                    case LIB3DS_NODE_OMNILIGHT: {
618                        Lib3dsOmnilightNode *n = (Lib3dsOmnilightNode*)node;
619                        track = &n->color_track;
620                        break;
621                    }
622                    case LIB3DS_NODE_SPOTLIGHT: {
623                        Lib3dsSpotlightNode *n = (Lib3dsSpotlightNode*)node;
624                        track = &n->color_track;
625                        break;
626                    }
627                    default:
628                        lib3ds_chunk_unknown(chunk, io);
629                }
630                if (track) {
631                    lib3ds_track_read(track, io);
632                }
633                break;
634            }
635
636            case CHK_POS_TRACK_TAG: {
637                Lib3dsTrack *track = 0;
638                switch (node->type) {
639                    case LIB3DS_NODE_MESH_INSTANCE: {
640                        Lib3dsMeshInstanceNode *n = (Lib3dsMeshInstanceNode*)node;
641                        track = &n->pos_track;
642                        break;
643                    }
644                    case LIB3DS_NODE_CAMERA: {
645                        Lib3dsCameraNode *n = (Lib3dsCameraNode*)node;
646                        track = &n->pos_track;
647                        break;
648                    }
649                    case LIB3DS_NODE_CAMERA_TARGET: {
650                        Lib3dsTargetNode *n = (Lib3dsTargetNode*)node;
651                        track = &n->pos_track;
652                        break;
653                    }
654                    case LIB3DS_NODE_OMNILIGHT: {
655                        Lib3dsOmnilightNode *n = (Lib3dsOmnilightNode*)node;
656                        track = &n->pos_track;
657                        break;
658                    }
659                    case LIB3DS_NODE_SPOTLIGHT: {
660                        Lib3dsSpotlightNode *n = (Lib3dsSpotlightNode*)node;
661                        track = &n->pos_track;
662                        break;
663                    }
664                    case LIB3DS_NODE_SPOTLIGHT_TARGET: {
665                        Lib3dsTargetNode *n = (Lib3dsTargetNode*)node;
666                        track = &n->pos_track;
667                        break;
668                    }
669                    default:
670                        lib3ds_chunk_unknown(chunk, io);
671                }
672                if (track) {
673                    lib3ds_track_read(track, io);
674                }
675                break;
676            }
677
678            case CHK_ROT_TRACK_TAG: {
679                if (node->type == LIB3DS_NODE_MESH_INSTANCE) {
680                    Lib3dsMeshInstanceNode *n = (Lib3dsMeshInstanceNode*)node;
681                    n->rot_track.type = LIB3DS_TRACK_QUAT;
682                    lib3ds_track_read(&n->rot_track, io);
683                } else {
684                    lib3ds_chunk_unknown(chunk, io);
685                }
686                break;
687            }
688
689            case CHK_SCL_TRACK_TAG: {
690                if (node->type == LIB3DS_NODE_MESH_INSTANCE) {
691                    Lib3dsMeshInstanceNode *n = (Lib3dsMeshInstanceNode*)node;
692                    n->scl_track.type = LIB3DS_TRACK_VECTOR;
693                    lib3ds_track_read(&n->scl_track, io);
694                } else {
695                    lib3ds_chunk_unknown(chunk, io);
696                }
697                break;
698            }
699
700            case CHK_FOV_TRACK_TAG: {
701                if (node->type == LIB3DS_NODE_CAMERA) {
702                    Lib3dsCameraNode *n = (Lib3dsCameraNode*)node;
703                    n->fov_track.type = LIB3DS_TRACK_FLOAT;
704                    lib3ds_track_read(&n->fov_track, io);
705                } else {
706                    lib3ds_chunk_unknown(chunk, io);
707                }
708                break;
709            }
710
711            case CHK_HOT_TRACK_TAG: {
712                if (node->type == LIB3DS_NODE_SPOTLIGHT) {
713                    Lib3dsSpotlightNode *n = (Lib3dsSpotlightNode*)node;
714                    n->hotspot_track.type = LIB3DS_TRACK_FLOAT;
715                    lib3ds_track_read(&n->hotspot_track, io);
716                } else {
717                    lib3ds_chunk_unknown(chunk, io);
718                }
719                break;
720            }
721
722            case CHK_FALL_TRACK_TAG: {
723                if (node->type == LIB3DS_NODE_SPOTLIGHT) {
724                    Lib3dsSpotlightNode *n = (Lib3dsSpotlightNode*)node;
725                    n->falloff_track.type= LIB3DS_TRACK_FLOAT;
726                    lib3ds_track_read(&n->falloff_track, io);
727                } else {
728                    lib3ds_chunk_unknown(chunk, io);
729                }
730                break;
731            }
732
733            case CHK_ROLL_TRACK_TAG: {
734                switch (node->type) {
735                    case LIB3DS_NODE_CAMERA: {
736                        Lib3dsCameraNode *n = (Lib3dsCameraNode*)node;
737                        n->roll_track.type = LIB3DS_TRACK_FLOAT;
738                        lib3ds_track_read(&n->roll_track, io);
739                        break;
740                    }
741                    case LIB3DS_NODE_SPOTLIGHT: {
742                        Lib3dsSpotlightNode *n = (Lib3dsSpotlightNode*)node;
743                        n->roll_track.type = LIB3DS_TRACK_FLOAT;
744                        lib3ds_track_read(&n->roll_track, io);
745                        break;
746                    }
747                    default:
748                        lib3ds_chunk_unknown(chunk, io);
749                }
750                break;
751            }
752
753            case CHK_HIDE_TRACK_TAG: {
754                if (node->type == LIB3DS_NODE_MESH_INSTANCE) {
755                    Lib3dsMeshInstanceNode *n = (Lib3dsMeshInstanceNode*)node;
756                    n->hide_track.type = LIB3DS_TRACK_BOOL;
757                    lib3ds_track_read(&n->hide_track, io);
758                } else {
759                    lib3ds_chunk_unknown(chunk, io);
760                }
761                break;
762            }
763
764            case CHK_MORPH_SMOOTH: {
765                if (node->type == LIB3DS_NODE_MESH_INSTANCE) {
766                    Lib3dsMeshInstanceNode *n = (Lib3dsMeshInstanceNode*)node;
767                    n->morph_smooth = lib3ds_io_read_float(io);
768                } else {
769                    lib3ds_chunk_unknown(chunk, io);
770                }
771            }
772            break;
773
774            /*
775            case LIB3DS_MORPH_TRACK_TAG: {
776                if (node->type == LIB3DS_NODE_MESH_INSTANCE) {
777                    Lib3dsMeshInstanceNode *n = (Lib3dsMeshInstanceNode*)node;
778                    n->morph_track = lib3ds_track_new(node, LIB3DS_TRACK_MORPH, 0);
779                    lib3ds_track_read(n->morph_track, io);
780                } else {
781                    lib3ds_chunk_unknown(chunk, io);
782                }
783            }
784            break;
785            */
786
787            default:
788                lib3ds_chunk_unknown(chunk, io);
789        }
790    }
791
792    lib3ds_chunk_read_end(&c, io);
793}
794
795
796void
797lib3ds_node_write(Lib3dsNode *node, uint16_t node_id, uint16_t parent_id, Lib3dsIo *io) {
798    Lib3dsChunk c;
799
800    switch (node->type) {
801        case LIB3DS_NODE_AMBIENT_COLOR:
802            c.chunk = CHK_AMBIENT_NODE_TAG;
803            break;
804
805        case LIB3DS_NODE_MESH_INSTANCE:
806            c.chunk = CHK_OBJECT_NODE_TAG;
807            break;
808
809        case LIB3DS_NODE_CAMERA:
810            c.chunk = CHK_CAMERA_NODE_TAG;
811            break;
812
813        case LIB3DS_NODE_CAMERA_TARGET:
814            c.chunk = CHK_TARGET_NODE_TAG;
815            break;
816
817        case LIB3DS_NODE_OMNILIGHT:
818            c.chunk = CHK_LIGHT_NODE_TAG;
819            break;
820
821        case LIB3DS_NODE_SPOTLIGHT:
822            c.chunk = CHK_SPOTLIGHT_NODE_TAG;
823            break;
824
825        case LIB3DS_NODE_SPOTLIGHT_TARGET:
826            c.chunk = CHK_L_TARGET_NODE_TAG;
827            break;
828
829        default:
830            assert(0);
831            return;
832    }
833   
834    lib3ds_chunk_write_start(&c, io);
835
836    { /*---- CHK_NODE_ID ----*/
837        Lib3dsChunk c;
838        c.chunk = CHK_NODE_ID;
839        c.size = 8;
840        lib3ds_chunk_write(&c, io);
841        lib3ds_io_write_intw(io, node_id);
842    }
843
844    { /*---- CHK_NODE_HDR ----*/
845        Lib3dsChunk c;
846        c.chunk = CHK_NODE_HDR;
847        c.size = 6 + 1 + (uint32_t)strlen(node->name) + 2 + 2 + 2;
848        lib3ds_chunk_write(&c, io);
849        lib3ds_io_write_string(io, node->name);
850        lib3ds_io_write_word(io, node->flags & 0xffff);
851        lib3ds_io_write_word(io, (node->flags >> 16) & 0xffff);
852        lib3ds_io_write_word(io, parent_id);
853    }
854
855    switch (c.chunk) {
856        case CHK_AMBIENT_NODE_TAG: {
857            Lib3dsAmbientColorNode *n = (Lib3dsAmbientColorNode*)node;
858            if (n->color_track.nkeys) { /*---- CHK_COL_TRACK_TAG ----*/
859                Lib3dsChunk c;
860                c.chunk = CHK_COL_TRACK_TAG;
861                lib3ds_chunk_write_start(&c, io);
862                lib3ds_track_write(&n->color_track, io);
863                lib3ds_chunk_write_end(&c, io);
864            }
865            break;
866        }
867
868        case CHK_OBJECT_NODE_TAG: {
869            Lib3dsMeshInstanceNode *n = (Lib3dsMeshInstanceNode*)node;
870            { /*---- CHK_PIVOT ----*/
871                Lib3dsChunk c;
872                c.chunk = CHK_PIVOT;
873                c.size = 18;
874                lib3ds_chunk_write(&c, io);
875                lib3ds_io_write_vector(io, n->pivot);
876            }
877
878            { /*---- CHK_INSTANCE_NAME ----*/
879                Lib3dsChunk c;
880                const char *name;
881                if (strlen(n->instance_name)) {
882                    name = n->instance_name;
883
884                    c.chunk = CHK_INSTANCE_NAME;
885                    c.size = 6 + 1 + (uint32_t)strlen(name);
886                    lib3ds_chunk_write(&c, io);
887                    lib3ds_io_write_string(io, name);
888                }
889            }
890            {
891                int i;
892                for (i = 0; i < 3; ++i) {
893                    if ((fabs(n->bbox_min[i]) > LIB3DS_EPSILON) ||
894                        (fabs(n->bbox_max[i]) > LIB3DS_EPSILON)) {
895                        break;
896                    }
897                }
898
899                if (i < 3) { /*---- CHK_BOUNDBOX ----*/
900                    Lib3dsChunk c;
901                    c.chunk = CHK_BOUNDBOX;
902                    c.size = 30;
903                    lib3ds_chunk_write(&c, io);
904                    lib3ds_io_write_vector(io, n->bbox_min);
905                    lib3ds_io_write_vector(io, n->bbox_max);
906                }
907            }
908
909            if (n->pos_track.nkeys) { /*---- CHK_POS_TRACK_TAG ----*/
910                Lib3dsChunk c;
911                c.chunk = CHK_POS_TRACK_TAG;
912                lib3ds_chunk_write_start(&c, io);
913                lib3ds_track_write(&n->pos_track, io);
914                lib3ds_chunk_write_end(&c, io);
915            }
916            if (n->rot_track.nkeys) { /*---- CHK_ROT_TRACK_TAG ----*/
917                Lib3dsChunk c;
918                c.chunk = CHK_ROT_TRACK_TAG;
919                lib3ds_chunk_write_start(&c, io);
920                lib3ds_track_write(&n->rot_track, io);
921                lib3ds_chunk_write_end(&c, io);
922            }
923            if (n->scl_track.nkeys) { /*---- LIB3DS_SCL_TRACK_TAG ----*/
924                Lib3dsChunk c;
925                c.chunk = CHK_SCL_TRACK_TAG;
926                lib3ds_chunk_write_start(&c, io);
927                lib3ds_track_write(&n->scl_track, io);
928                lib3ds_chunk_write_end(&c, io);
929            }
930            if (n->hide_track.nkeys) { /*---- CHK_HIDE_TRACK_TAG ----*/
931                Lib3dsChunk c;
932                c.chunk = CHK_HIDE_TRACK_TAG;
933                lib3ds_chunk_write_start(&c, io);
934                lib3ds_track_write(&n->hide_track, io);
935                lib3ds_chunk_write_end(&c, io);
936            }
937            if (fabs(n->morph_smooth) > LIB3DS_EPSILON) { /*---- CHK_MORPH_SMOOTH ----*/
938                Lib3dsChunk c;
939                c.chunk = CHK_MORPH_SMOOTH;
940                c.size = 10;
941                lib3ds_chunk_write(&c, io);
942                lib3ds_io_write_float(io, n->morph_smooth);
943            }
944            break;
945        }
946
947        case CHK_CAMERA_NODE_TAG: {
948            Lib3dsCameraNode *n = (Lib3dsCameraNode*)node;
949            if (n->pos_track.nkeys) { /*---- CHK_POS_TRACK_TAG ----*/
950                Lib3dsChunk c;
951                c.chunk = CHK_POS_TRACK_TAG;
952                lib3ds_chunk_write_start(&c, io);
953                lib3ds_track_write(&n->pos_track, io);
954                lib3ds_chunk_write_end(&c, io);
955            }
956            if (n->fov_track.nkeys) { /*---- CHK_FOV_TRACK_TAG ----*/
957                Lib3dsChunk c;
958                c.chunk = CHK_FOV_TRACK_TAG;
959                lib3ds_chunk_write_start(&c, io);
960                lib3ds_track_write(&n->fov_track, io);
961                lib3ds_chunk_write_end(&c, io);
962            }
963            if (n->roll_track.nkeys) { /*---- CHK_ROLL_TRACK_TAG ----*/
964                Lib3dsChunk c;
965                c.chunk = CHK_ROLL_TRACK_TAG;
966                lib3ds_chunk_write_start(&c, io);
967                lib3ds_track_write(&n->roll_track, io);
968                lib3ds_chunk_write_end(&c, io);
969            }
970            break;
971        }
972
973        case CHK_TARGET_NODE_TAG: {
974            Lib3dsTargetNode *n = (Lib3dsTargetNode*)node;
975            if (n->pos_track.nkeys) { /*---- CHK_POS_TRACK_TAG ----*/
976                Lib3dsChunk c;
977                c.chunk = CHK_POS_TRACK_TAG;
978                lib3ds_chunk_write_start(&c, io);
979                lib3ds_track_write(&n->pos_track, io);
980                lib3ds_chunk_write_end(&c, io);
981            }
982            break;
983        }
984
985        case CHK_LIGHT_NODE_TAG: {
986            Lib3dsOmnilightNode *n = (Lib3dsOmnilightNode*)node;
987            if (n->pos_track.nkeys) { /*---- CHK_POS_TRACK_TAG ----*/
988                Lib3dsChunk c;
989                c.chunk = CHK_POS_TRACK_TAG;
990                lib3ds_chunk_write_start(&c, io);
991                lib3ds_track_write(&n->pos_track, io);
992                lib3ds_chunk_write_end(&c, io);
993            }
994            if (n->color_track.nkeys) { /*---- CHK_COL_TRACK_TAG ----*/
995                Lib3dsChunk c;
996                c.chunk = CHK_COL_TRACK_TAG;
997                lib3ds_chunk_write_start(&c, io);
998                lib3ds_track_write(&n->color_track, io);
999                lib3ds_chunk_write_end(&c, io);
1000            }
1001            break;
1002        }
1003
1004        case CHK_SPOTLIGHT_NODE_TAG: {
1005            Lib3dsSpotlightNode *n = (Lib3dsSpotlightNode*)node;
1006            if (n->pos_track.nkeys) { /*---- CHK_POS_TRACK_TAG ----*/
1007                Lib3dsChunk c;
1008                c.chunk = CHK_POS_TRACK_TAG;
1009                lib3ds_chunk_write_start(&c, io);
1010                lib3ds_track_write(&n->pos_track, io);
1011                lib3ds_chunk_write_end(&c, io);
1012            }
1013            if (n->color_track.nkeys) { /*---- CHK_COL_TRACK_TAG ----*/
1014                Lib3dsChunk c;
1015                c.chunk = CHK_COL_TRACK_TAG;
1016                lib3ds_chunk_write_start(&c, io);
1017                lib3ds_track_write(&n->color_track, io);
1018                lib3ds_chunk_write_end(&c, io);
1019            }
1020            if (n->hotspot_track.nkeys) { /*---- CHK_HOT_TRACK_TAG ----*/
1021                Lib3dsChunk c;
1022                c.chunk = CHK_HOT_TRACK_TAG;
1023                lib3ds_chunk_write_start(&c, io);
1024                lib3ds_track_write(&n->hotspot_track, io);
1025                lib3ds_chunk_write_end(&c, io);
1026            }
1027            if (n->falloff_track.nkeys) { /*---- CHK_FALL_TRACK_TAG ----*/
1028                Lib3dsChunk c;
1029                c.chunk = CHK_FALL_TRACK_TAG;
1030                lib3ds_chunk_write_start(&c, io);
1031                lib3ds_track_write(&n->falloff_track, io);
1032                lib3ds_chunk_write_end(&c, io);
1033            }
1034            if (n->roll_track.nkeys) { /*---- CHK_ROLL_TRACK_TAG ----*/
1035                Lib3dsChunk c;
1036                c.chunk = CHK_ROLL_TRACK_TAG;
1037                lib3ds_chunk_write_start(&c, io);
1038                lib3ds_track_write(&n->roll_track, io);
1039                lib3ds_chunk_write_end(&c, io);
1040            }
1041            break;
1042        }
1043
1044        case CHK_L_TARGET_NODE_TAG: {
1045            Lib3dsTargetNode *n = (Lib3dsTargetNode*)node;
1046            if (n->pos_track.nkeys) { /*---- CHK_POS_TRACK_TAG ----*/
1047                Lib3dsChunk c;
1048                c.chunk = CHK_POS_TRACK_TAG;
1049                lib3ds_chunk_write_start(&c, io);
1050                lib3ds_track_write(&n->pos_track, io);
1051                lib3ds_chunk_write_end(&c, io);
1052            }
1053            break;
1054        }
1055
1056        default:
1057            break;
1058    }
1059
1060    lib3ds_chunk_write_end(&c, io);
1061}
Note: See TracBrowser for help on using the browser.