Index: /OpenSceneGraph/trunk/src/osgPlugins/3ds/WriterCompareTriangle.h
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/WriterCompareTriangle.h (revision 10853)
+++ /OpenSceneGraph/trunk/src/osgPlugins/3ds/WriterCompareTriangle.h (revision 10853)
@@ -0,0 +1,51 @@
+#ifndef _3DS_WRITER_COMPARE_TRIANGLE_HEADER__
+#define _3DS_WRITER_COMPARE_TRIANGLE_HEADER__
+
+#include <osg/Geode>
+#include <osg/Geometry>
+#include <iostream>
+
+struct Triangle
+{
+    unsigned int t1;
+    unsigned int t2;
+    unsigned int t3;
+    unsigned int material;
+};
+
+class WriterCompareTriangle {
+public:
+    WriterCompareTriangle(const osg::Geode & geode, unsigned int nbVertices);
+
+    bool operator()(const std::pair<Triangle, int>    &    t1, 
+                    const std::pair<Triangle, int>    &    t2) const;
+private:
+    void // This function prevent from cut scene in too many blocs
+        setMaxMin(unsigned int & nbVerticesX,
+                  unsigned int & nbVerticesY,
+                  unsigned int & nbVerticesZ) const;
+
+    /**
+    *  Cut the scene in different bloc to sort.
+    *  \param nbVertices is the number of vertice in mesh.
+    *  \param sceneBox contain the size of the scene.
+    */
+    void
+    cutscene(int                        nbVertices,
+             const osg::BoundingBox   &    sceneBox);
+
+    /** 
+    *  Find in which box those points are.
+    *  \return the place of the box in the vector.
+    *  \sa See cutScene() about the definition of the boxes for faces sorting.
+    */
+    int inWhichBox(const osg::BoundingBox::value_type x, 
+                   const osg::BoundingBox::value_type y,
+                   const osg::BoundingBox::value_type z) const;
+    int inWhichBox(const osg::BoundingBox::vec_type & point) const;
+
+    const osg::Geode                  &    geode;
+    std::vector<osg::BoundingBox>        boxList;
+};
+
+#endif // _3DS_WRITER_COMPARE_TRIANGLE_HEADER__
Index: /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_material.c
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_material.c (revision 10853)
+++ /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_material.c (revision 10853)
@@ -0,0 +1,861 @@
+/*
+    Copyright (C) 1996-2008 by Jan Eric Kyprianidis <www.kyprianidis.com>
+    All rights reserved.
+    
+    This program is free  software: you can redistribute it and/or modify 
+    it under the terms of the GNU Lesser General Public License as published 
+    by the Free Software Foundation, either version 2.1 of the License, or 
+    (at your option) any later version.
+
+    Thisprogram  is  distributed in the hope that it will be useful, 
+    but WITHOUT ANY WARRANTY; without even the implied warranty of 
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
+    GNU Lesser General Public License for more details.
+    
+    You should  have received a copy of the GNU Lesser General Public License
+    along with  this program; If not, see <http://www.gnu.org/licenses/>. 
+*/
+#include "lib3ds_impl.h"
+
+
+static void
+initialize_texture_map(Lib3dsTextureMap *map) {
+    map->flags = 0x10;
+    map->percent = 1.0f;
+    map->scale[0] = 1.0f;
+    map->scale[1] = 1.0f;
+}
+
+
+/*!
+ * Creates and returns a new, empty Lib3dsMaterial object.
+ *
+ * Initial value of the material is a shiny grey.
+ *
+ * \return A pointer to the Lib3dsMaterial structure.
+ *  If the structure cannot be allocated, NULL is returned.
+ */
+Lib3dsMaterial*
+lib3ds_material_new(const char* name) {
+    Lib3dsMaterial *mat;
+
+    mat = (Lib3dsMaterial*)calloc(sizeof(Lib3dsMaterial), 1);
+    if (!mat) {
+        return(0);
+    }
+
+    if (name) {
+        strcpy(mat->name, name);
+    }
+    mat->ambient[0] = mat->ambient[1] = mat->ambient[2] = 0.588235f;
+    mat->diffuse[0] = mat->diffuse[1] = mat->diffuse[2] = 0.588235f;
+    mat->specular[0] = mat->specular[1] = mat->specular[2] = 0.898039f;
+    mat->shininess = 0.1f;
+    mat->wire_size = 1.0f;
+    mat->shading = 3;
+
+    initialize_texture_map(&mat->texture1_map);
+    initialize_texture_map(&mat->texture1_mask);
+    initialize_texture_map(&mat->texture2_map);
+    initialize_texture_map(&mat->texture2_mask);
+    initialize_texture_map(&mat->opacity_map);
+    initialize_texture_map(&mat->opacity_mask);
+    initialize_texture_map(&mat->bump_map);
+    initialize_texture_map(&mat->bump_mask);
+    initialize_texture_map(&mat->specular_map);
+    initialize_texture_map(&mat->specular_mask);
+    initialize_texture_map(&mat->shininess_map);
+    initialize_texture_map(&mat->shininess_mask);
+    initialize_texture_map(&mat->self_illum_map);
+    initialize_texture_map(&mat->self_illum_mask);
+    initialize_texture_map(&mat->reflection_map);
+    initialize_texture_map(&mat->reflection_mask);
+
+    return(mat);
+}
+
+
+void
+lib3ds_material_free(Lib3dsMaterial *material) {
+    memset(material, 0, sizeof(Lib3dsMaterial));
+    free(material);
+}
+
+
+static void
+color_read(float rgb[3], Lib3dsIo *io) {
+    Lib3dsChunk c;
+    uint16_t chunk;
+    int have_lin = FALSE;
+
+    lib3ds_chunk_read_start(&c, 0, io);
+
+    while ((chunk = lib3ds_chunk_read_next(&c, io)) != 0) {
+        switch (chunk) {
+            case CHK_LIN_COLOR_24: {
+                int i;
+                for (i = 0; i < 3; ++i) {
+                    rgb[i] = 1.0f * lib3ds_io_read_byte(io) / 255.0f;
+                }
+                have_lin = TRUE;
+                break;
+            }
+
+            case CHK_COLOR_24: {
+                /* gamma corrected color chunk
+                   replaced in 3ds R3 by LIN_COLOR_24 */
+                if (!have_lin) {
+                    int i;
+                    for (i = 0; i < 3; ++i) {
+                        rgb[i] = 1.0f * lib3ds_io_read_byte(io) / 255.0f;
+                    }
+                }
+                break;
+            }
+
+            case CHK_LIN_COLOR_F: {
+                int i;
+                for (i = 0; i < 3; ++i) {
+                    rgb[i] = lib3ds_io_read_float(io);
+                }
+                have_lin = TRUE;
+                break;
+            }
+
+            case CHK_COLOR_F: {
+                if (!have_lin) {
+                    int i;
+                    for (i = 0; i < 3; ++i) {
+                        rgb[i] = lib3ds_io_read_float(io);
+                    }
+                }
+                break;
+            }
+
+            default:
+                lib3ds_chunk_unknown(chunk, io);
+        }
+    }
+
+    lib3ds_chunk_read_end(&c, io);
+}
+
+
+static void
+int_percentage_read(float *p, Lib3dsIo *io) {
+    Lib3dsChunk c;
+    uint16_t chunk;
+
+    lib3ds_chunk_read_start(&c, 0, io);
+
+    while ((chunk = lib3ds_chunk_read_next(&c, io)) != 0) {
+        switch (chunk) {
+            case CHK_INT_PERCENTAGE: {
+                int16_t i = lib3ds_io_read_intw(io);
+                *p = (float)(1.0 * i / 100.0);
+                break;
+            }
+
+            default:
+                lib3ds_chunk_unknown(chunk, io);
+        }
+    }
+
+    lib3ds_chunk_read_end(&c, io);
+}
+
+
+static void
+texture_map_read(Lib3dsTextureMap *map, Lib3dsIo *io) {
+    Lib3dsChunk c;
+    uint16_t chunk;
+
+    lib3ds_chunk_read_start(&c, 0, io);
+
+    while ((chunk = lib3ds_chunk_read_next(&c, io)) != 0) {
+        switch (chunk) {
+            case CHK_INT_PERCENTAGE: {
+                map->percent = 1.0f * lib3ds_io_read_intw(io) / 100.0f;
+                break;
+            }
+
+            case CHK_MAT_MAPNAME: {
+                lib3ds_io_read_string(io, map->name, 64);
+                lib3ds_io_log(io, LIB3DS_LOG_INFO, "  NAME=%s", map->name);
+                break;
+            }
+
+            case CHK_MAT_MAP_TILING: {
+                map->flags = lib3ds_io_read_word(io);
+                break;
+            }
+
+            case CHK_MAT_MAP_TEXBLUR: 
+                map->blur = lib3ds_io_read_float(io);
+                break;
+
+            case CHK_MAT_MAP_USCALE:
+                map->scale[0] = lib3ds_io_read_float(io);
+                break;
+
+            case CHK_MAT_MAP_VSCALE: {
+                map->scale[1] = lib3ds_io_read_float(io);
+                break;
+            }
+            case CHK_MAT_MAP_UOFFSET: {
+                map->offset[0] = lib3ds_io_read_float(io);
+                break;
+            }
+
+            case CHK_MAT_MAP_VOFFSET: {
+                map->offset[1] = lib3ds_io_read_float(io);
+                break;
+            }
+
+            case CHK_MAT_MAP_ANG: {
+                map->rotation = lib3ds_io_read_float(io);
+                break;
+            }
+
+            case CHK_MAT_MAP_COL1: {
+                map->tint_1[0] = 1.0f * lib3ds_io_read_byte(io) / 255.0f;
+                map->tint_1[1] = 1.0f * lib3ds_io_read_byte(io) / 255.0f;
+                map->tint_1[2] = 1.0f * lib3ds_io_read_byte(io) / 255.0f;
+                break;
+            }
+
+            case CHK_MAT_MAP_COL2: {
+                map->tint_2[0] = 1.0f * lib3ds_io_read_byte(io) / 255.0f;
+                map->tint_2[1] = 1.0f * lib3ds_io_read_byte(io) / 255.0f;
+                map->tint_2[2] = 1.0f * lib3ds_io_read_byte(io) / 255.0f;
+                break;
+            }
+
+            case CHK_MAT_MAP_RCOL: {
+                map->tint_r[0] = 1.0f * lib3ds_io_read_byte(io) / 255.0f;
+                map->tint_r[1] = 1.0f * lib3ds_io_read_byte(io) / 255.0f;
+                map->tint_r[2] = 1.0f * lib3ds_io_read_byte(io) / 255.0f;
+                break;
+            }
+
+            case CHK_MAT_MAP_GCOL: {
+                map->tint_g[0] = 1.0f * lib3ds_io_read_byte(io) / 255.0f;
+                map->tint_g[1] = 1.0f * lib3ds_io_read_byte(io) / 255.0f;
+                map->tint_g[2] = 1.0f * lib3ds_io_read_byte(io) / 255.0f;
+                break;
+            }
+
+            case CHK_MAT_MAP_BCOL: {
+                map->tint_b[0] = 1.0f * lib3ds_io_read_byte(io) / 255.0f;
+                map->tint_b[1] = 1.0f * lib3ds_io_read_byte(io) / 255.0f;
+                map->tint_b[2] = 1.0f * lib3ds_io_read_byte(io) / 255.0f;
+                break;
+            }
+
+            default:
+                lib3ds_chunk_unknown(chunk,io);
+        }
+    }
+
+    lib3ds_chunk_read_end(&c, io);
+}
+
+
+void
+lib3ds_material_read(Lib3dsMaterial *material, Lib3dsIo *io) {
+    Lib3dsChunk c;
+    uint16_t chunk;
+
+    assert(material);
+    lib3ds_chunk_read_start(&c, CHK_MAT_ENTRY, io);
+
+    while ((chunk = lib3ds_chunk_read_next(&c, io)) != 0) {
+        switch (chunk) {
+            case CHK_MAT_NAME: {
+                lib3ds_io_read_string(io, material->name, 64);
+                lib3ds_io_log(io, LIB3DS_LOG_INFO, "  NAME=%s", material->name);
+                break;
+            }
+
+            case CHK_MAT_AMBIENT: {
+                lib3ds_chunk_read_reset(&c, io);
+                color_read(material->ambient, io);
+                break;
+            }
+
+            case CHK_MAT_DIFFUSE: {
+                lib3ds_chunk_read_reset(&c, io);
+                color_read(material->diffuse, io);
+                break;
+            }
+
+            case CHK_MAT_SPECULAR: {
+                lib3ds_chunk_read_reset(&c, io);
+                color_read(material->specular, io);
+                break;
+            }
+
+            case CHK_MAT_SHININESS: {
+                lib3ds_chunk_read_reset(&c, io);
+                int_percentage_read(&material->shininess, io);
+                break;
+            }
+
+            case CHK_MAT_SHIN2PCT: {
+                lib3ds_chunk_read_reset(&c, io);
+                int_percentage_read(&material->shin_strength, io);
+                break;
+            }
+
+            case CHK_MAT_TRANSPARENCY: {
+                lib3ds_chunk_read_reset(&c, io);
+                int_percentage_read(&material->transparency, io);
+                break;
+            }
+
+            case CHK_MAT_XPFALL: {
+                lib3ds_chunk_read_reset(&c, io);
+                int_percentage_read(&material->falloff, io);
+                break;
+            }
+
+            case CHK_MAT_SELF_ILPCT: {
+                lib3ds_chunk_read_reset(&c, io);
+                int_percentage_read(&material->self_illum, io);
+                break;
+            }
+
+            case CHK_MAT_USE_XPFALL: {
+                material->use_falloff = TRUE;
+                break;
+            }
+
+            case CHK_MAT_REFBLUR: {
+                lib3ds_chunk_read_reset(&c, io);
+                int_percentage_read(&material->blur, io);
+                break;
+            }
+
+            case CHK_MAT_USE_REFBLUR: {
+                material->use_blur = TRUE;
+                break;
+            }
+
+            case CHK_MAT_SHADING: {
+                material->shading = lib3ds_io_read_intw(io);
+                break;
+            }
+
+            case CHK_MAT_SELF_ILLUM: {
+                material->self_illum_flag = TRUE;
+                break;
+            }
+
+            case CHK_MAT_TWO_SIDE: {
+                material->two_sided = TRUE;
+                break;
+            }
+
+            case CHK_MAT_DECAL: {
+                material->map_decal = TRUE;
+                break;
+            }
+
+            case CHK_MAT_ADDITIVE: {
+                material->is_additive = TRUE;
+                break;
+            }
+
+            case CHK_MAT_FACEMAP: {
+                material->face_map = TRUE;
+                break;
+            }
+
+            case CHK_MAT_PHONGSOFT: {
+                material->soften = TRUE;
+                break;
+            }
+
+            case CHK_MAT_WIRE: {
+                material->use_wire = TRUE;
+                break;
+            }
+
+            case CHK_MAT_WIREABS: {
+                material->use_wire_abs = TRUE;
+                break;
+            }
+            case CHK_MAT_WIRE_SIZE: {
+                material->wire_size = lib3ds_io_read_float(io);
+                break;
+            }
+
+            case CHK_MAT_TEXMAP: {
+                lib3ds_chunk_read_reset(&c, io);
+                texture_map_read(&material->texture1_map, io);
+                break;
+            }
+
+            case CHK_MAT_TEXMASK: {
+                lib3ds_chunk_read_reset(&c, io);
+                texture_map_read(&material->texture1_mask, io);
+                break;
+            }
+
+            case CHK_MAT_TEX2MAP: {
+                lib3ds_chunk_read_reset(&c, io);
+                texture_map_read(&material->texture2_map, io);
+                break;
+            }
+
+            case CHK_MAT_TEX2MASK: {
+                lib3ds_chunk_read_reset(&c, io);
+                texture_map_read(&material->texture2_mask, io);
+                break;
+            }
+
+            case CHK_MAT_OPACMAP: {
+                lib3ds_chunk_read_reset(&c, io);
+                texture_map_read(&material->opacity_map, io);
+                break;
+            }
+
+            case CHK_MAT_OPACMASK: {
+                lib3ds_chunk_read_reset(&c, io);
+                texture_map_read(&material->opacity_mask, io);
+                break;
+            }
+
+            case CHK_MAT_BUMPMAP: {
+                lib3ds_chunk_read_reset(&c, io);
+                texture_map_read(&material->bump_map, io);
+                break;
+            }
+            case CHK_MAT_BUMPMASK: {
+                lib3ds_chunk_read_reset(&c, io);
+                texture_map_read(&material->bump_mask, io);
+                break;
+            }
+            case CHK_MAT_SPECMAP: {
+                lib3ds_chunk_read_reset(&c, io);
+                texture_map_read(&material->specular_map, io);
+                break;
+            }
+
+            case CHK_MAT_SPECMASK: {
+                lib3ds_chunk_read_reset(&c, io);
+                texture_map_read(&material->specular_mask, io);
+                break;
+            }
+
+            case CHK_MAT_SHINMAP: {
+                lib3ds_chunk_read_reset(&c, io);
+                texture_map_read(&material->shininess_map, io);
+                break;
+            }
+
+            case CHK_MAT_SHINMASK: {
+                lib3ds_chunk_read_reset(&c, io);
+                texture_map_read(&material->shininess_mask, io);
+                break;
+            }
+
+            case CHK_MAT_SELFIMAP: {
+                lib3ds_chunk_read_reset(&c, io);
+                texture_map_read(&material->self_illum_map, io);
+                break;
+            }
+
+            case CHK_MAT_SELFIMASK: {
+                lib3ds_chunk_read_reset(&c, io);
+                texture_map_read(&material->self_illum_mask, io);
+                break;
+            }
+
+            case CHK_MAT_REFLMAP: {
+                lib3ds_chunk_read_reset(&c, io);
+                texture_map_read(&material->reflection_map, io);
+                break;
+            }
+
+            case CHK_MAT_REFLMASK: {
+                lib3ds_chunk_read_reset(&c, io);
+                texture_map_read(&material->reflection_mask, io);
+                break;
+            }
+
+            case CHK_MAT_ACUBIC: {
+                lib3ds_io_read_intb(io);
+                material->autorefl_map_anti_alias = lib3ds_io_read_intb(io);
+                material->autorefl_map_flags = lib3ds_io_read_intw(io);
+                material->autorefl_map_size = lib3ds_io_read_intd(io);
+                material->autorefl_map_frame_step = lib3ds_io_read_intd(io);
+                break;
+            }
+
+            default:
+                lib3ds_chunk_unknown(chunk, io);
+        }
+    }
+
+    lib3ds_chunk_read_end(&c, io);
+}
+
+
+static void
+color_write(float rgb[3], Lib3dsIo *io) {
+    Lib3dsChunk c;
+
+    c.chunk = CHK_COLOR_24;
+    c.size = 9;
+    lib3ds_chunk_write(&c, io);
+    lib3ds_io_write_byte(io, (uint8_t)floor(255.0*rgb[0] + 0.5));
+    lib3ds_io_write_byte(io, (uint8_t)floor(255.0*rgb[1] + 0.5));
+    lib3ds_io_write_byte(io, (uint8_t)floor(255.0*rgb[2] + 0.5));
+
+    c.chunk = CHK_LIN_COLOR_24;
+    c.size = 9;
+    lib3ds_chunk_write(&c, io);
+    lib3ds_io_write_byte(io, (uint8_t)floor(255.0*rgb[0] + 0.5));
+    lib3ds_io_write_byte(io, (uint8_t)floor(255.0*rgb[1] + 0.5));
+    lib3ds_io_write_byte(io, (uint8_t)floor(255.0*rgb[2] + 0.5));
+}
+
+
+static void
+int_percentage_write(float p, Lib3dsIo *io) {
+    Lib3dsChunk c;
+
+    c.chunk = CHK_INT_PERCENTAGE;
+    c.size = 8;
+    lib3ds_chunk_write(&c, io);
+    lib3ds_io_write_intw(io, (uint8_t)floor(100.0*p + 0.5));
+}
+
+
+static void
+texture_map_write(uint16_t chunk, Lib3dsTextureMap *map, Lib3dsIo *io) {
+    Lib3dsChunk c;
+
+    if (strlen(map->name) == 0) {
+        return;
+    }
+    c.chunk = chunk;
+    lib3ds_chunk_write_start(&c, io);
+
+    int_percentage_write(map->percent, io);
+
+    { /*---- CHK_MAT_MAPNAME ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_MAT_MAPNAME;
+        c.size = 6 + (uint32_t)strlen(map->name) + 1;
+        lib3ds_chunk_write(&c, io);
+        lib3ds_io_write_string(io, map->name);
+    }
+
+    { /*---- CHK_MAT_MAP_TILING ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_MAT_MAP_TILING;
+        c.size = 8;
+        lib3ds_chunk_write(&c, io);
+        lib3ds_io_write_word(io, (uint16_t)map->flags);
+    }
+
+    { /*---- CHK_MAT_MAP_TEXBLUR ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_MAT_MAP_TEXBLUR;
+        c.size = 10;
+        lib3ds_chunk_write(&c, io);
+        lib3ds_io_write_float(io, map->blur);
+    }
+
+    { /*---- CHK_MAT_MAP_USCALE ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_MAT_MAP_USCALE;
+        c.size = 10;
+        lib3ds_chunk_write(&c, io);
+        lib3ds_io_write_float(io, map->scale[0]);
+    }
+
+    { /*---- CHK_MAT_MAP_VSCALE ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_MAT_MAP_VSCALE;
+        c.size = 10;
+        lib3ds_chunk_write(&c, io);
+        lib3ds_io_write_float(io, map->scale[1]);
+    }
+
+    { /*---- CHK_MAT_MAP_UOFFSET ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_MAT_MAP_UOFFSET;
+        c.size = 10;
+        lib3ds_chunk_write(&c, io);
+        lib3ds_io_write_float(io, map->offset[0]);
+    }
+
+    { /*---- CHK_MAT_MAP_VOFFSET ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_MAT_MAP_VOFFSET;
+        c.size = 10;
+        lib3ds_chunk_write(&c, io);
+        lib3ds_io_write_float(io, map->offset[1]);
+    }
+
+    { /*---- CHK_MAT_MAP_ANG ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_MAT_MAP_ANG;
+        c.size = 10;
+        lib3ds_chunk_write(&c, io);
+        lib3ds_io_write_float(io, map->rotation);
+    }
+
+    { /*---- CHK_MAT_MAP_COL1 ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_MAT_MAP_COL1;
+        c.size = 9;
+        lib3ds_chunk_write(&c, io);
+        lib3ds_io_write_byte(io, (uint8_t)floor(255.0*map->tint_1[0] + 0.5));
+        lib3ds_io_write_byte(io, (uint8_t)floor(255.0*map->tint_1[1] + 0.5));
+        lib3ds_io_write_byte(io, (uint8_t)floor(255.0*map->tint_1[2] + 0.5));
+    }
+
+    { /*---- CHK_MAT_MAP_COL2 ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_MAT_MAP_COL2;
+        c.size = 9;
+        lib3ds_chunk_write(&c, io);
+        lib3ds_io_write_byte(io, (uint8_t)floor(255.0*map->tint_2[0] + 0.5));
+        lib3ds_io_write_byte(io, (uint8_t)floor(255.0*map->tint_2[1] + 0.5));
+        lib3ds_io_write_byte(io, (uint8_t)floor(255.0*map->tint_2[2] + 0.5));
+    }
+
+    { /*---- CHK_MAT_MAP_RCOL ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_MAT_MAP_RCOL;
+        c.size = 9;
+        lib3ds_chunk_write(&c, io);
+        lib3ds_io_write_byte(io, (uint8_t)floor(255.0*map->tint_r[0] + 0.5));
+        lib3ds_io_write_byte(io, (uint8_t)floor(255.0*map->tint_r[1] + 0.5));
+        lib3ds_io_write_byte(io, (uint8_t)floor(255.0*map->tint_r[2] + 0.5));
+    }
+
+    { /*---- CHK_MAT_MAP_GCOL ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_MAT_MAP_GCOL;
+        c.size = 9;
+        lib3ds_chunk_write(&c, io);
+        lib3ds_io_write_byte(io, (uint8_t)floor(255.0*map->tint_g[0] + 0.5));
+        lib3ds_io_write_byte(io, (uint8_t)floor(255.0*map->tint_g[1] + 0.5));
+        lib3ds_io_write_byte(io, (uint8_t)floor(255.0*map->tint_g[2] + 0.5));
+    }
+
+    { /*---- CHK_MAT_MAP_BCOL ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_MAT_MAP_BCOL;
+        c.size = 9;
+        lib3ds_chunk_write(&c, io);
+        lib3ds_io_write_byte(io, (uint8_t)floor(255.0*map->tint_b[0] + 0.5));
+        lib3ds_io_write_byte(io, (uint8_t)floor(255.0*map->tint_b[1] + 0.5));
+        lib3ds_io_write_byte(io, (uint8_t)floor(255.0*map->tint_b[2] + 0.5));
+    }
+
+    lib3ds_chunk_write_end(&c, io);
+}
+
+
+void
+lib3ds_material_write(Lib3dsMaterial *material, Lib3dsIo *io) {
+    Lib3dsChunk c;
+
+    c.chunk = CHK_MAT_ENTRY;
+    lib3ds_chunk_write_start(&c, io);
+
+    { /*---- CHK_MAT_NAME ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_MAT_NAME;
+        c.size = 6 + (uint32_t)strlen(material->name) + 1;
+        lib3ds_chunk_write(&c, io);
+        lib3ds_io_write_string(io, material->name);
+    }
+
+    { /*---- CHK_MAT_AMBIENT ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_MAT_AMBIENT;
+        c.size = 24;
+        lib3ds_chunk_write(&c, io);
+        color_write(material->ambient, io);
+    }
+
+    { /*---- CHK_MAT_DIFFUSE ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_MAT_DIFFUSE;
+        c.size = 24;
+        lib3ds_chunk_write(&c, io);
+        color_write(material->diffuse, io);
+    }
+
+    { /*---- CHK_MAT_SPECULAR ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_MAT_SPECULAR;
+        c.size = 24;
+        lib3ds_chunk_write(&c, io);
+        color_write(material->specular, io);
+    }
+
+    { /*---- CHK_MAT_SHININESS ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_MAT_SHININESS;
+        c.size = 14;
+        lib3ds_chunk_write(&c, io);
+        int_percentage_write(material->shininess, io);
+    }
+
+    { /*---- CHK_MAT_SHIN2PCT ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_MAT_SHIN2PCT;
+        c.size = 14;
+        lib3ds_chunk_write(&c, io);
+        int_percentage_write(material->shin_strength, io);
+    }
+
+    { /*---- CHK_MAT_TRANSPARENCY ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_MAT_TRANSPARENCY;
+        c.size = 14;
+        lib3ds_chunk_write(&c, io);
+        int_percentage_write(material->transparency, io);
+    }
+
+    { /*---- CHK_MAT_XPFALL ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_MAT_XPFALL;
+        c.size = 14;
+        lib3ds_chunk_write(&c, io);
+        int_percentage_write(material->falloff, io);
+    }
+
+    if (material->use_falloff) { /*---- CHK_MAT_USE_XPFALL ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_MAT_USE_XPFALL;
+        c.size = 6;
+        lib3ds_chunk_write(&c, io);
+    }
+
+    { /*---- CHK_MAT_SHADING ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_MAT_SHADING;
+        c.size = 8;
+        lib3ds_chunk_write(&c, io);
+        lib3ds_io_write_intw(io, (int16_t)material->shading);
+    }
+
+    { /*---- CHK_MAT_REFBLUR ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_MAT_REFBLUR;
+        c.size = 14;
+        lib3ds_chunk_write(&c, io);
+        int_percentage_write(material->blur, io);
+    }
+
+    if (material->use_blur) { /*---- CHK_MAT_USE_REFBLUR ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_MAT_USE_REFBLUR;
+        c.size = 6;
+        lib3ds_chunk_write(&c, io);
+    }
+
+    if (material->self_illum_flag) { /*---- CHK_MAT_SELF_ILLUM ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_MAT_SELF_ILLUM;
+        c.size = 6;
+        lib3ds_chunk_write(&c, io);
+    }
+
+    if (material->two_sided) { /*---- CHK_MAT_TWO_SIDE ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_MAT_TWO_SIDE;
+        c.size = 6;
+        lib3ds_chunk_write(&c, io);
+    }
+
+    if (material->map_decal) { /*---- CHK_MAT_DECAL ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_MAT_DECAL;
+        c.size = 6;
+        lib3ds_chunk_write(&c, io);
+    }
+
+    if (material->is_additive) { /*---- CHK_MAT_ADDITIVE ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_MAT_ADDITIVE;
+        c.size = 6;
+        lib3ds_chunk_write(&c, io);
+    }
+
+    if (material->use_wire) { /*---- CHK_MAT_WIRE ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_MAT_WIRE;
+        c.size = 6;
+        lib3ds_chunk_write(&c, io);
+    }
+
+    if (material->use_wire_abs) { /*---- CHK_MAT_WIREABS ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_MAT_WIREABS;
+        c.size = 6;
+        lib3ds_chunk_write(&c, io);
+    }
+
+    { /*---- CHK_MAT_WIRE_SIZE ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_MAT_WIRE_SIZE;
+        c.size = 10;
+        lib3ds_chunk_write(&c, io);
+        lib3ds_io_write_float(io, material->wire_size);
+    }
+
+    if (material->face_map) { /*---- CHK_MAT_FACEMAP ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_MAT_FACEMAP;
+        c.size = 6;
+        lib3ds_chunk_write(&c, io);
+    }
+
+    if (material->soften) { /*---- CHK_MAT_PHONGSOFT ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_MAT_PHONGSOFT;
+        c.size = 6;
+        lib3ds_chunk_write(&c, io);
+    }
+
+    texture_map_write(CHK_MAT_TEXMAP, &material->texture1_map, io);
+    texture_map_write(CHK_MAT_TEXMASK, &material->texture1_mask, io);
+    texture_map_write(CHK_MAT_TEX2MAP, &material->texture2_map, io);
+    texture_map_write(CHK_MAT_TEX2MASK, &material->texture2_mask, io);
+    texture_map_write(CHK_MAT_OPACMAP, &material->opacity_map, io);
+    texture_map_write(CHK_MAT_OPACMASK, &material->opacity_mask, io);
+    texture_map_write(CHK_MAT_BUMPMAP, &material->bump_map, io);
+    texture_map_write(CHK_MAT_BUMPMASK, &material->bump_mask, io);
+    texture_map_write(CHK_MAT_SPECMAP, &material->specular_map, io);
+    texture_map_write(CHK_MAT_SPECMASK, &material->specular_mask, io);
+    texture_map_write(CHK_MAT_SHINMAP, &material->shininess_map, io);
+    texture_map_write(CHK_MAT_SHINMASK, &material->shininess_mask, io);
+    texture_map_write(CHK_MAT_SELFIMAP, &material->self_illum_map, io);
+    texture_map_write(CHK_MAT_SELFIMASK, &material->self_illum_mask, io);
+    texture_map_write(CHK_MAT_REFLMAP,  &material->reflection_map, io);
+    texture_map_write(CHK_MAT_REFLMASK,  &material->reflection_mask, io);
+
+    { /*---- CHK_MAT_ACUBIC ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_MAT_ACUBIC;
+        c.size = 18;
+        lib3ds_chunk_write(&c, io);
+        lib3ds_io_write_intb(io, 0);
+        lib3ds_io_write_intb(io, (int8_t)material->autorefl_map_anti_alias);
+        lib3ds_io_write_intw(io, (int16_t)material->autorefl_map_flags);
+        lib3ds_io_write_intd(io, material->autorefl_map_size);
+        lib3ds_io_write_intd(io, material->autorefl_map_frame_step);
+    }
+
+    lib3ds_chunk_write_end(&c, io);
+}
Index: /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_vector.c
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_vector.c (revision 10853)
+++ /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_vector.c (revision 10853)
@@ -0,0 +1,246 @@
+/*
+    Copyright (C) 1996-2008 by Jan Eric Kyprianidis <www.kyprianidis.com>
+    All rights reserved.
+    
+    This program is free  software: you can redistribute it and/or modify 
+    it under the terms of the GNU Lesser General Public License as published 
+    by the Free Software Foundation, either version 2.1 of the License, or 
+    (at your option) any later version.
+
+    Thisprogram  is  distributed in the hope that it will be useful, 
+    but WITHOUT ANY WARRANTY; without even the implied warranty of 
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
+    GNU Lesser General Public License for more details.
+    
+    You should  have received a copy of the GNU Lesser General Public License
+    along with  this program; If not, see <http://www.gnu.org/licenses/>. 
+*/
+#include "lib3ds_impl.h"
+
+
+void 
+lib3ds_vector_make(float c[3], float x, float y, float z) {
+    c[0] = x;
+    c[1] = y;
+    c[2] = z;
+}
+
+
+void
+lib3ds_vector_zero(float c[3]) {
+    int i;
+    for (i = 0; i < 3; ++i) {
+        c[i] = 0.0f;
+    }
+}
+
+
+void
+lib3ds_vector_copy(float dst[3], float src[3]) {
+    int i;
+    for (i = 0; i < 3; ++i) {
+        dst[i] = src[i];
+    }
+}
+
+
+/*!
+ * Add two vectors.
+ *
+ * \param c Result.
+ * \param a First addend.
+ * \param b Second addend.
+ */
+void
+lib3ds_vector_add(float c[3], float a[3], float b[3]) {
+    int i;
+    for (i = 0; i < 3; ++i) {
+        c[i] = a[i] + b[i];
+    }
+}
+
+
+/*!
+ * Subtract two vectors.
+ *
+ * \param c Result.
+ * \param a Addend.
+ * \param b Minuend.
+ */
+void
+lib3ds_vector_sub(float c[3], float a[3], float b[3]) {
+    int i;
+    for (i = 0; i < 3; ++i) {
+        c[i] = a[i] - b[i];
+    }
+}
+
+
+/*!
+ * Multiply a vector by a scalar.
+ *
+ * \param c Vector to be multiplied.
+ * \param k Scalar.
+ */
+void
+lib3ds_vector_scalar_mul(float c[3], float a[3], float k) {
+    int i;
+    for (i = 0; i < 3; ++i) {
+        c[i] = a[i] * k;
+    }
+}
+
+
+/*!
+ * Compute cross product.
+ *
+ * \param c Result.
+ * \param a First vector.
+ * \param b Second vector.
+ */
+void
+lib3ds_vector_cross(float c[3], float a[3], float b[3]) {
+    c[0] = a[1] * b[2] - a[2] * b[1];
+    c[1] = a[2] * b[0] - a[0] * b[2];
+    c[2] = a[0] * b[1] - a[1] * b[0];
+}
+
+
+/*!
+ * Compute dot product.
+ *
+ * \param a First vector.
+ * \param b Second vector.
+ *
+ * \return Dot product.
+ */
+float
+lib3ds_vector_dot(float a[3], float b[3]) {
+    return(a[0]*b[0] + a[1]*b[1] + a[2]*b[2]);
+}
+
+
+/*!
+ * Compute length of vector.
+ *
+ * Computes |c| = sqrt(x*x + y*y + z*z)
+ *
+ * \param c Vector to compute.
+ *
+ * \return Length of vector.
+ */
+float
+lib3ds_vector_length(float c[3]) {
+    return((float)sqrt(c[0]*c[0] + c[1]*c[1] + c[2]*c[2]));
+}
+
+
+/*!
+ * Normalize a vector.
+ *
+ * Scales a vector so that its length is 1.0.
+ *
+ * \param c Vector to normalize.
+ */
+void
+lib3ds_vector_normalize(float c[3]) {
+    float l, m;
+
+    l = (float)sqrt(c[0] * c[0] + c[1] * c[1] + c[2] * c[2]);
+    if (fabs(l) < LIB3DS_EPSILON) {
+        if ((c[0] >= c[1]) && (c[0] >= c[2])) {
+            c[0] = 1.0f;
+            c[1] = c[2] = 0.0f;
+        } else
+            if (c[1] >= c[2]) {
+                c[1] = 1.0f;
+                c[0] = c[2] = 0.0f;
+            } else {
+                c[2] = 1.0f;
+                c[0] = c[1] = 0.0f;
+            }
+    } else {
+        m = 1.0f / l;
+        c[0] *= m;
+        c[1] *= m;
+        c[2] *= m;
+    }
+}
+
+
+/*!
+ * Compute a vector normal to two line segments.
+ *
+ * Computes the normal vector to the lines b-a and b-c.
+ *
+ * \param n Returned normal vector.
+ * \param a Endpoint of first line.
+ * \param b Base point of both lines.
+ * \param c Endpoint of second line.
+ */
+void
+lib3ds_vector_normal(float n[3], float a[3], float b[3], float c[3]) {
+    float p[3], q[3];
+
+    lib3ds_vector_sub(p, c, b);
+    lib3ds_vector_sub(q, a, b);
+    lib3ds_vector_cross(n, p, q);
+    lib3ds_vector_normalize(n);
+}
+
+
+/*!
+ * Multiply a point by a transformation matrix.
+ *
+ * Applies the given transformation matrix to the given point.  With some
+ * transformation matrices, a vector may also be transformed.
+ *
+ * \param c Result.
+ * \param m Transformation matrix.
+ * \param a Input point.
+ */
+void
+lib3ds_vector_transform(float c[3], float m[4][4], float a[3]) {
+    c[0] = m[0][0] * a[0] + m[1][0] * a[1] + m[2][0] * a[2] + m[3][0];
+    c[1] = m[0][1] * a[0] + m[1][1] * a[1] + m[2][1] * a[2] + m[3][1];
+    c[2] = m[0][2] * a[0] + m[1][2] * a[1] + m[2][2] * a[2] + m[3][2];
+}
+
+
+/*!
+ * c[i] = min(c[i], a[i]);
+ *
+ * Computes minimum values of x,y,z independently.
+ */
+void
+lib3ds_vector_min(float c[3], float a[3]) {
+    int i;
+    for (i = 0; i < 3; ++i) {
+        if (a[i] < c[i]) {
+            c[i] = a[i];
+        }
+    }
+}
+
+
+/*!
+ * c[i] = max(c[i], a[i]);
+ *
+ * Computes maximum values of x,y,z independently.
+ */
+void
+lib3ds_vector_max(float c[3], float a[3]) {
+    int i;
+    for (i = 0; i < 3; ++i) {
+        if (a[i] > c[i]) {
+            c[i] = a[i];
+        }
+    }
+}
+
+
+void
+lib3ds_vector_dump(float c[3]) {
+    fprintf(stderr, "%f %f %f\n", c[0], c[1], c[2]);
+}
+
Index: /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_track.c
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_track.c (revision 10853)
+++ /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_track.c (revision 10853)
@@ -0,0 +1,551 @@
+/*
+    Copyright (C) 1996-2008 by Jan Eric Kyprianidis <www.kyprianidis.com>
+    All rights reserved.
+    
+    This program is free  software: you can redistribute it and/or modify 
+    it under the terms of the GNU Lesser General Public License as published 
+    by the Free Software Foundation, either version 2.1 of the License, or 
+    (at your option) any later version.
+
+    Thisprogram  is  distributed in the hope that it will be useful, 
+    but WITHOUT ANY WARRANTY; without even the implied warranty of 
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
+    GNU Lesser General Public License for more details.
+    
+    You should  have received a copy of the GNU Lesser General Public License
+    along with  this program; If not, see <http://www.gnu.org/licenses/>. 
+*/
+#include "lib3ds_impl.h"
+
+
+Lib3dsTrack* 
+lib3ds_track_new(Lib3dsTrackType type, int nkeys) {
+    Lib3dsTrack *track = (Lib3dsTrack*)calloc(sizeof(Lib3dsTrack), 1);
+    track->type = type;
+    lib3ds_track_resize(track, nkeys);
+    return track;
+}
+
+
+void 
+lib3ds_track_free(Lib3dsTrack *track) {
+    assert(track);
+    lib3ds_track_resize(track, 0);
+    memset(track, 0, sizeof(Lib3dsTrack));
+    free(track);
+}
+
+
+void 
+lib3ds_track_resize(Lib3dsTrack *track, int nkeys) {
+    char *p;
+
+    assert(track);
+    if (track->nkeys == nkeys)
+        return;
+
+    p = (char*)realloc(track->keys, sizeof(Lib3dsKey) * nkeys);
+    if (nkeys > track->nkeys) {
+        memset(p + (sizeof(Lib3dsKey)*track->nkeys), 0, sizeof(Lib3dsKey)*(nkeys - track->nkeys));
+    }
+    track->keys = (Lib3dsKey*)p;
+    track->nkeys = nkeys;
+}
+
+
+static void 
+pos_key_setup(int n, Lib3dsKey *pp, Lib3dsKey *pc, Lib3dsKey *pn, float *dd, float *ds) {
+    float tm, cm, cp, bm, bp, tmcm, tmcp, ksm, ksp, kdm, kdp, c;
+    float dt, fp, fn;
+    float delm[3], delp[3];
+    int i;
+
+    assert(pc);
+    fp = fn = 1.0f;
+    if (pp && pn) {
+        dt = 0.5f * (pn->frame - pp->frame);
+        fp = (float)(pc->frame - pp->frame) / dt;
+        fn = (float)(pn->frame - pc->frame) / dt;
+        c  = (float)fabs(pc->cont);
+        fp = fp + c - c * fp;
+        fn = fn + c - c * fn;
+    }
+
+    cm = 1.0f - pc->cont;
+    tm = 0.5f * (1.0f - pc->tens);
+    cp = 2.0f - cm;
+    bm = 1.0f - pc->bias;
+    bp = 2.0f - bm;
+    tmcm = tm * cm;
+    tmcp = tm * cp;
+    ksm = tmcm * bp * fp;
+    ksp = tmcp * bm * fp;
+    kdm = tmcp * bp * fn;
+    kdp = tmcm * bm * fn;
+
+    for (i = 0; i < n; ++i) delm[i] = delp[i] = 0;
+    if (pp) {
+        for (i = 0; i < n; ++i) delm[i] = pc->value[i] - pp->value[i];
+    }
+    if (pn) {
+        for (i = 0; i < n; ++i) delp[i] = pn->value[i] - pc->value[i];
+    }
+    if (!pp) {
+        for (i = 0; i < n; ++i) delm[i] = delp[i];
+    }
+    if (!pn) {
+        for (i = 0; i < n; ++i) delp[i] = delm[i];
+    }
+
+    for (i = 0; i < n; ++i) {
+        ds[i] = ksm * delm[i] + ksp * delp[i];
+        dd[i] = kdm * delm[i] + kdp * delp[i];
+    }
+}
+
+
+static void 
+rot_key_setup(Lib3dsKey *prev, Lib3dsKey *cur, Lib3dsKey *next, float a[4], float b[4]) {
+    float tm, cm, cp, bm, bp, tmcm, tmcp, ksm, ksp, kdm, kdp, c;
+    float dt, fp, fn;
+    float q[4], qm[4], qp[4], qa[4], qb[4];
+    int i;
+
+    assert(cur);
+    if (prev) {
+        if (cur->value[3] > LIB3DS_TWOPI - LIB3DS_EPSILON) {
+            lib3ds_quat_axis_angle(qm, cur->value, 0.0f);
+            lib3ds_quat_ln(qm);
+        } else {
+            lib3ds_quat_copy(q, prev->value);
+            if (lib3ds_quat_dot(q, cur->value) < 0) lib3ds_quat_neg(q);
+            lib3ds_quat_ln_dif(qm, q, cur->value);
+        }
+    }
+    if (next) {
+        if (next->value[3] > LIB3DS_TWOPI - LIB3DS_EPSILON) {
+            lib3ds_quat_axis_angle(qp, next->value, 0.0f);
+            lib3ds_quat_ln(qp);
+        } else {
+            lib3ds_quat_copy(q, next->value);
+            if (lib3ds_quat_dot(q, cur->value) < 0) lib3ds_quat_neg(q);
+            lib3ds_quat_ln_dif(qp, cur->value, q);
+        }
+    }
+    if (!prev) lib3ds_quat_copy(qm, qp);
+    if (!next) lib3ds_quat_copy(qp, qm);
+
+    fp = fn = 1.0f;
+    cm = 1.0f - cur->cont;
+    if (prev && next) {
+        dt = 0.5f * (next->frame - prev->frame);
+        fp = (float)(cur->frame - prev->frame) / dt;
+        fn = (float)(next->frame - cur->frame) / dt;
+        c  = (float)fabs(cur->cont);
+        fp = fp + c - c * fp;
+        fn = fn + c - c * fn;
+    }
+
+    tm = 0.5f * (1.0f - cur->tens);
+    cp = 2.0f - cm;
+    bm = 1.0f - cur->bias;
+    bp = 2.0f - bm;
+    tmcm = tm * cm;
+    tmcp = tm * cp;
+    ksm = 1.0f - tmcm * bp * fp;
+    ksp = -tmcp * bm * fp;
+    kdm = tmcp * bp * fn;
+    kdp = tmcm * bm * fn - 1.0f;
+
+    for (i = 0; i < 4; i++) {
+        qa[i] = 0.5f * (kdm * qm[i] + kdp * qp[i]);
+        qb[i] = 0.5f * (ksm * qm[i] + ksp * qp[i]);
+    }
+    lib3ds_quat_exp(qa);
+    lib3ds_quat_exp(qb);
+
+    lib3ds_quat_mul(a, cur->value, qa);
+    lib3ds_quat_mul(b, cur->value, qb);
+}
+
+
+static void
+quat_for_index(Lib3dsTrack *track, int index, float q[4]) {
+    float p[4];
+    int i;
+    lib3ds_quat_identity(q);
+    for (i = 0; i <= index; ++i) {
+        lib3ds_quat_axis_angle(p, track->keys[i].value, track->keys[i].value[3]);
+        lib3ds_quat_mul(q, p, q);
+    }
+}
+
+
+static int 
+find_index(Lib3dsTrack *track, float t, float *u) {
+    int i;
+    float nt;
+    int t0, t1;
+
+    assert(track);
+    assert(track->nkeys > 0);
+    
+    if (track->nkeys <= 1)
+        return -1;
+    
+    t0 = track->keys[0].frame;
+    t1 = track->keys[track->nkeys-1].frame;
+    if (track->flags & LIB3DS_TRACK_REPEAT) {
+        nt = (float)fmod(t - t0, t1 - t0) + t0;
+    } else {
+        nt = t;
+    }
+
+    if (nt <= t0) {
+        return -1;
+    }
+    if (nt >= t1) {
+        return track->nkeys;
+    }
+
+    for (i = 1; i < track->nkeys; ++i) {
+        if (nt < track->keys[i].frame)
+            break;
+    }
+
+    *u = nt - (float)track->keys[i-1].frame;
+    *u /= (float)(track->keys[i].frame - track->keys[i-1].frame);
+
+    assert((*u >= 0.0f) && (*u <= 1.0f));
+    return i;
+}
+
+
+static void 
+setup_segment(Lib3dsTrack *track, int index, Lib3dsKey *pp, Lib3dsKey *p0, Lib3dsKey *p1, Lib3dsKey *pn) {
+    int ip, in;
+    
+    pp->frame = pn->frame = -1;
+    if (index >= 2) {
+        ip = index - 2;
+        *pp = track->keys[index - 2];
+    } else {
+        if (track->flags & LIB3DS_TRACK_SMOOTH) {
+            ip = track->nkeys - 2;
+            *pp = track->keys[track->nkeys - 2];
+            pp->frame = track->keys[track->nkeys - 2].frame - (track->keys[track->nkeys - 1].frame - track->keys[0].frame);
+        }
+		else ip = -1;		// Avoids a compiler warning
+    }
+
+    *p0 = track->keys[index - 1];
+    *p1 = track->keys[index];
+
+    if (index < (int)track->nkeys - 1) {
+        in = index + 1;
+        *pn = track->keys[index + 1];
+    } else {
+        if (track->flags & LIB3DS_TRACK_SMOOTH) {
+            in = 1;
+            *pn = track->keys[1];
+            pn->frame = track->keys[1].frame + (track->keys[track->nkeys-1].frame - track->keys[0].frame);
+        }
+    }
+
+    if (track->type == LIB3DS_TRACK_QUAT) {
+        float q[4];
+        if (pp->frame >= 0) {
+            quat_for_index(track, ip, pp->value);
+        } else {
+            lib3ds_quat_identity(pp->value);
+        }
+
+        quat_for_index(track, index - 1, p0->value);
+        lib3ds_quat_axis_angle(q, track->keys[index].value, track->keys[index].value[3]);
+        lib3ds_quat_mul(p1->value, q, p0->value);
+
+        if (pn->frame >= 0) {
+            lib3ds_quat_axis_angle(q, track->keys[in].value, track->keys[in].value[3]);
+            lib3ds_quat_mul(pn->value, q, p1->value);
+        } else {
+            lib3ds_quat_identity(pn->value);
+        }
+    }
+}
+
+
+void 
+lib3ds_track_eval_bool(Lib3dsTrack *track, int *b, float t) {
+    *b = FALSE;
+    if (track) {
+        int index;
+        float u;
+
+        assert(track->type == LIB3DS_TRACK_BOOL);
+        if (!track->nkeys) {
+            return;
+        }
+
+        index = find_index(track, t, &u);
+        if (index < 0) {
+            *b = FALSE;
+            return;
+        }
+        if (index >= track->nkeys) {
+            *b = !(track->nkeys & 1);
+            return;
+        }
+        *b = !(index & 1);
+    }
+}
+
+
+static void 
+track_eval_linear(Lib3dsTrack *track, float *value, float t) {
+    Lib3dsKey pp, p0, p1, pn;
+    float u;
+    int index;
+    float dsp[3], ddp[3], dsn[3], ddn[3];
+
+    assert(track);
+    if (!track->nkeys) {
+        int i;
+        for (i = 0; i < track->type; ++i) value[i] = 0.0f;
+        return;
+    }
+
+    index = find_index(track, t, &u);
+
+    if (index < 0) {
+        int i;
+        for (i = 0; i < track->type; ++i) value[i] = track->keys[0].value[i];
+        return;
+    }
+    if (index >= track->nkeys) {
+        int i;
+        for (i = 0; i < track->type; ++i) value[i] = track->keys[track->nkeys-1].value[i];
+        return;
+    }
+
+    setup_segment(track, index, &pp, &p0, &p1, &pn);
+
+    pos_key_setup(track->type, pp.frame>=0? &pp : NULL, &p0, &p1, ddp, dsp);
+    pos_key_setup(track->type, &p0, &p1, pn.frame>=0? &pn : NULL, ddn, dsn);
+
+    lib3ds_math_cubic_interp(
+        value,
+        p0.value,
+        ddp,
+        dsn,
+        p1.value,
+        track->type,
+        u
+    );
+}
+
+
+void 
+lib3ds_track_eval_float(Lib3dsTrack *track, float *f, float t) {
+    *f = 0;
+    if (track) {
+        assert(track->type == LIB3DS_TRACK_FLOAT);
+        track_eval_linear(track, f, t);
+    }
+}
+
+
+void 
+lib3ds_track_eval_vector(Lib3dsTrack *track, float v[3], float t) {
+    lib3ds_vector_zero(v);
+    if (track) {
+        assert(track->type == LIB3DS_TRACK_VECTOR);
+        track_eval_linear(track, v, t);
+    }
+}
+
+
+void 
+lib3ds_track_eval_quat(Lib3dsTrack *track, float q[4], float t) {
+    lib3ds_quat_identity(q);
+    if (track) {
+        Lib3dsKey pp, p0, p1, pn;
+        float u;
+        int index;
+        float ap[4], bp[4], an[4], bn[4];
+
+        assert(track->type == LIB3DS_TRACK_QUAT);
+        if (!track->nkeys) {
+            return;
+        }
+
+        index = find_index(track, t, &u);
+        if (index < 0) {
+            lib3ds_quat_axis_angle(q, track->keys[0].value, track->keys[0].value[3]);
+            return;
+        }
+        if (index >= track->nkeys) { 
+            quat_for_index(track, track->nkeys - 1, q);
+            return;
+        }
+
+        setup_segment(track, index, &pp, &p0, &p1, &pn);
+
+        rot_key_setup(pp.frame>=0? &pp : NULL, &p0, &p1, ap, bp);
+        rot_key_setup(&p0, &p1, pn.frame>=0? &pn : NULL, an, bn);
+
+        lib3ds_quat_squad(q, p0.value, ap, bn, p1.value, u);
+    }
+}
+
+
+static void 
+tcb_read(Lib3dsKey *key, Lib3dsIo *io) {
+    key->flags = lib3ds_io_read_word(io);
+    if (key->flags & LIB3DS_KEY_USE_TENS) {
+        key->tens = lib3ds_io_read_float(io);
+    }
+    if (key->flags & LIB3DS_KEY_USE_CONT) {
+        key->cont = lib3ds_io_read_float(io);
+    }
+    if (key->flags & LIB3DS_KEY_USE_BIAS) {
+        key->bias = lib3ds_io_read_float(io);
+    }
+    if (key->flags & LIB3DS_KEY_USE_EASE_TO) {
+        key->ease_to = lib3ds_io_read_float(io);
+    }
+    if (key->flags & LIB3DS_KEY_USE_EASE_FROM) {
+        key->ease_from = lib3ds_io_read_float(io);
+    }
+}
+
+
+void 
+lib3ds_track_read(Lib3dsTrack *track, Lib3dsIo *io) {
+    unsigned nkeys;
+    unsigned i;
+
+    track->flags = lib3ds_io_read_word(io);
+    lib3ds_io_read_dword(io);
+    lib3ds_io_read_dword(io);
+    nkeys = lib3ds_io_read_intd(io);
+    lib3ds_track_resize(track, nkeys);
+
+    switch (track->type) {
+        case LIB3DS_TRACK_BOOL:
+            for (i = 0; i < nkeys; ++i) {
+                track->keys[i].frame = lib3ds_io_read_intd(io);
+                tcb_read(&track->keys[i], io);
+            }
+            break;
+
+        case LIB3DS_TRACK_FLOAT:
+            for (i = 0; i < nkeys; ++i) {
+                track->keys[i].frame = lib3ds_io_read_intd(io);
+                tcb_read(&track->keys[i], io);
+                track->keys[i].value[0] = lib3ds_io_read_float(io);
+            }
+            break;
+
+        case LIB3DS_TRACK_VECTOR:
+            for (i = 0; i < nkeys; ++i) {
+                track->keys[i].frame = lib3ds_io_read_intd(io);
+                tcb_read(&track->keys[i], io);
+                lib3ds_io_read_vector(io, track->keys[i].value);
+            }
+            break;
+
+        case LIB3DS_TRACK_QUAT:
+            for (i = 0; i < nkeys; ++i) {
+                track->keys[i].frame = lib3ds_io_read_intd(io);
+                tcb_read(&track->keys[i], io);
+                track->keys[i].value[3] = lib3ds_io_read_float(io);
+                lib3ds_io_read_vector(io, track->keys[i].value);
+            }
+            break;
+
+        /*case LIB3DS_TRACK_MORPH:
+            for (i = 0; i < nkeys; ++i) {
+                track->keys[i].frame = lib3ds_io_read_intd(io);
+                tcb_read(&track->keys[i].tcb, io);
+                lib3ds_io_read_string(io, track->keys[i].data.m.name, 64);
+            }
+            break;*/
+
+        default:
+            break;
+    }
+}
+
+
+void
+tcb_write(Lib3dsKey *key, Lib3dsIo *io) {
+    lib3ds_io_write_word(io, (uint16_t)key->flags);
+    if (key->flags & LIB3DS_KEY_USE_TENS) {
+        lib3ds_io_write_float(io, key->tens);
+    }
+    if (key->flags & LIB3DS_KEY_USE_CONT) {
+        lib3ds_io_write_float(io, key->cont);
+    }
+    if (key->flags & LIB3DS_KEY_USE_BIAS) {
+        lib3ds_io_write_float(io, key->bias);
+    }
+    if (key->flags & LIB3DS_KEY_USE_EASE_TO) {
+        lib3ds_io_write_float(io, key->ease_to);
+    }
+    if (key->flags & LIB3DS_KEY_USE_EASE_FROM) {
+        lib3ds_io_write_float(io, key->ease_from);
+    }
+}
+
+
+void
+lib3ds_track_write(Lib3dsTrack *track, Lib3dsIo *io) {
+    int i;
+
+    lib3ds_io_write_word(io, (uint16_t)track->flags);
+    lib3ds_io_write_dword(io, 0);
+    lib3ds_io_write_dword(io, 0);
+    lib3ds_io_write_dword(io, track->nkeys);
+
+    switch (track->type) {
+        case LIB3DS_TRACK_BOOL:
+            for (i = 0; i < track->nkeys; ++i) {
+                lib3ds_io_write_intd(io, track->keys[i].frame);
+                tcb_write(&track->keys[i], io);
+            }
+            break;
+
+        case LIB3DS_TRACK_FLOAT:
+            for (i = 0; i < track->nkeys; ++i) {
+                lib3ds_io_write_intd(io, track->keys[i].frame);
+                tcb_write(&track->keys[i], io);
+                lib3ds_io_write_float(io, track->keys[i].value[0]);
+            }
+            break;
+
+        case LIB3DS_TRACK_VECTOR:
+            for (i = 0; i < track->nkeys; ++i) {
+                lib3ds_io_write_intd(io, track->keys[i].frame);
+                tcb_write(&track->keys[i], io);
+                lib3ds_io_write_vector(io, track->keys[i].value);
+            }
+            break;
+
+        case LIB3DS_TRACK_QUAT:
+            for (i = 0; i < track->nkeys; ++i) {
+                lib3ds_io_write_intd(io, track->keys[i].frame);
+                tcb_write(&track->keys[i], io);
+                lib3ds_io_write_float(io, track->keys[i].value[3]);
+                lib3ds_io_write_vector(io, track->keys[i].value);
+            }
+            break;
+
+        /*case LIB3DS_TRACK_MORPH:
+            for (i = 0; i < track->nkeys; ++i) {
+                lib3ds_io_write_intd(io, track->keys[i].frame);
+                tcb_write(&track->keys[i].tcb, io);
+                lib3ds_io_write_string(io, track->keys[i].data.m.name);
+            }
+            break;*/
+    }
+}
Index: /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/AUTHORS
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/AUTHORS (revision 10853)
+++ /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/AUTHORS (revision 10853)
@@ -0,0 +1,17 @@
+Author of lib3ds is Jan Eric Kyprianidis <www.kyprianidis.com>
+
+The following people have contributed additional changes to lib3ds:
+
+Reed Hedges
+David Rogers
+Edward Falk
+Gernot Zeigler
+Haik Lorenz
+Jean-Charles Quillet
+Mike Frysinger
+Miles Bader
+Tomas Rapkauskas
+Torsten Blank 
+Ralf Corsepius
+Stephane Denis
+
Index: /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_matrix.c
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_matrix.c (revision 10853)
+++ /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_matrix.c (revision 10853)
@@ -0,0 +1,466 @@
+/*
+    Copyright (C) 1996-2008 by Jan Eric Kyprianidis <www.kyprianidis.com>
+    All rights reserved.
+    
+    This program is free  software: you can redistribute it and/or modify 
+    it under the terms of the GNU Lesser General Public License as published 
+    by the Free Software Foundation, either version 2.1 of the License, or 
+    (at your option) any later version.
+
+    Thisprogram  is  distributed in the hope that it will be useful, 
+    but WITHOUT ANY WARRANTY; without even the implied warranty of 
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
+    GNU Lesser General Public License for more details.
+    
+    You should  have received a copy of the GNU Lesser General Public License
+    along with  this program; If not, see <http://www.gnu.org/licenses/>. 
+*/
+#include "lib3ds_impl.h"
+
+
+/*!
+ * Clear a matrix to all zeros.
+ *
+ * \param m Matrix to be cleared.
+ */
+void
+lib3ds_matrix_zero(float m[4][4]) {
+    int i, j;
+
+    for (i = 0; i < 4; i++) {
+        for (j = 0; j < 4; j++) m[i][j] = 0.0f;
+    }
+}
+
+
+/*!
+ * Set a matrix to identity.
+ *
+ * \param m Matrix to be set.
+ */
+void
+lib3ds_matrix_identity(float m[4][4]) {
+    int i, j;
+
+    for (i = 0; i < 4; i++) {
+        for (j = 0; j < 4; j++) m[i][j] = 0.0;
+    }
+    for (i = 0; i < 4; i++) m[i][i] = 1.0;
+}
+
+
+/*!
+ * Copy a matrix.
+ */
+void
+lib3ds_matrix_copy(float dest[4][4], float src[4][4]) {
+    memcpy(dest, src, 16 * sizeof(float));
+}
+
+
+/*!
+ * Negate a matrix -- all elements negated.
+ */
+void
+lib3ds_matrix_neg(float m[4][4]) {
+    int i, j;
+
+    for (j = 0; j < 4; j++) {
+        for (i = 0; i < 4; i++) {
+            m[j][i] = -m[j][i];
+        }
+    }
+}
+
+
+/*!
+ * Transpose a matrix in place.
+ */
+void
+lib3ds_matrix_transpose(float m[4][4]) {
+    int i, j;
+    float swp;
+
+    for (j = 0; j < 4; j++) {
+        for (i = j + 1; i < 4; i++) {
+            swp = m[j][i];
+            m[j][i] = m[i][j];
+            m[i][j] = swp;
+        }
+    }
+}
+
+
+/*!
+ * Add two matrices.
+ */
+void
+lib3ds_matrix_add(float m[4][4], float a[4][4], float b[4][4]) {
+    int i, j;
+
+    for (j = 0; j < 4; j++) {
+        for (i = 0; i < 4; i++) {
+            m[j][i] = a[j][i] + b[j][i];
+        }
+    }
+}
+
+
+/*!
+ * Subtract two matrices.
+ *
+ * \param m Result.
+ * \param a Addend.
+ * \param b Minuend.
+ */
+void
+lib3ds_matrix_sub(float m[4][4], float a[4][4], float b[4][4]) {
+    int i, j;
+
+    for (j = 0; j < 4; j++) {
+        for (i = 0; i < 4; i++) {
+            m[j][i] = a[j][i] - b[j][i];
+        }
+    }
+}
+
+
+/*!
+ * Multiplies a matrix by a second one (m = m * n).
+ */
+void
+lib3ds_matrix_mult(float m[4][4], float a[4][4], float b[4][4]) {
+    float tmp[4][4];
+    int i, j, k;
+    float ab;
+
+    memcpy(tmp, a, 16 * sizeof(float));
+    for (j = 0; j < 4; j++) {
+        for (i = 0; i < 4; i++) {
+            ab = 0.0f;
+            for (k = 0; k < 4; k++) ab += tmp[k][i] * b[j][k];
+            m[j][i] = ab;
+        }
+    }
+}
+
+
+/*!
+ * Multiply a matrix by a scalar.
+ *
+ * \param m Matrix to be set.
+ * \param k Scalar.
+ */
+void
+lib3ds_matrix_scalar(float m[4][4], float k) {
+    int i, j;
+
+    for (j = 0; j < 4; j++) {
+        for (i = 0; i < 4; i++) {
+            m[j][i] *= k;
+        }
+    }
+}
+
+
+static float
+det2x2(
+    float a, float b,
+    float c, float d) {
+    return((a)*(d) - (b)*(c));
+}
+
+
+static float
+det3x3(
+    float a1, float a2, float a3,
+    float b1, float b2, float b3,
+    float c1, float c2, float c3) {
+    return(
+              a1*det2x2(b2, b3, c2, c3) -
+              b1*det2x2(a2, a3, c2, c3) +
+              c1*det2x2(a2, a3, b2, b3)
+          );
+}
+
+
+/*!
+ * Find determinant of a matrix.
+ */
+float
+lib3ds_matrix_det(float m[4][4]) {
+    float a1, a2, a3, a4, b1, b2, b3, b4, c1, c2, c3, c4, d1, d2, d3, d4;
+
+    a1 = m[0][0];
+    b1 = m[1][0];
+    c1 = m[2][0];
+    d1 = m[3][0];
+    a2 = m[0][1];
+    b2 = m[1][1];
+    c2 = m[2][1];
+    d2 = m[3][1];
+    a3 = m[0][2];
+    b3 = m[1][2];
+    c3 = m[2][2];
+    d3 = m[3][2];
+    a4 = m[0][3];
+    b4 = m[1][3];
+    c4 = m[2][3];
+    d4 = m[3][3];
+    return(
+              a1 * det3x3(b2, b3, b4, c2, c3, c4, d2, d3, d4) -
+              b1 * det3x3(a2, a3, a4, c2, c3, c4, d2, d3, d4) +
+              c1 * det3x3(a2, a3, a4, b2, b3, b4, d2, d3, d4) -
+              d1 * det3x3(a2, a3, a4, b2, b3, b4, c2, c3, c4)
+          );
+}
+
+
+/*!
+ * Invert a matrix in place.
+ *
+ * \param m Matrix to invert.
+ *
+ * \return LIB3DS_TRUE on success, LIB3DS_FALSE on failure.
+ *
+ * GGemsII, K.Wu, Fast Matrix Inversion
+ */
+int
+lib3ds_matrix_inv(float m[4][4]) {
+    int i, j, k;
+    int pvt_i[4], pvt_j[4];            /* Locations of pivot elements */
+    float pvt_val;               /* Value of current pivot element */
+    float hold;                  /* Temporary storage */
+    float determinat;
+
+    determinat = 1.0f;
+    for (k = 0; k < 4; k++)  {
+        /* Locate k'th pivot element */
+        pvt_val = m[k][k];          /* Initialize for search */
+        pvt_i[k] = k;
+        pvt_j[k] = k;
+        for (i = k; i < 4; i++) {
+            for (j = k; j < 4; j++) {
+                if (fabs(m[i][j]) > fabs(pvt_val)) {
+                    pvt_i[k] = i;
+                    pvt_j[k] = j;
+                    pvt_val = m[i][j];
+                }
+            }
+        }
+
+        /* Product of pivots, gives determinant when finished */
+        determinat *= pvt_val;
+        if (fabs(determinat) < LIB3DS_EPSILON) {
+            return(FALSE);  /* Matrix is singular (zero determinant) */
+        }
+
+        /* "Interchange" rows (with sign change stuff) */
+        i = pvt_i[k];
+        if (i != k) {             /* If rows are different */
+            for (j = 0; j < 4; j++) {
+                hold = -m[k][j];
+                m[k][j] = m[i][j];
+                m[i][j] = hold;
+            }
+        }
+
+        /* "Interchange" columns */
+        j = pvt_j[k];
+        if (j != k) {            /* If columns are different */
+            for (i = 0; i < 4; i++) {
+                hold = -m[i][k];
+                m[i][k] = m[i][j];
+                m[i][j] = hold;
+            }
+        }
+
+        /* Divide column by minus pivot value */
+        for (i = 0; i < 4; i++) {
+            if (i != k) m[i][k] /= (-pvt_val) ;
+        }
+
+        /* Reduce the matrix */
+        for (i = 0; i < 4; i++) {
+            hold = m[i][k];
+            for (j = 0; j < 4; j++) {
+                if (i != k && j != k) m[i][j] += hold * m[k][j];
+            }
+        }
+
+        /* Divide row by pivot */
+        for (j = 0; j < 4; j++) {
+            if (j != k) m[k][j] /= pvt_val;
+        }
+
+        /* Replace pivot by reciprocal (at last we can touch it). */
+        m[k][k] = 1.0f / pvt_val;
+    }
+
+    /* That was most of the work, one final pass of row/column interchange */
+    /* to finish */
+    for (k = 4 - 2; k >= 0; k--) { /* Don't need to work with 1 by 1 corner*/
+        i = pvt_j[k];          /* Rows to swap correspond to pivot COLUMN */
+        if (i != k) {          /* If rows are different */
+            for (j = 0; j < 4; j++) {
+                hold = m[k][j];
+                m[k][j] = -m[i][j];
+                m[i][j] = hold;
+            }
+        }
+
+        j = pvt_i[k];         /* Columns to swap correspond to pivot ROW */
+        if (j != k)           /* If columns are different */
+            for (i = 0; i < 4; i++) {
+                hold = m[i][k];
+                m[i][k] = -m[i][j];
+                m[i][j] = hold;
+            }
+    }
+    return(TRUE);
+}
+
+
+/*!
+ * Apply a translation to a matrix.
+ */
+void
+lib3ds_matrix_translate(float m[4][4], float x, float y, float z) {
+    int i;
+
+    for (i = 0; i < 3; i++) {
+        m[3][i] += m[0][i] * x + m[1][i] * y + m[2][i] * z;
+    }
+}
+
+
+/*!
+ * Apply scale factors to a matrix.
+ */
+void
+lib3ds_matrix_scale(float m[4][4], float x, float y, float z) {
+    int i;
+
+    for (i = 0; i < 4; i++) {
+        m[0][i] *= x;
+        m[1][i] *= y;
+        m[2][i] *= z;
+    }
+}
+
+
+/*!
+ * Apply a rotation about an arbitrary axis to a matrix.
+ */
+void
+lib3ds_matrix_rotate_quat(float m[4][4], float q[4]) {
+    float s, xs, ys, zs, wx, wy, wz, xx, xy, xz, yy, yz, zz, l;
+    float R[4][4];
+
+    l = q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3];
+    if (fabs(l) < LIB3DS_EPSILON) {
+        s = 1.0f;
+    } else {
+        s = 2.0f / l;
+    }
+
+    xs = q[0] * s;
+    ys = q[1] * s;
+    zs = q[2] * s;
+    wx = q[3] * xs;
+    wy = q[3] * ys;
+    wz = q[3] * zs;
+    xx = q[0] * xs;
+    xy = q[0] * ys;
+    xz = q[0] * zs;
+    yy = q[1] * ys;
+    yz = q[1] * zs;
+    zz = q[2] * zs;
+
+    R[0][0] = 1.0f - (yy + zz);
+    R[1][0] = xy - wz;
+    R[2][0] = xz + wy;
+    R[0][1] = xy + wz;
+    R[1][1] = 1.0f - (xx + zz);
+    R[2][1] = yz - wx;
+    R[0][2] = xz - wy;
+    R[1][2] = yz + wx;
+    R[2][2] = 1.0f - (xx + yy);
+    R[3][0] = R[3][1] = R[3][2] = R[0][3] = R[1][3] = R[2][3] = 0.0f;
+    R[3][3] = 1.0f;
+
+    lib3ds_matrix_mult(m, m, R);
+}
+
+
+/*!
+ * Apply a rotation about an arbitrary axis to a matrix.
+ */
+void
+lib3ds_matrix_rotate(float m[4][4], float angle, float ax, float ay, float az) {
+    float q[4];
+    float axis[3];
+
+    lib3ds_vector_make(axis, ax, ay, az);
+    lib3ds_quat_axis_angle(q, axis, angle);
+    lib3ds_matrix_rotate_quat(m, q);
+}
+
+
+/*!
+ * Compute a camera matrix based on position, target and roll.
+ *
+ * Generates a translate/rotate matrix that maps world coordinates
+ * to camera coordinates.  Resulting matrix does not include perspective
+ * transform.
+ *
+ * \param matrix Destination matrix.
+ * \param pos Camera position
+ * \param tgt Camera target
+ * \param roll Roll angle
+ */
+void
+lib3ds_matrix_camera(float matrix[4][4], float pos[3], float tgt[3], float roll) {
+    float M[4][4];
+    float x[3], y[3], z[3];
+
+    lib3ds_vector_sub(y, tgt, pos);
+    lib3ds_vector_normalize(y);
+
+    if (y[0] != 0. || y[1] != 0) {
+        z[0] = 0;
+        z[1] = 0;
+        z[2] = 1.0;
+    } else { /* Special case:  looking straight up or down z axis */
+        z[0] = -1.0;
+        z[1] = 0;
+        z[2] = 0;
+    }
+
+    lib3ds_vector_cross(x, y, z);
+    lib3ds_vector_cross(z, x, y);
+    lib3ds_vector_normalize(x);
+    lib3ds_vector_normalize(z);
+
+    lib3ds_matrix_identity(M);
+    M[0][0] = x[0];
+    M[1][0] = x[1];
+    M[2][0] = x[2];
+    M[0][1] = y[0];
+    M[1][1] = y[1];
+    M[2][1] = y[2];
+    M[0][2] = z[0];
+    M[1][2] = z[1];
+    M[2][2] = z[2];
+
+    lib3ds_matrix_identity(matrix);
+    lib3ds_matrix_rotate(matrix, roll, 0, 1, 0);
+    lib3ds_matrix_mult(matrix, matrix, M);
+    lib3ds_matrix_translate(matrix, -pos[0], -pos[1], -pos[2]);
+}
+
+
+
+
+
+
Index: /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_impl.h
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_impl.h (revision 10853)
+++ /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_impl.h (revision 10853)
@@ -0,0 +1,388 @@
+/* -*- c -*- */
+#ifndef INCLUDED_LIB3DS_IMPL_H
+#define INCLUDED_LIB3DS_IMPL_H
+/*
+    Copyright (C) 1996-2008 by Jan Eric Kyprianidis <www.kyprianidis.com>
+    All rights reserved.
+    
+    This program is free  software: you can redistribute it and/or modify 
+    it under the terms of the GNU Lesser General Public License as published 
+    by the Free Software Foundation, either version 2.1 of the License, or 
+    (at your option) any later version.
+
+    Thisprogram  is  distributed in the hope that it will be useful, 
+    but WITHOUT ANY WARRANTY; without even the implied warranty of 
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
+    GNU Lesser General Public License for more details.
+    
+    You should  have received a copy of the GNU Lesser General Public License
+    along with  this program; If not, see <http://www.gnu.org/licenses/>. 
+*/
+
+#include "lib3ds.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <math.h>
+#include <float.h>
+#include <assert.h>
+#include <setjmp.h>
+#include <stdarg.h>
+
+#ifdef _MSC_VER
+#pragma warning ( disable : 4996 )
+#endif
+
+#ifndef _MSC_VER
+#include <stdint.h>
+#else
+typedef unsigned __int8 uint8_t;
+typedef unsigned __int16 uint16_t;
+typedef unsigned __int32 uint32_t;
+typedef signed __int8 int8_t;
+typedef signed __int16 int16_t;
+typedef signed __int32 int32_t;
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#define LIB3DS_EPSILON (1e-5)
+#define LIB3DS_PI 3.14159265358979323846
+#define LIB3DS_TWOPI (2.0*LIB3DS_PI)
+#define LIB3DS_HALFPI (LIB3DS_PI/2.0)
+#define LIB3DS_RAD_TO_DEG(x) ((180.0/LIB3DS_PI)*(x))
+#define LIB3DS_DEG_TO_RAD(x) ((LIB3DS_PI/180.0)*(x))
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum Lib3dsChunks {
+  CHK_NULL_CHUNK             =0x0000,
+  CHK_M3DMAGIC               =0x4D4D,    /*3DS file*/
+  CHK_SMAGIC                 =0x2D2D,    
+  CHK_LMAGIC                 =0x2D3D,    
+  CHK_MLIBMAGIC              =0x3DAA,    /*MLI file*/
+  CHK_MATMAGIC               =0x3DFF,    
+  CHK_CMAGIC                 =0xC23D,    /*PRJ file*/
+  CHK_M3D_VERSION            =0x0002,
+  CHK_M3D_KFVERSION          =0x0005,
+
+  CHK_COLOR_F                =0x0010,
+  CHK_COLOR_24               =0x0011,
+  CHK_LIN_COLOR_24           =0x0012,
+  CHK_LIN_COLOR_F            =0x0013,
+  CHK_INT_PERCENTAGE         =0x0030,
+  CHK_FLOAT_PERCENTAGE       =0x0031,
+
+  CHK_MDATA                  =0x3D3D,
+  CHK_MESH_VERSION           =0x3D3E,
+  CHK_MASTER_SCALE           =0x0100,
+  CHK_LO_SHADOW_BIAS         =0x1400,
+  CHK_HI_SHADOW_BIAS         =0x1410,
+  CHK_SHADOW_MAP_SIZE        =0x1420,
+  CHK_SHADOW_SAMPLES         =0x1430,
+  CHK_SHADOW_RANGE           =0x1440,
+  CHK_SHADOW_FILTER          =0x1450,
+  CHK_RAY_BIAS               =0x1460,
+  CHK_O_CONSTS               =0x1500,
+  CHK_AMBIENT_LIGHT          =0x2100,
+  CHK_BIT_MAP                =0x1100,
+  CHK_SOLID_BGND             =0x1200,
+  CHK_V_GRADIENT             =0x1300,
+  CHK_USE_BIT_MAP            =0x1101,
+  CHK_USE_SOLID_BGND         =0x1201,
+  CHK_USE_V_GRADIENT         =0x1301,
+  CHK_FOG                    =0x2200,
+  CHK_FOG_BGND               =0x2210,
+  CHK_LAYER_FOG              =0x2302,
+  CHK_DISTANCE_CUE           =0x2300,
+  CHK_DCUE_BGND              =0x2310,
+  CHK_USE_FOG                =0x2201,
+  CHK_USE_LAYER_FOG          =0x2303,
+  CHK_USE_DISTANCE_CUE       =0x2301,
+
+  CHK_MAT_ENTRY              =0xAFFF,
+  CHK_MAT_NAME               =0xA000,
+  CHK_MAT_AMBIENT            =0xA010,
+  CHK_MAT_DIFFUSE            =0xA020,
+  CHK_MAT_SPECULAR           =0xA030,
+  CHK_MAT_SHININESS          =0xA040,
+  CHK_MAT_SHIN2PCT           =0xA041,
+  CHK_MAT_TRANSPARENCY       =0xA050,
+  CHK_MAT_XPFALL             =0xA052,
+  CHK_MAT_USE_XPFALL         =0xA240,
+  CHK_MAT_REFBLUR            =0xA053,
+  CHK_MAT_SHADING            =0xA100,
+  CHK_MAT_USE_REFBLUR        =0xA250,
+  CHK_MAT_SELF_ILLUM         =0xA080,
+  CHK_MAT_TWO_SIDE           =0xA081,
+  CHK_MAT_DECAL              =0xA082,
+  CHK_MAT_ADDITIVE           =0xA083,
+  CHK_MAT_SELF_ILPCT         =0xA084,
+  CHK_MAT_WIRE               =0xA085,
+  CHK_MAT_FACEMAP            =0xA088,
+  CHK_MAT_PHONGSOFT          =0xA08C,
+  CHK_MAT_WIREABS            =0xA08E,
+  CHK_MAT_WIRE_SIZE          =0xA087,
+  CHK_MAT_TEXMAP             =0xA200,
+  CHK_MAT_SXP_TEXT_DATA      =0xA320,
+  CHK_MAT_TEXMASK            =0xA33E,
+  CHK_MAT_SXP_TEXTMASK_DATA  =0xA32A,
+  CHK_MAT_TEX2MAP            =0xA33A,
+  CHK_MAT_SXP_TEXT2_DATA     =0xA321,
+  CHK_MAT_TEX2MASK           =0xA340,
+  CHK_MAT_SXP_TEXT2MASK_DATA =0xA32C,
+  CHK_MAT_OPACMAP            =0xA210,
+  CHK_MAT_SXP_OPAC_DATA      =0xA322,
+  CHK_MAT_OPACMASK           =0xA342,
+  CHK_MAT_SXP_OPACMASK_DATA  =0xA32E,
+  CHK_MAT_BUMPMAP            =0xA230,
+  CHK_MAT_SXP_BUMP_DATA      =0xA324,
+  CHK_MAT_BUMPMASK           =0xA344,
+  CHK_MAT_SXP_BUMPMASK_DATA  =0xA330,
+  CHK_MAT_SPECMAP            =0xA204,
+  CHK_MAT_SXP_SPEC_DATA      =0xA325,
+  CHK_MAT_SPECMASK           =0xA348,
+  CHK_MAT_SXP_SPECMASK_DATA  =0xA332,
+  CHK_MAT_SHINMAP            =0xA33C,
+  CHK_MAT_SXP_SHIN_DATA      =0xA326,
+  CHK_MAT_SHINMASK           =0xA346,
+  CHK_MAT_SXP_SHINMASK_DATA  =0xA334,
+  CHK_MAT_SELFIMAP           =0xA33D,
+  CHK_MAT_SXP_SELFI_DATA     =0xA328,
+  CHK_MAT_SELFIMASK          =0xA34A,
+  CHK_MAT_SXP_SELFIMASK_DATA =0xA336,
+  CHK_MAT_REFLMAP            =0xA220,
+  CHK_MAT_REFLMASK           =0xA34C,
+  CHK_MAT_SXP_REFLMASK_DATA  =0xA338,
+  CHK_MAT_ACUBIC             =0xA310,
+  CHK_MAT_MAPNAME            =0xA300,
+  CHK_MAT_MAP_TILING         =0xA351,
+  CHK_MAT_MAP_TEXBLUR        =0xA353,
+  CHK_MAT_MAP_USCALE         =0xA354,
+  CHK_MAT_MAP_VSCALE         =0xA356,
+  CHK_MAT_MAP_UOFFSET        =0xA358,
+  CHK_MAT_MAP_VOFFSET        =0xA35A,
+  CHK_MAT_MAP_ANG            =0xA35C,
+  CHK_MAT_MAP_COL1           =0xA360,
+  CHK_MAT_MAP_COL2           =0xA362,
+  CHK_MAT_MAP_RCOL           =0xA364,
+  CHK_MAT_MAP_GCOL           =0xA366,
+  CHK_MAT_MAP_BCOL           =0xA368,
+
+  CHK_NAMED_OBJECT           =0x4000,
+  CHK_N_DIRECT_LIGHT         =0x4600,
+  CHK_DL_OFF                 =0x4620,
+  CHK_DL_OUTER_RANGE         =0x465A,
+  CHK_DL_INNER_RANGE         =0x4659,
+  CHK_DL_MULTIPLIER          =0x465B,
+  CHK_DL_EXCLUDE             =0x4654,
+  CHK_DL_ATTENUATE           =0x4625,
+  CHK_DL_SPOTLIGHT           =0x4610,
+  CHK_DL_SPOT_ROLL           =0x4656,
+  CHK_DL_SHADOWED            =0x4630,
+  CHK_DL_LOCAL_SHADOW2       =0x4641,
+  CHK_DL_SEE_CONE            =0x4650,
+  CHK_DL_SPOT_RECTANGULAR    =0x4651,
+  CHK_DL_SPOT_ASPECT         =0x4657,
+  CHK_DL_SPOT_PROJECTOR      =0x4653,
+  CHK_DL_SPOT_OVERSHOOT      =0x4652,
+  CHK_DL_RAY_BIAS            =0x4658,
+  CHK_DL_RAYSHAD             =0x4627,
+  CHK_N_CAMERA               =0x4700,
+  CHK_CAM_SEE_CONE           =0x4710,
+  CHK_CAM_RANGES             =0x4720,
+  CHK_OBJ_HIDDEN             =0x4010,
+  CHK_OBJ_VIS_LOFTER         =0x4011,
+  CHK_OBJ_DOESNT_CAST        =0x4012,
+  CHK_OBJ_DONT_RCVSHADOW     =0x4017,
+  CHK_OBJ_MATTE              =0x4013,
+  CHK_OBJ_FAST               =0x4014,
+  CHK_OBJ_PROCEDURAL         =0x4015,
+  CHK_OBJ_FROZEN             =0x4016,
+  CHK_N_TRI_OBJECT           =0x4100,
+  CHK_POINT_ARRAY            =0x4110,
+  CHK_POINT_FLAG_ARRAY       =0x4111,
+  CHK_FACE_ARRAY             =0x4120,
+  CHK_MSH_MAT_GROUP          =0x4130,
+  CHK_SMOOTH_GROUP           =0x4150,
+  CHK_MSH_BOXMAP             =0x4190,
+  CHK_TEX_VERTS              =0x4140,
+  CHK_MESH_MATRIX            =0x4160,
+  CHK_MESH_COLOR             =0x4165,
+  CHK_MESH_TEXTURE_INFO      =0x4170,
+
+  CHK_KFDATA                 =0xB000,
+  CHK_KFHDR                  =0xB00A,
+  CHK_KFSEG                  =0xB008,
+  CHK_KFCURTIME              =0xB009,
+  CHK_AMBIENT_NODE_TAG       =0xB001,
+  CHK_OBJECT_NODE_TAG        =0xB002,
+  CHK_CAMERA_NODE_TAG        =0xB003,
+  CHK_TARGET_NODE_TAG        =0xB004,
+  CHK_LIGHT_NODE_TAG         =0xB005,
+  CHK_L_TARGET_NODE_TAG      =0xB006,
+  CHK_SPOTLIGHT_NODE_TAG     =0xB007,
+  CHK_NODE_ID                =0xB030,
+  CHK_NODE_HDR               =0xB010,
+  CHK_PIVOT                  =0xB013,
+  CHK_INSTANCE_NAME          =0xB011,
+  CHK_MORPH_SMOOTH           =0xB015,
+  CHK_BOUNDBOX               =0xB014,
+  CHK_POS_TRACK_TAG          =0xB020,
+  CHK_COL_TRACK_TAG          =0xB025,
+  CHK_ROT_TRACK_TAG          =0xB021,
+  CHK_SCL_TRACK_TAG          =0xB022,
+  CHK_MORPH_TRACK_TAG        =0xB026,
+  CHK_FOV_TRACK_TAG          =0xB023,
+  CHK_ROLL_TRACK_TAG         =0xB024,
+  CHK_HOT_TRACK_TAG          =0xB027,
+  CHK_FALL_TRACK_TAG         =0xB028,
+  CHK_HIDE_TRACK_TAG         =0xB029,
+
+  CHK_POLY_2D                = 0x5000,
+  CHK_SHAPE_OK               = 0x5010,
+  CHK_SHAPE_NOT_OK           = 0x5011,
+  CHK_SHAPE_HOOK             = 0x5020,
+  CHK_PATH_3D                = 0x6000,
+  CHK_PATH_MATRIX            = 0x6005,
+  CHK_SHAPE_2D               = 0x6010,
+  CHK_M_SCALE                = 0x6020,
+  CHK_M_TWIST                = 0x6030,
+  CHK_M_TEETER               = 0x6040,
+  CHK_M_FIT                  = 0x6050,
+  CHK_M_BEVEL                = 0x6060,
+  CHK_XZ_CURVE               = 0x6070,
+  CHK_YZ_CURVE               = 0x6080,
+  CHK_INTERPCT               = 0x6090,
+  CHK_DEFORM_LIMIT           = 0x60A0,
+
+  CHK_USE_CONTOUR            = 0x6100,
+  CHK_USE_TWEEN              = 0x6110,
+  CHK_USE_SCALE              = 0x6120,
+  CHK_USE_TWIST              = 0x6130,
+  CHK_USE_TEETER             = 0x6140,
+  CHK_USE_FIT                = 0x6150,
+  CHK_USE_BEVEL              = 0x6160,
+
+  CHK_DEFAULT_VIEW           = 0x3000,
+  CHK_VIEW_TOP               = 0x3010,
+  CHK_VIEW_BOTTOM            = 0x3020,
+  CHK_VIEW_LEFT              = 0x3030,
+  CHK_VIEW_RIGHT             = 0x3040,
+  CHK_VIEW_FRONT             = 0x3050,
+  CHK_VIEW_BACK              = 0x3060,
+  CHK_VIEW_USER              = 0x3070,
+  CHK_VIEW_CAMERA            = 0x3080,
+  CHK_VIEW_WINDOW            = 0x3090,
+
+  CHK_VIEWPORT_LAYOUT_OLD    = 0x7000,
+  CHK_VIEWPORT_DATA_OLD      = 0x7010,
+  CHK_VIEWPORT_LAYOUT        = 0x7001,
+  CHK_VIEWPORT_DATA          = 0x7011,
+  CHK_VIEWPORT_DATA_3        = 0x7012,
+  CHK_VIEWPORT_SIZE          = 0x7020,
+  CHK_NETWORK_VIEW           = 0x7030
+} Lib3dsChunks;
+
+typedef struct Lib3dsChunk {
+    uint16_t chunk;
+    uint32_t size;
+    uint32_t end;
+    uint32_t cur;
+} Lib3dsChunk; 
+
+extern void lib3ds_chunk_read(Lib3dsChunk *c, Lib3dsIo *io);
+extern void lib3ds_chunk_read_start(Lib3dsChunk *c, uint16_t chunk, Lib3dsIo *io);
+extern void lib3ds_chunk_read_tell(Lib3dsChunk *c, Lib3dsIo *io);
+extern uint16_t lib3ds_chunk_read_next(Lib3dsChunk *c, Lib3dsIo *io);
+extern void lib3ds_chunk_read_reset(Lib3dsChunk *c, Lib3dsIo *io);
+extern void lib3ds_chunk_read_end(Lib3dsChunk *c, Lib3dsIo *io);
+extern void lib3ds_chunk_write(Lib3dsChunk *c, Lib3dsIo *io);
+extern void lib3ds_chunk_write_start(Lib3dsChunk *c, Lib3dsIo *io);
+extern void lib3ds_chunk_write_end(Lib3dsChunk *c, Lib3dsIo *io);
+extern const char* lib3ds_chunk_name(uint16_t chunk);
+extern void lib3ds_chunk_unknown(uint16_t chunk, Lib3dsIo *io);
+
+typedef struct Lib3dsIoImpl {
+    jmp_buf jmpbuf;
+    int log_indent;
+    void *tmp_mem;
+    Lib3dsNode *tmp_node;
+} Lib3dsIoImpl;
+
+extern void lib3ds_io_setup(Lib3dsIo *io);
+extern void lib3ds_io_cleanup(Lib3dsIo *io);
+
+extern long lib3ds_io_seek(Lib3dsIo *io, long offset, Lib3dsIoSeek origin);
+extern long lib3ds_io_tell(Lib3dsIo *io);
+extern size_t lib3ds_io_read(Lib3dsIo *io, void *buffer, size_t size);
+extern size_t lib3ds_io_write(Lib3dsIo *io, const void *buffer, size_t size);
+extern void lib3ds_io_log(Lib3dsIo *io, Lib3dsLogLevel level, const char *format, ...);
+extern void lib3ds_io_log_indent(Lib3dsIo *io, int indent);
+extern void lib3ds_io_read_error(Lib3dsIo *io);
+extern void lib3ds_io_write_error(Lib3dsIo *io);
+
+extern uint8_t lib3ds_io_read_byte(Lib3dsIo *io);
+extern uint16_t lib3ds_io_read_word(Lib3dsIo *io);
+extern uint32_t lib3ds_io_read_dword(Lib3dsIo *io);
+extern int8_t lib3ds_io_read_intb(Lib3dsIo *io);
+extern int16_t lib3ds_io_read_intw(Lib3dsIo *io);
+extern int32_t lib3ds_io_read_intd(Lib3dsIo *io);
+extern float lib3ds_io_read_float(Lib3dsIo *io);
+extern void lib3ds_io_read_vector(Lib3dsIo *io, float v[3]);
+extern void lib3ds_io_read_rgb(Lib3dsIo *io, float rgb[3]);
+extern void lib3ds_io_read_string(Lib3dsIo *io, char *s, int buflen);
+
+extern void lib3ds_io_write_byte(Lib3dsIo *io, uint8_t b);
+extern void lib3ds_io_write_word(Lib3dsIo *io, uint16_t w);
+extern void lib3ds_io_write_dword(Lib3dsIo *io, uint32_t d);
+extern void lib3ds_io_write_intb(Lib3dsIo *io, int8_t b);
+extern void lib3ds_io_write_intw(Lib3dsIo *io, int16_t w);
+extern void lib3ds_io_write_intd(Lib3dsIo *io, int32_t d);
+extern void lib3ds_io_write_float(Lib3dsIo *io, float l);
+extern void lib3ds_io_write_vector(Lib3dsIo *io, float v[3]);
+extern void lib3ds_io_write_rgb(Lib3dsIo *io, float rgb[3]);
+extern void lib3ds_io_write_string(Lib3dsIo *io, const char *s);
+
+extern void lib3ds_atmosphere_read(Lib3dsAtmosphere *atmosphere, Lib3dsIo *io);
+extern void lib3ds_atmosphere_write(Lib3dsAtmosphere *atmosphere, Lib3dsIo *io);
+extern void lib3ds_background_read(Lib3dsBackground *background, Lib3dsIo *io);
+extern void lib3ds_background_write(Lib3dsBackground *background, Lib3dsIo *io);
+extern void lib3ds_shadow_read(Lib3dsShadow *shadow, Lib3dsIo *io);
+extern void lib3ds_shadow_write(Lib3dsShadow *shadow, Lib3dsIo *io);
+extern void lib3ds_viewport_read(Lib3dsViewport *viewport, Lib3dsIo *io);
+extern void lib3ds_viewport_write(Lib3dsViewport *viewport, Lib3dsIo *io);
+extern void lib3ds_material_read(Lib3dsMaterial *material, Lib3dsIo *io);
+extern void lib3ds_material_write(Lib3dsMaterial *material, Lib3dsIo *io);
+extern void lib3ds_camera_read(Lib3dsCamera *camera, Lib3dsIo *io);
+extern void lib3ds_camera_write(Lib3dsCamera *camera, Lib3dsIo *io);
+extern void lib3ds_light_read(Lib3dsLight *light, Lib3dsIo *io);
+extern void lib3ds_light_write(Lib3dsLight *light, Lib3dsIo *io);
+extern void lib3ds_mesh_read(Lib3dsFile *file, Lib3dsMesh *mesh, Lib3dsIo *io);
+extern void lib3ds_mesh_write(Lib3dsFile *file, Lib3dsMesh *mesh, Lib3dsIo *io);
+extern void lib3ds_track_read(Lib3dsTrack *track, Lib3dsIo *io);
+extern void lib3ds_track_write(Lib3dsTrack *track, Lib3dsIo *io);
+extern void lib3ds_node_read(Lib3dsNode *node, Lib3dsIo *io);
+extern void lib3ds_node_write(Lib3dsNode *node, uint16_t node_id, uint16_t parent_id, Lib3dsIo *io);
+
+typedef void (*Lib3dsFreeFunc)(void *ptr);
+
+extern void* lib3ds_util_realloc_array(void *ptr, int old_size, int new_size, int element_size);
+extern void lib3ds_util_reserve_array(void ***ptr, int *n, int *size, int new_size, int force, Lib3dsFreeFunc free_func);
+extern void lib3ds_util_insert_array(void ***ptr, int *n, int *size, void *element, int index);
+extern void lib3ds_util_remove_array(void ***ptr, int *n, int index, Lib3dsFreeFunc free_func);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+
Index: /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_atmosphere.c
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_atmosphere.c (revision 10853)
+++ /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_atmosphere.c (revision 10853)
@@ -0,0 +1,253 @@
+/*
+    Copyright (C) 1996-2008 by Jan Eric Kyprianidis <www.kyprianidis.com>
+    All rights reserved.
+    
+    This program is free  software: you can redistribute it and/or modify 
+    it under the terms of the GNU Lesser General Public License as published 
+    by the Free Software Foundation, either version 2.1 of the License, or 
+    (at your option) any later version.
+
+    Thisprogram  is  distributed in the hope that it will be useful, 
+    but WITHOUT ANY WARRANTY; without even the implied warranty of 
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
+    GNU Lesser General Public License for more details.
+    
+    You should  have received a copy of the GNU Lesser General Public License
+    along with  this program; If not, see <http://www.gnu.org/licenses/>. 
+*/
+#include "lib3ds_impl.h"
+
+
+static void
+fog_read(Lib3dsAtmosphere *at, Lib3dsIo *io) {
+    Lib3dsChunk c;
+    uint16_t chunk;
+
+    lib3ds_chunk_read_start(&c, CHK_FOG, io);
+
+    at->fog_near_plane = lib3ds_io_read_float(io);
+    at->fog_near_density = lib3ds_io_read_float(io);
+    at->fog_far_plane = lib3ds_io_read_float(io);
+    at->fog_far_density = lib3ds_io_read_float(io);
+    lib3ds_chunk_read_tell(&c, io);
+
+    while ((chunk = lib3ds_chunk_read_next(&c, io)) != 0) {
+        switch (chunk) {
+            case CHK_LIN_COLOR_F: {
+                int i;
+                for (i = 0; i < 3; ++i) {
+                    at->fog_color[i] = lib3ds_io_read_float(io);
+                }
+            }
+            break;
+
+            case CHK_COLOR_F:
+                break;
+
+            case CHK_FOG_BGND: {
+                at->fog_background = TRUE;
+            }
+            break;
+
+            default:
+                lib3ds_chunk_unknown(chunk, io);
+        }
+    }
+
+    lib3ds_chunk_read_end(&c, io);
+}
+
+
+static void
+layer_fog_read(Lib3dsAtmosphere *at, Lib3dsIo *io) {
+    Lib3dsChunk c;
+    uint16_t chunk;
+    int have_lin = FALSE;
+
+    lib3ds_chunk_read_start(&c, CHK_LAYER_FOG, io);
+
+    at->layer_fog_near_y = lib3ds_io_read_float(io);
+    at->layer_fog_far_y = lib3ds_io_read_float(io);
+    at->layer_fog_density = lib3ds_io_read_float(io);
+    at->layer_fog_flags = lib3ds_io_read_dword(io);
+    lib3ds_chunk_read_tell(&c, io);
+
+    while ((chunk = lib3ds_chunk_read_next(&c, io)) != 0) {
+        switch (chunk) {
+            case CHK_LIN_COLOR_F:
+                lib3ds_io_read_rgb(io, at->layer_fog_color);
+                have_lin = TRUE;
+                break;
+
+            case CHK_COLOR_F:
+                lib3ds_io_read_rgb(io, at->layer_fog_color);
+                break;
+
+            default:
+                lib3ds_chunk_unknown(chunk, io);
+        }
+    }
+
+    lib3ds_chunk_read_end(&c, io);
+}
+
+
+static void
+distance_cue_read(Lib3dsAtmosphere *at, Lib3dsIo *io) {
+    Lib3dsChunk c;
+    uint16_t chunk;
+
+    lib3ds_chunk_read_start(&c, CHK_DISTANCE_CUE, io);
+
+    at->dist_cue_near_plane = lib3ds_io_read_float(io);
+    at->dist_cue_near_dimming = lib3ds_io_read_float(io);
+    at->dist_cue_far_plane = lib3ds_io_read_float(io);
+    at->dist_cue_far_dimming = lib3ds_io_read_float(io);
+    lib3ds_chunk_read_tell(&c, io);
+
+    while ((chunk = lib3ds_chunk_read_next(&c, io)) != 0) {
+        switch (chunk) {
+            case CHK_DCUE_BGND: {
+                at->dist_cue_background = TRUE;
+            }
+            break;
+
+            default:
+                lib3ds_chunk_unknown(chunk, io);
+        }
+    }
+
+    lib3ds_chunk_read_end(&c, io);
+}
+
+
+void
+lib3ds_atmosphere_read(Lib3dsAtmosphere *atmosphere, Lib3dsIo *io) {
+    Lib3dsChunk c;
+
+    lib3ds_chunk_read(&c, io);
+    switch (c.chunk) {
+        case CHK_FOG: {
+            lib3ds_chunk_read_reset(&c, io);
+            fog_read(atmosphere, io);
+            break;
+        }
+
+        case CHK_LAYER_FOG: {
+            lib3ds_chunk_read_reset(&c, io);
+            layer_fog_read(atmosphere, io);
+            break;
+        }
+
+        case CHK_DISTANCE_CUE: {
+            lib3ds_chunk_read_reset(&c, io);
+            distance_cue_read(atmosphere, io);
+            break;
+        }
+
+        case CHK_USE_FOG: {
+            atmosphere->use_fog = TRUE;
+            break;
+        }
+
+        case CHK_USE_LAYER_FOG: {
+            atmosphere->use_layer_fog = TRUE;
+            break;
+        }
+
+        case CHK_USE_DISTANCE_CUE: {
+            atmosphere->use_dist_cue = TRUE;
+            break;
+        }
+    }
+}
+
+
+void
+lib3ds_atmosphere_write(Lib3dsAtmosphere *atmosphere, Lib3dsIo *io) {
+    if (atmosphere->use_fog) { /*---- LIB3DS_FOG ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_FOG;
+        lib3ds_chunk_write_start(&c, io);
+
+        lib3ds_io_write_float(io, atmosphere->fog_near_plane);
+        lib3ds_io_write_float(io, atmosphere->fog_near_density);
+        lib3ds_io_write_float(io, atmosphere->fog_far_plane);
+        lib3ds_io_write_float(io, atmosphere->fog_far_density);
+        {
+            Lib3dsChunk c;
+            c.chunk = CHK_COLOR_F;
+            c.size = 18;
+            lib3ds_chunk_write(&c, io);
+            lib3ds_io_write_rgb(io, atmosphere->fog_color);
+        }
+        if (atmosphere->fog_background) {
+            Lib3dsChunk c;
+            c.chunk = CHK_FOG_BGND;
+            c.size = 6;
+            lib3ds_chunk_write(&c, io);
+        }
+
+        lib3ds_chunk_write_end(&c, io);
+    }
+
+    if (atmosphere->use_layer_fog) { /*---- LIB3DS_LAYER_FOG ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_LAYER_FOG;
+        c.size = 40;
+        lib3ds_chunk_write(&c, io);
+        lib3ds_io_write_float(io, atmosphere->layer_fog_near_y);
+        lib3ds_io_write_float(io, atmosphere->layer_fog_far_y);
+        lib3ds_io_write_float(io, atmosphere->layer_fog_near_y);
+        lib3ds_io_write_dword(io, atmosphere->layer_fog_flags);
+        {
+            Lib3dsChunk c;
+            c.chunk = CHK_COLOR_F;
+            c.size = 18;
+            lib3ds_chunk_write(&c, io);
+            lib3ds_io_write_rgb(io, atmosphere->fog_color);
+        }
+    }
+
+    if (atmosphere->use_dist_cue) { /*---- LIB3DS_DISTANCE_CUE ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_DISTANCE_CUE;
+        lib3ds_chunk_write_start(&c, io);
+
+        lib3ds_io_write_float(io, atmosphere->dist_cue_near_plane);
+        lib3ds_io_write_float(io, atmosphere->dist_cue_near_dimming);
+        lib3ds_io_write_float(io, atmosphere->dist_cue_far_plane);
+        lib3ds_io_write_float(io, atmosphere->dist_cue_far_dimming);
+        if (atmosphere->dist_cue_background) {
+            Lib3dsChunk c;
+            c.chunk = CHK_DCUE_BGND;
+            c.size = 6;
+            lib3ds_chunk_write(&c, io);
+        }
+
+        lib3ds_chunk_write_end(&c, io);
+    }
+
+    if (atmosphere->use_fog) { /*---- LIB3DS_USE_FOG ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_USE_FOG;
+        c.size = 6;
+        lib3ds_chunk_write(&c, io);
+    }
+
+    if (atmosphere->use_layer_fog) { /*---- LIB3DS_USE_LAYER_FOG ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_USE_LAYER_FOG;
+        c.size = 6;
+        lib3ds_chunk_write(&c, io);
+    }
+
+    if (atmosphere->use_dist_cue) { /*---- LIB3DS_USE_DISTANCE_CUE ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_USE_V_GRADIENT;
+        c.size = 6;
+        lib3ds_chunk_write(&c, io);
+    }
+}
+
+
Index: /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_io.c
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_io.c (revision 10853)
+++ /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_io.c (revision 10853)
@@ -0,0 +1,521 @@
+/*
+    Copyright (C) 1996-2008 by Jan Eric Kyprianidis <www.kyprianidis.com>
+    All rights reserved.
+    
+    This program is free  software: you can redistribute it and/or modify 
+    it under the terms of the GNU Lesser General Public License as published 
+    by the Free Software Foundation, either version 2.1 of the License, or 
+    (at your option) any later version.
+
+    Thisprogram  is  distributed in the hope that it will be useful, 
+    but WITHOUT ANY WARRANTY; without even the implied warranty of 
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
+    GNU Lesser General Public License for more details.
+    
+    You should  have received a copy of the GNU Lesser General Public License
+    along with  this program; If not, see <http://www.gnu.org/licenses/>. 
+*/
+#include "lib3ds_impl.h"
+
+/* --- Code for OpenSceneGraph --- */
+#include "lib3ds.h"		// For setByteOrder()
+#include <osg/Endian>
+
+static bool s_requiresByteSwap = false;
+extern LIB3DSAPI void setByteOrder()
+{
+    s_requiresByteSwap = osg::getCpuByteOrder()==osg::BigEndian;
+}
+/* --- (end) Code for OpenSceneGraph --- */
+
+typedef union {
+    uint32_t dword_value;
+    float float_value;
+} Lib3dsDwordFloat;
+
+
+void
+lib3ds_io_setup(Lib3dsIo *io) {
+    assert(io);
+    io->impl = calloc(sizeof(Lib3dsIoImpl), 1);
+}
+
+
+void
+lib3ds_io_cleanup(Lib3dsIo *io) {
+    Lib3dsIoImpl *impl;
+    assert(io);
+    impl = (Lib3dsIoImpl*)io->impl;
+    if (impl->tmp_mem) {
+        free(impl->tmp_mem);
+        impl->tmp_mem = NULL;
+    }
+    if (impl->tmp_node) {
+        lib3ds_node_free(impl->tmp_node);
+        impl->tmp_node = NULL;
+    }
+    free(impl);
+}
+
+
+long
+lib3ds_io_seek(Lib3dsIo *io, long offset, Lib3dsIoSeek origin) {
+    assert(io);
+    if (!io || !io->seek_func) {
+        return 0;
+    }
+    return (*io->seek_func)(io->self, offset, origin);
+}
+
+
+long
+lib3ds_io_tell(Lib3dsIo *io) {
+    assert(io);
+    if (!io || !io->tell_func) {
+        return 0;
+    }
+    return (*io->tell_func)(io->self);
+}
+
+
+size_t
+lib3ds_io_read(Lib3dsIo *io, void *buffer, size_t size) {
+    assert(io);
+    if (!io || !io->read_func) {
+        return 0;
+    }
+    return (*io->read_func)(io->self, buffer, size);
+}
+
+
+size_t
+lib3ds_io_write(Lib3dsIo *io, const void *buffer, size_t size) {
+    assert(io);
+    if (!io || !io->write_func) {
+        return 0;
+    }
+    return (*io->write_func)(io->self, buffer, size);
+}
+
+
+static void 
+lib3ds_io_log_str(Lib3dsIo *io, Lib3dsLogLevel level, const char *str) {
+    if (!io || !io->log_func)
+        return;
+    (*io->log_func)(io->self, level, ((Lib3dsIoImpl*)io->impl)->log_indent, str);
+}
+
+
+void 
+lib3ds_io_log(Lib3dsIo *io, Lib3dsLogLevel level, const char *format, ...) {
+    va_list args;
+    /* FIXME */ char str[1024];
+
+    assert(io);
+    if (!io || !io->log_func)
+        return;
+
+    va_start(args, format);
+    /* FIXME: */ vsprintf(str, format, args); 
+    lib3ds_io_log_str(io, level, str);
+
+    if (level == LIB3DS_LOG_ERROR) {
+        longjmp(((Lib3dsIoImpl*)io->impl)->jmpbuf, 1);
+    }
+}
+
+
+void 
+lib3ds_io_log_indent(Lib3dsIo *io, int indent) {
+    assert(io);
+    if (!io)
+        return;
+    ((Lib3dsIoImpl*)io->impl)->log_indent += indent;
+}
+
+
+void 
+lib3ds_io_read_error(Lib3dsIo *io) {
+    lib3ds_io_log(io, LIB3DS_LOG_ERROR, "Reading from input stream failed.");
+}
+
+
+void 
+lib3ds_io_write_error(Lib3dsIo *io) {
+    lib3ds_io_log(io, LIB3DS_LOG_ERROR, "Writing to output stream failed.");
+}
+
+
+/*!
+ * Read a byte from a file stream.
+ */
+uint8_t
+lib3ds_io_read_byte(Lib3dsIo *io) {
+    uint8_t b;
+
+    assert(io);
+    lib3ds_io_read(io, &b, 1);
+    return(b);
+}
+
+
+/**
+ * Read a word from a file stream in little endian format.
+ */
+uint16_t
+lib3ds_io_read_word(Lib3dsIo *io) {
+    uint8_t b[2];
+    uint16_t w;
+
+    assert(io);
+    lib3ds_io_read(io, b, 2);
+    w = ((uint16_t)b[1] << 8) |
+        ((uint16_t)b[0]);
+	/* --- Code for OpenSceneGraph --- */
+    if (s_requiresByteSwap)
+    {
+        osg::swapBytes2((char*)w);
+    }
+	/* --- (end) Code for OpenSceneGraph --- */
+	return(w);
+}
+
+
+/*!
+ * Read a dword from file a stream in little endian format.
+ */
+uint32_t
+lib3ds_io_read_dword(Lib3dsIo *io) {
+    uint8_t b[4];
+    uint32_t d;
+
+    assert(io);
+    lib3ds_io_read(io, b, 4);
+    d = ((uint32_t)b[3] << 24) |
+        ((uint32_t)b[2] << 16) |
+        ((uint32_t)b[1] << 8) |
+        ((uint32_t)b[0]);
+	/* --- Code for OpenSceneGraph --- */
+    if (s_requiresByteSwap)
+    {
+        osg::swapBytes4((char*)d);
+    }
+	/* --- (end) Code for OpenSceneGraph --- */
+    return(d);
+}
+
+
+/*!
+ * Read a signed byte from a file stream.
+ */
+int8_t
+lib3ds_io_read_intb(Lib3dsIo *io) {
+    int8_t b;
+
+    assert(io);
+    lib3ds_io_read(io, &b, 1);
+    return(b);
+}
+
+
+/*!
+ * Read a signed word from a file stream in little endian format.
+ */
+int16_t
+lib3ds_io_read_intw(Lib3dsIo *io) {
+    uint8_t b[2];
+    uint16_t w;
+
+    assert(io);
+    lib3ds_io_read(io, b, 2);
+    w = ((uint16_t)b[1] << 8) |
+        ((uint16_t)b[0]);
+	/* --- Code for OpenSceneGraph --- */
+    if (s_requiresByteSwap)
+    {
+        osg::swapBytes2((char*)w);
+    }
+	/* --- (end) Code for OpenSceneGraph --- */
+	return((int16_t)w);
+}
+
+
+/*!
+ * Read a signed dword a from file stream in little endian format.
+ */
+int32_t
+lib3ds_io_read_intd(Lib3dsIo *io) {
+    uint8_t b[4];
+    uint32_t d;
+
+    assert(io);
+    lib3ds_io_read(io, b, 4);
+    d = ((uint32_t)b[3] << 24) |
+        ((uint32_t)b[2] << 16) |
+        ((uint32_t)b[1] << 8) |
+        ((uint32_t)b[0]);
+	/* --- Code for OpenSceneGraph --- */
+    if (s_requiresByteSwap)
+    {
+        osg::swapBytes4((char*)d);
+    }
+	/* --- (end) Code for OpenSceneGraph --- */
+    return((int32_t)d);
+}
+
+
+/*!
+ * Read a float from a file stream in little endian format.
+ */
+float
+lib3ds_io_read_float(Lib3dsIo *io) {
+    uint8_t b[4];
+    Lib3dsDwordFloat d;
+
+    assert(io);
+    lib3ds_io_read(io, b, 4);
+    d.dword_value = ((uint32_t)b[3] << 24) |
+                    ((uint32_t)b[2] << 16) |
+                    ((uint32_t)b[1] << 8) |
+                    ((uint32_t)b[0]);
+	/* --- Code for OpenSceneGraph --- */
+    if (s_requiresByteSwap)
+    {
+		osg::swapBytes4((char*)d.dword_value);
+    }
+	/* --- (end) Code for OpenSceneGraph --- */
+	return d.float_value;
+}
+
+
+/*!
+ * Read a vector from a file stream in little endian format.
+ *
+ * \param io IO input handle.
+ * \param v  The vector to store the data.
+ */
+void
+lib3ds_io_read_vector(Lib3dsIo *io, float v[3]) {
+    assert(io);
+    v[0] = lib3ds_io_read_float(io);
+    v[1] = lib3ds_io_read_float(io);
+    v[2] = lib3ds_io_read_float(io);
+}
+
+
+void
+lib3ds_io_read_rgb(Lib3dsIo *io, float rgb[3]) {
+    assert(io);
+    rgb[0] = lib3ds_io_read_float(io);
+    rgb[1] = lib3ds_io_read_float(io);
+    rgb[2] = lib3ds_io_read_float(io);
+}
+
+
+/*!
+ * Read a zero-terminated string from a file stream.
+ *
+ * \param io      IO input handle.
+ * \param s       The buffer to store the read string.
+ * \param buflen  Buffer length.
+ *
+ * \return        True on success, False otherwise.
+ */
+void
+lib3ds_io_read_string(Lib3dsIo *io, char *s, int buflen) {
+    char c;
+    int k = 0;
+
+    assert(io);
+    for (;;) {
+        if (lib3ds_io_read(io, &c, 1) != 1) {
+            lib3ds_io_read_error(io);
+        }
+        *s++ = c;
+        if (!c) {
+            break;
+        }
+        ++k;
+        if (k >= buflen) {
+            lib3ds_io_log(io, LIB3DS_LOG_ERROR, "Invalid string in input stream.");
+        }
+    }
+}
+
+
+/*!
+ * Writes a byte into a file stream.
+ */
+void
+lib3ds_io_write_byte(Lib3dsIo *io, uint8_t b) {
+    assert(io);
+    if (lib3ds_io_write(io, &b, 1) != 1) {
+        lib3ds_io_write_error(io);
+    }
+}
+
+
+/*!
+ * Writes a word into a little endian file stream.
+ */
+void
+lib3ds_io_write_word(Lib3dsIo *io, uint16_t w) {
+	/* --- Code for OpenSceneGraph --- */
+    if (s_requiresByteSwap)
+    {
+		osg::swapBytes2((char*)w);
+    }
+	/* --- (end) Code for OpenSceneGraph --- */
+
+	uint8_t b[2];
+
+    assert(io);
+    b[1] = ((uint16_t)w & 0xFF00) >> 8;
+    b[0] = ((uint16_t)w & 0x00FF);
+    if (lib3ds_io_write(io, b, 2) != 2) {
+        lib3ds_io_write_error(io);
+    }
+}
+
+
+/*!
+ * Writes a dword into a little endian file stream.
+ */
+void
+lib3ds_io_write_dword(Lib3dsIo *io, uint32_t d) {
+	/* --- Code for OpenSceneGraph --- */
+    if (s_requiresByteSwap)
+    {
+        osg::swapBytes4((char*)d);
+    }
+	/* --- (end) Code for OpenSceneGraph --- */
+    uint8_t b[4];
+
+    assert(io);
+    b[3] = (uint8_t)(((uint32_t)d & 0xFF000000) >> 24);
+    b[2] = (uint8_t)(((uint32_t)d & 0x00FF0000) >> 16);
+    b[1] = (uint8_t)(((uint32_t)d & 0x0000FF00) >> 8);
+    b[0] = (uint8_t)(((uint32_t)d & 0x000000FF));
+    if (lib3ds_io_write(io, b, 4) != 4) {
+        lib3ds_io_write_error(io);
+    }
+}
+
+
+/*!
+ * Writes a signed byte in a file stream.
+ */
+void
+lib3ds_io_write_intb(Lib3dsIo *io, int8_t b) {
+    assert(io);
+    if (lib3ds_io_write(io, &b, 1) != 1) {
+        lib3ds_io_write_error(io);
+    }
+}
+
+
+/*!
+ * Writes a signed word into a little endian file stream.
+ */
+void
+lib3ds_io_write_intw(Lib3dsIo *io, int16_t w) {
+	/* --- Code for OpenSceneGraph --- */
+    if (s_requiresByteSwap)
+    {
+        osg::swapBytes2((char*)w);
+    }
+	/* --- (end) Code for OpenSceneGraph --- */
+    uint8_t b[2];
+
+    assert(io);
+    b[1] = ((uint16_t)w & 0xFF00) >> 8;
+    b[0] = ((uint16_t)w & 0x00FF);
+    if (lib3ds_io_write(io, b, 2) != 2) {
+        lib3ds_io_write_error(io);
+    }
+}
+
+
+/*!
+ * Writes a signed dword into a little endian file stream.
+ */
+void
+lib3ds_io_write_intd(Lib3dsIo *io, int32_t d) {
+	/* --- Code for OpenSceneGraph --- */
+    if (s_requiresByteSwap)
+    {
+        osg::swapBytes4((char*)d);
+    }
+	/* --- (end) Code for OpenSceneGraph --- */
+    uint8_t b[4];
+
+    assert(io);
+    b[3] = (uint8_t)(((uint32_t)d & 0xFF000000) >> 24);
+    b[2] = (uint8_t)(((uint32_t)d & 0x00FF0000) >> 16);
+    b[1] = (uint8_t)(((uint32_t)d & 0x0000FF00) >> 8);
+    b[0] = (uint8_t)(((uint32_t)d & 0x000000FF));
+    if (lib3ds_io_write(io, b, 4) != 4) {
+        lib3ds_io_write_error(io);
+    }
+}
+
+
+/*!
+ * Writes a float into a little endian file stream.
+ */
+void
+lib3ds_io_write_float(Lib3dsIo *io, float l) {
+	uint8_t b[4];
+    Lib3dsDwordFloat d;
+
+    assert(io);
+    d.float_value = l;
+	/* --- Code for OpenSceneGraph --- */
+    if (s_requiresByteSwap)
+    {
+		osg::swapBytes4((char*)d.dword_value);
+    }
+	/* --- (end) Code for OpenSceneGraph --- */
+    b[3] = (uint8_t)(((uint32_t)d.dword_value & 0xFF000000) >> 24);
+    b[2] = (uint8_t)(((uint32_t)d.dword_value & 0x00FF0000) >> 16);
+    b[1] = (uint8_t)(((uint32_t)d.dword_value & 0x0000FF00) >> 8);
+    b[0] = (uint8_t)(((uint32_t)d.dword_value & 0x000000FF));
+    if (lib3ds_io_write(io, b, 4) != 4) {
+        lib3ds_io_write_error(io);
+    }
+}
+
+
+/*!
+ * Writes a vector into a file stream in little endian format.
+ */
+void
+lib3ds_io_write_vector(Lib3dsIo *io, float v[3]) {
+    int i;
+    for (i = 0; i < 3; ++i) {
+        lib3ds_io_write_float(io, v[i]);
+    }
+}
+
+
+void
+lib3ds_io_write_rgb(Lib3dsIo *io, float rgb[3]) {
+    int i;
+    for (i = 0; i < 3; ++i) {
+        lib3ds_io_write_float(io, rgb[i]);
+    }
+}
+
+
+/*!
+ * Writes a zero-terminated string into a file stream.
+ */
+void
+lib3ds_io_write_string(Lib3dsIo *io, const char *s) {
+    size_t len;
+    assert(io && s);
+    len = strlen(s);
+    if (lib3ds_io_write(io, s, len + 1) != len +1) {
+        lib3ds_io_write_error(io);
+    }
+}
Index: /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_light.c
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_light.c (revision 10853)
+++ /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_light.c (revision 10853)
@@ -0,0 +1,323 @@
+/*
+    Copyright (C) 1996-2008 by Jan Eric Kyprianidis <www.kyprianidis.com>
+    All rights reserved.
+    
+    This program is free  software: you can redistribute it and/or modify 
+    it under the terms of the GNU Lesser General Public License as published 
+    by the Free Software Foundation, either version 2.1 of the License, or 
+    (at your option) any later version.
+
+    Thisprogram  is  distributed in the hope that it will be useful, 
+    but WITHOUT ANY WARRANTY; without even the implied warranty of 
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
+    GNU Lesser General Public License for more details.
+    
+    You should  have received a copy of the GNU Lesser General Public License
+    along with  this program; If not, see <http://www.gnu.org/licenses/>. 
+*/
+#include "lib3ds_impl.h"
+
+
+Lib3dsLight*
+lib3ds_light_new(const char *name) {
+    Lib3dsLight *light;
+
+    assert(name);
+    assert(strlen(name) < 64);
+
+    light = (Lib3dsLight*)calloc(sizeof(Lib3dsLight), 1);
+    if (!light) {
+        return(0);
+    }
+    strcpy(light->name, name);
+    return(light);
+}
+
+
+void
+lib3ds_light_free(Lib3dsLight *light) {
+    memset(light, 0, sizeof(Lib3dsLight));
+    free(light);
+}
+
+
+static void
+spotlight_read(Lib3dsLight *light, Lib3dsIo *io) {
+    Lib3dsChunk c;
+    uint16_t chunk;
+    int i;
+
+    lib3ds_chunk_read_start(&c, CHK_DL_SPOTLIGHT, io);
+
+    light->spot_light = TRUE;
+    for (i = 0; i < 3; ++i) {
+        light->target[i] = lib3ds_io_read_float(io);
+    }
+    light->hotspot = lib3ds_io_read_float(io);
+    light->falloff = lib3ds_io_read_float(io);
+    lib3ds_chunk_read_tell(&c, io);
+
+    while ((chunk = lib3ds_chunk_read_next(&c, io)) != 0) {
+        switch (chunk) {
+            case CHK_DL_SPOT_ROLL: 
+                light->roll = lib3ds_io_read_float(io);
+                break;
+
+            case CHK_DL_SHADOWED: {
+                light->shadowed = TRUE;
+                break;
+            }
+
+            case CHK_DL_LOCAL_SHADOW2: {
+                light->shadow_bias = lib3ds_io_read_float(io);
+                light->shadow_filter = lib3ds_io_read_float(io);
+                light->shadow_size = lib3ds_io_read_intw(io);
+                break;
+            }
+
+            case CHK_DL_SEE_CONE: {
+                light->see_cone = TRUE;
+                break;
+            }
+
+            case CHK_DL_SPOT_RECTANGULAR: {
+                light->rectangular_spot = TRUE;
+                break;
+            }
+
+            case CHK_DL_SPOT_ASPECT: {
+                light->spot_aspect = lib3ds_io_read_float(io);
+                break;
+            }
+
+            case CHK_DL_SPOT_PROJECTOR: {
+                light->use_projector = TRUE;
+                lib3ds_io_read_string(io, light->projector, 64);
+                break;
+            }
+
+            case CHK_DL_SPOT_OVERSHOOT: {
+                light->spot_overshoot = TRUE;
+                break;
+            }
+
+            case CHK_DL_RAY_BIAS: {
+                light->ray_bias = lib3ds_io_read_float(io);
+                break;
+            }
+
+            case CHK_DL_RAYSHAD: {
+                light->ray_shadows = TRUE;
+                break;
+            }
+
+            default:
+                lib3ds_chunk_unknown(chunk, io);
+        }
+    }
+
+    lib3ds_chunk_read_end(&c, io);
+}
+
+
+void
+lib3ds_light_read(Lib3dsLight *light, Lib3dsIo *io) {
+    Lib3dsChunk c;
+    uint16_t chunk;
+
+    lib3ds_chunk_read_start(&c, CHK_N_DIRECT_LIGHT, io);
+
+    {
+        int i;
+        for (i = 0; i < 3; ++i) {
+            light->position[i] = lib3ds_io_read_float(io);
+        }
+    }
+    lib3ds_chunk_read_tell(&c, io);
+
+    while ((chunk = lib3ds_chunk_read_next(&c, io)) != 0) {
+        switch (chunk) {
+            case CHK_COLOR_F: {
+                int i;
+                for (i = 0; i < 3; ++i) {
+                    light->color[i] = lib3ds_io_read_float(io);
+                }
+                break;
+            }
+
+            case CHK_DL_OFF: 
+                light->off = TRUE;
+                break;
+
+            case CHK_DL_OUTER_RANGE: 
+                light->outer_range = lib3ds_io_read_float(io);
+                break;
+
+            case CHK_DL_INNER_RANGE: 
+                light->inner_range = lib3ds_io_read_float(io);
+                break;
+
+            case CHK_DL_MULTIPLIER: 
+                light->multiplier = lib3ds_io_read_float(io);
+                break;
+
+            case CHK_DL_EXCLUDE: {
+                /* FIXME: */
+                lib3ds_chunk_unknown(chunk, io);
+                break;
+            }
+
+            case CHK_DL_ATTENUATE: 
+                light->attenuation = lib3ds_io_read_float(io);
+                break;
+
+            case CHK_DL_SPOTLIGHT: {
+                lib3ds_chunk_read_reset(&c, io);
+                spotlight_read(light, io);
+                break;
+            }
+
+            default:
+                lib3ds_chunk_unknown(chunk, io);
+        }
+    }
+
+    lib3ds_chunk_read_end(&c, io);
+}
+
+
+void
+lib3ds_light_write(Lib3dsLight *light, Lib3dsIo *io) {
+    Lib3dsChunk c;
+
+    c.chunk = CHK_N_DIRECT_LIGHT;
+    lib3ds_chunk_write_start(&c, io);
+
+    lib3ds_io_write_vector(io, light->position);
+    { /*---- LIB3DS_COLOR_F ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_COLOR_F;
+        c.size = 18;
+        lib3ds_chunk_write(&c, io);
+        lib3ds_io_write_rgb(io, light->color);
+    }
+    if (light->off) { /*---- LIB3DS_DL_OFF ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_DL_OFF;
+        c.size = 6;
+        lib3ds_chunk_write(&c, io);
+    }
+    { /*---- LIB3DS_DL_OUTER_RANGE ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_DL_OUTER_RANGE;
+        c.size = 10;
+        lib3ds_chunk_write(&c, io);
+        lib3ds_io_write_float(io, light->outer_range);
+    }
+    { /*---- LIB3DS_DL_INNER_RANGE ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_DL_INNER_RANGE;
+        c.size = 10;
+        lib3ds_chunk_write(&c, io);
+        lib3ds_io_write_float(io, light->inner_range);
+    }
+    { /*---- LIB3DS_DL_MULTIPLIER ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_DL_MULTIPLIER;
+        c.size = 10;
+        lib3ds_chunk_write(&c, io);
+        lib3ds_io_write_float(io, light->multiplier);
+    }
+    if (light->attenuation) { /*---- LIB3DS_DL_ATTENUATE ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_DL_ATTENUATE;
+        c.size = 6;
+        lib3ds_chunk_write(&c, io);
+    }
+
+    if (light->spot_light) {
+        Lib3dsChunk c;
+
+        c.chunk = CHK_DL_SPOTLIGHT;
+        lib3ds_chunk_write_start(&c, io);
+
+        lib3ds_io_write_vector(io, light->target);
+        lib3ds_io_write_float(io, light->hotspot);
+        lib3ds_io_write_float(io, light->falloff);
+
+        { /*---- LIB3DS_DL_SPOT_ROLL ----*/
+            Lib3dsChunk c;
+            c.chunk = CHK_DL_SPOT_ROLL;
+            c.size = 10;
+            lib3ds_chunk_write(&c, io);
+            lib3ds_io_write_float(io, light->roll);
+        }
+        if (light->shadowed) { /*---- LIB3DS_DL_SHADOWED ----*/
+            Lib3dsChunk c;
+            c.chunk = CHK_DL_SHADOWED;
+            c.size = 6;
+            lib3ds_chunk_write(&c, io);
+        }
+        if ((fabs(light->shadow_bias) > LIB3DS_EPSILON) ||
+            (fabs(light->shadow_filter) > LIB3DS_EPSILON) ||
+            (light->shadow_size != 0)) { /*---- LIB3DS_DL_LOCAL_SHADOW2 ----*/
+            Lib3dsChunk c;
+            c.chunk = CHK_DL_LOCAL_SHADOW2;
+            c.size = 16;
+            lib3ds_chunk_write(&c, io);
+            lib3ds_io_write_float(io, light->shadow_bias);
+            lib3ds_io_write_float(io, light->shadow_filter);
+            lib3ds_io_write_intw(io, (int16_t)light->shadow_size);
+        }
+        if (light->see_cone) { /*---- LIB3DS_DL_SEE_CONE ----*/
+            Lib3dsChunk c;
+            c.chunk = CHK_DL_SEE_CONE;
+            c.size = 6;
+            lib3ds_chunk_write(&c, io);
+        }
+        if (light->rectangular_spot) { /*---- LIB3DS_DL_SPOT_RECTANGULAR ----*/
+            Lib3dsChunk c;
+            c.chunk = CHK_DL_SPOT_RECTANGULAR;
+            c.size = 6;
+            lib3ds_chunk_write(&c, io);
+        }
+        if (fabs(light->spot_aspect) > LIB3DS_EPSILON) { /*---- LIB3DS_DL_SPOT_ASPECT ----*/
+            Lib3dsChunk c;
+            c.chunk = CHK_DL_SPOT_ASPECT;
+            c.size = 10;
+            lib3ds_chunk_write(&c, io);
+            lib3ds_io_write_float(io, light->spot_aspect);
+        }
+        if (light->use_projector) { /*---- LIB3DS_DL_SPOT_PROJECTOR ----*/
+            Lib3dsChunk c;
+            c.chunk = CHK_DL_SPOT_PROJECTOR;
+            c.size = 10;
+            lib3ds_chunk_write(&c, io);
+            lib3ds_io_write_string(io, light->projector);
+        }
+        if (light->spot_overshoot) { /*---- LIB3DS_DL_SPOT_OVERSHOOT ----*/
+            Lib3dsChunk c;
+            c.chunk = CHK_DL_SPOT_OVERSHOOT;
+            c.size = 6;
+            lib3ds_chunk_write(&c, io);
+        }
+        if (fabs(light->ray_bias) > LIB3DS_EPSILON) { /*---- LIB3DS_DL_RAY_BIAS ----*/
+            Lib3dsChunk c;
+            c.chunk = CHK_DL_RAY_BIAS;
+            c.size = 10;
+            lib3ds_chunk_write(&c, io);
+            lib3ds_io_write_float(io, light->ray_bias);
+        }
+        if (light->ray_shadows) { /*---- LIB3DS_DL_RAYSHAD ----*/
+            Lib3dsChunk c;
+            c.chunk = CHK_DL_RAYSHAD;
+            c.size = 6;
+            lib3ds_chunk_write(&c, io);
+        }
+        lib3ds_chunk_write_end(&c, io);
+    }
+
+    lib3ds_chunk_write_end(&c, io);
+}
+
+
Index: /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_chunk.c
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_chunk.c (revision 10853)
+++ /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_chunk.c (revision 10853)
@@ -0,0 +1,146 @@
+/*
+    Copyright (C) 1996-2008 by Jan Eric Kyprianidis <www.kyprianidis.com>
+    All rights reserved.
+    
+    This program is free  software: you can redistribute it and/or modify 
+    it under the terms of the GNU Lesser General Public License as published 
+    by the Free Software Foundation, either version 2.1 of the License, or 
+    (at your option) any later version.
+
+    Thisprogram  is  distributed in the hope that it will be useful, 
+    but WITHOUT ANY WARRANTY; without even the implied warranty of 
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
+    GNU Lesser General Public License for more details.
+    
+    You should  have received a copy of the GNU Lesser General Public License
+    along with  this program; If not, see <http://www.gnu.org/licenses/>. 
+*/
+#include "lib3ds_impl.h"
+
+
+/*#define LIB3DS_CHUNK_DEBUG*/
+/*#define LIB3DS_CHUNK_WARNING*/
+
+
+/*!
+ * Reads a 3d-Studio chunk header from a little endian file stream.
+ *
+ * \param c  The chunk to store the data.
+ * \param io The file stream.
+ *
+ * \return   True on success, False otherwise.
+ */
+void
+lib3ds_chunk_read(Lib3dsChunk *c, Lib3dsIo *io) {
+    assert(c);
+    assert(io);
+    c->cur = lib3ds_io_tell(io);
+    c->chunk = lib3ds_io_read_word(io);
+    c->size = lib3ds_io_read_dword(io);
+    c->end = c->cur + c->size;
+    c->cur += 6;
+    if (c->size < 6) {
+        lib3ds_io_log(io, LIB3DS_LOG_ERROR, "Invalid chunk header.");
+    }
+
+}
+
+
+void
+lib3ds_chunk_read_start(Lib3dsChunk *c, uint16_t chunk, Lib3dsIo *io) {
+    assert(c);
+    assert(io);
+    lib3ds_chunk_read(c, io);
+    if ((chunk != 0) && (c->chunk != chunk)) {
+        lib3ds_io_log(io, LIB3DS_LOG_ERROR, "Unexpected chunk found.");
+    }
+    ((Lib3dsIoImpl*)io->impl)->log_indent++;
+}
+
+
+void
+lib3ds_chunk_read_tell(Lib3dsChunk *c, Lib3dsIo *io) {
+    c->cur = lib3ds_io_tell(io);
+}
+
+
+uint16_t
+lib3ds_chunk_read_next(Lib3dsChunk *c, Lib3dsIo *io) {
+    Lib3dsChunk d;
+
+    if (c->cur >= c->end) {
+        assert(c->cur == c->end);
+        return 0;
+    }
+
+    lib3ds_io_seek(io, (long)c->cur, LIB3DS_SEEK_SET);
+    d.chunk = lib3ds_io_read_word(io);
+    d.size = lib3ds_io_read_dword(io);
+    c->cur += d.size;
+
+    if (io->log_func) {
+        lib3ds_io_log(io, LIB3DS_LOG_INFO, "%s (0x%X) size=%lu", lib3ds_chunk_name(d.chunk), d.chunk, d.size);
+    }
+
+    return d.chunk;
+}
+
+
+void
+lib3ds_chunk_read_reset(Lib3dsChunk *c, Lib3dsIo *io) {
+    lib3ds_io_seek(io, -6, LIB3DS_SEEK_CUR);
+}
+
+
+void
+lib3ds_chunk_read_end(Lib3dsChunk *c, Lib3dsIo *io) {
+    ((Lib3dsIoImpl*)io->impl)->log_indent--;
+    lib3ds_io_seek(io, c->end, LIB3DS_SEEK_SET);
+}
+
+
+/*!
+ * Writes a 3d-Studio chunk header into a little endian file stream.
+ *
+ * \param c  The chunk to be written.
+ * \param io The file stream.
+ *
+ * \return   True on success, False otherwise.
+ */
+void
+lib3ds_chunk_write(Lib3dsChunk *c, Lib3dsIo *io) {
+    assert(c);
+    lib3ds_io_write_word(io, c->chunk);
+    lib3ds_io_write_dword(io, c->size);
+}
+
+
+void
+lib3ds_chunk_write_start(Lib3dsChunk *c, Lib3dsIo *io) {
+    assert(c);
+    c->size = 0;
+    c->cur = lib3ds_io_tell(io);
+    lib3ds_io_write_word(io, c->chunk);
+    lib3ds_io_write_dword(io, c->size);
+}
+
+
+void
+lib3ds_chunk_write_end(Lib3dsChunk *c, Lib3dsIo *io) {
+    assert(c);
+    c->size = lib3ds_io_tell(io) - c->cur;
+    lib3ds_io_seek(io, c->cur + 2, LIB3DS_SEEK_SET);
+    lib3ds_io_write_dword(io, c->size);
+    c->cur += c->size;
+    lib3ds_io_seek(io, c->cur, LIB3DS_SEEK_SET);
+}
+
+
+void
+lib3ds_chunk_unknown(uint16_t chunk, Lib3dsIo *io) {
+    if (io->log_func) {
+        lib3ds_io_log(io, LIB3DS_LOG_WARN, "Unknown Chunk: %s (0x%X)", lib3ds_chunk_name(chunk), chunk);
+    }
+}
+
+
Index: /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_quat.c
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_quat.c (revision 10853)
+++ /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_quat.c (revision 10853)
@@ -0,0 +1,294 @@
+/*
+    Copyright (C) 1996-2008 by Jan Eric Kyprianidis <www.kyprianidis.com>
+    All rights reserved.
+    
+    This program is free  software: you can redistribute it and/or modify 
+    it under the terms of the GNU Lesser General Public License as published 
+    by the Free Software Foundation, either version 2.1 of the License, or 
+    (at your option) any later version.
+
+    Thisprogram  is  distributed in the hope that it will be useful, 
+    but WITHOUT ANY WARRANTY; without even the implied warranty of 
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
+    GNU Lesser General Public License for more details.
+    
+    You should  have received a copy of the GNU Lesser General Public License
+    along with  this program; If not, see <http://www.gnu.org/licenses/>. 
+*/
+#include "lib3ds_impl.h"
+
+
+/*!
+ * Set a quaternion to Identity
+ */
+void
+lib3ds_quat_identity(float c[4]) {
+    c[0] = c[1] = c[2] = 0.0f;
+    c[3] = 1.0f;
+}
+
+
+/*!
+ * Copy a quaternion.
+ */
+void
+lib3ds_quat_copy(float dest[4], float src[4]) {
+    int i;
+    for (i = 0; i < 4; ++i) {
+        dest[i] = src[i];
+    }
+}
+
+
+/*!
+ * Compute a quaternion from axis and angle.
+ *
+ * \param c Computed quaternion
+ * \param axis Rotation axis
+ * \param angle Angle of rotation, radians.
+ */
+void
+lib3ds_quat_axis_angle(float c[4], float axis[3], float angle) {
+    double omega, s;
+    double l;
+
+    l = sqrt(axis[0] * axis[0] + axis[1] * axis[1] + axis[2] * axis[2]);
+    if (l < LIB3DS_EPSILON) {
+        c[0] = c[1] = c[2] = 0.0f;
+        c[3] = 1.0f;
+    } else {
+        omega = -0.5 * angle;
+        s = sin(omega) / l;
+        c[0] = (float)s * axis[0];
+        c[1] = (float)s * axis[1];
+        c[2] = (float)s * axis[2];
+        c[3] = (float)cos(omega);
+    }
+}
+
+
+/*!
+ * Negate a quaternion
+ */
+void
+lib3ds_quat_neg(float c[4]) {
+    int i;
+    for (i = 0; i < 4; ++i) {
+        c[i] = -c[i];
+    }
+}
+
+
+/*!
+ * Compute the conjugate of a quaternion
+ */
+void
+lib3ds_quat_cnj(float c[4]) {
+    int i;
+    for (i = 0; i < 3; ++i) {
+        c[i] = -c[i];
+    }
+}
+
+
+/*!
+ * Multiply two quaternions.
+ *
+ * \param c Result
+ * \param a,b Inputs
+ */
+void
+lib3ds_quat_mul(float c[4], float a[4], float b[4]) {
+    float qa[4], qb[4];
+    lib3ds_quat_copy(qa, a);
+    lib3ds_quat_copy(qb, b);
+    c[0] = qa[3] * qb[0] + qa[0] * qb[3] + qa[1] * qb[2] - qa[2] * qb[1];
+    c[1] = qa[3] * qb[1] + qa[1] * qb[3] + qa[2] * qb[0] - qa[0] * qb[2];
+    c[2] = qa[3] * qb[2] + qa[2] * qb[3] + qa[0] * qb[1] - qa[1] * qb[0];
+    c[3] = qa[3] * qb[3] - qa[0] * qb[0] - qa[1] * qb[1] - qa[2] * qb[2];
+}
+
+
+/*!
+ * Multiply a quaternion by a scalar.
+ */
+void
+lib3ds_quat_scalar(float c[4], float k) {
+    int i;
+    for (i = 0; i < 4; ++i) {
+        c[i] *= k;
+    }
+}
+
+
+/*!
+ * Normalize a quaternion.
+ */
+void
+lib3ds_quat_normalize(float c[4]) {
+    double l, m;
+
+    l = sqrt(c[0] * c[0] + c[1] * c[1] + c[2] * c[2] + c[3] * c[3]);
+    if (fabs(l) < LIB3DS_EPSILON) {
+        c[0] = c[1] = c[2] = 0.0f;
+        c[3] = 1.0f;
+    } else {
+        int i;
+        m = 1.0f / l;
+        for (i = 0; i < 4; ++i) {
+            c[i] = (float)(c[i] * m);
+        }
+    }
+}
+
+
+/*!
+ * Compute the inverse of a quaternion.
+ */
+void
+lib3ds_quat_inv(float c[4]) {
+    double l, m;
+
+    l = sqrt(c[0] * c[0] + c[1] * c[1] + c[2] * c[2] + c[3] * c[3]);
+    if (fabs(l) < LIB3DS_EPSILON) {
+        c[0] = c[1] = c[2] = 0.0f;
+        c[3] = 1.0f;
+    } else {
+        m = 1.0f / l;
+        c[0] = (float)(-c[0] * m);
+        c[1] = (float)(-c[1] * m);
+        c[2] = (float)(-c[2] * m);
+        c[3] = (float)(c[3] * m);
+    }
+}
+
+
+/*!
+ * Compute the dot-product of a quaternion.
+ */
+float
+lib3ds_quat_dot(float a[4], float b[4]) {
+    return(a[0]*b[0] + a[1]*b[1] + a[2]*b[2] + a[3]*b[3]);
+}
+
+
+float
+lib3ds_quat_norm(float c[4]) {
+    return(c[0]*c[0] + c[1]*c[1] + c[2]*c[2] + c[3]*c[3]);
+}
+
+
+void
+lib3ds_quat_ln(float c[4]) {
+    double om, s, t;
+
+    s = sqrt(c[0] * c[0] + c[1] * c[1] + c[2] * c[2]);
+    om = atan2(s, (double)c[3]);
+    if (fabs(s) < LIB3DS_EPSILON) {
+        t = 0.0f;
+    } else {
+        t = om / s;
+    }
+    {
+        int i;
+        for (i = 0; i < 3; ++i) {
+            c[i] = (float)(c[i] * t);
+        }
+        c[3] = 0.0f;
+    }
+}
+
+
+void
+lib3ds_quat_ln_dif(float c[4], float a[4], float b[4]) {
+    float invp[4];
+
+    lib3ds_quat_copy(invp, a);
+    lib3ds_quat_inv(invp);
+    lib3ds_quat_mul(c, invp, b);
+    lib3ds_quat_ln(c);
+}
+
+
+void
+lib3ds_quat_exp(float c[4]) {
+    double om, sinom;
+
+    om = sqrt(c[0] * c[0] + c[1] * c[1] + c[2] * c[2]);
+    if (fabs(om) < LIB3DS_EPSILON) {
+        sinom = 1.0f;
+    } else {
+        sinom = sin(om) / om;
+    }
+    {
+        int i;
+        for (i = 0; i < 3; ++i) {
+            c[i] = (float)(c[i] * sinom);
+        }
+        c[3] = (float)cos(om);
+    }
+}
+
+
+void
+lib3ds_quat_slerp(float c[4], float a[4], float b[4], float t) {
+    double l;
+    double om, sinom;
+    double sp, sq;
+    float flip = 1.0f;
+    int i;
+
+    l = a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3];
+    if (l < 0) { 
+        flip = -1.0f;
+        l = -l; 
+    }    
+    
+    om = acos(l);
+    sinom = sin(om);
+    if (fabs(sinom) > LIB3DS_EPSILON) {
+        sp = sin((1.0f - t) * om) / sinom;
+        sq = sin(t * om) / sinom;
+    } else {
+        sp = 1.0f - t;
+        sq = t;
+    }
+    sq *= flip;
+    for (i = 0; i < 4; ++i) {
+        c[i] = (float)(sp * a[i] + sq * b[i]);
+    }
+}
+
+
+void
+lib3ds_quat_squad(float c[4], float a[4], float p[4], float q[4], float b[4], float t) {
+    float ab[4];
+    float pq[4];
+
+    lib3ds_quat_slerp(ab, a, b, t);
+    lib3ds_quat_slerp(pq, p, q, t);
+    lib3ds_quat_slerp(c, ab, pq, 2*t*(1 - t));
+}
+
+
+void
+lib3ds_quat_tangent(float c[4], float p[4], float q[4], float n[4]) {
+    float dn[4], dp[4], x[4];
+    int i;
+
+    lib3ds_quat_ln_dif(dn, q, n);
+    lib3ds_quat_ln_dif(dp, q, p);
+
+    for (i = 0; i < 4; i++) {
+        x[i] = -1.0f / 4.0f * (dn[i] + dp[i]);
+    }
+    lib3ds_quat_exp(x);
+    lib3ds_quat_mul(c, q, x);
+}
+
+
+void
+lib3ds_quat_dump(float q[4]) {
+    printf("%f %f %f %f\n", q[0], q[1], q[2], q[3]);
+}
+
Index: /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/README
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/README (revision 10853)
+++ /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/README (revision 10853)
@@ -0,0 +1,17 @@
+This is a modified subset of lib3DS (v2.0.0-rc1 - 20080909).
+The original lib can be found at www.lib3ds.org.
+The modifications are for compatibility only (fixes for compilation).
+
+Here is the original README:
+-----
+
+Lib3ds is a free toolkit for handling the "3DS" format for 3D model files.  
+Its main goal is to simplify the creation of 3DS import and export filters. 
+ 
+This  program  is  distributed in  the  hope that it will  be useful,  but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+The official Lib3ds Homepage can be found at: www.lib3ds.org
+
Index: /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_util.c
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_util.c (revision 10853)
+++ /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_util.c (revision 10853)
@@ -0,0 +1,89 @@
+/*
+    Copyright (C) 1996-2008 by Jan Eric Kyprianidis <www.kyprianidis.com>
+    All rights reserved.
+    
+    This program is free  software: you can redistribute it and/or modify 
+    it under the terms of the GNU Lesser General Public License as published 
+    by the Free Software Foundation, either version 2.1 of the License, or 
+    (at your option) any later version.
+
+    Thisprogram  is  distributed in the hope that it will be useful, 
+    but WITHOUT ANY WARRANTY; without even the implied warranty of 
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
+    GNU Lesser General Public License for more details.
+    
+    You should  have received a copy of the GNU Lesser General Public License
+    along with  this program; If not, see <http://www.gnu.org/licenses/>. 
+*/
+#include "lib3ds_impl.h"
+
+
+void* lib3ds_util_realloc_array(void *ptr, int old_size, int new_size, int element_size) {
+    if (!ptr)
+        old_size = 0;
+    if (old_size != new_size) {
+        ptr = realloc(ptr, element_size * new_size);
+        if (old_size < new_size) {
+            memset((char*)ptr + element_size * old_size, 0, element_size * (new_size - old_size));
+        }
+    }
+    return ptr;
+}
+
+
+void lib3ds_util_reserve_array(void ***ptr, int *n, int *size, int new_size, int force, Lib3dsFreeFunc free_func) {
+    assert(ptr && n && size);
+    if ((*size < new_size) || force) {
+        if (force && free_func) {
+            int i;
+            for (i = new_size; i < *n; ++i) {
+                free_func((*ptr)[i]);
+                (*ptr)[i] = 0;
+            }
+        }
+        *ptr = (void**)realloc(*ptr, sizeof(void*) * new_size);
+        *size = new_size;
+        if (*n > new_size) {
+            *n = new_size;
+        }
+    }
+}
+
+
+void lib3ds_util_insert_array(void ***ptr, int *n, int *size, void *element, int index) {
+    int i;
+    assert(ptr && n && size && element);
+    i = ((index >= 0) && (index < *n)) ? index : *n;
+    if (i >= *size) {
+        int new_size = 2 * (*size);
+        #ifdef _DEBUG
+            if (new_size < 1) {
+                new_size = 1;
+            }
+        #else
+            if (new_size < 32) {
+                new_size = 32;
+            }
+        #endif
+        lib3ds_util_reserve_array(ptr, n, size, new_size, FALSE, NULL);
+    }
+    assert(*ptr);
+    if (i < *n) {
+        memmove(&(*ptr)[i+1], &(*ptr)[i], sizeof(void*) * (*n - i));
+    }
+    (*ptr)[i] = element;
+    *n = *n + 1;
+}
+
+
+void lib3ds_util_remove_array(void ***ptr, int *n, int index, Lib3dsFreeFunc free_func) {
+    assert(ptr && n);
+    if ((index >= 0) && (index < *n)) {
+        assert(*ptr);
+        free_func((*ptr)[index]);
+        if (index < *n - 1) {
+            memmove(&(*ptr)[index], &(*ptr)[index+1], sizeof(void*) * (*n - index - 1));
+        }
+        *n = *n - 1;
+    }
+}
Index: /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_viewport.c
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_viewport.c (revision 10853)
+++ /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_viewport.c (revision 10853)
@@ -0,0 +1,296 @@
+/*
+    Copyright (C) 1996-2008 by Jan Eric Kyprianidis <www.kyprianidis.com>
+    All rights reserved.
+
+    This program is free  software: you can redistribute it and/or modify 
+    it under the terms of the GNU Lesser General Public License as published 
+    by the Free Software Foundation, either version 2.1 of the License, or 
+    (at your option) any later version.
+
+    Thisprogram  is  distributed in the hope that it will be useful, 
+    but WITHOUT ANY WARRANTY; without even the implied warranty of 
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
+    GNU Lesser General Public License for more details.
+
+    You should  have received a copy of the GNU Lesser General Public License
+    along with  this program; If not, see <http://www.gnu.org/licenses/>. 
+*/
+#include "lib3ds_impl.h"
+
+
+void
+lib3ds_viewport_read(Lib3dsViewport *viewport, Lib3dsIo *io) {
+    Lib3dsChunk c;
+    uint16_t chunk;
+
+    memset(viewport, 0, sizeof(*viewport));
+    lib3ds_chunk_read_start(&c, 0, io);
+    switch (c.chunk) {
+        case CHK_VIEWPORT_LAYOUT: {
+            int cur = 0;
+            viewport->layout_style = lib3ds_io_read_word(io);
+            viewport->layout_active = lib3ds_io_read_intw(io);
+            lib3ds_io_read_intw(io);
+            viewport->layout_swap = lib3ds_io_read_intw(io);
+            lib3ds_io_read_intw(io);
+            viewport->layout_swap_prior = lib3ds_io_read_intw(io);
+            viewport->layout_swap_view = lib3ds_io_read_intw(io);
+            lib3ds_chunk_read_tell(&c, io);
+            while ((chunk = lib3ds_chunk_read_next(&c, io)) != 0) {
+                switch (chunk) {
+                    case CHK_VIEWPORT_SIZE: {
+                        viewport->layout_position[0] = lib3ds_io_read_word(io);
+                        viewport->layout_position[1] = lib3ds_io_read_word(io);
+                        viewport->layout_size[0] = lib3ds_io_read_word(io);
+                        viewport->layout_size[1] = lib3ds_io_read_word(io);
+                        break;
+                    }
+
+                    case CHK_VIEWPORT_DATA_3: {
+                        if (cur < LIB3DS_LAYOUT_MAX_VIEWS) {
+                            lib3ds_io_read_intw(io);
+                            viewport->layout_views[cur].axis_lock = lib3ds_io_read_word(io);
+                            viewport->layout_views[cur].position[0] = lib3ds_io_read_intw(io);
+                            viewport->layout_views[cur].position[1] = lib3ds_io_read_intw(io);
+                            viewport->layout_views[cur].size[0] = lib3ds_io_read_intw(io);
+                            viewport->layout_views[cur].size[1] = lib3ds_io_read_intw(io);
+                            viewport->layout_views[cur].type = lib3ds_io_read_word(io);
+                            viewport->layout_views[cur].zoom = lib3ds_io_read_float(io);
+                            lib3ds_io_read_vector(io, viewport->layout_views[cur].center);
+                            viewport->layout_views[cur].horiz_angle = lib3ds_io_read_float(io);
+                            viewport->layout_views[cur].vert_angle = lib3ds_io_read_float(io);
+                            lib3ds_io_read(io, viewport->layout_views[cur].camera, 11);
+                            ++cur;
+                        }
+                        break;
+                    }
+
+                    case CHK_VIEWPORT_DATA:
+                        /* 3DS R2 & R3 chunk unsupported */
+                        break;
+
+                    default:
+                        lib3ds_chunk_unknown(chunk, io);
+                }
+            }
+            break;
+        }
+
+        case CHK_DEFAULT_VIEW: {
+            while ((chunk = lib3ds_chunk_read_next(&c, io)) != 0) {
+                switch (chunk) {
+                    case CHK_VIEW_TOP: {
+                        viewport->default_type = LIB3DS_VIEW_TOP;
+                        lib3ds_io_read_vector(io, viewport->default_position);
+                        viewport->default_width = lib3ds_io_read_float(io);
+                        break;
+                    }
+
+                    case CHK_VIEW_BOTTOM: {
+                        viewport->default_type = LIB3DS_VIEW_BOTTOM;
+                        lib3ds_io_read_vector(io, viewport->default_position);
+                        viewport->default_width = lib3ds_io_read_float(io);
+                        break;
+                    }
+
+                    case CHK_VIEW_LEFT: {
+                        viewport->default_type = LIB3DS_VIEW_LEFT;
+                        lib3ds_io_read_vector(io, viewport->default_position);
+                        viewport->default_width = lib3ds_io_read_float(io);
+                        break;
+                    }
+
+                    case CHK_VIEW_RIGHT: {
+                        viewport->default_type = LIB3DS_VIEW_RIGHT;
+                        lib3ds_io_read_vector(io, viewport->default_position);
+                        viewport->default_width = lib3ds_io_read_float(io);
+                        break;
+                    }
+
+                    case CHK_VIEW_FRONT: {
+                        viewport->default_type = LIB3DS_VIEW_FRONT;
+                        lib3ds_io_read_vector(io, viewport->default_position);
+                        viewport->default_width = lib3ds_io_read_float(io);
+                        break;
+                    }
+
+                    case CHK_VIEW_BACK: {
+                        viewport->default_type = LIB3DS_VIEW_BACK;
+                        lib3ds_io_read_vector(io, viewport->default_position);
+                        viewport->default_width = lib3ds_io_read_float(io);
+                        break;
+                    }
+
+                    case CHK_VIEW_USER: {
+                        viewport->default_type = LIB3DS_VIEW_USER;
+                        lib3ds_io_read_vector(io, viewport->default_position);
+                        viewport->default_width = lib3ds_io_read_float(io);
+                        viewport->default_horiz_angle = lib3ds_io_read_float(io);
+                        viewport->default_vert_angle = lib3ds_io_read_float(io);
+                        viewport->default_roll_angle = lib3ds_io_read_float(io);
+                        break;
+                    }
+
+                    case CHK_VIEW_CAMERA: {
+                        viewport->default_type = LIB3DS_VIEW_CAMERA;
+                        lib3ds_io_read(io, viewport->default_camera, 11);
+                        break;
+                    }
+
+                    default:
+                        lib3ds_chunk_unknown(chunk, io);
+                }
+            }
+            break;
+        }
+    }
+
+    lib3ds_chunk_read_end(&c, io);
+}
+
+
+void
+lib3ds_viewport_write(Lib3dsViewport *viewport, Lib3dsIo *io) {
+    if (viewport->layout_nviews) {
+        Lib3dsChunk c;
+        int i;
+
+        c.chunk = CHK_VIEWPORT_LAYOUT;
+        lib3ds_chunk_write_start(&c, io);
+
+        lib3ds_io_write_word(io, (uint16_t)viewport->layout_style);
+        lib3ds_io_write_intw(io, (int16_t)viewport->layout_active);
+        lib3ds_io_write_intw(io, (int16_t)0);
+        lib3ds_io_write_intw(io, (int16_t)viewport->layout_swap);
+        lib3ds_io_write_intw(io, (int16_t)0);
+        lib3ds_io_write_intw(io, (int16_t)viewport->layout_swap_prior);
+        lib3ds_io_write_intw(io, (int16_t)viewport->layout_swap_view);
+
+        {
+            Lib3dsChunk c;
+            c.chunk = CHK_VIEWPORT_SIZE;
+            c.size = 14;
+            lib3ds_chunk_write(&c, io);
+            lib3ds_io_write_intw(io, viewport->layout_position[0]);
+            lib3ds_io_write_intw(io, viewport->layout_position[1]);
+            lib3ds_io_write_intw(io, viewport->layout_size[0]);
+            lib3ds_io_write_intw(io, viewport->layout_size[1]);
+        }
+
+        for (i = 0; i < viewport->layout_nviews; ++i) {
+            Lib3dsChunk c;
+            c.chunk = CHK_VIEWPORT_DATA_3;
+            c.size = 55;
+            lib3ds_chunk_write(&c, io);
+
+            lib3ds_io_write_intw(io, 0);
+            lib3ds_io_write_word(io, (uint16_t)viewport->layout_views[i].axis_lock);
+            lib3ds_io_write_intw(io, (int16_t)viewport->layout_views[i].position[0]);
+            lib3ds_io_write_intw(io, (int16_t)viewport->layout_views[i].position[1]);
+            lib3ds_io_write_intw(io, (int16_t)viewport->layout_views[i].size[0]);
+            lib3ds_io_write_intw(io, (int16_t)viewport->layout_views[i].size[1]);
+            lib3ds_io_write_word(io, (int16_t)viewport->layout_views[i].type);
+            lib3ds_io_write_float(io, viewport->layout_views[i].zoom);
+            lib3ds_io_write_vector(io, viewport->layout_views[i].center);
+            lib3ds_io_write_float(io, viewport->layout_views[i].horiz_angle);
+            lib3ds_io_write_float(io, viewport->layout_views[i].vert_angle);
+            lib3ds_io_write(io, viewport->layout_views[i].camera, 11);
+        }
+
+        lib3ds_chunk_write_end(&c, io);
+    }
+
+    if (viewport->default_type) {
+        Lib3dsChunk c;
+
+        c.chunk = CHK_DEFAULT_VIEW;
+        lib3ds_chunk_write_start(&c, io);
+
+        switch (viewport->default_type) {
+            case LIB3DS_VIEW_TOP: {
+                Lib3dsChunk c;
+                c.chunk = CHK_VIEW_TOP;
+                c.size = 22;
+                lib3ds_chunk_write(&c, io);
+                lib3ds_io_write_vector(io, viewport->default_position);
+                lib3ds_io_write_float(io, viewport->default_width);
+                break;
+            }
+
+            case LIB3DS_VIEW_BOTTOM: {
+                Lib3dsChunk c;
+                c.chunk = CHK_VIEW_BOTTOM;
+                c.size = 22;
+                lib3ds_chunk_write(&c, io);
+                lib3ds_io_write_vector(io, viewport->default_position);
+                lib3ds_io_write_float(io, viewport->default_width);
+                break;
+            }
+
+            case LIB3DS_VIEW_LEFT: {
+                Lib3dsChunk c;
+                c.chunk = CHK_VIEW_LEFT;
+                c.size = 22;
+                lib3ds_chunk_write(&c, io);
+                lib3ds_io_write_vector(io, viewport->default_position);
+                lib3ds_io_write_float(io, viewport->default_width);
+                break;
+            }
+
+            case LIB3DS_VIEW_RIGHT: {
+                Lib3dsChunk c;
+                c.chunk = CHK_VIEW_RIGHT;
+                c.size = 22;
+                lib3ds_chunk_write(&c, io);
+                lib3ds_io_write_vector(io, viewport->default_position);
+                lib3ds_io_write_float(io, viewport->default_width);
+                break;
+            }
+
+            case LIB3DS_VIEW_FRONT: {
+                Lib3dsChunk c;
+                c.chunk = CHK_VIEW_FRONT;
+                c.size = 22;
+                lib3ds_chunk_write(&c, io);
+                lib3ds_io_write_vector(io, viewport->default_position);
+                lib3ds_io_write_float(io, viewport->default_width);
+                break;
+            }
+
+            case LIB3DS_VIEW_BACK: {
+                Lib3dsChunk c;
+                c.chunk = CHK_VIEW_BACK;
+                c.size = 22;
+                lib3ds_chunk_write(&c, io);
+                lib3ds_io_write_vector(io, viewport->default_position);
+                lib3ds_io_write_float(io, viewport->default_width);
+                break;
+            }
+
+            case LIB3DS_VIEW_USER: {
+                Lib3dsChunk c;
+                c.chunk = CHK_VIEW_USER;
+                c.size = 34;
+                lib3ds_chunk_write(&c, io);
+                lib3ds_io_write_vector(io, viewport->default_position);
+                lib3ds_io_write_float(io, viewport->default_width);
+                lib3ds_io_write_float(io, viewport->default_horiz_angle);
+                lib3ds_io_write_float(io, viewport->default_vert_angle);
+                lib3ds_io_write_float(io, viewport->default_roll_angle);
+                break;
+            }
+
+            case LIB3DS_VIEW_CAMERA: {
+                Lib3dsChunk c;
+                c.chunk = CHK_VIEW_CAMERA;
+                c.size = 17;
+                lib3ds_chunk_write(&c, io);
+                lib3ds_io_write(io, viewport->default_camera, 11);
+                break;
+            }
+        }
+
+        lib3ds_chunk_write_end(&c, io);
+    }
+}
+
Index: /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_background.c
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_background.c (revision 10853)
+++ /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_background.c (revision 10853)
@@ -0,0 +1,213 @@
+/*
+    Copyright (C) 1996-2008 by Jan Eric Kyprianidis <www.kyprianidis.com>
+    All rights reserved.
+    
+    This program is free  software: you can redistribute it and/or modify 
+    it under the terms of the GNU Lesser General Public License as published 
+    by the Free Software Foundation, either version 2.1 of the License, or 
+    (at your option) any later version.
+
+    Thisprogram  is  distributed in the hope that it will be useful, 
+    but WITHOUT ANY WARRANTY; without even the implied warranty of 
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
+    GNU Lesser General Public License for more details.
+    
+    You should  have received a copy of the GNU Lesser General Public License
+    along with  this program; If not, see <http://www.gnu.org/licenses/>. 
+*/
+#include "lib3ds_impl.h"
+
+
+static void
+solid_bgnd_read(Lib3dsBackground *background, Lib3dsIo *io) {
+    Lib3dsChunk c;
+    uint16_t chunk;
+    int have_lin = FALSE;
+
+    lib3ds_chunk_read_start(&c, CHK_SOLID_BGND, io);
+
+    while ((chunk = lib3ds_chunk_read_next(&c, io)) != 0) {
+        switch (chunk) {
+            case CHK_LIN_COLOR_F:
+                lib3ds_io_read_rgb(io, background->solid_color);
+                have_lin = TRUE;
+                break;
+
+            case CHK_COLOR_F:
+                lib3ds_io_read_rgb(io, background->solid_color);
+                break;
+
+            default:
+                lib3ds_chunk_unknown(chunk, io);
+        }
+    }
+
+    lib3ds_chunk_read_end(&c, io);
+}
+
+
+static void
+v_gradient_read(Lib3dsBackground *background, Lib3dsIo *io) {
+    Lib3dsChunk c;
+    uint16_t chunk;
+    int index[2];
+    float col[2][3][3];
+    int have_lin = 0;
+
+    lib3ds_chunk_read_start(&c, CHK_V_GRADIENT, io);
+
+    background->gradient_percent = lib3ds_io_read_float(io);
+    lib3ds_chunk_read_tell(&c, io);
+
+    index[0] = index[1] = 0;
+    while ((chunk = lib3ds_chunk_read_next(&c, io)) != 0) {
+        switch (chunk) {
+            case CHK_COLOR_F:
+                lib3ds_io_read_rgb(io, col[0][index[0]]);
+                index[0]++;
+                break;
+
+            case CHK_LIN_COLOR_F:
+                lib3ds_io_read_rgb(io, col[1][index[1]]);
+                index[1]++;
+                have_lin = 1;
+                break;
+
+            default:
+                lib3ds_chunk_unknown(chunk, io);
+        }
+    }
+    {
+        int i;
+        for (i = 0; i < 3; ++i) {
+            background->gradient_top[i] = col[have_lin][0][i];
+            background->gradient_middle[i] = col[have_lin][1][i];
+            background->gradient_bottom[i] = col[have_lin][2][i];
+        }
+    }
+    lib3ds_chunk_read_end(&c, io);
+}
+
+
+void
+lib3ds_background_read(Lib3dsBackground *background, Lib3dsIo *io) {
+    Lib3dsChunk c;
+
+    lib3ds_chunk_read(&c, io);
+    switch (c.chunk) {
+        case CHK_BIT_MAP: {
+            lib3ds_io_read_string(io, background->bitmap_name, 64);
+            break;
+        }
+
+        case CHK_SOLID_BGND: {
+            lib3ds_chunk_read_reset(&c, io);
+            solid_bgnd_read(background, io);
+            break;
+        }
+
+        case CHK_V_GRADIENT: {
+            lib3ds_chunk_read_reset(&c, io);
+            v_gradient_read(background, io);
+            break;
+        }
+
+        case CHK_USE_BIT_MAP: {
+            background->use_bitmap = TRUE;
+            break;
+        }
+
+        case CHK_USE_SOLID_BGND: {
+            background->use_solid = TRUE;
+            break;
+        }
+
+        case CHK_USE_V_GRADIENT: {
+            background->use_gradient = TRUE;
+            break;
+        }
+    }
+}
+
+
+static void
+colorf_write(float rgb[3], Lib3dsIo *io) {
+    Lib3dsChunk c;
+
+    c.chunk = CHK_COLOR_F;
+    c.size = 18;
+    lib3ds_chunk_write(&c, io);
+    lib3ds_io_write_rgb(io, rgb);
+
+    c.chunk = CHK_LIN_COLOR_F;
+    c.size = 18;
+    lib3ds_chunk_write(&c, io);
+    lib3ds_io_write_rgb(io, rgb);
+}
+
+
+static int
+colorf_defined(float rgb[3]) {
+    int i;
+    for (i = 0; i < 3; ++i) {
+        if (fabs(rgb[i]) > LIB3DS_EPSILON) {
+            break;
+        }
+    }
+    return(i < 3);
+}
+
+
+void
+lib3ds_background_write(Lib3dsBackground *background, Lib3dsIo *io) {
+    if (strlen(background->bitmap_name)) { /*---- LIB3DS_BIT_MAP ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_BIT_MAP;
+        c.size = 6 + 1 + (uint32_t)strlen(background->bitmap_name);
+        lib3ds_chunk_write(&c, io);
+        lib3ds_io_write_string(io, background->bitmap_name);
+    }
+
+    if (colorf_defined(background->solid_color)) { /*---- LIB3DS_SOLID_BGND ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_SOLID_BGND;
+        c.size = 42;
+        lib3ds_chunk_write(&c, io);
+        colorf_write(background->solid_color, io);
+    }
+
+    if (colorf_defined(background->gradient_top) ||
+        colorf_defined(background->gradient_middle) ||
+        colorf_defined(background->gradient_bottom)) { /*---- LIB3DS_V_GRADIENT ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_V_GRADIENT;
+        c.size = 118;
+        lib3ds_chunk_write(&c, io);
+        lib3ds_io_write_float(io, background->gradient_percent);
+        colorf_write(background->gradient_top, io);
+        colorf_write(background->gradient_middle, io);
+        colorf_write(background->gradient_bottom, io);
+    }
+
+    if (background->use_bitmap) { /*---- LIB3DS_USE_BIT_MAP ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_USE_BIT_MAP;
+        c.size = 6;
+        lib3ds_chunk_write(&c, io);
+    }
+
+    if (background->use_solid) { /*---- LIB3DS_USE_SOLID_BGND ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_USE_SOLID_BGND;
+        c.size = 6;
+        lib3ds_chunk_write(&c, io);
+    }
+
+    if (background->use_gradient) { /*---- LIB3DS_USE_V_GRADIENT ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_USE_V_GRADIENT;
+        c.size = 6;
+        lib3ds_chunk_write(&c, io);
+    }
+}
+
Index: /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_file.c
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_file.c (revision 10853)
+++ /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_file.c (revision 10853)
@@ -0,0 +1,1426 @@
+/*
+    Copyright (C) 1996-2008 by Jan Eric Kyprianidis <www.kyprianidis.com>
+    All rights reserved.
+    
+    This program is free  software: you can redistribute it and/or modify 
+    it under the terms of the GNU Lesser General Public License as published 
+    by the Free Software Foundation, either version 2.1 of the License, or 
+    (at your option) any later version.
+
+    Thisprogram  is  distributed in the hope that it will be useful, 
+    but WITHOUT ANY WARRANTY; without even the implied warranty of 
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
+    GNU Lesser General Public License for more details.
+    
+    You should  have received a copy of the GNU Lesser General Public License
+    along with  this program; If not, see <http://www.gnu.org/licenses/>. 
+*/
+#include "lib3ds_impl.h"
+
+
+static long
+fileio_seek_func(void *self, long offset, Lib3dsIoSeek origin) {
+    FILE *f = (FILE*)self;
+    int o;
+    switch (origin) {
+        case LIB3DS_SEEK_SET:
+            o = SEEK_SET;
+            break;
+
+        case LIB3DS_SEEK_CUR:
+            o = SEEK_CUR;
+            break;
+
+        case LIB3DS_SEEK_END:
+            o = SEEK_END;
+            break;
+
+        default:
+            assert(0);
+            return(0);
+    }
+    return (fseek(f, offset, o));
+}
+
+
+static long
+fileio_tell_func(void *self) {
+    FILE *f = (FILE*)self;
+    return(ftell(f));
+}
+
+
+static size_t
+fileio_read_func(void *self, void *buffer, size_t size) {
+    FILE *f = (FILE*)self;
+    return(fread(buffer, 1, size, f));
+}
+
+
+static size_t
+fileio_write_func(void *self, const void *buffer, size_t size) {
+    FILE *f = (FILE*)self;
+    return(fwrite(buffer, 1, size, f));
+}
+
+
+/*!
+ * Loads a .3DS file from disk into memory.
+ *
+ * \param filename  The filename of the .3DS file
+ *
+ * \return   A pointer to the Lib3dsFile structure containing the
+ *           data of the .3DS file.
+ *           If the .3DS file can not be loaded NULL is returned.
+ *
+ * \note     To free the returned structure use lib3ds_free.
+ *
+ * \see lib3ds_file_save
+ * \see lib3ds_file_new
+ * \see lib3ds_file_free
+ */
+Lib3dsFile*
+lib3ds_file_open(const char *filename) {
+    FILE *f;
+    Lib3dsFile *file;
+    Lib3dsIo io;
+
+    f = fopen(filename, "rb");
+    if (!f) {
+        return NULL;
+    }
+    file = lib3ds_file_new();
+    if (!file) {
+        fclose(f);
+        return NULL;
+    }
+
+    memset(&io, 0, sizeof(io));
+    io.self = f;
+    io.seek_func = fileio_seek_func;
+    io.tell_func = fileio_tell_func;
+    io.read_func = fileio_read_func;
+    io.write_func = fileio_write_func;
+    io.log_func = NULL;
+
+    if (!lib3ds_file_read(file, &io)) {
+        fclose(f);
+        free(file);
+        return NULL;
+    }
+
+    fclose(f);
+    return file;
+}
+
+
+/*!
+ * Saves a .3DS file from memory to disk.
+ *
+ * \param file      A pointer to a Lib3dsFile structure containing the
+ *                  the data that should be stored.
+ * \param filename  The filename of the .3DS file to store the data in.
+ *
+ * \return          TRUE on success, FALSE otherwise.
+ *
+ * \see lib3ds_file_open
+ */
+int
+lib3ds_file_save(Lib3dsFile *file, const char *filename) {
+    FILE *f;
+    Lib3dsIo io;
+    int result;
+
+    f = fopen(filename, "wb");
+    if (!f) {
+        return FALSE;
+    }
+
+    memset(&io, 0, sizeof(io));
+    io.self = f;
+    io.seek_func = fileio_seek_func;
+    io.tell_func = fileio_tell_func;
+    io.read_func = fileio_read_func;
+    io.write_func = fileio_write_func;
+    io.log_func = NULL;
+
+    result = lib3ds_file_write(file, &io);
+    fclose(f);
+    return result;
+}
+
+
+/*!
+ * Creates and returns a new, empty Lib3dsFile object.
+ *
+ * \return A pointer to the Lib3dsFile structure.
+ *  If the structure cannot be allocated, NULL is returned.
+ */
+Lib3dsFile*
+lib3ds_file_new() {
+    Lib3dsFile *file;
+
+    file = (Lib3dsFile*)calloc(sizeof(Lib3dsFile), 1);
+    if (!file) {
+        return(0);
+    }
+    file->mesh_version = 3;
+    file->master_scale = 1.0f;
+    file->keyf_revision = 5;
+    strcpy(file->name, "LIB3DS");
+
+    file->frames = 100;
+    file->segment_from = 0;
+    file->segment_to = 100;
+    file->current_frame = 0;
+
+    return(file);
+}
+
+
+/*!
+ * Free a Lib3dsFile object and all of its resources.
+ *
+ * \param file The Lib3dsFile object to be freed.
+ */
+void
+lib3ds_file_free(Lib3dsFile* file) {
+    assert(file);
+    lib3ds_file_reserve_materials(file, 0, TRUE);
+    lib3ds_file_reserve_cameras(file, 0, TRUE);
+    lib3ds_file_reserve_lights(file, 0, TRUE);
+    lib3ds_file_reserve_meshes(file, 0, TRUE);
+    {
+        Lib3dsNode *p, *q;
+
+        for (p = file->nodes; p; p = q) {
+            q = p->next;
+            lib3ds_node_free(p);
+        }
+    }
+    free(file);
+}
+
+
+/*!
+ * Evaluate all of the nodes in this Lib3dsFile object.
+ *
+ * \param file The Lib3dsFile object to be evaluated.
+ * \param t time value, between 0. and file->frames
+ *
+ * \see lib3ds_node_eval
+ */
+void
+lib3ds_file_eval(Lib3dsFile *file, float t) {
+    Lib3dsNode *p;
+
+    for (p = file->nodes; p != 0; p = p->next) {
+        lib3ds_node_eval(p, t);
+    }
+}
+
+
+static void
+named_object_read(Lib3dsFile *file, Lib3dsIo *io) {
+    Lib3dsChunk c;
+    char name[64];
+    uint16_t chunk;
+    Lib3dsMesh *mesh = NULL;
+    Lib3dsCamera *camera = NULL;
+    Lib3dsLight *light = NULL;
+    uint32_t object_flags;
+
+    lib3ds_chunk_read_start(&c, CHK_NAMED_OBJECT, io);
+    
+    lib3ds_io_read_string(io, name, 64);
+    lib3ds_io_log(io, LIB3DS_LOG_INFO, "  NAME=%s", name);
+    lib3ds_chunk_read_tell(&c, io);
+
+    object_flags = 0;
+    while ((chunk = lib3ds_chunk_read_next(&c, io)) != 0) {
+        switch (chunk) {
+            case CHK_N_TRI_OBJECT: {
+                mesh = lib3ds_mesh_new(name);
+                lib3ds_file_insert_mesh(file, mesh, -1);
+                lib3ds_chunk_read_reset(&c, io);
+                lib3ds_mesh_read(file, mesh, io);
+                break;
+            }
+
+            case CHK_N_CAMERA: {
+                camera = lib3ds_camera_new(name);
+                lib3ds_file_insert_camera(file, camera, -1);
+                lib3ds_chunk_read_reset(&c, io);
+                lib3ds_camera_read(camera, io);
+                break;
+            }
+
+            case CHK_N_DIRECT_LIGHT: {
+                light = lib3ds_light_new(name);
+                lib3ds_file_insert_light(file, light, -1);
+                lib3ds_chunk_read_reset(&c, io);
+                lib3ds_light_read(light, io);
+                break;
+            }
+
+            case CHK_OBJ_HIDDEN:
+                object_flags |= LIB3DS_OBJECT_HIDDEN;
+                break;
+
+            case CHK_OBJ_DOESNT_CAST:
+                object_flags |= LIB3DS_OBJECT_DOESNT_CAST;
+                break;
+
+            case CHK_OBJ_VIS_LOFTER:
+                object_flags |= LIB3DS_OBJECT_VIS_LOFTER;
+                break;
+
+            case CHK_OBJ_MATTE:
+                object_flags |= LIB3DS_OBJECT_MATTE;
+                break;
+
+            case CHK_OBJ_DONT_RCVSHADOW:
+                object_flags |= LIB3DS_OBJECT_DONT_RCVSHADOW;
+                break;
+
+            case CHK_OBJ_FAST:
+                object_flags |= LIB3DS_OBJECT_FAST;
+                break;
+
+            case CHK_OBJ_FROZEN:
+                object_flags |= LIB3DS_OBJECT_FROZEN;
+                break;
+
+            default:
+                lib3ds_chunk_unknown(chunk, io);
+        }
+    }
+
+    if (mesh)
+        mesh->object_flags = object_flags;
+    if (camera)
+        camera->object_flags = object_flags;
+    if (light)
+        light->object_flags = object_flags;
+
+    lib3ds_chunk_read_end(&c, io);
+}
+
+
+static void
+ambient_read(Lib3dsFile *file, Lib3dsIo *io) {
+    Lib3dsChunk c;
+    uint16_t chunk;
+    int have_lin = FALSE;
+
+    lib3ds_chunk_read_start(&c, CHK_AMBIENT_LIGHT, io);
+
+    while ((chunk = lib3ds_chunk_read_next(&c, io)) != 0) {
+        switch (chunk) {
+            case CHK_LIN_COLOR_F: {
+                int i;
+                for (i = 0; i < 3; ++i) {
+                    file->ambient[i] = lib3ds_io_read_float(io);
+                }
+                have_lin = TRUE;
+                break;
+            }
+
+            case CHK_COLOR_F: {
+                /* gamma corrected color chunk
+                   replaced in 3ds R3 by LIN_COLOR_24 */
+                if (!have_lin) {
+                    int i;
+                    for (i = 0; i < 3; ++i) {
+                        file->ambient[i] = lib3ds_io_read_float(io);
+                    }
+                }
+                break;
+            }
+
+            default:
+                lib3ds_chunk_unknown(chunk, io);
+        }
+    }
+
+    lib3ds_chunk_read_end(&c, io);
+}
+
+
+static void
+mdata_read(Lib3dsFile *file, Lib3dsIo *io) {
+    Lib3dsChunk c;
+    uint16_t chunk;
+
+    lib3ds_chunk_read_start(&c, CHK_MDATA, io);
+
+    while ((chunk = lib3ds_chunk_read_next(&c, io)) != 0) {
+        switch (chunk) {
+            case CHK_MESH_VERSION: {
+                file->mesh_version = lib3ds_io_read_intd(io);
+                break;
+            }
+
+            case CHK_MASTER_SCALE: {
+                file->master_scale = lib3ds_io_read_float(io);
+                break;
+            }
+
+            case CHK_SHADOW_MAP_SIZE:
+            case CHK_LO_SHADOW_BIAS:
+            case CHK_HI_SHADOW_BIAS:
+            case CHK_SHADOW_SAMPLES:
+            case CHK_SHADOW_RANGE:
+            case CHK_SHADOW_FILTER:
+            case CHK_RAY_BIAS: {
+                lib3ds_chunk_read_reset(&c, io);
+                lib3ds_shadow_read(&file->shadow, io);
+                break;
+            }
+
+            case CHK_VIEWPORT_LAYOUT:
+            case CHK_DEFAULT_VIEW: {
+                lib3ds_chunk_read_reset(&c, io);
+                lib3ds_viewport_read(&file->viewport, io);
+                break;
+            }
+
+            case CHK_O_CONSTS: {
+                int i;
+                for (i = 0; i < 3; ++i) {
+                    file->construction_plane[i] = lib3ds_io_read_float(io);
+                }
+                break;
+            }
+
+            case CHK_AMBIENT_LIGHT: {
+                lib3ds_chunk_read_reset(&c, io);
+                ambient_read(file, io);
+                break;
+            }
+
+            case CHK_BIT_MAP:
+            case CHK_SOLID_BGND:
+            case CHK_V_GRADIENT:
+            case CHK_USE_BIT_MAP:
+            case CHK_USE_SOLID_BGND:
+            case CHK_USE_V_GRADIENT: {
+                lib3ds_chunk_read_reset(&c, io);
+                lib3ds_background_read(&file->background, io);
+                break;
+            }
+
+            case CHK_FOG:
+            case CHK_LAYER_FOG:
+            case CHK_DISTANCE_CUE:
+            case CHK_USE_FOG:
+            case CHK_USE_LAYER_FOG:
+            case CHK_USE_DISTANCE_CUE: {
+                lib3ds_chunk_read_reset(&c, io);
+                lib3ds_atmosphere_read(&file->atmosphere, io);
+                break;
+            }
+
+            case CHK_MAT_ENTRY: {
+                Lib3dsMaterial *material = lib3ds_material_new(NULL);
+                lib3ds_file_insert_material(file, material, -1);
+                lib3ds_chunk_read_reset(&c, io);
+                lib3ds_material_read(material, io);
+                break;
+            }
+
+            case CHK_NAMED_OBJECT: {
+                lib3ds_chunk_read_reset(&c, io);
+                named_object_read(file, io);
+                break;
+            }
+
+            default:
+                lib3ds_chunk_unknown(chunk, io);
+        }
+    }
+
+    lib3ds_chunk_read_end(&c, io);
+}
+
+
+static int 
+compare_node_id( const void *a, const void *b ) {
+   return (*((Lib3dsNode**)a))->node_id - (*((Lib3dsNode**)b))->node_id;
+}
+
+
+static int 
+compare_node_id2( const void *a, const void *b ) {
+   return *((unsigned short*)a) - (*((Lib3dsNode**)b))->node_id;
+}
+
+
+static void
+kfdata_read(Lib3dsFile *file, Lib3dsIo *io) {
+    Lib3dsChunk c;
+    uint16_t chunk;
+    unsigned num_nodes = 0;
+    //Lib3dsIoImpl *impl = (Lib3dsIoImpl*)io->impl;
+    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 = 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);
+}
+
+
+/*!
+ * Read 3ds file data into a Lib3dsFile object.
+ *
+ * \param file The Lib3dsFile object to be filled.
+ * \param io A Lib3dsIo object previously set up by the caller.
+ *
+ * \return LIB3DS_TRUE on success, LIB3DS_FALSE on failure.
+ */
+int
+lib3ds_file_read(Lib3dsFile *file, Lib3dsIo *io) {
+    Lib3dsChunk c;
+    uint16_t chunk;
+    Lib3dsIoImpl *impl;
+
+    lib3ds_io_setup(io);
+    impl = (Lib3dsIoImpl*)io->impl;
+
+    if (setjmp(impl->jmpbuf) != 0) {
+        lib3ds_io_cleanup(io);
+        return FALSE;
+    }
+
+    lib3ds_chunk_read_start(&c, 0, io);
+    switch (c.chunk) {
+        case CHK_MDATA: {
+            lib3ds_chunk_read_reset(&c, io);
+            mdata_read(file, io);
+            break;
+        }
+
+        case CHK_M3DMAGIC:
+        case CHK_MLIBMAGIC:
+        case CHK_CMAGIC: {
+            while ((chunk = lib3ds_chunk_read_next(&c, io)) != 0) {
+                switch (chunk) {
+                    case CHK_M3D_VERSION: {
+                        file->mesh_version = lib3ds_io_read_dword(io);
+                        break;
+                    }
+
+                    case CHK_MDATA: {
+                        lib3ds_chunk_read_reset(&c, io);
+                        mdata_read(file, io);
+                        break;
+                    }
+
+                    case CHK_KFDATA: {
+                        lib3ds_chunk_read_reset(&c, io);
+                        kfdata_read(file, io);
+                        break;
+                    }
+
+                    default:
+                        lib3ds_chunk_unknown(chunk, io);
+                }
+            }
+            break;
+        }
+
+        default:
+            lib3ds_chunk_unknown(c.chunk, io);
+            return FALSE;
+    }
+
+    lib3ds_chunk_read_end(&c, io);
+
+    memset(impl->jmpbuf, 0, sizeof(impl->jmpbuf));
+    lib3ds_io_cleanup(io);
+    return TRUE;
+}
+
+
+static void
+colorf_write(float rgb[3], Lib3dsIo *io) {
+    Lib3dsChunk c;
+
+    c.chunk = CHK_COLOR_F;
+    c.size = 18;
+    lib3ds_chunk_write(&c, io);
+    lib3ds_io_write_rgb(io, rgb);
+
+    c.chunk = CHK_LIN_COLOR_F;
+    c.size = 18;
+    lib3ds_chunk_write(&c, io);
+    lib3ds_io_write_rgb(io, rgb);
+}
+
+
+static void
+object_flags_write(uint32_t flags, Lib3dsIo *io) {
+    if (flags) {
+        Lib3dsChunk c;
+        c.size = 6;
+
+        if (flags & LIB3DS_OBJECT_HIDDEN) {
+            c.chunk = CHK_OBJ_HIDDEN;
+            lib3ds_chunk_write(&c, io);
+        }
+        if (flags & LIB3DS_OBJECT_VIS_LOFTER) {
+            c.chunk = CHK_OBJ_VIS_LOFTER;
+            lib3ds_chunk_write(&c, io);
+        }
+        if (flags & LIB3DS_OBJECT_DOESNT_CAST) {
+            c.chunk = CHK_OBJ_DOESNT_CAST;
+            lib3ds_chunk_write(&c, io);
+        }
+        if (flags & LIB3DS_OBJECT_MATTE) {
+            c.chunk = CHK_OBJ_MATTE;
+            lib3ds_chunk_write(&c, io);
+        }
+        if (flags & LIB3DS_OBJECT_DONT_RCVSHADOW) {
+            c.chunk = CHK_OBJ_DOESNT_CAST;
+            lib3ds_chunk_write(&c, io);
+        }
+        if (flags & LIB3DS_OBJECT_FAST) {
+            c.chunk = CHK_OBJ_FAST;
+            lib3ds_chunk_write(&c, io);
+        }
+        if (flags & LIB3DS_OBJECT_FROZEN) {
+            c.chunk = CHK_OBJ_FROZEN;
+            lib3ds_chunk_write(&c, io);
+        }
+    }
+}
+
+
+static void
+mdata_write(Lib3dsFile *file, Lib3dsIo *io) {
+    Lib3dsChunk c;
+
+    c.chunk = CHK_MDATA;
+    lib3ds_chunk_write_start(&c, io);
+
+    { /*---- LIB3DS_MESH_VERSION ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_MESH_VERSION;
+        c.size = 10;
+        lib3ds_chunk_write(&c, io);
+        lib3ds_io_write_intd(io, file->mesh_version);
+    }
+    { /*---- LIB3DS_MASTER_SCALE ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_MASTER_SCALE;
+        c.size = 10;
+        lib3ds_chunk_write(&c, io);
+        lib3ds_io_write_float(io, file->master_scale);
+    }
+    { /*---- LIB3DS_O_CONSTS ----*/
+        int i;
+        for (i = 0; i < 3; ++i) {
+            if (fabs(file->construction_plane[i]) > LIB3DS_EPSILON) {
+                break;
+            }
+        }
+        if (i < 3) {
+            Lib3dsChunk c;
+            c.chunk = CHK_O_CONSTS;
+            c.size = 18;
+            lib3ds_chunk_write(&c, io);
+            lib3ds_io_write_vector(io, file->construction_plane);
+        }
+    }
+
+    { /*---- LIB3DS_AMBIENT_LIGHT ----*/
+        int i;
+        for (i = 0; i < 3; ++i) {
+            if (fabs(file->ambient[i]) > LIB3DS_EPSILON) {
+                break;
+            }
+        }
+        if (i < 3) {
+            Lib3dsChunk c;
+            c.chunk = CHK_AMBIENT_LIGHT;
+            c.size = 42;
+            lib3ds_chunk_write(&c, io);
+            colorf_write(file->ambient, io);
+        }
+    }
+    lib3ds_background_write(&file->background, io);
+    lib3ds_atmosphere_write(&file->atmosphere, io);
+    lib3ds_shadow_write(&file->shadow, io);
+    lib3ds_viewport_write(&file->viewport, io);
+    {
+        int i;
+        for (i = 0; i < file->nmaterials; ++i) {
+            lib3ds_material_write(file->materials[i], io);
+        }
+    }
+    {
+        Lib3dsChunk c;
+        int i;
+
+        for (i = 0; i < file->ncameras; ++i) {
+            c.chunk = CHK_NAMED_OBJECT;
+            lib3ds_chunk_write_start(&c, io);
+            lib3ds_io_write_string(io, file->cameras[i]->name);
+            lib3ds_camera_write(file->cameras[i], io);
+            object_flags_write(file->cameras[i]->object_flags, io);
+            lib3ds_chunk_write_end(&c, io);
+        }
+    }
+    {
+        Lib3dsChunk c;
+        int i;
+
+        for (i = 0; i < file->nlights; ++i) {
+            c.chunk = CHK_NAMED_OBJECT;
+            lib3ds_chunk_write_start(&c, io);
+            lib3ds_io_write_string(io, file->lights[i]->name);
+            lib3ds_light_write(file->lights[i], io);
+            object_flags_write(file->lights[i]->object_flags, io);
+            lib3ds_chunk_write_end(&c, io);
+        }
+    }
+    {
+        Lib3dsChunk c;
+        int i;
+
+        for (i = 0; i < file->nmeshes; ++i) {
+            c.chunk = CHK_NAMED_OBJECT;
+            lib3ds_chunk_write_start(&c, io);
+            lib3ds_io_write_string(io, file->meshes[i]->name);
+            lib3ds_mesh_write(file, file->meshes[i], io);
+            object_flags_write(file->meshes[i]->object_flags, io);
+            lib3ds_chunk_write_end(&c, io);
+        }
+    }
+
+    lib3ds_chunk_write_end(&c, io);
+}
+
+
+
+static void
+nodes_write(Lib3dsNode *first_node, uint16_t *default_id, uint16_t parent_id, Lib3dsIo *io) {
+    Lib3dsNode *p;
+    for (p = first_node; p != NULL; p = p->next) {
+        uint16_t node_id;
+        if ((p->type == LIB3DS_NODE_AMBIENT_COLOR) || (p->node_id != 65535)) {
+            node_id = p->node_id;
+        } else {
+            node_id = *default_id;
+        }
+        ++(*default_id);
+        lib3ds_node_write(p, node_id, parent_id, io);
+
+        nodes_write(p->childs, default_id, node_id, io);
+    }
+}
+
+
+static void
+kfdata_write(Lib3dsFile *file, Lib3dsIo *io) {
+    Lib3dsChunk c;
+
+    if (!file->nodes) {
+        return;
+    }
+
+    c.chunk = CHK_KFDATA;
+    lib3ds_chunk_write_start(&c, io);
+
+    { /*---- LIB3DS_KFHDR ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_KFHDR;
+        c.size = 6 + 2 + (uint32_t)strlen(file->name) + 1 + 4;
+        lib3ds_chunk_write(&c, io);
+        lib3ds_io_write_intw(io, (int16_t)file->keyf_revision);
+        lib3ds_io_write_string(io, file->name);
+        lib3ds_io_write_intd(io, file->frames);
+    }
+    { /*---- LIB3DS_KFSEG ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_KFSEG;
+        c.size = 14;
+        lib3ds_chunk_write(&c, io);
+        lib3ds_io_write_intd(io, file->segment_from);
+        lib3ds_io_write_intd(io, file->segment_to);
+    }
+    { /*---- LIB3DS_KFCURTIME ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_KFCURTIME;
+        c.size = 10;
+        lib3ds_chunk_write(&c, io);
+        lib3ds_io_write_intd(io, file->current_frame);
+    }
+    lib3ds_viewport_write(&file->viewport_keyf, io);
+
+    {
+        uint16_t default_id = 0;
+        nodes_write(file->nodes, &default_id, 65535, io);
+    }
+
+    lib3ds_chunk_write_end(&c, io);
+}
+
+
+/*!
+ * Write 3ds file data from a Lib3dsFile object to a file.
+ *
+ * \param file The Lib3dsFile object to be written.
+ * \param io A Lib3dsIo object previously set up by the caller.
+ *
+ * \return LIB3DS_TRUE on success, LIB3DS_FALSE on failure.
+ */
+int
+lib3ds_file_write(Lib3dsFile *file, Lib3dsIo *io) {
+    Lib3dsChunk c;
+    Lib3dsIoImpl *impl;
+
+    lib3ds_io_setup(io);
+    impl = (Lib3dsIoImpl*)io->impl;
+
+    if (setjmp(impl->jmpbuf) != 0) {
+        lib3ds_io_cleanup(io);
+        return FALSE;
+    }
+
+    c.chunk = CHK_M3DMAGIC;
+    lib3ds_chunk_write_start(&c, io);
+
+    { /*---- LIB3DS_M3D_VERSION ----*/
+        Lib3dsChunk c;
+
+        c.chunk = CHK_M3D_VERSION;
+        c.size = 10;
+        lib3ds_chunk_write(&c, io);
+        lib3ds_io_write_dword(io, file->mesh_version);
+    }
+
+    mdata_write(file, io);
+    kfdata_write(file, io);
+
+    lib3ds_chunk_write_end(&c, io);
+
+    memset(impl->jmpbuf, 0, sizeof(impl->jmpbuf));
+    lib3ds_io_cleanup(io);
+    return TRUE;
+}
+
+
+void lib3ds_file_reserve_materials(Lib3dsFile *file, int size, int force) {
+    assert(file);
+    lib3ds_util_reserve_array((void***)&file->materials, &file->nmaterials, &file->materials_size, 
+                              size, force, (Lib3dsFreeFunc)lib3ds_material_free);
+}
+
+
+void
+lib3ds_file_insert_material(Lib3dsFile *file, Lib3dsMaterial *material, int index) {
+    assert(file);
+    lib3ds_util_insert_array((void***)&file->materials, &file->nmaterials, &file->materials_size, material, index);
+}
+
+
+void
+lib3ds_file_remove_material(Lib3dsFile *file, int index) {
+    assert(file);
+    lib3ds_util_remove_array((void***)&file->materials, &file->nmaterials, index, (Lib3dsFreeFunc)lib3ds_material_free);
+}
+
+
+int
+lib3ds_file_material_by_name(Lib3dsFile *file, const char *name) {
+    int i;
+
+    assert(file);
+    for (i = 0; i < file->nmaterials; ++i) {
+        if (strcmp(file->materials[i]->name, name) == 0) {
+            return(i);
+        }
+    }
+    return -1;
+}
+
+
+void 
+lib3ds_file_reserve_cameras(Lib3dsFile *file, int size, int force) {
+    assert(file);
+    lib3ds_util_reserve_array((void***)&file->cameras, &file->ncameras, &file->cameras_size, 
+                              size, force, (Lib3dsFreeFunc)lib3ds_camera_free);
+}
+
+
+void
+lib3ds_file_insert_camera(Lib3dsFile *file, Lib3dsCamera *camera, int index) {
+    assert(file);
+    lib3ds_util_insert_array((void***)&file->cameras, &file->ncameras, &file->cameras_size, camera, index);
+}
+
+
+void
+lib3ds_file_remove_camera(Lib3dsFile *file, int index) {
+    assert(file);
+    lib3ds_util_remove_array((void***)&file->cameras, &file->ncameras, index, (Lib3dsFreeFunc)lib3ds_camera_free);
+}
+
+
+int
+lib3ds_file_camera_by_name(Lib3dsFile *file, const char *name) {
+    int i;
+
+    assert(file);
+    for (i = 0; i < file->ncameras; ++i) {
+        if (strcmp(file->cameras[i]->name, name) == 0) {
+            return(i);
+        }
+    }
+    return -1;
+}
+
+
+void 
+lib3ds_file_reserve_lights(Lib3dsFile *file, int size, int force) {
+    assert(file);
+    lib3ds_util_reserve_array((void***)&file->lights, &file->nlights, &file->lights_size, 
+                              size, force, (Lib3dsFreeFunc)lib3ds_light_free);
+}
+
+
+void
+lib3ds_file_insert_light(Lib3dsFile *file, Lib3dsLight *light, int index) {
+    assert(file);
+    lib3ds_util_insert_array((void***)&file->lights, &file->nlights, &file->lights_size, light, index);
+}
+
+
+void
+lib3ds_file_remove_light(Lib3dsFile *file, int index) {
+    assert(file);
+    lib3ds_util_remove_array((void***)&file->lights, &file->nlights, index, (Lib3dsFreeFunc)lib3ds_light_free);
+}
+
+
+int
+lib3ds_file_light_by_name(Lib3dsFile *file, const char *name) {
+    int i;
+
+    assert(file);
+    for (i = 0; i < file->nlights; ++i) {
+        if (strcmp(file->lights[i]->name, name) == 0) {
+            return(i);
+        }
+    }
+    return -1;
+}
+
+
+void 
+lib3ds_file_reserve_meshes(Lib3dsFile *file, int size, int force) {
+    assert(file);
+    lib3ds_util_reserve_array((void***)&file->meshes, &file->nmeshes, &file->meshes_size, 
+                               size, force, (Lib3dsFreeFunc)lib3ds_mesh_free);
+}
+
+
+void
+lib3ds_file_insert_mesh(Lib3dsFile *file, Lib3dsMesh *mesh, int index) {
+    assert(file);
+    lib3ds_util_insert_array((void***)&file->meshes, &file->nmeshes, &file->meshes_size, mesh, index);
+}
+
+
+void
+lib3ds_file_remove_mesh(Lib3dsFile *file, int index) {
+    assert(file);
+    lib3ds_util_remove_array((void***)&file->meshes, &file->nmeshes, index, (Lib3dsFreeFunc)lib3ds_mesh_free);
+}
+
+
+int
+lib3ds_file_mesh_by_name(Lib3dsFile *file, const char *name) {
+    int i;
+
+    assert(file);
+    for (i = 0; i < file->nmeshes; ++i) {
+        if (strcmp(file->meshes[i]->name, name) == 0) {
+            return(i);
+        }
+    }
+    return -1;
+}
+
+
+Lib3dsMesh* 
+lib3ds_file_mesh_for_node(Lib3dsFile *file, Lib3dsNode *node) {
+    int index;
+    Lib3dsMeshInstanceNode *n;
+
+    if (node->type != LIB3DS_NODE_MESH_INSTANCE)
+        return NULL;
+    n = (Lib3dsMeshInstanceNode*)node;
+
+    index = lib3ds_file_mesh_by_name(file, node->name);
+
+    return (index >= 0)? file->meshes[index] : NULL;
+}
+
+
+/*!
+ * Return a node object by name and type.
+ *
+ * This function performs a recursive search for the specified node.
+ * Both name and type must match.
+ *
+ * \param file The Lib3dsFile to be searched.
+ * \param name The target node name.
+ * \param type The target node type
+ *
+ * \return A pointer to the first matching node, or NULL if not found.
+ *
+ * \see lib3ds_node_by_name
+ */
+Lib3dsNode*
+lib3ds_file_node_by_name(Lib3dsFile *file, const char* name, Lib3dsNodeType type) {
+    Lib3dsNode *p, *q;
+
+    assert(file);
+    for (p = file->nodes; p != 0; p = p->next) {
+        if ((p->type == type) && (strcmp(p->name, name) == 0)) {
+            return(p);
+        }
+        q = lib3ds_node_by_name(p, name, type);
+        if (q) {
+            return(q);
+        }
+    }
+    return(0);
+}
+
+
+/*!
+ * Return a node object by id.
+ *
+ * This function performs a recursive search for the specified node.
+ *
+ * \param file The Lib3dsFile to be searched.
+ * \param node_id The target node id.
+ *
+ * \return A pointer to the first matching node, or NULL if not found.
+ *
+ * \see lib3ds_node_by_id
+ */
+Lib3dsNode*
+lib3ds_file_node_by_id(Lib3dsFile *file, uint16_t node_id) {
+    Lib3dsNode *p, *q;
+
+    assert(file);
+    for (p = file->nodes; p != 0; p = p->next) {
+        if (p->node_id == node_id) {
+            return(p);
+        }
+        q = lib3ds_node_by_id(p, node_id);
+        if (q) {
+            return(q);
+        }
+    }
+    return(0);
+}
+
+
+void
+lib3ds_file_append_node(Lib3dsFile *file, Lib3dsNode *node, Lib3dsNode *parent) {
+    Lib3dsNode *p;
+
+    assert(file);
+    assert(node);
+    p = parent? parent->childs : file->nodes;
+    if (p) {
+        while (p->next) {
+            p = p->next;
+        }
+        p->next = node;
+    } else {
+        if (parent) {
+            parent->childs = node;
+        } else {
+            file->nodes = node;
+        } 
+    }
+    node->parent = parent;
+    node->next = NULL;
+}
+
+
+void
+lib3ds_file_insert_node(Lib3dsFile *file, Lib3dsNode *node, Lib3dsNode *before) {
+    Lib3dsNode *p, *q;
+
+    assert(node);
+    assert(file);
+
+    if (before) {
+        p = before->parent? before->parent->childs : file->nodes;
+        assert(p);
+        q = NULL;
+        while (p != before) {
+            q = p;
+            p = p->next;
+        }
+        if (q) {
+            node->next = q->next;
+            q->next = node;
+        } else {
+            node->next = file->nodes;
+            file->nodes = node;
+        }
+        node->parent = before->parent;
+    } else {
+        node->next = file->nodes;
+        node->parent = NULL;
+        file->nodes = node;
+    }
+}
+
+
+/*!
+ * Remove a node from the a Lib3dsFile object.
+ *
+ * \param file The Lib3dsFile object to be modified.
+ * \param node The Lib3dsNode object to be removed from file
+ *
+ * \return LIB3DS_TRUE on success, LIB3DS_FALSE if node is not found in file
+ */
+void
+lib3ds_file_remove_node(Lib3dsFile *file, Lib3dsNode *node) {
+    Lib3dsNode *p, *n;
+
+    if (node->parent) {
+        for (p = 0, n = node->parent->childs; n; p = n, n = n->next) {
+            if (n == node) {
+                break;
+            }
+        }
+        if (!n) {
+            return;
+        }
+
+        if (!p) {
+            node->parent->childs = n->next;
+        } else {
+            p->next = n->next;
+        }
+    } else {
+        for (p = 0, n = file->nodes; n; p = n, n = n->next) {
+            if (n == node) {
+                break;
+            }
+        }
+        if (!n) {
+            return;
+        }
+
+        if (!p) {
+            file->nodes = n->next;
+        } else {
+            p->next = n->next;
+        }
+    }
+}
+
+
+static void
+file_minmax_node_id_impl(Lib3dsFile *file, Lib3dsNode *node, uint16_t *min_id, uint16_t *max_id) {
+    Lib3dsNode *p;
+    
+    if (min_id && (*min_id > node->node_id))
+        *min_id = node->node_id;
+    if (max_id && (*max_id < node->node_id))
+        *max_id = node->node_id;
+    
+    p = node->childs;
+    while (p) {
+        file_minmax_node_id_impl(file, p, min_id, max_id);
+        p = p->next;
+    }
+}
+
+
+void 
+lib3ds_file_minmax_node_id(Lib3dsFile *file, uint16_t *min_id, uint16_t *max_id) {
+    Lib3dsNode *p;
+    
+    if (min_id)
+        *min_id = 65535;
+    if (max_id)
+        *max_id = 0;
+
+    p = file->nodes;
+    while (p) {
+        file_minmax_node_id_impl(file, p, min_id, max_id);
+        p = p->next;
+    }
+}
+
+
+void
+lib3ds_file_bounding_box_of_objects(Lib3dsFile *file, int 
+                                    include_meshes, int include_cameras, int include_lights,
+                                    float bmin[3], float bmax[3]) {
+    bmin[0] = bmin[1] = bmin[2] = FLT_MAX;
+    bmax[0] = bmax[1] = bmax[2] = -FLT_MAX;
+
+    if (include_meshes) {
+        float lmin[3], lmax[3];
+        int i;
+        for (i = 0; i < file->nmeshes; ++i) {
+            lib3ds_mesh_bounding_box(file->meshes[i], lmin, lmax);
+            lib3ds_vector_min(bmin, lmin);
+            lib3ds_vector_max(bmax, lmax);
+        }
+    }
+    if (include_cameras) {
+        int i;
+        for (i = 0; i < file->ncameras; ++i) {
+            lib3ds_vector_min(bmin, file->cameras[i]->position);
+            lib3ds_vector_max(bmax, file->cameras[i]->position);
+            lib3ds_vector_min(bmin, file->cameras[i]->target);
+            lib3ds_vector_max(bmax, file->cameras[i]->target);
+        }
+    }
+    if (include_lights) {
+        int i;
+        for (i = 0; i < file->ncameras; ++i) {
+            lib3ds_vector_min(bmin, file->lights[i]->position);
+            lib3ds_vector_max(bmax, file->lights[i]->position);
+            if (file->lights[i]->spot_light) {
+                lib3ds_vector_min(bmin, file->lights[i]->target);
+                lib3ds_vector_max(bmax, file->lights[i]->target);
+            }
+        }
+    }
+}
+
+
+static void
+file_bounding_box_of_nodes_impl(Lib3dsNode *node, Lib3dsFile *file, 
+                                int include_meshes, int include_cameras, int include_lights,
+                                float bmin[3], float bmax[3], float matrix[4][4]) {
+    switch (node->type) {
+        case LIB3DS_NODE_MESH_INSTANCE:
+            if (include_meshes) {
+                int index;
+                Lib3dsMeshInstanceNode *n = (Lib3dsMeshInstanceNode*)node;
+
+                index = lib3ds_file_mesh_by_name(file, n->instance_name);
+                if (index < 0)
+                    index = lib3ds_file_mesh_by_name(file, node->name);
+                if (index >= 0) {
+                    Lib3dsMesh *mesh;
+                    float inv_matrix[4][4], M[4][4];
+                    float v[3];
+                    int i;
+
+                    mesh = file->meshes[index];
+                    lib3ds_matrix_copy(inv_matrix, mesh->matrix);
+                    lib3ds_matrix_inv(inv_matrix);
+                    lib3ds_matrix_mult(M, matrix, node->matrix);
+                    lib3ds_matrix_translate(M, -n->pivot[0], -n->pivot[1], -n->pivot[2]);
+                    lib3ds_matrix_mult(M, M, inv_matrix);
+
+                    for (i = 0; i < mesh->nvertices; ++i) {
+                        lib3ds_vector_transform(v, M, mesh->vertices[i]);
+                        lib3ds_vector_min(bmin, v);
+                        lib3ds_vector_max(bmax, v);
+                    }
+                }
+            }
+            break;
+
+        case LIB3DS_NODE_CAMERA:
+        case LIB3DS_NODE_CAMERA_TARGET:
+            if (include_cameras) {
+                float z[3], v[3];
+                float M[4][4];
+                lib3ds_matrix_mult(M, matrix, node->matrix);
+                lib3ds_vector_zero(z);
+                lib3ds_vector_transform(v, M, z);
+                lib3ds_vector_min(bmin, v);
+                lib3ds_vector_max(bmax, v);
+            }
+            break;
+
+        case LIB3DS_NODE_OMNILIGHT:
+        case LIB3DS_NODE_SPOTLIGHT:
+        case LIB3DS_NODE_SPOTLIGHT_TARGET:
+            if (include_lights) {
+                float z[3], v[3];
+                float M[4][4];
+                lib3ds_matrix_mult(M, matrix, node->matrix);
+                lib3ds_vector_zero(z);
+                lib3ds_vector_transform(v, M, z);
+                lib3ds_vector_min(bmin, v);
+                lib3ds_vector_max(bmax, v);
+            }
+            break;
+    }
+    {
+        Lib3dsNode *p = node->childs;
+        while (p) {
+            file_bounding_box_of_nodes_impl(p, file, include_meshes, include_cameras, include_lights, bmin, bmax, matrix);
+            p = p->next;
+        }
+    }
+}
+
+
+void
+lib3ds_file_bounding_box_of_nodes(Lib3dsFile *file, 
+                                  int include_meshes, int include_cameras,int include_lights,
+                                  float bmin[3], float bmax[3], float matrix[4][4]) {
+    Lib3dsNode *p;
+    float M[4][4];
+
+    if (matrix) {
+        lib3ds_matrix_copy(M, matrix);
+    } else {
+        lib3ds_matrix_identity(M);
+    }
+
+    bmin[0] = bmin[1] = bmin[2] = FLT_MAX;
+    bmax[0] = bmax[1] = bmax[2] = -FLT_MAX;
+    p = file->nodes;
+    while (p) {
+        file_bounding_box_of_nodes_impl(p, file, include_meshes, include_cameras, include_lights, bmin, bmax, M);
+        p = p->next;
+    }
+}
+
+
+void
+lib3ds_file_create_nodes_for_meshes(Lib3dsFile *file) {
+    Lib3dsNode *p;
+    int i;
+    for (i = 0; i < file->nmeshes; ++i) {
+        Lib3dsMesh *mesh = file->meshes[i];
+        p = lib3ds_node_new(LIB3DS_NODE_MESH_INSTANCE);
+        strcpy(p->name, mesh->name);
+        lib3ds_file_insert_node(file, p, NULL);
+    }
+}
Index: /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_chunktable.c
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_chunktable.c (revision 10853)
+++ /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_chunktable.c (revision 10853)
@@ -0,0 +1,259 @@
+/*
+    Copyright (C) 1996-2008 by Jan Eric Kyprianidis <www.kyprianidis.com>
+    All rights reserved.
+    
+    This program is free  software: you can redistribute it and/or modify 
+    it under the terms of the GNU Lesser General Public License as published 
+    by the Free Software Foundation, either version 2.1 of the License, or 
+    (at your option) any later version.
+
+    Thisprogram  is  distributed in the hope that it will be useful, 
+    but WITHOUT ANY WARRANTY; without even the implied warranty of 
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
+    GNU Lesser General Public License for more details.
+    
+    You should  have received a copy of the GNU Lesser General Public License
+    along with  this program; If not, see <http://www.gnu.org/licenses/>. 
+*/
+#include "lib3ds_impl.h"
+
+
+typedef struct Lib3dsChunkTable {
+    uint32_t chunk;
+    const char* name;
+} Lib3dsChunkTable;
+
+
+static Lib3dsChunkTable lib3ds_chunk_table[] = {
+    {CHK_NULL_CHUNK, "NULL_CHUNK"},
+    {CHK_M3DMAGIC, "M3DMAGIC"},
+    {CHK_SMAGIC, "SMAGIC"},
+    {CHK_LMAGIC, "LMAGIC"},
+    {CHK_MLIBMAGIC, "MLIBMAGIC"},
+    {CHK_MATMAGIC, "MATMAGIC"},
+    {CHK_CMAGIC, "CMAGIC"},
+    {CHK_M3D_VERSION, "M3D_VERSION"},
+    {CHK_M3D_KFVERSION, "M3D_KFVERSION"},
+    {CHK_COLOR_F, "COLOR_F"},
+    {CHK_COLOR_24, "COLOR_24"},
+    {CHK_LIN_COLOR_24, "LIN_COLOR_24"},
+    {CHK_LIN_COLOR_F, "LIN_COLOR_F"},
+    {CHK_INT_PERCENTAGE, "INT_PERCENTAGE"},
+    {CHK_FLOAT_PERCENTAGE, "FLOAT_PERCENTAGE"},
+    {CHK_MDATA, "MDATA"},
+    {CHK_MESH_VERSION, "MESH_VERSION"},
+    {CHK_MASTER_SCALE, "MASTER_SCALE"},
+    {CHK_LO_SHADOW_BIAS, "LO_SHADOW_BIAS"},
+    {CHK_HI_SHADOW_BIAS, "HI_SHADOW_BIAS"},
+    {CHK_SHADOW_MAP_SIZE, "SHADOW_MAP_SIZE"},
+    {CHK_SHADOW_SAMPLES, "SHADOW_SAMPLES"},
+    {CHK_SHADOW_RANGE, "SHADOW_RANGE"},
+    {CHK_SHADOW_FILTER, "SHADOW_FILTER"},
+    {CHK_RAY_BIAS, "RAY_BIAS"},
+    {CHK_O_CONSTS, "O_CONSTS"},
+    {CHK_AMBIENT_LIGHT, "AMBIENT_LIGHT"},
+    {CHK_BIT_MAP, "BIT_MAP"},
+    {CHK_SOLID_BGND, "SOLID_BGND"},
+    {CHK_V_GRADIENT, "V_GRADIENT"},
+    {CHK_USE_BIT_MAP, "USE_BIT_MAP"},
+    {CHK_USE_SOLID_BGND, "USE_SOLID_BGND"},
+    {CHK_USE_V_GRADIENT, "USE_V_GRADIENT"},
+    {CHK_FOG, "FOG"},
+    {CHK_FOG_BGND, "FOG_BGND"},
+    {CHK_LAYER_FOG, "LAYER_FOG"},
+    {CHK_DISTANCE_CUE, "DISTANCE_CUE"},
+    {CHK_DCUE_BGND, "DCUE_BGND"},
+    {CHK_USE_FOG, "USE_FOG"},
+    {CHK_USE_LAYER_FOG, "USE_LAYER_FOG"},
+    {CHK_USE_DISTANCE_CUE, "USE_DISTANCE_CUE"},
+    {CHK_MAT_ENTRY, "MAT_ENTRY"},
+    {CHK_MAT_NAME, "MAT_NAME"},
+    {CHK_MAT_AMBIENT, "MAT_AMBIENT"},
+    {CHK_MAT_DIFFUSE, "MAT_DIFFUSE"},
+    {CHK_MAT_SPECULAR, "MAT_SPECULAR"},
+    {CHK_MAT_SHININESS, "MAT_SHININESS"},
+    {CHK_MAT_SHIN2PCT, "MAT_SHIN2PCT"},
+    {CHK_MAT_TRANSPARENCY, "MAT_TRANSPARENCY"},
+    {CHK_MAT_XPFALL, "MAT_XPFALL"},
+    {CHK_MAT_USE_XPFALL, "MAT_USE_XPFALL"},
+    {CHK_MAT_REFBLUR, "MAT_REFBLUR"},
+    {CHK_MAT_SHADING, "MAT_SHADING"},
+    {CHK_MAT_USE_REFBLUR, "MAT_USE_REFBLUR"},
+    {CHK_MAT_SELF_ILLUM, "MAT_SELF_ILLUM"},
+    {CHK_MAT_TWO_SIDE, "MAT_TWO_SIDE"},
+    {CHK_MAT_DECAL, "MAT_DECAL"},
+    {CHK_MAT_ADDITIVE, "MAT_ADDITIVE"},
+    {CHK_MAT_SELF_ILPCT, "MAT_SELF_ILPCT"},
+    {CHK_MAT_WIRE, "MAT_WIRE"},
+    {CHK_MAT_FACEMAP, "MAT_FACEMAP"},
+    {CHK_MAT_PHONGSOFT, "MAT_PHONGSOFT"},
+    {CHK_MAT_WIREABS, "MAT_WIREABS"},
+    {CHK_MAT_WIRE_SIZE, "MAT_WIRE_SIZE"},
+    {CHK_MAT_TEXMAP, "MAT_TEXMAP"},
+    {CHK_MAT_SXP_TEXT_DATA, "MAT_SXP_TEXT_DATA"},
+    {CHK_MAT_TEXMASK, "MAT_TEXMASK"},
+    {CHK_MAT_SXP_TEXTMASK_DATA, "MAT_SXP_TEXTMASK_DATA"},
+    {CHK_MAT_TEX2MAP, "MAT_TEX2MAP"},
+    {CHK_MAT_SXP_TEXT2_DATA, "MAT_SXP_TEXT2_DATA"},
+    {CHK_MAT_TEX2MASK, "MAT_TEX2MASK"},
+    {CHK_MAT_SXP_TEXT2MASK_DATA, "MAT_SXP_TEXT2MASK_DATA"},
+    {CHK_MAT_OPACMAP, "MAT_OPACMAP"},
+    {CHK_MAT_SXP_OPAC_DATA, "MAT_SXP_OPAC_DATA"},
+    {CHK_MAT_OPACMASK, "MAT_OPACMASK"},
+    {CHK_MAT_SXP_OPACMASK_DATA, "MAT_SXP_OPACMASK_DATA"},
+    {CHK_MAT_BUMPMAP, "MAT_BUMPMAP"},
+    {CHK_MAT_SXP_BUMP_DATA, "MAT_SXP_BUMP_DATA"},
+    {CHK_MAT_BUMPMASK, "MAT_BUMPMASK"},
+    {CHK_MAT_SXP_BUMPMASK_DATA, "MAT_SXP_BUMPMASK_DATA"},
+    {CHK_MAT_SPECMAP, "MAT_SPECMAP"},
+    {CHK_MAT_SXP_SPEC_DATA, "MAT_SXP_SPEC_DATA"},
+    {CHK_MAT_SPECMASK, "MAT_SPECMASK"},
+    {CHK_MAT_SXP_SPECMASK_DATA, "MAT_SXP_SPECMASK_DATA"},
+    {CHK_MAT_SHINMAP, "MAT_SHINMAP"},
+    {CHK_MAT_SXP_SHIN_DATA, "MAT_SXP_SHIN_DATA"},
+    {CHK_MAT_SHINMASK, "MAT_SHINMASK"},
+    {CHK_MAT_SXP_SHINMASK_DATA, "MAT_SXP_SHINMASK_DATA"},
+    {CHK_MAT_SELFIMAP, "MAT_SELFIMAP"},
+    {CHK_MAT_SXP_SELFI_DATA, "MAT_SXP_SELFI_DATA"},
+    {CHK_MAT_SELFIMASK, "MAT_SELFIMASK"},
+    {CHK_MAT_SXP_SELFIMASK_DATA, "MAT_SXP_SELFIMASK_DATA"},
+    {CHK_MAT_REFLMAP, "MAT_REFLMAP"},
+    {CHK_MAT_REFLMASK, "MAT_REFLMASK"},
+    {CHK_MAT_SXP_REFLMASK_DATA, "MAT_SXP_REFLMASK_DATA"},
+    {CHK_MAT_ACUBIC, "MAT_ACUBIC"},
+    {CHK_MAT_MAPNAME, "MAT_MAPNAME"},
+    {CHK_MAT_MAP_TILING, "MAT_MAP_TILING"},
+    {CHK_MAT_MAP_TEXBLUR, "MAT_MAP_TEXBLUR"},
+    {CHK_MAT_MAP_USCALE, "MAT_MAP_USCALE"},
+    {CHK_MAT_MAP_VSCALE, "MAT_MAP_VSCALE"},
+    {CHK_MAT_MAP_UOFFSET, "MAT_MAP_UOFFSET"},
+    {CHK_MAT_MAP_VOFFSET, "MAT_MAP_VOFFSET"},
+    {CHK_MAT_MAP_ANG, "MAT_MAP_ANG"},
+    {CHK_MAT_MAP_COL1, "MAT_MAP_COL1"},
+    {CHK_MAT_MAP_COL2, "MAT_MAP_COL2"},
+    {CHK_MAT_MAP_RCOL, "MAT_MAP_RCOL"},
+    {CHK_MAT_MAP_GCOL, "MAT_MAP_GCOL"},
+    {CHK_MAT_MAP_BCOL, "MAT_MAP_BCOL"},
+    {CHK_NAMED_OBJECT, "NAMED_OBJECT"},
+    {CHK_N_DIRECT_LIGHT, "N_DIRECT_LIGHT"},
+    {CHK_DL_OFF, "DL_OFF"},
+    {CHK_DL_OUTER_RANGE, "DL_OUTER_RANGE"},
+    {CHK_DL_INNER_RANGE, "DL_INNER_RANGE"},
+    {CHK_DL_MULTIPLIER, "DL_MULTIPLIER"},
+    {CHK_DL_EXCLUDE, "DL_EXCLUDE"},
+    {CHK_DL_ATTENUATE, "DL_ATTENUATE"},
+    {CHK_DL_SPOTLIGHT, "DL_SPOTLIGHT"},
+    {CHK_DL_SPOT_ROLL, "DL_SPOT_ROLL"},
+    {CHK_DL_SHADOWED, "DL_SHADOWED"},
+    {CHK_DL_LOCAL_SHADOW2, "DL_LOCAL_SHADOW2"},
+    {CHK_DL_SEE_CONE, "DL_SEE_CONE"},
+    {CHK_DL_SPOT_RECTANGULAR, "DL_SPOT_RECTANGULAR"},
+    {CHK_DL_SPOT_ASPECT, "DL_SPOT_ASPECT"},
+    {CHK_DL_SPOT_PROJECTOR, "DL_SPOT_PROJECTOR"},
+    {CHK_DL_SPOT_OVERSHOOT, "DL_SPOT_OVERSHOOT"},
+    {CHK_DL_RAY_BIAS, "DL_RAY_BIAS"},
+    {CHK_DL_RAYSHAD, "DL_RAYSHAD"},
+    {CHK_N_CAMERA, "N_CAMERA"},
+    {CHK_CAM_SEE_CONE, "CAM_SEE_CONE"},
+    {CHK_CAM_RANGES, "CAM_RANGES"},
+    {CHK_OBJ_HIDDEN, "OBJ_HIDDEN"},
+    {CHK_OBJ_VIS_LOFTER, "OBJ_VIS_LOFTER"},
+    {CHK_OBJ_DOESNT_CAST, "OBJ_DOESNT_CAST"},
+    {CHK_OBJ_DONT_RCVSHADOW, "OBJ_DONT_RCVSHADOW"},
+    {CHK_OBJ_MATTE, "OBJ_MATTE"},
+    {CHK_OBJ_FAST, "OBJ_FAST"},
+    {CHK_OBJ_PROCEDURAL, "OBJ_PROCEDURAL"},
+    {CHK_OBJ_FROZEN, "OBJ_FROZEN"},
+    {CHK_N_TRI_OBJECT, "N_TRI_OBJECT"},
+    {CHK_POINT_ARRAY, "POINT_ARRAY"},
+    {CHK_POINT_FLAG_ARRAY, "POINT_FLAG_ARRAY"},
+    {CHK_FACE_ARRAY, "FACE_ARRAY"},
+    {CHK_MSH_MAT_GROUP, "MSH_MAT_GROUP"},
+    {CHK_SMOOTH_GROUP, "SMOOTH_GROUP"},
+    {CHK_MSH_BOXMAP, "MSH_BOXMAP"},
+    {CHK_TEX_VERTS, "TEX_VERTS"},
+    {CHK_MESH_MATRIX, "MESH_MATRIX"},
+    {CHK_MESH_COLOR, "MESH_COLOR"},
+    {CHK_MESH_TEXTURE_INFO, "MESH_TEXTURE_INFO"},
+    {CHK_KFDATA, "KFDATA"},
+    {CHK_KFHDR, "KFHDR"},
+    {CHK_KFSEG, "KFSEG"},
+    {CHK_KFCURTIME, "KFCURTIME"},
+    {CHK_AMBIENT_NODE_TAG, "AMBIENT_NODE_TAG"},
+    {CHK_OBJECT_NODE_TAG, "OBJECT_NODE_TAG"},
+    {CHK_CAMERA_NODE_TAG, "CAMERA_NODE_TAG"},
+    {CHK_TARGET_NODE_TAG, "TARGET_NODE_TAG"},
+    {CHK_LIGHT_NODE_TAG, "LIGHT_NODE_TAG"},
+    {CHK_L_TARGET_NODE_TAG, "L_TARGET_NODE_TAG"},
+    {CHK_SPOTLIGHT_NODE_TAG, "SPOTLIGHT_NODE_TAG"},
+    {CHK_NODE_ID, "NODE_ID"},
+    {CHK_NODE_HDR, "NODE_HDR"},
+    {CHK_PIVOT, "PIVOT"},
+    {CHK_INSTANCE_NAME, "INSTANCE_NAME"},
+    {CHK_MORPH_SMOOTH, "MORPH_SMOOTH"},
+    {CHK_BOUNDBOX, "BOUNDBOX"},
+    {CHK_POS_TRACK_TAG, "POS_TRACK_TAG"},
+    {CHK_COL_TRACK_TAG, "COL_TRACK_TAG"},
+    {CHK_ROT_TRACK_TAG, "ROT_TRACK_TAG"},
+    {CHK_SCL_TRACK_TAG, "SCL_TRACK_TAG"},
+    {CHK_MORPH_TRACK_TAG, "MORPH_TRACK_TAG"},
+    {CHK_FOV_TRACK_TAG, "FOV_TRACK_TAG"},
+    {CHK_ROLL_TRACK_TAG, "ROLL_TRACK_TAG"},
+    {CHK_HOT_TRACK_TAG, "HOT_TRACK_TAG"},
+    {CHK_FALL_TRACK_TAG, "FALL_TRACK_TAG"},
+    {CHK_HIDE_TRACK_TAG, "HIDE_TRACK_TAG"},
+    {CHK_POLY_2D, "POLY_2D"},
+    {CHK_SHAPE_OK, "SHAPE_OK"},
+    {CHK_SHAPE_NOT_OK, "SHAPE_NOT_OK"},
+    {CHK_SHAPE_HOOK, "SHAPE_HOOK"},
+    {CHK_PATH_3D, "PATH_3D"},
+    {CHK_PATH_MATRIX, "PATH_MATRIX"},
+    {CHK_SHAPE_2D, "SHAPE_2D"},
+    {CHK_M_SCALE, "M_SCALE"},
+    {CHK_M_TWIST, "M_TWIST"},
+    {CHK_M_TEETER, "M_TEETER"},
+    {CHK_M_FIT, "M_FIT"},
+    {CHK_M_BEVEL, "M_BEVEL"},
+    {CHK_XZ_CURVE, "XZ_CURVE"},
+    {CHK_YZ_CURVE, "YZ_CURVE"},
+    {CHK_INTERPCT, "INTERPCT"},
+    {CHK_DEFORM_LIMIT, "DEFORM_LIMIT"},
+    {CHK_USE_CONTOUR, "USE_CONTOUR"},
+    {CHK_USE_TWEEN, "USE_TWEEN"},
+    {CHK_USE_SCALE, "USE_SCALE"},
+    {CHK_USE_TWIST, "USE_TWIST"},
+    {CHK_USE_TEETER, "USE_TEETER"},
+    {CHK_USE_FIT, "USE_FIT"},
+    {CHK_USE_BEVEL, "USE_BEVEL"},
+    {CHK_DEFAULT_VIEW, "DEFAULT_VIEW"},
+    {CHK_VIEW_TOP, "VIEW_TOP"},
+    {CHK_VIEW_BOTTOM, "VIEW_BOTTOM"},
+    {CHK_VIEW_LEFT, "VIEW_LEFT"},
+    {CHK_VIEW_RIGHT, "VIEW_RIGHT"},
+    {CHK_VIEW_FRONT, "VIEW_FRONT"},
+    {CHK_VIEW_BACK, "VIEW_BACK"},
+    {CHK_VIEW_USER, "VIEW_USER"},
+    {CHK_VIEW_CAMERA, "VIEW_CAMERA"},
+    {CHK_VIEW_WINDOW, "VIEW_WINDOW"},
+    {CHK_VIEWPORT_LAYOUT_OLD, "VIEWPORT_LAYOUT_OLD"},
+    {CHK_VIEWPORT_DATA_OLD, "VIEWPORT_DATA_OLD"},
+    {CHK_VIEWPORT_LAYOUT, "VIEWPORT_LAYOUT"},
+    {CHK_VIEWPORT_DATA, "VIEWPORT_DATA"},
+    {CHK_VIEWPORT_DATA_3, "VIEWPORT_DATA_3"},
+    {CHK_VIEWPORT_SIZE, "VIEWPORT_SIZE"},
+    {CHK_NETWORK_VIEW, "NETWORK_VIEW"},
+    {0, 0}
+};
+
+
+const char*
+lib3ds_chunk_name(uint16_t chunk) {
+    Lib3dsChunkTable *p;
+
+    for (p = lib3ds_chunk_table; p->name != 0; ++p) {
+        if (p->chunk == chunk) {
+            return(p->name);
+        }
+    }
+    return("***UNKNOWN***");
+}
Index: /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds.h
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds.h (revision 10853)
+++ /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds.h (revision 10853)
@@ -0,0 +1,805 @@
+/* -*- c -*- */
+#ifndef INCLUDED_LIB3DS_H
+#define INCLUDED_LIB3DS_H
+/*
+    Copyright (C) 1996-2008 by Jan Eric Kyprianidis <www.kyprianidis.com>
+    All rights reserved.
+    
+    This program is free  software: you can redistribute it and/or modify 
+    it under the terms of the GNU Lesser General Public License as published 
+    by the Free Software Foundation, either version 2.1 of the License, or 
+    (at your option) any later version.
+
+    Thisprogram  is  distributed in the hope that it will be useful, 
+    but WITHOUT ANY WARRANTY; without even the implied warranty of 
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
+    GNU Lesser General Public License for more details.
+    
+    You should  have received a copy of the GNU Lesser General Public License
+    along with  this program; If not, see <http://www.gnu.org/licenses/>. 
+ */
+
+#include <stddef.h>
+
+#ifndef LIB3DSAPI
+    #if defined(_MSC_VER) && !defined(LIB3DS_STATIC)
+        #ifdef LIB3DS_EXPORTS
+            #define LIB3DSAPI __declspec(dllexport)
+        #else               
+            #define LIB3DSAPI __declspec(dllimport)
+        #endif           
+    #else
+        #define LIB3DSAPI
+    #endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @defgroup api API */
+/** @{ */
+
+typedef enum Lib3dsIoSeek {
+    LIB3DS_SEEK_SET     = 0,
+    LIB3DS_SEEK_CUR     = 1,
+    LIB3DS_SEEK_END     = 2
+} Lib3dsIoSeek;
+
+typedef enum Lib3dsLogLevel {
+    LIB3DS_LOG_ERROR    = 0,
+    LIB3DS_LOG_WARN     = 1,
+    LIB3DS_LOG_INFO     = 2,
+    LIB3DS_LOG_DEBUG    = 3
+} Lib3dsLogLevel;
+
+typedef struct Lib3dsIo {
+    void*   impl;
+    void*   self;
+    long    (*seek_func) (void *self, long offset, Lib3dsIoSeek origin);
+    long    (*tell_func) (void *self);
+    size_t  (*read_func) (void *self, void *buffer, size_t size);
+    size_t  (*write_func)(void *self, const void *buffer, size_t size);
+    void    (*log_func)  (void *self, Lib3dsLogLevel level, int indent, const char *msg);
+} Lib3dsIo;
+
+/* Atmosphere settings */
+typedef struct Lib3dsAtmosphere {
+    int         use_fog;
+    float       fog_color[3];
+    int         fog_background;
+    float       fog_near_plane;
+    float       fog_near_density;
+    float       fog_far_plane;
+    float       fog_far_density;
+    int         use_layer_fog;
+    unsigned    layer_fog_flags;
+    float       layer_fog_color[3];
+    float       layer_fog_near_y;
+    float       layer_fog_far_y;
+    float       layer_fog_density;
+    int         use_dist_cue;
+    int         dist_cue_background;     /* bool */
+    float       dist_cue_near_plane;
+    float       dist_cue_near_dimming;
+    float       dist_cue_far_plane;
+    float       dist_cue_far_dimming;
+} Lib3dsAtmosphere;
+
+/* Background settings */
+typedef struct Lib3dsBackground {
+    int         use_bitmap;
+    char        bitmap_name[64];
+    int         use_solid;
+    float       solid_color[3];
+    int         use_gradient;
+    float       gradient_percent;
+    float       gradient_top[3];
+    float       gradient_middle[3];
+    float       gradient_bottom[3];
+} Lib3dsBackground;
+
+/* Shadow settings */
+typedef struct Lib3dsShadow {
+    short       map_size;           /* Global shadow map size that ranges from 10 to 4096 */
+    float       low_bias;           /* Global shadow low bias */
+    float       hi_bias;            /* Global shadow hi bias */
+    float       filter;             /* Global shadow filter that ranges from 1 (lowest) to 10 (highest) */
+    float       ray_bias;           /* Global raytraced shadow bias */
+} Lib3dsShadow;
+
+/* Layout view types */
+typedef enum Lib3dsViewType {
+    LIB3DS_VIEW_NOT_USED   = 0,
+    LIB3DS_VIEW_TOP        = 1,
+    LIB3DS_VIEW_BOTTOM     = 2,
+    LIB3DS_VIEW_LEFT       = 3,
+    LIB3DS_VIEW_RIGHT      = 4,
+    LIB3DS_VIEW_FRONT      = 5,
+    LIB3DS_VIEW_BACK       = 6,
+    LIB3DS_VIEW_USER       = 7,
+    LIB3DS_VIEW_SPOTLIGHT  = 18,
+    LIB3DS_VIEW_CAMERA     = 65535
+} Lib3dsViewType;
+
+/* Layout styles */
+typedef enum Lib3dsLayoutStyle {
+    LIB3DS_LAYOUT_SINGLE                    = 0,
+    LIB3DS_LAYOUT_TWO_PANE_VERT_SPLIT       = 1,
+    LIB3DS_LAYOUT_TWO_PANE_HORIZ_SPLIT      = 2,
+    LIB3DS_LAYOUT_FOUR_PANE                 = 3,
+    LIB3DS_LAYOUT_THREE_PANE_LEFT_SPLIT     = 4,
+    LIB3DS_LAYOUT_THREE_PANE_BOTTOM_SPLIT   = 5,
+    LIB3DS_LAYOUT_THREE_PANE_RIGHT_SPLIT    = 6,
+    LIB3DS_LAYOUT_THREE_PANE_TOP_SPLIT      = 7,
+    LIB3DS_LAYOUT_THREE_PANE_VERT_SPLIT     = 8,
+    LIB3DS_LAYOUT_THREE_PANE_HORIZ_SPLIT    = 9,
+    LIB3DS_LAYOUT_FOUR_PANE_LEFT_SPLIT      = 10,
+    LIB3DS_LAYOUT_FOUR_PANE_RIGHT_SPLIT     = 11
+} Lib3dsLayoutStyle;
+
+/* Layout view settings */
+typedef struct Lib3dsView {
+    int         type;
+    unsigned    axis_lock;
+    short       position[2];
+    short       size[2];
+    float       zoom;
+    float       center[3];
+    float       horiz_angle;
+    float       vert_angle;
+    char        camera[11];
+} Lib3dsView;
+
+#define LIB3DS_LAYOUT_MAX_VIEWS 32
+
+/* Viewport and default view settings */
+typedef struct Lib3dsViewport {
+    int             layout_style;
+    int             layout_active;
+    int             layout_swap;
+    int             layout_swap_prior;
+    int             layout_swap_view;
+    unsigned short  layout_position[2];
+    unsigned short  layout_size[2];
+    int             layout_nviews;
+    Lib3dsView      layout_views[LIB3DS_LAYOUT_MAX_VIEWS];
+    int             default_type;
+    float           default_position[3];
+    float           default_width;
+    float           default_horiz_angle;
+    float           default_vert_angle;
+    float           default_roll_angle;
+    char            default_camera[64];
+} Lib3dsViewport;
+
+/* Material texture map flags */
+typedef enum Lib3dsTextureMapFlags {
+    LIB3DS_TEXTURE_DECALE       = 0x0001,
+    LIB3DS_TEXTURE_MIRROR       = 0x0002,
+    LIB3DS_TEXTURE_NEGATE       = 0x0008,
+    LIB3DS_TEXTURE_NO_TILE      = 0x0010,
+    LIB3DS_TEXTURE_SUMMED_AREA  = 0x0020,
+    LIB3DS_TEXTURE_ALPHA_SOURCE = 0x0040,
+    LIB3DS_TEXTURE_TINT         = 0x0080,
+    LIB3DS_TEXTURE_IGNORE_ALPHA = 0x0100,
+    LIB3DS_TEXTURE_RGB_TINT     = 0x0200
+} Lib3dsTextureMapFlags;
+
+/* Material texture map */
+typedef struct Lib3dsTextureMap {
+    unsigned    user_id;
+    void*       user_ptr;
+    char        name[64];
+    unsigned    flags;
+    float       percent;
+    float       blur;
+    float       scale[2];
+    float       offset[2];
+    float       rotation;
+    float       tint_1[3];
+    float       tint_2[3];
+    float       tint_r[3];
+    float       tint_g[3];
+    float       tint_b[3];
+} Lib3dsTextureMap;
+
+/* Auto reflection texture map flags */
+typedef enum Lib3dsAutoReflMapFlags {
+    LIB3DS_AUTOREFL_USE                     = 0x0001,
+    LIB3DS_AUTOREFL_READ_FIRST_FRAME_ONLY   = 0x0004,
+    LIB3DS_AUTOREFL_FLAT_MIRROR             = 0x0008 
+} Lib3dsAutoReflMapFlags;
+
+/* Material shading type */
+typedef enum Lib3dsShading {
+    LIB3DS_SHADING_WIRE_FRAME = 0,
+    LIB3DS_SHADING_FLAT       = 1, 
+    LIB3DS_SHADING_GOURAUD    = 2, 
+    LIB3DS_SHADING_PHONG      = 3, 
+    LIB3DS_SHADING_METAL      = 4
+} Lib3dsShading; 
+
+/** Material */
+typedef struct Lib3dsMaterial {
+    unsigned            user_id;
+    void*               user_ptr;
+    char                name[64];           /* Material name */
+    float               ambient[3];         /* Material ambient reflectivity */
+    float               diffuse[3];         /* Material diffuse reflectivity */
+    float               specular[3];        /* Material specular reflectivity */
+    float               shininess;          /* Material specular exponent */
+    float               shin_strength;
+    int                 use_blur;
+    float               blur;
+    float               transparency;
+    float               falloff;
+    int                 is_additive;
+    int                 self_illum_flag; /* bool */
+    float               self_illum;
+    int                 use_falloff;
+    int                 shading;
+    int                 soften;         /* bool */
+    int                 face_map;       /* bool */
+    int                 two_sided;      /* Material visible from back */
+    int                 map_decal;      /* bool */
+    int                 use_wire;
+    int                 use_wire_abs;
+    float               wire_size;
+    Lib3dsTextureMap    texture1_map;
+    Lib3dsTextureMap    texture1_mask;
+    Lib3dsTextureMap    texture2_map;
+    Lib3dsTextureMap    texture2_mask;
+    Lib3dsTextureMap    opacity_map;
+    Lib3dsTextureMap    opacity_mask;
+    Lib3dsTextureMap    bump_map;
+    Lib3dsTextureMap    bump_mask;
+    Lib3dsTextureMap    specular_map;
+    Lib3dsTextureMap    specular_mask;
+    Lib3dsTextureMap    shininess_map;
+    Lib3dsTextureMap    shininess_mask;
+    Lib3dsTextureMap    self_illum_map;
+    Lib3dsTextureMap    self_illum_mask;
+    Lib3dsTextureMap    reflection_map;
+    Lib3dsTextureMap    reflection_mask;
+    unsigned            autorefl_map_flags;
+    int                 autorefl_map_anti_alias;  /* 0=None, 1=Low, 2=Medium, 3=High */
+    int                 autorefl_map_size;
+    int                 autorefl_map_frame_step;
+} Lib3dsMaterial;
+
+/** Object flags for cameras, lights and meshes */
+typedef enum Lib3dsObjectFlags {
+    LIB3DS_OBJECT_HIDDEN          = 0x01, 
+    LIB3DS_OBJECT_VIS_LOFTER      = 0x02, 
+    LIB3DS_OBJECT_DOESNT_CAST     = 0x04, 
+    LIB3DS_OBJECT_MATTE           = 0x08, 
+    LIB3DS_OBJECT_DONT_RCVSHADOW  = 0x10, 
+    LIB3DS_OBJECT_FAST            = 0x20, 
+    LIB3DS_OBJECT_FROZEN          = 0x40 
+} Lib3dsObjectFlags;
+
+/** Camera object */
+typedef struct Lib3dsCamera {
+    unsigned    user_id;
+    void*       user_ptr;
+    char        name[64];
+    unsigned    object_flags; /*< @see Lib3dsObjectFlags */ 
+    float       position[3];
+    float       target[3];
+    float       roll;
+    float       fov;
+    int         see_cone;
+    float       near_range;
+    float       far_range;
+} Lib3dsCamera; 
+
+/** Light object */
+typedef struct Lib3dsLight {
+    unsigned    user_id;
+    void*       user_ptr;
+    char        name[64];
+    unsigned    object_flags; 
+    int         spot_light;     /* bool */
+    int         see_cone;
+    float       color[3];
+    float       position[3];
+    float       target[3];
+    float       roll;
+    int         off;              /* bool */
+    float       outer_range;
+    float       inner_range;
+    float       multiplier;
+    /*const char**  excludes;*/
+    float       attenuation;
+    int         rectangular_spot;   /* bool */
+    int         shadowed;           /* bool */
+    float       shadow_bias;
+    float       shadow_filter;
+    int         shadow_size;
+    float       spot_aspect;
+    int         use_projector;
+    char        projector[64];
+    int         spot_overshoot;      /* bool */
+    int         ray_shadows;         /* bool */
+    float       ray_bias;
+    float       hotspot;
+    float       falloff;
+} Lib3dsLight; 
+
+/* Texture map projection */
+typedef enum {
+  LIB3DS_MAP_NONE           = -1,
+  LIB3DS_MAP_PLANAR         = 0,
+  LIB3DS_MAP_CYLINDRICAL    = 1,
+  LIB3DS_MAP_SPHERICAL      = 2
+} Lib3dsMapType;
+
+/**  Meaning of Lib3dsFace::flags. ABC are points of the current face 
+    (A: is 1st vertex, B is 2nd vertex, C is 3rd vertex) */
+typedef enum Lib3dsFaceFlags {
+  LIB3DS_FACE_VIS_AC    = 0x01,       /**< Bit 0: Edge visibility AC */
+  LIB3DS_FACE_VIS_BC    = 0x02,       /**< Bit 1: Edge visibility BC */
+  LIB3DS_FACE_VIS_AB    = 0x04,       /**< Bit 2: Edge visibility AB */
+  LIB3DS_FACE_WRAP_U    = 0x08,       /**< Bit 3: Face is at tex U wrap seam */
+  LIB3DS_FACE_WRAP_V    = 0x10,       /**< Bit 4: Face is at tex V wrap seam */
+  LIB3DS_FACE_SELECT_3  = (1<<13),    /**< Bit 13: Selection of the face in selection 3*/
+  LIB3DS_FACE_SELECT_2  = (1<<14),    /**< Bit 14: Selection of the face in selection 2*/
+  LIB3DS_FACE_SELECT_1  = (1<<15)    /**< Bit 15: Selection of the face in selection 1*/
+} Lib3dsFaceFlags;
+
+typedef struct Lib3dsFace {
+    unsigned short  index[3];
+    unsigned short  flags;
+    int             material;
+    unsigned        smoothing_group;
+} Lib3dsFace; 
+
+/* Triangular mesh object */
+typedef struct Lib3dsMesh {
+    unsigned        user_id;
+    void*           user_ptr;
+    char            name[64];            /**< Mesh name. Don't use more than 8 characters  */
+    unsigned        object_flags;        /**< @see Lib3dsObjectFlags */ 
+    int             color;               /**< Index to editor palette [0..255] */
+    float           matrix[4][4];        /**< Transformation matrix for mesh data */
+    unsigned short  nvertices;           /**< Number of vertices in vertex array (max. 65535) */
+    float           (*vertices)[3];
+    float           (*texcos)[2];
+    unsigned short* vflags;
+    unsigned short  nfaces;              /**< Number of faces in face array (max. 65535) */
+    Lib3dsFace*     faces;               
+    char            box_front[64];
+    char            box_back[64];
+    char            box_left[64];
+    char            box_right[64];
+    char            box_top[64];
+    char            box_bottom[64];
+    int             map_type;
+    float           map_pos[3];
+    float           map_matrix[4][4];
+    float           map_scale;
+    float           map_tile[2];
+    float           map_planar_size[2];
+    float           map_cylinder_height;
+} Lib3dsMesh; 
+
+typedef enum Lib3dsNodeType {
+    LIB3DS_NODE_AMBIENT_COLOR   = 0,
+    LIB3DS_NODE_MESH_INSTANCE   = 1,
+    LIB3DS_NODE_CAMERA          = 2,
+    LIB3DS_NODE_CAMERA_TARGET   = 3,
+    LIB3DS_NODE_OMNILIGHT       = 4,
+    LIB3DS_NODE_SPOTLIGHT       = 5,
+    LIB3DS_NODE_SPOTLIGHT_TARGET= 6
+} Lib3dsNodeType;
+
+typedef enum Lib3dsNodeFlags{
+    LIB3DS_NODE_HIDDEN           = 0x000800,
+    LIB3DS_NODE_SHOW_PATH        = 0x010000,
+    LIB3DS_NODE_SMOOTHING        = 0x020000,
+    LIB3DS_NODE_MOTION_BLUR      = 0x100000,
+    LIB3DS_NODE_MORPH_MATERIALS  = 0x400000
+} Lib3dsNodeFlags;
+
+typedef struct Lib3dsNode {
+    unsigned            user_id;
+    void*               user_ptr;
+    struct Lib3dsNode*  next;
+    struct Lib3dsNode*  childs;
+    struct Lib3dsNode*  parent;
+    Lib3dsNodeType      type;
+    unsigned short      node_id;            /**< 0..65535 */
+    char                name[64];
+    unsigned            flags;
+    float               matrix[4][4];
+} Lib3dsNode;
+
+typedef enum Lib3dsKeyFlags {
+    LIB3DS_KEY_USE_TENS         = 0x01,
+    LIB3DS_KEY_USE_CONT         = 0x02,
+    LIB3DS_KEY_USE_BIAS         = 0x04,
+    LIB3DS_KEY_USE_EASE_TO      = 0x08,
+    LIB3DS_KEY_USE_EASE_FROM    = 0x10
+} Lib3dsKeyFlags;
+
+typedef struct Lib3dsKey {
+    int         frame;
+    unsigned    flags;
+    float       tens;
+    float       cont;
+    float       bias;
+    float       ease_to;
+    float       ease_from;
+    float       value[4];
+} Lib3dsKey;
+
+typedef enum Lib3dsTrackType {
+    LIB3DS_TRACK_BOOL   = 0,
+    LIB3DS_TRACK_FLOAT  = 1,
+    LIB3DS_TRACK_VECTOR = 3,
+    LIB3DS_TRACK_QUAT   = 4
+} Lib3dsTrackType;
+
+typedef enum {
+    LIB3DS_TRACK_REPEAT   = 0x0001,
+    LIB3DS_TRACK_SMOOTH   = 0x0002,
+    LIB3DS_TRACK_LOCK_X   = 0x0008,
+    LIB3DS_TRACK_LOCK_Y   = 0x0010,
+    LIB3DS_TRACK_LOCK_Z   = 0x0020,
+    LIB3DS_TRACK_UNLINK_X = 0x0100,
+    LIB3DS_TRACK_UNLINK_Y = 0x0200,
+    LIB3DS_TRACK_UNLINK_Z = 0x0400
+} Lib3dsTrackFlags;
+
+typedef struct Lib3dsTrack {
+    unsigned        flags;
+    Lib3dsTrackType type; 
+    int             nkeys;
+    Lib3dsKey*      keys;   
+} Lib3dsTrack;
+
+typedef struct Lib3dsAmbientColorNode {
+    Lib3dsNode      base;
+    float           color[3];
+    Lib3dsTrack     color_track;
+} Lib3dsAmbientColorNode;
+
+typedef struct Lib3dsMeshInstanceNode {
+    Lib3dsNode      base;
+    float           pivot[3];
+    char            instance_name[64];
+    float           bbox_min[3];
+    float           bbox_max[3];
+    int             hide;
+    float           pos[3];
+    float           rot[4];
+    float           scl[3];
+    float           morph_smooth;
+    char            morph[64];
+    Lib3dsTrack     pos_track;
+    Lib3dsTrack     rot_track;
+    Lib3dsTrack     scl_track;
+    Lib3dsTrack     hide_track;
+} Lib3dsMeshInstanceNode;
+
+typedef struct Lib3dsCameraNode {
+    Lib3dsNode      base;
+    float           pos[3];
+    float           fov;
+    float           roll;
+    Lib3dsTrack     pos_track;
+    Lib3dsTrack     fov_track;
+    Lib3dsTrack     roll_track;
+} Lib3dsCameraNode;
+
+typedef struct Lib3dsTargetNode {
+    Lib3dsNode      base;
+    float           pos[3];
+    Lib3dsTrack     pos_track;
+} Lib3dsTargetNode;
+
+typedef struct Lib3dsOmnilightNode {
+    Lib3dsNode      base;
+    float           pos[3];
+    float           color[3];
+    Lib3dsTrack     pos_track;
+    Lib3dsTrack     color_track;
+} Lib3dsOmnilightNode;
+
+typedef struct Lib3dsSpotlightNode {
+    Lib3dsNode      base;
+    float           pos[3];
+    float           color[3];
+    float           hotspot;
+    float           falloff;
+    float           roll;
+    Lib3dsTrack     pos_track;
+    Lib3dsTrack     color_track;
+    Lib3dsTrack     hotspot_track;
+    Lib3dsTrack     falloff_track;
+    Lib3dsTrack     roll_track;
+} Lib3dsSpotlightNode;
+
+typedef struct Lib3dsFile {
+    unsigned            user_id;
+    void*               user_ptr;
+    unsigned            mesh_version;
+    unsigned            keyf_revision;
+    char                name[12+1];
+    float               master_scale;
+    float               construction_plane[3];
+    float               ambient[3];
+    Lib3dsShadow        shadow;
+    Lib3dsBackground    background;
+    Lib3dsAtmosphere    atmosphere;
+    Lib3dsViewport      viewport;
+    Lib3dsViewport      viewport_keyf;
+    int                 frames;
+    int                 segment_from;
+    int                 segment_to;
+    int                 current_frame;
+    int                 materials_size;
+    int                 nmaterials;         
+    Lib3dsMaterial**    materials;        
+    int                 cameras_size;  
+    int                 ncameras;                      
+    Lib3dsCamera**      cameras;
+    int                 lights_size;
+    int                 nlights;                      
+    Lib3dsLight**       lights;
+    int                 meshes_size;
+    int                 nmeshes;                      
+    Lib3dsMesh**        meshes;                         
+    Lib3dsNode*         nodes;
+} Lib3dsFile; 
+
+extern LIB3DSAPI Lib3dsFile* lib3ds_file_open(const char *filename);
+extern LIB3DSAPI int lib3ds_file_save(Lib3dsFile *file, const char *filename);
+extern LIB3DSAPI Lib3dsFile* lib3ds_file_new();
+extern LIB3DSAPI void lib3ds_file_free(Lib3dsFile *file);
+extern LIB3DSAPI void lib3ds_file_eval(Lib3dsFile *file, float t);
+extern LIB3DSAPI int lib3ds_file_read(Lib3dsFile *file, Lib3dsIo *io);
+extern LIB3DSAPI int lib3ds_file_write(Lib3dsFile *file, Lib3dsIo *io);
+extern LIB3DSAPI void lib3ds_file_reserve_materials(Lib3dsFile *file, int size, int force);
+extern LIB3DSAPI void lib3ds_file_insert_material(Lib3dsFile *file, Lib3dsMaterial *material, int index);
+extern LIB3DSAPI void lib3ds_file_remove_material(Lib3dsFile *file, int index);
+extern LIB3DSAPI int lib3ds_file_material_by_name(Lib3dsFile *file, const char *name);
+extern LIB3DSAPI void lib3ds_file_reserve_cameras(Lib3dsFile *file, int size, int force);
+extern LIB3DSAPI void lib3ds_file_insert_camera(Lib3dsFile *file, Lib3dsCamera *camera, int index);
+extern LIB3DSAPI void lib3ds_file_remove_camera(Lib3dsFile *file, int index);
+extern LIB3DSAPI int lib3ds_file_camera_by_name(Lib3dsFile *file, const char *name);
+extern LIB3DSAPI void lib3ds_file_reserve_lights(Lib3dsFile *file, int size, int force);
+extern LIB3DSAPI void lib3ds_file_insert_light(Lib3dsFile *file, Lib3dsLight *light, int index);
+extern LIB3DSAPI void lib3ds_file_remove_light(Lib3dsFile *file, int index);
+extern LIB3DSAPI int lib3ds_file_light_by_name(Lib3dsFile *file, const char *name);
+extern LIB3DSAPI void lib3ds_file_reserve_meshes(Lib3dsFile *file, int size, int force);
+extern LIB3DSAPI void lib3ds_file_insert_mesh(Lib3dsFile *file, Lib3dsMesh *mesh, int index);
+extern LIB3DSAPI void lib3ds_file_remove_mesh(Lib3dsFile *file, int index);
+extern LIB3DSAPI int lib3ds_file_mesh_by_name(Lib3dsFile *file, const char *name);
+extern LIB3DSAPI Lib3dsMesh* lib3ds_file_mesh_for_node(Lib3dsFile *file, Lib3dsNode *node);
+extern LIB3DSAPI Lib3dsNode* lib3ds_file_node_by_name(Lib3dsFile *file, const char* name, Lib3dsNodeType type);
+extern LIB3DSAPI Lib3dsNode* lib3ds_file_node_by_id(Lib3dsFile *file, unsigned short node_id);
+extern LIB3DSAPI void lib3ds_file_append_node(Lib3dsFile *file, Lib3dsNode *node, Lib3dsNode *parent);
+extern LIB3DSAPI void lib3ds_file_insert_node(Lib3dsFile *file, Lib3dsNode *node, Lib3dsNode *at);
+extern LIB3DSAPI void lib3ds_file_remove_node(Lib3dsFile *file, Lib3dsNode *node);
+extern LIB3DSAPI void lib3ds_file_minmax_node_id(Lib3dsFile *file, unsigned short *min_id, unsigned short *max_id);
+extern LIB3DSAPI void lib3ds_file_create_nodes_for_meshes(Lib3dsFile *file);
+
+
+/**
+    This function computes the bounding box of meshes, cameras 
+    and lights defined in the 3D editor.
+
+    \param file             The Lib3dsFile object to be examined.
+    \param include_meshes   Include meshes in bounding box calculation.
+    \param include_cameras  Include cameras in bounding box calculation.
+    \param include_lights   Include lights in bounding box calculation.
+    \param bmin             Returned minimum x,y,z values.
+    \param bmax             Returned maximum x,y,z values.
+ */
+extern LIB3DSAPI void lib3ds_file_bounding_box_of_objects(
+    Lib3dsFile *file, 
+    int include_meshes, 
+    int include_cameras,
+    int include_lights,
+    float bmin[3],
+    float bmax[3]);
+
+/**
+    This function computes the bounding box of mesh, camera 
+    and light instances defined in the Keyframer.
+    
+    \param file             The Lib3dsFile object to be examined.
+    \param include_meshes   Include meshes in bounding box calculation.
+    \param include_cameras  Include cameras in bounding box calculation.
+    \param include_lights   Include lights in bounding box calculation.
+    \param bmin             Returned minimum x,y,z values.
+    \param bmax             Returned maximum x,y,z values.
+    \param matrix           A matrix describing the coordinate system to
+                            calculate the bounding box in.
+ */
+extern LIB3DSAPI void lib3ds_file_bounding_box_of_nodes(
+    Lib3dsFile *file, 
+    int include_meshes, 
+    int include_cameras, 
+    int include_lights, 
+    float bmin[3], 
+    float bmax[3], 
+    float matrix[4][4]);
+
+extern LIB3DSAPI Lib3dsMaterial* lib3ds_material_new(const char *name);
+extern LIB3DSAPI void lib3ds_material_free(Lib3dsMaterial *material);
+extern LIB3DSAPI Lib3dsCamera* lib3ds_camera_new(const char *name);
+extern LIB3DSAPI void lib3ds_camera_free(Lib3dsCamera *mesh);
+extern LIB3DSAPI Lib3dsLight* lib3ds_light_new(const char *name);
+extern LIB3DSAPI void lib3ds_light_free(Lib3dsLight *mesh);
+extern LIB3DSAPI Lib3dsMesh* lib3ds_mesh_new(const char *name);
+extern LIB3DSAPI void lib3ds_mesh_free(Lib3dsMesh *mesh);
+extern LIB3DSAPI void lib3ds_mesh_resize_vertices(Lib3dsMesh *mesh, int nvertices, int use_texcos, int use_flags);
+extern LIB3DSAPI void lib3ds_mesh_resize_faces(Lib3dsMesh *mesh, int nfaces);
+extern LIB3DSAPI void lib3ds_mesh_bounding_box(Lib3dsMesh *mesh, float bmin[3], float bmax[3]);
+extern LIB3DSAPI void lib3ds_mesh_calculate_face_normals(Lib3dsMesh *mesh, float (*face_normals)[3]);
+extern LIB3DSAPI void lib3ds_mesh_calculate_vertex_normals(Lib3dsMesh *mesh, float (*normals)[3]);
+
+extern LIB3DSAPI Lib3dsNode* lib3ds_node_new(Lib3dsNodeType type);
+extern LIB3DSAPI Lib3dsAmbientColorNode* lib3ds_node_new_ambient_color(float color0[3]);
+extern LIB3DSAPI Lib3dsMeshInstanceNode* lib3ds_node_new_mesh_instance(Lib3dsMesh *mesh, const char* instance_name, float pos0[3], float scl0[3], float rot0[4]);
+extern LIB3DSAPI Lib3dsCameraNode* lib3ds_node_new_camera(Lib3dsCamera *camera);
+extern LIB3DSAPI Lib3dsTargetNode* lib3ds_node_new_camera_target(Lib3dsCamera *camera);
+extern LIB3DSAPI Lib3dsOmnilightNode* lib3ds_node_new_omnilight(Lib3dsLight *light);
+extern LIB3DSAPI Lib3dsSpotlightNode* lib3ds_node_new_spotlight(Lib3dsLight *light);
+extern LIB3DSAPI Lib3dsTargetNode* lib3ds_node_new_spotlight_target(Lib3dsLight *light);
+extern LIB3DSAPI void lib3ds_node_free(Lib3dsNode *node);
+extern LIB3DSAPI void lib3ds_node_eval(Lib3dsNode *node, float t);
+extern LIB3DSAPI Lib3dsNode* lib3ds_node_by_name(Lib3dsNode *node, const char* name, Lib3dsNodeType type);
+extern LIB3DSAPI Lib3dsNode* lib3ds_node_by_id(Lib3dsNode *node, unsigned short node_id);
+
+extern LIB3DSAPI Lib3dsTrack* lib3ds_track_new(Lib3dsTrackType type, int nkeys);
+extern LIB3DSAPI void lib3ds_track_free(Lib3dsTrack *track);
+extern LIB3DSAPI void lib3ds_track_resize(Lib3dsTrack *track, int nkeys);
+extern LIB3DSAPI void lib3ds_track_eval_bool(Lib3dsTrack *track, int *b, float t);
+extern LIB3DSAPI void lib3ds_track_eval_float(Lib3dsTrack *track, float *f, float t);
+extern LIB3DSAPI void lib3ds_track_eval_vector(Lib3dsTrack *track, float v[3], float t);
+extern LIB3DSAPI void lib3ds_track_eval_quat(Lib3dsTrack *track, float q[4], float t);
+
+/** 
+    Calculates the ease in/out function. See Lib3dsKey for details. 
+    
+    \param fp           Previous frame number.
+    \param fc           Current frame number.
+    \param fn           Next frame number. 
+    \param ease_from    Ease in value [0, 1.0] 
+    \param ease_to      Ease out value [0, 1.0]
+*/
+extern LIB3DSAPI float lib3ds_math_ease(
+    float fp,
+    float fc,
+    float fn,
+    float ease_from,
+    float ease_to);
+
+/**  
+    Computes a point on a n-dimensional cubic hermite spline. 
+    \param v   
+        [out] Result 
+    \param a
+        [in] First point of the spline.
+    \param p   
+        [in] Tangent at the first point of the spline.
+    \param q
+        [in] Tangent at the second point of the spline.
+    \param b
+        [in] Second point of the spline.
+    \param n
+        [in] Dimension
+    \param t
+        [in] Parameter value [0...1] 
+*/
+extern LIB3DSAPI void lib3ds_math_cubic_interp(
+    float *v, 
+    float *a,
+    float *p,
+    float *q,
+    float *b,
+    int n,
+    float t);
+
+extern LIB3DSAPI void lib3ds_vector_make(
+    float c[3],
+    float x,
+    float y,
+    float z);
+
+/** 
+    Sets all components of a vector to zero. 
+    \param c
+        The Pointer to the vector.
+*/
+extern LIB3DSAPI void lib3ds_vector_zero(
+    float c[3]);
+
+/** 
+    Copies all components of a vector to another vector. 
+    \param dst
+        [out] The destination vector.
+    \param src
+        [in] The source vector.
+*/
+extern LIB3DSAPI void lib3ds_vector_copy( 
+    float dst[3],  
+    float src[3]);
+
+/** 
+    Negates all components of a vector. 
+    \param c
+        The Pointer to the vector.
+*/
+extern LIB3DSAPI void lib3ds_vector_neg(
+    float c[3]);
+
+extern LIB3DSAPI void lib3ds_vector_make(float c[3], float x, float y, float z);
+extern LIB3DSAPI void lib3ds_vector_zero(float c[3]);
+extern LIB3DSAPI void lib3ds_vector_add(float c[3], float a[3], float b[3]);
+extern LIB3DSAPI void lib3ds_vector_sub(float c[3], float a[3], float b[3]);
+extern LIB3DSAPI void lib3ds_vector_scalar_mul(float c[3], float a[3], float k);
+extern LIB3DSAPI void lib3ds_vector_cross(float c[3], float a[3], float b[3]);
+extern LIB3DSAPI float lib3ds_vector_dot(float a[3], float b[3]);
+extern LIB3DSAPI float lib3ds_vector_length(float c[3]);
+extern LIB3DSAPI void lib3ds_vector_normalize(float c[3]);
+extern LIB3DSAPI void lib3ds_vector_normal(float n[3], float a[3], float b[3], float c[3]);
+extern LIB3DSAPI void lib3ds_vector_min(float c[3], float a[3]);
+extern LIB3DSAPI void lib3ds_vector_max(float c[3], float a[3]);
+extern LIB3DSAPI void lib3ds_vector_transform(float c[3], float m[4][4], float a[3]);
+
+extern LIB3DSAPI void lib3ds_quat_identity(float c[4]);
+extern LIB3DSAPI void lib3ds_quat_copy(float dest[4], float src[4]);
+extern LIB3DSAPI void lib3ds_quat_axis_angle(float c[4], float axis[3], float angle);
+extern LIB3DSAPI void lib3ds_quat_neg(float c[4]);
+extern LIB3DSAPI void lib3ds_quat_cnj(float c[4]);
+extern LIB3DSAPI void lib3ds_quat_mul(float c[4], float a[4], float b[4]);
+extern LIB3DSAPI void lib3ds_quat_scalar(float c[4], float k);
+extern LIB3DSAPI void lib3ds_quat_normalize(float c[4]);
+extern LIB3DSAPI void lib3ds_quat_inv(float c[4]);
+extern LIB3DSAPI float lib3ds_quat_dot(float a[4], float b[4]);
+extern LIB3DSAPI float lib3ds_quat_norm(float c[4]);
+extern LIB3DSAPI void lib3ds_quat_ln(float c[4]);
+extern LIB3DSAPI void lib3ds_quat_ln_dif(float c[4], float a[4], float b[4]);
+extern LIB3DSAPI void lib3ds_quat_exp(float c[4]);
+extern LIB3DSAPI void lib3ds_quat_slerp(float c[4], float a[4], float b[4], float t);
+extern LIB3DSAPI void lib3ds_quat_squad(float c[4], float a[4], float p[4], float q[4], float b[4], float t);
+extern LIB3DSAPI void lib3ds_quat_tangent(float c[4], float p[4], float q[4], float n[4]);
+
+extern LIB3DSAPI void lib3ds_matrix_zero(float m[4][4]);
+extern LIB3DSAPI void lib3ds_matrix_identity(float  m[4][4]);
+extern LIB3DSAPI void lib3ds_matrix_copy(float dest[4][4], float src[4][4]);
+extern LIB3DSAPI void lib3ds_matrix_neg(float m[4][4]);
+extern LIB3DSAPI void lib3ds_matrix_transpose(float m[4][4]);
+extern LIB3DSAPI void lib3ds_matrix_add(float m[4][4], float a[4][4], float b[4][4]);
+extern LIB3DSAPI void lib3ds_matrix_sub(float m[4][4], float a[4][4], float b[4][4]);
+extern LIB3DSAPI void lib3ds_matrix_mult(float m[4][4], float a[4][4], float b[4][4]);
+extern LIB3DSAPI void lib3ds_matrix_scalar(float m[4][4], float k);
+extern LIB3DSAPI float lib3ds_matrix_det(float m[4][4]);
+extern LIB3DSAPI int lib3ds_matrix_inv(float m[4][4]);
+extern LIB3DSAPI void lib3ds_matrix_translate(float m[4][4], float x, float y, float z);
+extern LIB3DSAPI void lib3ds_matrix_scale(float m[4][4], float x, float y, float z);
+extern LIB3DSAPI void lib3ds_matrix_rotate_quat(float m[4][4], float q[4]);
+extern LIB3DSAPI void lib3ds_matrix_rotate(float m[4][4], float angle, float ax, float ay, float az);
+extern LIB3DSAPI void lib3ds_matrix_camera(float m[4][4], float pos[3], float tgt[3], float roll);
+
+/* --- Code for OpenSceneGraph --- */
+extern LIB3DSAPI void setByteOrder();
+
+/* Definitions for compatibility with previous lib3DS used: */
+typedef float Lib3dsMatrix[4][4];
+typedef float Lib3dsVector[3];
+typedef void Lib3dsUserData;
+/* --- (end) Code for OpenSceneGraph --- */
+
+
+/** @} */
+#ifdef __cplusplus
+}
+#endif
+#endif
+
Index: /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_node.c
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_node.c (revision 10853)
+++ /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_node.c (revision 10853)
@@ -0,0 +1,1062 @@
+/*
+    Copyright (C) 1996-2008 by Jan Eric Kyprianidis <www.kyprianidis.com>
+    All rights reserved.
+    
+    This program is free  software: you can redistribute it and/or modify 
+    it under the terms of the GNU Lesser General Public License as published 
+    by the Free Software Foundation, either version 2.1 of the License, or 
+    (at your option) any later version.
+
+    Thisprogram  is  distributed in the hope that it will be useful, 
+    but WITHOUT ANY WARRANTY; without even the implied warranty of 
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
+    GNU Lesser General Public License for more details.
+    
+    You should  have received a copy of the GNU Lesser General Public License
+    along with  this program; If not, see <http://www.gnu.org/licenses/>. 
+*/
+#include "lib3ds_impl.h"
+
+
+/*!
+ * Create and return a new node object.
+ *
+ * The node is returned with an identity matrix. All other fields
+ * are zero.
+ *
+ * \return Lib3dsNode
+ */
+Lib3dsNode*
+lib3ds_node_new(Lib3dsNodeType type) {
+    Lib3dsNode *node;
+    switch (type) {
+        case LIB3DS_NODE_AMBIENT_COLOR: {
+            Lib3dsAmbientColorNode *n = (Lib3dsAmbientColorNode*)calloc(sizeof(Lib3dsAmbientColorNode), 1);
+            node = (Lib3dsNode*)n;
+            strcpy(node->name, "$AMBIENT$");
+            n->color_track.type = LIB3DS_TRACK_VECTOR;
+            break;
+        }
+
+        case LIB3DS_NODE_MESH_INSTANCE: {
+            Lib3dsMeshInstanceNode *n = (Lib3dsMeshInstanceNode*)calloc(sizeof(Lib3dsMeshInstanceNode), 1);
+            node = (Lib3dsNode*)n;
+            strcpy(node->name, "$$$DUMMY");
+            n->pos_track.type = LIB3DS_TRACK_VECTOR;
+            n->scl_track.type = LIB3DS_TRACK_VECTOR;
+            n->rot_track.type = LIB3DS_TRACK_QUAT;
+            n->hide_track.type = LIB3DS_TRACK_BOOL;
+            break;
+        }
+
+        case LIB3DS_NODE_CAMERA: {
+            Lib3dsCameraNode *n = (Lib3dsCameraNode*)calloc(sizeof(Lib3dsCameraNode), 1);
+            node = (Lib3dsNode*)n;
+            n->pos_track.type = LIB3DS_TRACK_VECTOR;
+            n->fov_track.type = LIB3DS_TRACK_FLOAT;
+            n->roll_track.type = LIB3DS_TRACK_FLOAT;
+            break;
+        }
+
+        case LIB3DS_NODE_CAMERA_TARGET: {
+            Lib3dsTargetNode *n = (Lib3dsTargetNode*)calloc(sizeof(Lib3dsTargetNode), 1);
+            node = (Lib3dsNode*)n;
+            n->pos_track.type = LIB3DS_TRACK_VECTOR;
+            break;
+        }
+
+        case LIB3DS_NODE_OMNILIGHT: {
+            Lib3dsOmnilightNode *n = (Lib3dsOmnilightNode*)calloc(sizeof(Lib3dsOmnilightNode), 1);
+            node = (Lib3dsNode*)n;
+            n->pos_track.type = LIB3DS_TRACK_VECTOR;
+            n->color_track.type = LIB3DS_TRACK_VECTOR;
+            break;
+        }
+
+        case LIB3DS_NODE_SPOTLIGHT: {
+            Lib3dsSpotlightNode *n = (Lib3dsSpotlightNode*)calloc(sizeof(Lib3dsSpotlightNode), 1);
+            node = (Lib3dsNode*)n;
+            n->pos_track.type = LIB3DS_TRACK_VECTOR;
+            n->color_track.type = LIB3DS_TRACK_VECTOR;
+            n->hotspot_track.type = LIB3DS_TRACK_FLOAT;
+            n->falloff_track.type = LIB3DS_TRACK_FLOAT;
+            n->roll_track.type = LIB3DS_TRACK_FLOAT;
+            break;
+        }
+
+        case LIB3DS_NODE_SPOTLIGHT_TARGET: {
+            Lib3dsTargetNode *n = (Lib3dsTargetNode*)calloc(sizeof(Lib3dsTargetNode), 1);
+            node = (Lib3dsNode*)n;
+            n->pos_track.type = LIB3DS_TRACK_VECTOR;
+            break;
+        }
+
+        default:
+            assert(0);
+            return NULL;
+    }
+
+    node->type = type;
+    node->node_id = 65535;
+    node->user_id = 65535;
+    lib3ds_matrix_identity(node->matrix);
+    return node;
+}
+
+
+Lib3dsAmbientColorNode* 
+lib3ds_node_new_ambient_color(float color0[3]) {
+    Lib3dsNode *node;
+    Lib3dsAmbientColorNode *n;
+
+    node = lib3ds_node_new(LIB3DS_NODE_AMBIENT_COLOR);
+
+    n = (Lib3dsAmbientColorNode*)node;
+    lib3ds_track_resize(&n->color_track, 1);
+    if (color0) {
+        lib3ds_vector_copy(n->color_track.keys[0].value, color0);
+    } else {
+        lib3ds_vector_zero(n->color_track.keys[0].value);
+    }
+
+    return n;
+}
+
+
+Lib3dsMeshInstanceNode* 
+lib3ds_node_new_mesh_instance(Lib3dsMesh *mesh, const char *instance_name, float pos0[3], float scl0[3], float rot0[4]) {
+    Lib3dsNode *node;
+    Lib3dsMeshInstanceNode *n;
+    int i;
+
+    node = lib3ds_node_new(LIB3DS_NODE_MESH_INSTANCE);
+    if (mesh) {
+        strcpy(node->name, mesh->name);
+    } else {
+        strcpy(node->name, "$$$DUMMY");
+    }
+
+    n = (Lib3dsMeshInstanceNode*)node;
+    if (instance_name) {
+        strcpy(n->instance_name, instance_name);
+    }
+
+    lib3ds_track_resize(&n->pos_track, 1);
+    if (pos0) {
+        lib3ds_vector_copy(n->pos_track.keys[0].value, pos0);
+    }
+
+    lib3ds_track_resize(&n->scl_track, 1);
+    if (scl0) {
+        lib3ds_vector_copy(n->scl_track.keys[0].value, scl0);
+    } else {
+        lib3ds_vector_make(n->scl_track.keys[0].value, 1, 1, 1);
+    }
+
+    lib3ds_track_resize(&n->rot_track, 1);
+    if (rot0) {
+        for (i = 0; i < 4; ++i) n->rot_track.keys[0].value[i] = rot0[i];
+    } else {
+        for (i = 0; i < 4; ++i) n->rot_track.keys[0].value[i] = 0;
+    }
+
+    return n;
+}
+
+
+Lib3dsCameraNode* 
+lib3ds_node_new_camera(Lib3dsCamera *camera) {
+    Lib3dsNode *node = lib3ds_node_new(LIB3DS_NODE_CAMERA);
+    Lib3dsCameraNode *n;
+    
+    assert(camera);
+    node = lib3ds_node_new(LIB3DS_NODE_CAMERA);
+    strcpy(node->name, camera->name);
+
+    n = (Lib3dsCameraNode*)node;
+    lib3ds_track_resize(&n->pos_track, 1);
+    lib3ds_vector_copy(n->pos_track.keys[0].value, camera->position);
+
+    lib3ds_track_resize(&n->fov_track, 1);
+    n->fov_track.keys[0].value[0] = camera->fov;
+
+    lib3ds_track_resize(&n->roll_track, 1);
+    n->roll_track.keys[0].value[0] = camera->roll;
+
+    return n;
+}
+
+
+Lib3dsTargetNode* 
+lib3ds_node_new_camera_target(Lib3dsCamera *camera) {
+    Lib3dsNode *node;
+    Lib3dsTargetNode *n;
+    
+    assert(camera);
+    node = lib3ds_node_new(LIB3DS_NODE_CAMERA_TARGET);
+    strcpy(node->name, camera->name);
+
+    n = (Lib3dsTargetNode*)node;
+    lib3ds_track_resize(&n->pos_track, 1);
+    lib3ds_vector_copy(n->pos_track.keys[0].value, camera->target);
+
+    return n;
+}
+
+
+Lib3dsOmnilightNode* 
+lib3ds_node_new_omnilight(Lib3dsLight *light) {
+    Lib3dsNode *node;
+    Lib3dsOmnilightNode *n;
+
+    assert(light);
+    node = lib3ds_node_new(LIB3DS_NODE_OMNILIGHT);
+    strcpy(node->name, light->name);
+
+    n = (Lib3dsOmnilightNode*)node;
+    lib3ds_track_resize(&n->pos_track, 1);
+    lib3ds_vector_copy(n->pos_track.keys[0].value, light->position);
+
+    lib3ds_track_resize(&n->color_track, 1);
+    lib3ds_vector_copy(n->color_track.keys[0].value, light->color);
+
+    return n;
+}
+
+
+Lib3dsSpotlightNode* 
+lib3ds_node_new_spotlight(Lib3dsLight *light) {
+    Lib3dsNode *node;
+    Lib3dsSpotlightNode *n;
+
+    assert(light);
+    node = lib3ds_node_new(LIB3DS_NODE_SPOTLIGHT);
+    strcpy(node->name, light->name);
+
+    n = (Lib3dsSpotlightNode*)node;
+    lib3ds_track_resize(&n->pos_track, 1);
+    lib3ds_vector_copy(n->pos_track.keys[0].value, light->position);
+
+    lib3ds_track_resize(&n->color_track, 1);
+    lib3ds_vector_copy(n->color_track.keys[0].value, light->color);
+
+    lib3ds_track_resize(&n->hotspot_track, 1);
+    n->hotspot_track.keys[0].value[0] = light->hotspot;
+
+    lib3ds_track_resize(&n->falloff_track, 1);
+    n->falloff_track.keys[0].value[0] = light->falloff;
+
+    lib3ds_track_resize(&n->roll_track, 1);
+    n->roll_track.keys[0].value[0] = light->roll;
+
+    return n;
+}
+
+
+Lib3dsTargetNode* 
+lib3ds_node_new_spotligf_target(Lib3dsLight *light) {
+    Lib3dsNode *node;
+    Lib3dsTargetNode *n;
+    
+    assert(light);
+    node = lib3ds_node_new(LIB3DS_NODE_SPOTLIGHT_TARGET);
+    strcpy(node->name, light->name);
+
+    n = (Lib3dsTargetNode*)node;
+    lib3ds_track_resize(&n->pos_track, 1);
+    lib3ds_vector_copy(n->pos_track.keys[0].value, light->target);
+
+    return n;
+}
+
+
+static void
+free_node_and_childs(Lib3dsNode *node) {
+    assert(node);
+    switch (node->type) {
+        case LIB3DS_NODE_AMBIENT_COLOR: {
+            Lib3dsAmbientColorNode *n = (Lib3dsAmbientColorNode*)node;
+            lib3ds_track_resize(&n->color_track, 0);
+            break;
+        }
+
+        case LIB3DS_NODE_MESH_INSTANCE: {
+            Lib3dsMeshInstanceNode *n = (Lib3dsMeshInstanceNode*)node;
+            lib3ds_track_resize(&n->pos_track, 0);
+            lib3ds_track_resize(&n->rot_track, 0);
+            lib3ds_track_resize(&n->scl_track, 0);
+            lib3ds_track_resize(&n->hide_track, 0);
+            break;
+        }
+
+        case LIB3DS_NODE_CAMERA: {
+            Lib3dsCameraNode *n = (Lib3dsCameraNode*)node;
+            lib3ds_track_resize(&n->pos_track, 0);
+            lib3ds_track_resize(&n->fov_track, 0);
+            lib3ds_track_resize(&n->roll_track, 0);
+            break;
+        }
+
+        case LIB3DS_NODE_CAMERA_TARGET: {
+            Lib3dsTargetNode *n = (Lib3dsTargetNode*)node;
+            lib3ds_track_resize(&n->pos_track, 0);
+            break;
+        }
+
+        case LIB3DS_NODE_OMNILIGHT: {
+            Lib3dsOmnilightNode *n = (Lib3dsOmnilightNode*)node;
+            lib3ds_track_resize(&n->pos_track, 0);
+            lib3ds_track_resize(&n->color_track, 0);
+            break;
+        }
+
+        case LIB3DS_NODE_SPOTLIGHT: {
+            Lib3dsSpotlightNode *n = (Lib3dsSpotlightNode*)node;
+            lib3ds_track_resize(&n->pos_track, 0);
+            lib3ds_track_resize(&n->color_track, 0);
+            lib3ds_track_resize(&n->hotspot_track, 0);
+            lib3ds_track_resize(&n->falloff_track, 0);
+            lib3ds_track_resize(&n->roll_track, 0);
+            break;
+        }
+
+        case LIB3DS_NODE_SPOTLIGHT_TARGET: {
+            Lib3dsTargetNode *n = (Lib3dsTargetNode*)node;
+            lib3ds_track_resize(&n->pos_track, 0);
+            break;
+        }
+    } 
+    {
+        Lib3dsNode *p, *q;
+        for (p = node->childs; p; p = q) {
+            q = p->next;
+            free_node_and_childs(p);
+        }
+    }
+    free(node);
+}
+
+
+/*!
+ * Free a node and all of its resources.
+ *
+ * \param node Lib3dsNode object to be freed.
+ */
+void
+lib3ds_node_free(Lib3dsNode *node) {
+    assert(node);
+    free_node_and_childs(node);
+}
+
+
+/*!
+ * Evaluate an animation node.
+ *
+ * Recursively sets node and its children to their appropriate values
+ * for this point in the animation.
+ *
+ * \param node Node to be evaluated.
+ * \param t time value, between 0. and file->frames
+ */
+void
+lib3ds_node_eval(Lib3dsNode *node, float t) {
+    assert(node);
+    switch (node->type) {
+        case LIB3DS_NODE_AMBIENT_COLOR: {
+            Lib3dsAmbientColorNode *n = (Lib3dsAmbientColorNode*)node;
+            if (node->parent) {
+                lib3ds_matrix_copy(node->matrix, node->parent->matrix);
+            } else {
+                lib3ds_matrix_identity(node->matrix);
+            }
+            lib3ds_track_eval_vector(&n->color_track, n->color, t);
+            break;
+        }
+
+        case LIB3DS_NODE_MESH_INSTANCE: {
+            float M[4][4];
+            Lib3dsMeshInstanceNode *n = (Lib3dsMeshInstanceNode*)node;
+
+            lib3ds_track_eval_vector(&n->pos_track, n->pos, t);
+            lib3ds_track_eval_quat(&n->rot_track, n->rot, t);
+            if (n->scl_track.nkeys) {
+                lib3ds_track_eval_vector(&n->scl_track, n->scl, t);
+            } else {
+                n->scl[0] = n->scl[1] = n->scl[2] = 1.0f;
+            }
+            lib3ds_track_eval_bool(&n->hide_track, &n->hide, t);
+
+            lib3ds_matrix_identity(M);
+            lib3ds_matrix_translate(M, n->pos[0], n->pos[1], n->pos[2]);
+            lib3ds_matrix_rotate_quat(M, n->rot);
+            lib3ds_matrix_scale(M, n->scl[0], n->scl[1], n->scl[2]);
+
+            if (node->parent) {
+                lib3ds_matrix_mult(node->matrix, node->parent->matrix, M);
+            } else {
+                lib3ds_matrix_copy(node->matrix, M);
+            }
+            break;
+        }
+
+        case LIB3DS_NODE_CAMERA: {
+            Lib3dsCameraNode *n = (Lib3dsCameraNode*)node;
+            lib3ds_track_eval_vector(&n->pos_track, n->pos, t);
+            lib3ds_track_eval_float(&n->fov_track, &n->fov, t);
+            lib3ds_track_eval_float(&n->roll_track, &n->roll, t);
+            if (node->parent) {
+                lib3ds_matrix_copy(node->matrix, node->parent->matrix);
+            } else {
+                lib3ds_matrix_identity(node->matrix);
+            }
+            lib3ds_matrix_translate(node->matrix, n->pos[0], n->pos[1], n->pos[2]);
+            break;
+        }
+
+        case LIB3DS_NODE_CAMERA_TARGET: {
+            Lib3dsTargetNode *n = (Lib3dsTargetNode*)node;
+            lib3ds_track_eval_vector(&n->pos_track, n->pos, t);
+            if (node->parent) {
+                lib3ds_matrix_copy(node->matrix, node->parent->matrix);
+            } else {
+                lib3ds_matrix_identity(node->matrix);
+            }
+            lib3ds_matrix_translate(node->matrix, n->pos[0], n->pos[1], n->pos[2]);
+            break;
+        }
+
+        case LIB3DS_NODE_OMNILIGHT: {
+            Lib3dsOmnilightNode *n = (Lib3dsOmnilightNode*)node;
+            lib3ds_track_eval_vector(&n->pos_track, n->pos, t);
+            lib3ds_track_eval_vector(&n->color_track, n->color, t);
+            if (node->parent) {
+                lib3ds_matrix_copy(node->matrix, node->parent->matrix);
+            } else {
+                lib3ds_matrix_identity(node->matrix);
+            }
+            lib3ds_matrix_translate(node->matrix, n->pos[0], n->pos[1], n->pos[2]);
+            break;
+        }
+
+        case LIB3DS_NODE_SPOTLIGHT: {
+            Lib3dsSpotlightNode *n = (Lib3dsSpotlightNode*)node;
+            lib3ds_track_eval_vector(&n->pos_track, n->pos, t);
+            lib3ds_track_eval_vector(&n->color_track, n->color, t);
+            lib3ds_track_eval_float(&n->hotspot_track, &n->hotspot, t);
+            lib3ds_track_eval_float(&n->falloff_track, &n->falloff, t);
+            lib3ds_track_eval_float(&n->roll_track, &n->roll, t);
+            if (node->parent) {
+                lib3ds_matrix_copy(node->matrix, node->parent->matrix);
+            } else {
+                lib3ds_matrix_identity(node->matrix);
+            }
+            lib3ds_matrix_translate(node->matrix, n->pos[0], n->pos[1], n->pos[2]);
+            break;
+        }
+
+        case LIB3DS_NODE_SPOTLIGHT_TARGET: {
+            Lib3dsTargetNode *n = (Lib3dsTargetNode*)node;
+            lib3ds_track_eval_vector(&n->pos_track, n->pos, t);
+            if (node->parent) {
+                lib3ds_matrix_copy(node->matrix, node->parent->matrix);
+            } else {
+                lib3ds_matrix_identity(node->matrix);
+            }
+            lib3ds_matrix_translate(node->matrix, n->pos[0], n->pos[1], n->pos[2]);
+            break;
+        }
+    }
+    {
+        Lib3dsNode *p;
+        for (p = node->childs; p != 0; p = p->next) {
+            lib3ds_node_eval(p, t);
+        }
+    }
+}
+
+
+/*!
+ * Return a node object by name and type.
+ *
+ * This function performs a recursive search for the specified node.
+ * Both name and type must match.
+ *
+ * \param node The parent node for the search
+ * \param name The target node name.
+ * \param type The target node type
+ *
+ * \return A pointer to the first matching node, or NULL if not found.
+ */
+Lib3dsNode*
+lib3ds_node_by_name(Lib3dsNode *node, const char* name, Lib3dsNodeType type) {
+    Lib3dsNode *p, *q;
+
+    for (p = node->childs; p != 0; p = p->next) {
+        if ((p->type == type) && (strcmp(p->name, name) == 0)) {
+            return(p);
+        }
+        q = lib3ds_node_by_name(p, name, type);
+        if (q) {
+            return(q);
+        }
+    }
+    return(0);
+}
+
+
+/*!
+ * Return a node object by id.
+ *
+ * This function performs a recursive search for the specified node.
+ *
+ * \param node The parent node for the search
+ * \param node_id The target node id.
+ *
+ * \return A pointer to the first matching node, or NULL if not found.
+ */
+Lib3dsNode*
+lib3ds_node_by_id(Lib3dsNode *node, uint16_t node_id) {
+    Lib3dsNode *p, *q;
+
+    for (p = node->childs; p != 0; p = p->next) {
+        if (p->node_id == node_id) {
+            return(p);
+        }
+        q = lib3ds_node_by_id(p, node_id);
+        if (q) {
+            return(q);
+        }
+    }
+    return(0);
+}
+
+
+void
+lib3ds_node_read(Lib3dsNode *node, Lib3dsIo *io) {
+    Lib3dsChunk c;
+    uint16_t chunk;
+
+    assert(node);
+    lib3ds_chunk_read_start(&c, 0, io);
+
+    switch (c.chunk) {
+        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:
+            break;
+        default:
+            return;
+    }
+
+    while ((chunk = lib3ds_chunk_read_next(&c, io)) != 0)  {
+        switch (chunk) {
+            case CHK_NODE_ID: {
+                node->node_id = lib3ds_io_read_word(io);
+                lib3ds_io_log_indent(io, 1);
+                lib3ds_io_log(io, LIB3DS_LOG_INFO, "ID=%d", (short)node->node_id);
+                lib3ds_io_log_indent(io, -1);
+                break;
+            }
+
+            case CHK_NODE_HDR: {
+                lib3ds_io_read_string(io, node->name, 64);
+                node->flags = lib3ds_io_read_word(io);
+                node->flags |= ((uint32_t)lib3ds_io_read_word(io)) << 16;
+                node->user_id = lib3ds_io_read_word(io);
+
+                lib3ds_io_log_indent(io, 1);
+                lib3ds_io_log(io, LIB3DS_LOG_INFO, "NAME=%s", node->name);
+                lib3ds_io_log(io, LIB3DS_LOG_INFO, "PARENT=%d", (short)node->user_id);
+                lib3ds_io_log_indent(io, -1);
+                break;
+            }
+
+            case CHK_PIVOT: {
+                if (node->type == LIB3DS_NODE_MESH_INSTANCE) {
+                    Lib3dsMeshInstanceNode *n = (Lib3dsMeshInstanceNode*)node;
+                    lib3ds_io_read_vector(io, n->pivot);
+                } else {
+                    lib3ds_chunk_unknown(chunk, io);
+                }
+                break;
+            }
+
+            case CHK_INSTANCE_NAME: {
+                if (node->type == LIB3DS_NODE_MESH_INSTANCE) {
+                    Lib3dsMeshInstanceNode *n = (Lib3dsMeshInstanceNode*)node;
+                    lib3ds_io_read_string(io, n->instance_name, 64);
+                } else {
+                    lib3ds_chunk_unknown(chunk, io);
+                }
+                break;
+            }
+
+            case CHK_BOUNDBOX: {
+                if (node->type == LIB3DS_NODE_MESH_INSTANCE) {
+                    Lib3dsMeshInstanceNode *n = (Lib3dsMeshInstanceNode*)node;
+                    lib3ds_io_read_vector(io, n->bbox_min);
+                    lib3ds_io_read_vector(io, n->bbox_max);
+                } else {
+                    lib3ds_chunk_unknown(chunk, io);
+                }
+                break;
+            }
+
+            case CHK_COL_TRACK_TAG: {
+                Lib3dsTrack *track = 0;
+                switch (node->type) {
+                    case LIB3DS_NODE_AMBIENT_COLOR: {
+                        Lib3dsAmbientColorNode *n = (Lib3dsAmbientColorNode*)node;
+                        track = &n->color_track;
+                        break;
+                    }              
+                    case LIB3DS_NODE_OMNILIGHT: {
+                        Lib3dsOmnilightNode *n = (Lib3dsOmnilightNode*)node;
+                        track = &n->color_track;
+                        break;
+                    }
+                    case LIB3DS_NODE_SPOTLIGHT: {
+                        Lib3dsSpotlightNode *n = (Lib3dsSpotlightNode*)node;
+                        track = &n->color_track;
+                        break;
+                    }
+                    default:
+                        lib3ds_chunk_unknown(chunk, io);
+                }
+                if (track) {
+                    lib3ds_track_read(track, io);
+                }
+                break;
+            }
+
+            case CHK_POS_TRACK_TAG: {
+                Lib3dsTrack *track = 0;
+                switch (node->type) {
+                    case LIB3DS_NODE_MESH_INSTANCE: {
+                        Lib3dsMeshInstanceNode *n = (Lib3dsMeshInstanceNode*)node;
+                        track = &n->pos_track;
+                        break;
+                    }
+                    case LIB3DS_NODE_CAMERA: {
+                        Lib3dsCameraNode *n = (Lib3dsCameraNode*)node;
+                        track = &n->pos_track;
+                        break;
+                    }
+                    case LIB3DS_NODE_CAMERA_TARGET: {
+                        Lib3dsTargetNode *n = (Lib3dsTargetNode*)node;
+                        track = &n->pos_track;
+                        break;
+                    }
+                    case LIB3DS_NODE_OMNILIGHT: {
+                        Lib3dsOmnilightNode *n = (Lib3dsOmnilightNode*)node;
+                        track = &n->pos_track;
+                        break;
+                    }
+                    case LIB3DS_NODE_SPOTLIGHT: {
+                        Lib3dsSpotlightNode *n = (Lib3dsSpotlightNode*)node;
+                        track = &n->pos_track;
+                        break;
+                    }
+                    case LIB3DS_NODE_SPOTLIGHT_TARGET: {
+                        Lib3dsTargetNode *n = (Lib3dsTargetNode*)node;
+                        track = &n->pos_track;
+                        break;
+                    }
+                    default:
+                        lib3ds_chunk_unknown(chunk, io);
+                }
+                if (track) {
+                    lib3ds_track_read(track, io);
+                }
+                break;
+            }
+
+            case CHK_ROT_TRACK_TAG: {
+                if (node->type == LIB3DS_NODE_MESH_INSTANCE) {
+                    Lib3dsMeshInstanceNode *n = (Lib3dsMeshInstanceNode*)node;
+                    n->rot_track.type = LIB3DS_TRACK_QUAT;
+                    lib3ds_track_read(&n->rot_track, io);
+                } else {
+                    lib3ds_chunk_unknown(chunk, io);
+                }
+                break;
+            }
+
+            case CHK_SCL_TRACK_TAG: {
+                if (node->type == LIB3DS_NODE_MESH_INSTANCE) {
+                    Lib3dsMeshInstanceNode *n = (Lib3dsMeshInstanceNode*)node;
+                    n->scl_track.type = LIB3DS_TRACK_VECTOR;
+                    lib3ds_track_read(&n->scl_track, io);
+                } else {
+                    lib3ds_chunk_unknown(chunk, io);
+                }
+                break;
+            }
+
+            case CHK_FOV_TRACK_TAG: {
+                if (node->type == LIB3DS_NODE_CAMERA) {
+                    Lib3dsCameraNode *n = (Lib3dsCameraNode*)node;
+                    n->fov_track.type = LIB3DS_TRACK_FLOAT;
+                    lib3ds_track_read(&n->fov_track, io);
+                } else {
+                    lib3ds_chunk_unknown(chunk, io);
+                }
+                break;
+            }
+
+            case CHK_HOT_TRACK_TAG: {
+                if (node->type == LIB3DS_NODE_SPOTLIGHT) {
+                    Lib3dsSpotlightNode *n = (Lib3dsSpotlightNode*)node;
+                    n->hotspot_track.type = LIB3DS_TRACK_FLOAT;
+                    lib3ds_track_read(&n->hotspot_track, io);
+                } else {
+                    lib3ds_chunk_unknown(chunk, io);
+                }
+                break;
+            }
+
+            case CHK_FALL_TRACK_TAG: {
+                if (node->type == LIB3DS_NODE_SPOTLIGHT) {
+                    Lib3dsSpotlightNode *n = (Lib3dsSpotlightNode*)node;
+                    n->falloff_track.type= LIB3DS_TRACK_FLOAT;
+                    lib3ds_track_read(&n->falloff_track, io);
+                } else {
+                    lib3ds_chunk_unknown(chunk, io);
+                }
+                break;
+            }
+
+            case CHK_ROLL_TRACK_TAG: {
+                switch (node->type) {
+                    case LIB3DS_NODE_CAMERA: {
+                        Lib3dsCameraNode *n = (Lib3dsCameraNode*)node;
+                        n->roll_track.type = LIB3DS_TRACK_FLOAT;
+                        lib3ds_track_read(&n->roll_track, io);
+                        break;
+                    }
+                    case LIB3DS_NODE_SPOTLIGHT: {
+                        Lib3dsSpotlightNode *n = (Lib3dsSpotlightNode*)node;
+                        n->roll_track.type = LIB3DS_TRACK_FLOAT;
+                        lib3ds_track_read(&n->roll_track, io);
+                        break;
+                    }
+                    default:
+                        lib3ds_chunk_unknown(chunk, io);
+                }
+                break;
+            }
+
+            case CHK_HIDE_TRACK_TAG: {
+                if (node->type == LIB3DS_NODE_MESH_INSTANCE) {
+                    Lib3dsMeshInstanceNode *n = (Lib3dsMeshInstanceNode*)node;
+                    n->hide_track.type = LIB3DS_TRACK_BOOL;
+                    lib3ds_track_read(&n->hide_track, io);
+                } else {
+                    lib3ds_chunk_unknown(chunk, io);
+                }
+                break;
+            }
+
+            case CHK_MORPH_SMOOTH: {
+                if (node->type == LIB3DS_NODE_MESH_INSTANCE) {
+                    Lib3dsMeshInstanceNode *n = (Lib3dsMeshInstanceNode*)node;
+                    n->morph_smooth = lib3ds_io_read_float(io);
+                } else {
+                    lib3ds_chunk_unknown(chunk, io);
+                }
+            }
+            break;
+
+            /*
+            case LIB3DS_MORPH_TRACK_TAG: {
+                if (node->type == LIB3DS_NODE_MESH_INSTANCE) {
+                    Lib3dsMeshInstanceNode *n = (Lib3dsMeshInstanceNode*)node;
+                    n->morph_track = lib3ds_track_new(node, LIB3DS_TRACK_MORPH, 0);
+                    lib3ds_track_read(n->morph_track, io);
+                } else {
+                    lib3ds_chunk_unknown(chunk, io);
+                }
+            }
+            break;
+            */
+
+            default:
+                lib3ds_chunk_unknown(chunk, io);
+        }
+    }
+
+    lib3ds_chunk_read_end(&c, io);
+}
+
+
+void
+lib3ds_node_write(Lib3dsNode *node, uint16_t node_id, uint16_t parent_id, Lib3dsIo *io) {
+    Lib3dsChunk c;
+
+    switch (node->type) {
+        case LIB3DS_NODE_AMBIENT_COLOR:
+            c.chunk = CHK_AMBIENT_NODE_TAG;
+            break;
+
+        case LIB3DS_NODE_MESH_INSTANCE:
+            c.chunk = CHK_OBJECT_NODE_TAG;
+            break;
+
+        case LIB3DS_NODE_CAMERA:
+            c.chunk = CHK_CAMERA_NODE_TAG;
+            break;
+
+        case LIB3DS_NODE_CAMERA_TARGET:
+            c.chunk = CHK_TARGET_NODE_TAG;
+            break;
+
+        case LIB3DS_NODE_OMNILIGHT:
+            c.chunk = CHK_LIGHT_NODE_TAG;
+            break;
+
+        case LIB3DS_NODE_SPOTLIGHT:
+            c.chunk = CHK_SPOTLIGHT_NODE_TAG;
+            break;
+
+        case LIB3DS_NODE_SPOTLIGHT_TARGET:
+            c.chunk = CHK_L_TARGET_NODE_TAG;
+            break;
+
+        default:
+            assert(0);
+            return;
+    }
+    
+    lib3ds_chunk_write_start(&c, io);
+
+    { /*---- CHK_NODE_ID ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_NODE_ID;
+        c.size = 8;
+        lib3ds_chunk_write(&c, io);
+        lib3ds_io_write_intw(io, node_id);
+    }
+
+    { /*---- CHK_NODE_HDR ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_NODE_HDR;
+        c.size = 6 + 1 + (uint32_t)strlen(node->name) + 2 + 2 + 2;
+        lib3ds_chunk_write(&c, io);
+        lib3ds_io_write_string(io, node->name);
+        lib3ds_io_write_word(io, node->flags & 0xffff);
+        lib3ds_io_write_word(io, (node->flags >> 16) & 0xffff);
+        lib3ds_io_write_word(io, parent_id);
+    }
+
+    switch (c.chunk) {
+        case CHK_AMBIENT_NODE_TAG: {
+            Lib3dsAmbientColorNode *n = (Lib3dsAmbientColorNode*)node;
+            if (n->color_track.nkeys) { /*---- CHK_COL_TRACK_TAG ----*/
+                Lib3dsChunk c;
+                c.chunk = CHK_COL_TRACK_TAG;
+                lib3ds_chunk_write_start(&c, io);
+                lib3ds_track_write(&n->color_track, io);
+                lib3ds_chunk_write_end(&c, io);
+            }
+            break;
+        }
+
+        case CHK_OBJECT_NODE_TAG: {
+            Lib3dsMeshInstanceNode *n = (Lib3dsMeshInstanceNode*)node;
+            { /*---- CHK_PIVOT ----*/
+                Lib3dsChunk c;
+                c.chunk = CHK_PIVOT;
+                c.size = 18;
+                lib3ds_chunk_write(&c, io);
+                lib3ds_io_write_vector(io, n->pivot);
+            }
+
+            { /*---- CHK_INSTANCE_NAME ----*/
+                Lib3dsChunk c;
+                const char *name;
+                if (strlen(n->instance_name)) {
+                    name = n->instance_name;
+
+                    c.chunk = CHK_INSTANCE_NAME;
+                    c.size = 6 + 1 + (uint32_t)strlen(name);
+                    lib3ds_chunk_write(&c, io);
+                    lib3ds_io_write_string(io, name);
+                }
+            }
+            {
+                int i;
+                for (i = 0; i < 3; ++i) {
+                    if ((fabs(n->bbox_min[i]) > LIB3DS_EPSILON) ||
+                        (fabs(n->bbox_max[i]) > LIB3DS_EPSILON)) {
+                        break;
+                    }
+                }
+
+                if (i < 3) { /*---- CHK_BOUNDBOX ----*/
+                    Lib3dsChunk c;
+                    c.chunk = CHK_BOUNDBOX;
+                    c.size = 30;
+                    lib3ds_chunk_write(&c, io);
+                    lib3ds_io_write_vector(io, n->bbox_min);
+                    lib3ds_io_write_vector(io, n->bbox_max);
+                }
+            }
+
+            if (n->pos_track.nkeys) { /*---- CHK_POS_TRACK_TAG ----*/
+                Lib3dsChunk c;
+                c.chunk = CHK_POS_TRACK_TAG;
+                lib3ds_chunk_write_start(&c, io);
+                lib3ds_track_write(&n->pos_track, io);
+                lib3ds_chunk_write_end(&c, io);
+            }
+            if (n->rot_track.nkeys) { /*---- CHK_ROT_TRACK_TAG ----*/
+                Lib3dsChunk c;
+                c.chunk = CHK_ROT_TRACK_TAG;
+                lib3ds_chunk_write_start(&c, io);
+                lib3ds_track_write(&n->rot_track, io);
+                lib3ds_chunk_write_end(&c, io);
+            }
+            if (n->scl_track.nkeys) { /*---- LIB3DS_SCL_TRACK_TAG ----*/
+                Lib3dsChunk c;
+                c.chunk = CHK_SCL_TRACK_TAG;
+                lib3ds_chunk_write_start(&c, io);
+                lib3ds_track_write(&n->scl_track, io);
+                lib3ds_chunk_write_end(&c, io);
+            }
+            if (n->hide_track.nkeys) { /*---- CHK_HIDE_TRACK_TAG ----*/
+                Lib3dsChunk c;
+                c.chunk = CHK_HIDE_TRACK_TAG;
+                lib3ds_chunk_write_start(&c, io);
+                lib3ds_track_write(&n->hide_track, io);
+                lib3ds_chunk_write_end(&c, io);
+            }
+            if (fabs(n->morph_smooth) > LIB3DS_EPSILON) { /*---- CHK_MORPH_SMOOTH ----*/
+                Lib3dsChunk c;
+                c.chunk = CHK_MORPH_SMOOTH;
+                c.size = 10;
+                lib3ds_chunk_write(&c, io);
+                lib3ds_io_write_float(io, n->morph_smooth);
+            }
+            break;
+        }
+
+        case CHK_CAMERA_NODE_TAG: {
+            Lib3dsCameraNode *n = (Lib3dsCameraNode*)node;
+            if (n->pos_track.nkeys) { /*---- CHK_POS_TRACK_TAG ----*/
+                Lib3dsChunk c;
+                c.chunk = CHK_POS_TRACK_TAG;
+                lib3ds_chunk_write_start(&c, io);
+                lib3ds_track_write(&n->pos_track, io);
+                lib3ds_chunk_write_end(&c, io);
+            }
+            if (n->fov_track.nkeys) { /*---- CHK_FOV_TRACK_TAG ----*/
+                Lib3dsChunk c;
+                c.chunk = CHK_FOV_TRACK_TAG;
+                lib3ds_chunk_write_start(&c, io);
+                lib3ds_track_write(&n->fov_track, io);
+                lib3ds_chunk_write_end(&c, io);
+            }
+            if (n->roll_track.nkeys) { /*---- CHK_ROLL_TRACK_TAG ----*/
+                Lib3dsChunk c;
+                c.chunk = CHK_ROLL_TRACK_TAG;
+                lib3ds_chunk_write_start(&c, io);
+                lib3ds_track_write(&n->roll_track, io);
+                lib3ds_chunk_write_end(&c, io);
+            }
+            break;
+        }
+
+        case CHK_TARGET_NODE_TAG: {
+            Lib3dsTargetNode *n = (Lib3dsTargetNode*)node;
+            if (n->pos_track.nkeys) { /*---- CHK_POS_TRACK_TAG ----*/
+                Lib3dsChunk c;
+                c.chunk = CHK_POS_TRACK_TAG;
+                lib3ds_chunk_write_start(&c, io);
+                lib3ds_track_write(&n->pos_track, io);
+                lib3ds_chunk_write_end(&c, io);
+            }
+            break;
+        }
+
+        case CHK_LIGHT_NODE_TAG: {
+            Lib3dsOmnilightNode *n = (Lib3dsOmnilightNode*)node;
+            if (n->pos_track.nkeys) { /*---- CHK_POS_TRACK_TAG ----*/
+                Lib3dsChunk c;
+                c.chunk = CHK_POS_TRACK_TAG;
+                lib3ds_chunk_write_start(&c, io);
+                lib3ds_track_write(&n->pos_track, io);
+                lib3ds_chunk_write_end(&c, io);
+            }
+            if (n->color_track.nkeys) { /*---- CHK_COL_TRACK_TAG ----*/
+                Lib3dsChunk c;
+                c.chunk = CHK_COL_TRACK_TAG;
+                lib3ds_chunk_write_start(&c, io);
+                lib3ds_track_write(&n->color_track, io);
+                lib3ds_chunk_write_end(&c, io);
+            }
+            break;
+        }
+
+        case CHK_SPOTLIGHT_NODE_TAG: {
+            Lib3dsSpotlightNode *n = (Lib3dsSpotlightNode*)node;
+            if (n->pos_track.nkeys) { /*---- CHK_POS_TRACK_TAG ----*/
+                Lib3dsChunk c;
+                c.chunk = CHK_POS_TRACK_TAG;
+                lib3ds_chunk_write_start(&c, io);
+                lib3ds_track_write(&n->pos_track, io);
+                lib3ds_chunk_write_end(&c, io);
+            }
+            if (n->color_track.nkeys) { /*---- CHK_COL_TRACK_TAG ----*/
+                Lib3dsChunk c;
+                c.chunk = CHK_COL_TRACK_TAG;
+                lib3ds_chunk_write_start(&c, io);
+                lib3ds_track_write(&n->color_track, io);
+                lib3ds_chunk_write_end(&c, io);
+            }
+            if (n->hotspot_track.nkeys) { /*---- CHK_HOT_TRACK_TAG ----*/
+                Lib3dsChunk c;
+                c.chunk = CHK_HOT_TRACK_TAG;
+                lib3ds_chunk_write_start(&c, io);
+                lib3ds_track_write(&n->hotspot_track, io);
+                lib3ds_chunk_write_end(&c, io);
+            }
+            if (n->falloff_track.nkeys) { /*---- CHK_FALL_TRACK_TAG ----*/
+                Lib3dsChunk c;
+                c.chunk = CHK_FALL_TRACK_TAG;
+                lib3ds_chunk_write_start(&c, io);
+                lib3ds_track_write(&n->falloff_track, io);
+                lib3ds_chunk_write_end(&c, io);
+            }
+            if (n->roll_track.nkeys) { /*---- CHK_ROLL_TRACK_TAG ----*/
+                Lib3dsChunk c;
+                c.chunk = CHK_ROLL_TRACK_TAG;
+                lib3ds_chunk_write_start(&c, io);
+                lib3ds_track_write(&n->roll_track, io);
+                lib3ds_chunk_write_end(&c, io);
+            }
+            break; 
+        }
+
+        case CHK_L_TARGET_NODE_TAG: {
+            Lib3dsTargetNode *n = (Lib3dsTargetNode*)node;
+            if (n->pos_track.nkeys) { /*---- CHK_POS_TRACK_TAG ----*/
+                Lib3dsChunk c;
+                c.chunk = CHK_POS_TRACK_TAG;
+                lib3ds_chunk_write_start(&c, io);
+                lib3ds_track_write(&n->pos_track, io);
+                lib3ds_chunk_write_end(&c, io);
+            }
+            break;
+        }
+
+        default:
+            break;
+    }
+
+    lib3ds_chunk_write_end(&c, io);
+}
+
Index: /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_shadow.c
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_shadow.c (revision 10853)
+++ /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_shadow.c (revision 10853)
@@ -0,0 +1,96 @@
+/*
+    Copyright (C) 1996-2008 by Jan Eric Kyprianidis <www.kyprianidis.com>
+    All rights reserved.
+    
+    This program is free  software: you can redistribute it and/or modify 
+    it under the terms of the GNU Lesser General Public License as published 
+    by the Free Software Foundation, either version 2.1 of the License, or 
+    (at your option) any later version.
+
+    Thisprogram  is  distributed in the hope that it will be useful, 
+    but WITHOUT ANY WARRANTY; without even the implied warranty of 
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
+    GNU Lesser General Public License for more details.
+    
+    You should  have received a copy of the GNU Lesser General Public License
+    along with  this program; If not, see <http://www.gnu.org/licenses/>. 
+*/
+#include "lib3ds_impl.h"
+
+
+void
+lib3ds_shadow_read(Lib3dsShadow *shadow, Lib3dsIo *io) {
+    Lib3dsChunk c;
+
+    lib3ds_chunk_read(&c, io);
+    switch (c.chunk) {
+        case CHK_SHADOW_MAP_SIZE: {
+            shadow->map_size = lib3ds_io_read_intw(io);
+            break;
+        }
+
+        case CHK_LO_SHADOW_BIAS: {
+            shadow->low_bias = lib3ds_io_read_float(io);
+            break;
+        }
+
+        case CHK_HI_SHADOW_BIAS: {
+            shadow->hi_bias = lib3ds_io_read_float(io);
+            break;
+        }
+
+        case CHK_SHADOW_FILTER: {
+            shadow->filter = lib3ds_io_read_float(io);
+            break;
+        }
+
+        case CHK_RAY_BIAS: {
+            shadow->ray_bias = lib3ds_io_read_float(io);
+            break;
+        }
+    }
+}
+
+
+void
+lib3ds_shadow_write(Lib3dsShadow *shadow, Lib3dsIo *io) {
+    if (fabs(shadow->low_bias) > LIB3DS_EPSILON) { /*---- CHK_LO_SHADOW_BIAS ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_LO_SHADOW_BIAS;
+        c.size = 10;
+        lib3ds_chunk_write(&c, io);
+        lib3ds_io_write_float(io, shadow->low_bias);
+    }
+
+    if (fabs(shadow->hi_bias) > LIB3DS_EPSILON) { /*---- CHK_HI_SHADOW_BIAS ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_HI_SHADOW_BIAS;
+        c.size = 10;
+        lib3ds_chunk_write(&c, io);
+        lib3ds_io_write_float(io, shadow->hi_bias);
+    }
+
+    if (shadow->map_size) { /*---- CHK_SHADOW_MAP_SIZE ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_SHADOW_MAP_SIZE;
+        c.size = 8;
+        lib3ds_chunk_write(&c, io);
+        lib3ds_io_write_intw(io, shadow->map_size);
+    }
+
+    if (fabs(shadow->filter) > LIB3DS_EPSILON) { /*---- CHK_SHADOW_FILTER ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_SHADOW_FILTER;
+        c.size = 10;
+        lib3ds_chunk_write(&c, io);
+        lib3ds_io_write_float(io, shadow->filter);
+    }
+    if (fabs(shadow->ray_bias) > LIB3DS_EPSILON) { /*---- CHK_RAY_BIAS ----*/
+        Lib3dsChunk c;
+        c.chunk = CHK_RAY_BIAS;
+        c.size = 10;
+        lib3ds_chunk_write(&c, io);
+        lib3ds_io_write_float(io, shadow->ray_bias);
+    }
+}
+
Index: /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/COPYING
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/COPYING (revision 10853)
+++ /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/COPYING (revision 10853)
@@ -0,0 +1,340 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year  name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
Index: /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_camera.c
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_camera.c (revision 10853)
+++ /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_camera.c (revision 10853)
@@ -0,0 +1,165 @@
+/*
+    Copyright (C) 1996-2008 by Jan Eric Kyprianidis <www.kyprianidis.com>
+    All rights reserved.
+    
+    This program is free  software: you can redistribute it and/or modify 
+    it under the terms of the GNU Lesser General Public License as published 
+    by the Free Software Foundation, either version 2.1 of the License, or 
+    (at your option) any later version.
+
+    Thisprogram  is  distributed in the hope that it will be useful, 
+    but WITHOUT ANY WARRANTY; without even the implied warranty of 
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
+    GNU Lesser General Public License for more details.
+    
+    You should  have received a copy of the GNU Lesser General Public License
+    along with  this program; If not, see <http://www.gnu.org/licenses/>. 
+*/
+#include "lib3ds_impl.h"
+
+
+/*!
+ * Return a new Lib3dsCamera object.
+ *
+ * Object is initialized with the given name and fov=45.  All other
+ * values are 0.
+ *
+ * \param name Name of this camera.  Must not be NULL.  Must be < 64 characters.
+ *
+ * \return Lib3dsCamera object or NULL on failure.
+ */
+Lib3dsCamera*
+lib3ds_camera_new(const char *name) {
+    Lib3dsCamera *camera;
+
+    assert(name);
+    assert(strlen(name) < 64);
+
+    camera = (Lib3dsCamera*)calloc(sizeof(Lib3dsCamera), 1);
+    if (!camera) {
+        return(0);
+    }
+    strcpy(camera->name, name);
+    camera->fov = 45.0f;
+    return(camera);
+}
+
+
+/*!
+ * Free a Lib3dsCamera object and all of its resources.
+ *
+ * \param camera Lib3dsCamera object to be freed.
+ */
+void
+lib3ds_camera_free(Lib3dsCamera *camera) {
+    memset(camera, 0, sizeof(Lib3dsCamera));
+    free(camera);
+}
+
+
+/*!
+ * Read a camera definition from a file.
+ *
+ * This function is called by lib3ds_file_read(), and you probably
+ * don't want to call it directly.
+ *
+ * \param camera A Lib3dsCamera to be filled in.
+ * \param io A Lib3dsIo object previously set up by the caller.
+ *
+ * \see lib3ds_file_read
+ */
+void
+lib3ds_camera_read(Lib3dsCamera *camera, Lib3dsIo *io) {
+    Lib3dsChunk c;
+    uint16_t chunk;
+
+    lib3ds_chunk_read_start(&c, CHK_N_CAMERA, io);
+
+    {
+        int i;
+        for (i = 0; i < 3; ++i) {
+            camera->position[i] = lib3ds_io_read_float(io);
+        }
+        for (i = 0; i < 3; ++i) {
+            camera->target[i] = lib3ds_io_read_float(io);
+        }
+    }
+    camera->roll = lib3ds_io_read_float(io);
+    {
+        float s;
+        s = lib3ds_io_read_float(io);
+        if (fabs(s) < LIB3DS_EPSILON) {
+            camera->fov = 45.0;
+        } else {
+            camera->fov = 2400.0f / s;
+        }
+    }
+    lib3ds_chunk_read_tell(&c, io);
+
+    while ((chunk = lib3ds_chunk_read_next(&c, io)) != 0) {
+        switch (chunk) {
+            case CHK_CAM_SEE_CONE: {
+                camera->see_cone = TRUE;
+            }
+            break;
+
+            case CHK_CAM_RANGES: {
+                camera->near_range = lib3ds_io_read_float(io);
+                camera->far_range = lib3ds_io_read_float(io);
+            }
+            break;
+
+            default:
+                lib3ds_chunk_unknown(chunk, io);
+        }
+    }
+
+    lib3ds_chunk_read_end(&c, io);
+}
+
+
+/*!
+ * Write a camera definition to a file.
+ *
+ * This function is called by lib3ds_file_write(), and you probably
+ * don't want to call it directly.
+ *
+ * \param camera A Lib3dsCamera to be written.
+ * \param io A Lib3dsIo object previously set up by the caller.
+ *
+ * \see lib3ds_file_write
+ */
+void
+lib3ds_camera_write(Lib3dsCamera *camera, Lib3dsIo *io) {
+    Lib3dsChunk c;
+
+    c.chunk = CHK_N_CAMERA;
+    lib3ds_chunk_write_start(&c, io);
+
+    lib3ds_io_write_vector(io, camera->position);
+    lib3ds_io_write_vector(io, camera->target);
+    lib3ds_io_write_float(io, camera->roll);
+    if (fabs(camera->fov) < LIB3DS_EPSILON) {
+        lib3ds_io_write_float(io, 2400.0f / 45.0f);
+    } else {
+        lib3ds_io_write_float(io, 2400.0f / camera->fov);
+    }
+
+    if (camera->see_cone) {
+        Lib3dsChunk c;
+        c.chunk = CHK_CAM_SEE_CONE;
+        c.size = 6;
+        lib3ds_chunk_write(&c, io);
+    }
+    {
+        Lib3dsChunk c;
+        c.chunk = CHK_CAM_RANGES;
+        c.size = 14;
+        lib3ds_chunk_write(&c, io);
+        lib3ds_io_write_float(io, camera->near_range);
+        lib3ds_io_write_float(io, camera->far_range);
+    }
+
+    lib3ds_chunk_write_end(&c, io);
+}
+
Index: /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_math.c
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_math.c (revision 10853)
+++ /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_math.c (revision 10853)
@@ -0,0 +1,62 @@
+/*
+    Copyright (C) 1996-2008 by Jan Eric Kyprianidis <www.kyprianidis.com>
+    All rights reserved.
+    
+    This program is free  software: you can redistribute it and/or modify 
+    it under the terms of the GNU Lesser General Public License as published 
+    by the Free Software Foundation, either version 2.1 of the License, or 
+    (at your option) any later version.
+
+    Thisprogram  is  distributed in the hope that it will be useful, 
+    but WITHOUT ANY WARRANTY; without even the implied warranty of 
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
+    GNU Lesser General Public License for more details.
+    
+    You should  have received a copy of the GNU Lesser General Public License
+    along with  this program; If not, see <http://www.gnu.org/licenses/>. 
+*/
+#include "lib3ds_impl.h"
+
+
+float
+lib3ds_math_ease(float fp, float fc, float fn, float ease_from, float ease_to) {
+    double s, step;
+    double tofrom;
+    double a;
+
+    s = step = (float)(fc - fp) / (fn - fp);
+    tofrom = ease_to + ease_from;
+    if (tofrom != 0.0) {
+        if (tofrom > 1.0) {
+            ease_to = (float)(ease_to / tofrom);
+            ease_from = (float)(ease_from / tofrom);
+        }
+        a = 1.0 / (2.0 - (ease_to + ease_from));
+
+        if (step < ease_from) s = a / ease_from * step * step;
+        else {
+            if ((1.0 - ease_to) <= step) {
+                step = 1.0 - step;
+                s = 1.0 - a / ease_to * step * step;
+            } else {
+                s = ((2.0 * step) - ease_from) * a;
+            }
+        }
+    }
+    return((float)s);
+}
+
+
+void
+lib3ds_math_cubic_interp(float *v, float *a, float *p, float *q, float *b, int n, float t) {
+    float x, y, z, w;
+    int i;
+
+    x = 2 * t * t * t - 3 * t * t + 1;
+    y = -2 * t * t * t + 3 * t * t;
+    z = t * t * t - 2 * t * t + t;
+    w = t * t * t - t * t;
+    for (i = 0; i < n; ++i) {
+        v[i] = x * a[i] + y * b[i] + z * p[i] + w * q[i];
+    }
+}
Index: /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_mesh.c
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_mesh.c (revision 10853)
+++ /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_mesh.c (revision 10853)
@@ -0,0 +1,677 @@
+/*
+    Copyright (C) 1996-2008 by Jan Eric Kyprianidis <www.kyprianidis.com>
+    All rights reserved.
+    
+    This program is free  software: you can redistribute it and/or modify 
+    it under the terms of the GNU Lesser General Public License as published 
+    by the Free Software Foundation, either version 2.1 of the License, or 
+    (at your option) any later version.
+
+    Thisprogram  is  distributed in the hope that it will be useful, 
+    but WITHOUT ANY WARRANTY; without even the implied warranty of 
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
+    GNU Lesser General Public License for more details.
+    
+    You should  have received a copy of the GNU Lesser General Public License
+    along with  this program; If not, see <http://www.gnu.org/licenses/>. 
+*/
+#include "lib3ds_impl.h"
+
+
+/*!
+ * Create and return a new empty mesh object.
+ *
+ * Mesh is initialized with the name and an identity matrix; all
+ * other fields are zero.
+ *
+ * See Lib3dsFaceFlag for definitions of per-face flags.
+ *
+ * \param name Mesh name.  Must not be NULL.  Must be < 64 characters.
+ *
+ * \return mesh object or NULL on error.
+ */
+Lib3dsMesh*
+lib3ds_mesh_new(const char *name) {
+    Lib3dsMesh *mesh;
+
+    assert(name);
+    assert(strlen(name) < 64);
+
+    mesh = (Lib3dsMesh*) calloc(sizeof(Lib3dsMesh), 1);
+    if (!mesh) {
+        return (0);
+    }
+    strcpy(mesh->name, name);
+    lib3ds_matrix_identity(mesh->matrix);
+    mesh->map_type = LIB3DS_MAP_NONE;
+    return (mesh);
+}
+
+
+/*!
+ * Free a mesh object and all of its resources.
+ *
+ * \param mesh Mesh object to be freed.
+ */
+void
+lib3ds_mesh_free(Lib3dsMesh *mesh) {
+    lib3ds_mesh_resize_vertices(mesh, 0, 0, 0);
+    lib3ds_mesh_resize_faces(mesh, 0);
+    memset(mesh, 0, sizeof(Lib3dsMesh));
+    free(mesh);
+}
+
+
+void
+lib3ds_mesh_resize_vertices(Lib3dsMesh *mesh, int nvertices, int use_texcos, int use_flags) {
+    assert(mesh);
+    mesh->vertices = (float (*)[3])lib3ds_util_realloc_array(mesh->vertices, mesh->nvertices, nvertices, 3 * sizeof(float));
+    mesh->texcos = (float (*)[2])lib3ds_util_realloc_array(
+        mesh->texcos, 
+        mesh->texcos? mesh->nvertices : 0, 
+        use_texcos? nvertices : 0, 
+        2 * sizeof(float)
+    );
+    mesh->vflags = (unsigned short*)lib3ds_util_realloc_array(
+        mesh->vflags, 
+        mesh->vflags? mesh->nvertices : 0, 
+        use_flags? nvertices : 0, 
+        2 * sizeof(float)
+    );
+    mesh->nvertices = (unsigned short)nvertices;
+}
+
+
+void 
+lib3ds_mesh_resize_faces(Lib3dsMesh *mesh, int nfaces) {
+    int i;
+    assert(mesh);
+    mesh->faces = (Lib3dsFace *)lib3ds_util_realloc_array(mesh->faces, mesh->nfaces, nfaces, sizeof(Lib3dsFace));
+    for (i = mesh->nfaces; i < nfaces; ++i) {
+        mesh->faces[i].material = -1;
+    }
+    mesh->nfaces = (unsigned short)nfaces;
+}
+
+
+/*!
+ * Find the bounding box of a mesh object.
+ *
+ * \param mesh The mesh object
+ * \param bmin Returned bounding box
+ * \param bmax Returned bounding box
+ */
+void
+lib3ds_mesh_bounding_box(Lib3dsMesh *mesh, float bmin[3], float bmax[3]) {
+    int i;
+    bmin[0] = bmin[1] = bmin[2] = FLT_MAX;
+    bmax[0] = bmax[1] = bmax[2] = -FLT_MAX;
+
+    for (i = 0; i < mesh->nvertices; ++i) {
+        lib3ds_vector_min(bmin, mesh->vertices[i]);
+        lib3ds_vector_max(bmax, mesh->vertices[i]);
+    }
+}
+
+
+void
+lib3ds_mesh_calculate_face_normals(Lib3dsMesh *mesh, float (*face_normals)[3]) {
+    int i;
+
+    if (!mesh->nfaces) {
+        return;
+    }
+    for (i = 0; i < mesh->nfaces; ++i) {
+        lib3ds_vector_normal(
+            face_normals[i],
+            mesh->vertices[mesh->faces[i].index[0]],
+            mesh->vertices[mesh->faces[i].index[1]],
+            mesh->vertices[mesh->faces[i].index[2]]
+        );
+    }
+}
+
+
+typedef struct Lib3dsFaces {
+    struct Lib3dsFaces *next;
+    int index;
+    float normal[3];
+} Lib3dsFaces;
+
+
+/*!
+ * Calculates the vertex normals corresponding to the smoothing group
+ * settings for each face of a mesh.
+ *
+ * \param mesh      A pointer to the mesh to calculate the normals for.
+ * \param normals   A pointer to a buffer to store the calculated
+ *                  normals. The buffer must have the size:
+ *                  3*3*sizeof(float)*mesh->nfaces.
+ *
+ * To allocate the normal buffer do for example the following:
+ * \code
+ *  Lib3dsVector *normals = malloc(3*3*sizeof(float)*mesh->nfaces);
+ * \endcode
+ *
+ * To access the normal of the i-th vertex of the j-th face do the
+ * following:
+ * \code
+ *   normals[3*j+i]
+ * \endcode
+ */
+void
+lib3ds_mesh_calculate_vertex_normals(Lib3dsMesh *mesh, float (*normals)[3]) {
+    Lib3dsFaces **fl;
+    Lib3dsFaces *fa;
+    int i, j;
+
+    if (!mesh->nfaces) {
+        return;
+    }
+
+    fl = (Lib3dsFaces**)calloc(sizeof(Lib3dsFaces*), mesh->nvertices);
+    fa = (Lib3dsFaces*)malloc(sizeof(Lib3dsFaces) * 3 * mesh->nfaces);
+
+    for (i = 0; i < mesh->nfaces; ++i) {
+        for (j = 0; j < 3; ++j) {
+            Lib3dsFaces* l = &fa[3*i+j];
+            float p[3], q[3], n[3];
+            float len, weight;
+
+            l->index = i;
+            l->next = fl[mesh->faces[i].index[j]];
+            fl[mesh->faces[i].index[j]] = l;
+
+            lib3ds_vector_sub(p, mesh->vertices[mesh->faces[i].index[j<2? j + 1 : 0]], mesh->vertices[mesh->faces[i].index[j]]);
+            lib3ds_vector_sub(q, mesh->vertices[mesh->faces[i].index[j>0? j - 1 : 2]], mesh->vertices[mesh->faces[i].index[j]]);
+            lib3ds_vector_cross(n, p, q);
+            len = lib3ds_vector_length(n);
+            if (len > 0) {       
+                weight = (float)atan2(len, lib3ds_vector_dot(p, q));
+                lib3ds_vector_scalar_mul(l->normal, n, weight / len);
+            } else {
+                lib3ds_vector_zero(l->normal);
+            }
+        }
+    }
+
+    for (i = 0; i < mesh->nfaces; ++i) {
+        Lib3dsFace *f = &mesh->faces[i];
+        for (j = 0; j < 3; ++j) {
+            float n[3];
+            Lib3dsFaces *p;
+            Lib3dsFace *pf;
+
+            assert(mesh->faces[i].index[j] < mesh->nvertices);
+
+            if (f->smoothing_group) {
+                unsigned smoothing_group = f->smoothing_group;
+
+                lib3ds_vector_zero(n);
+                for (p = fl[mesh->faces[i].index[j]]; p; p = p->next) {
+                    pf = &mesh->faces[p->index];
+                    if (pf->smoothing_group & f->smoothing_group)
+                        smoothing_group |= pf->smoothing_group;
+                }
+
+                for (p = fl[mesh->faces[i].index[j]]; p; p = p->next) {
+                    pf = &mesh->faces[p->index];                
+                    if (smoothing_group & pf->smoothing_group) {
+                        lib3ds_vector_add(n, n, p->normal);
+                    }
+                }
+            } else {
+                lib3ds_vector_copy(n, fa[3*i+j].normal);
+            }
+
+            lib3ds_vector_normalize(n);
+            lib3ds_vector_copy(normals[3*i+j], n);
+        }
+    }
+
+    free(fa);
+    free(fl);
+}
+
+
+static void
+face_array_read(Lib3dsFile *file, Lib3dsMesh *mesh, Lib3dsIo *io) {
+    Lib3dsChunk c;
+    uint16_t chunk;
+    int i;
+    uint16_t nfaces;
+
+    lib3ds_chunk_read_start(&c, CHK_FACE_ARRAY, io);
+
+    lib3ds_mesh_resize_faces(mesh, 0);
+    nfaces = lib3ds_io_read_word(io);
+    if (nfaces) {
+        lib3ds_mesh_resize_faces(mesh, nfaces);
+        for (i = 0; i < nfaces; ++i) {
+            mesh->faces[i].index[0] = lib3ds_io_read_word(io);
+            mesh->faces[i].index[1] = lib3ds_io_read_word(io);
+            mesh->faces[i].index[2] = lib3ds_io_read_word(io);
+            mesh->faces[i].flags = lib3ds_io_read_word(io);
+        }
+        lib3ds_chunk_read_tell(&c, io);
+
+        while ((chunk = lib3ds_chunk_read_next(&c, io)) != 0) {
+            switch (chunk) {
+                case CHK_MSH_MAT_GROUP: {
+                    char name[64];
+                    unsigned n;
+                    unsigned i;
+                    int index;
+                    int material;
+
+                    lib3ds_io_read_string(io, name, 64);
+                    material = lib3ds_file_material_by_name(file, name);
+
+                    n = lib3ds_io_read_word(io);
+                    for (i = 0; i < n; ++i) {
+                        index = lib3ds_io_read_word(io);
+                        if (index < mesh->nfaces) {
+                            mesh->faces[index].material = material;
+                        } else {
+                            // TODO warning
+                        }
+                    }
+                    break;
+                }
+
+                case CHK_SMOOTH_GROUP: {
+                    int i;
+                    for (i = 0; i < mesh->nfaces; ++i) {
+                        mesh->faces[i].smoothing_group = lib3ds_io_read_dword(io);
+                    }
+                    break;
+                }
+
+                case CHK_MSH_BOXMAP: {
+                    lib3ds_io_read_string(io, mesh->box_front, 64);
+                    lib3ds_io_read_string(io, mesh->box_back, 64);
+                    lib3ds_io_read_string(io, mesh->box_left, 64);
+                    lib3ds_io_read_string(io, mesh->box_right, 64);
+                    lib3ds_io_read_string(io, mesh->box_top, 64);
+                    lib3ds_io_read_string(io, mesh->box_bottom, 64);
+                    break;
+                }
+
+                default:
+                    lib3ds_chunk_unknown(chunk,io);
+            }
+        }
+
+    }
+    lib3ds_chunk_read_end(&c, io);
+}
+
+
+void
+lib3ds_mesh_read(Lib3dsFile *file, Lib3dsMesh *mesh, Lib3dsIo *io) {
+    Lib3dsChunk c;
+    uint16_t chunk;
+
+    lib3ds_chunk_read_start(&c, CHK_N_TRI_OBJECT, io);
+
+    while ((chunk = lib3ds_chunk_read_next(&c, io)) != 0) {
+        switch (chunk) {
+            case CHK_MESH_MATRIX: {
+                int i, j;
+
+                lib3ds_matrix_identity(mesh->matrix);
+                for (i = 0; i < 4; i++) {
+                    for (j = 0; j < 3; j++) {
+                        mesh->matrix[i][j] = lib3ds_io_read_float(io);
+                    }
+                }
+                break;
+            }
+
+            case CHK_MESH_COLOR: {
+                mesh->color = lib3ds_io_read_byte(io);
+                break;
+            }
+
+            case CHK_POINT_ARRAY: {
+                int i;
+                uint16_t nvertices = lib3ds_io_read_word(io);
+                lib3ds_mesh_resize_vertices(mesh, nvertices, mesh->texcos != NULL, mesh->vflags != NULL);
+                for (i = 0; i < mesh->nvertices; ++i) {
+                    lib3ds_io_read_vector(io, mesh->vertices[i]);
+                }
+                break;
+            }
+
+            case CHK_POINT_FLAG_ARRAY: {
+                int i;
+                uint16_t nflags = lib3ds_io_read_word(io);
+                uint16_t nvertices = (mesh->nvertices >= nflags)? mesh->nvertices : nflags;
+                lib3ds_mesh_resize_vertices(mesh, nvertices, mesh->texcos != NULL, 1);
+                for (i = 0; i < nflags; ++i) {
+                    mesh->vflags[i] = lib3ds_io_read_word(io);
+                }
+                break;
+            }
+
+            case CHK_FACE_ARRAY: {
+                lib3ds_chunk_read_reset(&c, io);
+                face_array_read(file, mesh, io);
+                break;
+            }
+
+            case CHK_MESH_TEXTURE_INFO: {
+                int i, j;
+
+                //FIXME: mesh->map_type = lib3ds_io_read_word(io);
+
+                for (i = 0; i < 2; ++i) {
+                    mesh->map_tile[i] = lib3ds_io_read_float(io);
+                }
+                for (i = 0; i < 3; ++i) {
+                    mesh->map_pos[i] = lib3ds_io_read_float(io);
+                }
+                mesh->map_scale = lib3ds_io_read_float(io);
+
+                lib3ds_matrix_identity(mesh->map_matrix);
+                for (i = 0; i < 4; i++) {
+                    for (j = 0; j < 3; j++) {
+                        mesh->map_matrix[i][j] = lib3ds_io_read_float(io);
+                    }
+                }
+                for (i = 0; i < 2; ++i) {
+                    mesh->map_planar_size[i] = lib3ds_io_read_float(io);
+                }
+                mesh->map_cylinder_height = lib3ds_io_read_float(io);
+                break;
+            }
+
+            case CHK_TEX_VERTS: {
+                int i;
+                uint16_t ntexcos = lib3ds_io_read_word(io);
+                uint16_t nvertices = (mesh->nvertices >= ntexcos)? mesh->nvertices : ntexcos;;
+                if (!mesh->texcos) {
+                    lib3ds_mesh_resize_vertices(mesh, nvertices, 1, mesh->vflags != NULL);
+                }
+                for (i = 0; i < ntexcos; ++i) {
+                    mesh->texcos[i][0] = lib3ds_io_read_float(io);
+                    mesh->texcos[i][1] = lib3ds_io_read_float(io);
+                }
+                break;
+            }
+
+            default:
+                lib3ds_chunk_unknown(chunk, io);
+        }
+    }
+
+    if (lib3ds_matrix_det(mesh->matrix) < 0.0) {
+        /* Flip X coordinate of vertices if mesh matrix
+           has negative determinant */
+        float inv_matrix[4][4], M[4][4];
+        float tmp[3];
+        int i;
+
+        lib3ds_matrix_copy(inv_matrix, mesh->matrix);
+        lib3ds_matrix_inv(inv_matrix);
+
+        lib3ds_matrix_copy(M, mesh->matrix);
+        lib3ds_matrix_scale(M, -1.0f, 1.0f, 1.0f);
+        lib3ds_matrix_mult(M, M, inv_matrix);
+
+        for (i = 0; i < mesh->nvertices; ++i) {
+            lib3ds_vector_transform(tmp, M, mesh->vertices[i]);
+            lib3ds_vector_copy(mesh->vertices[i], tmp);
+        }
+    }
+
+    lib3ds_chunk_read_end(&c, io);
+}
+
+
+static void
+point_array_write(Lib3dsMesh *mesh, Lib3dsIo *io) {
+    Lib3dsChunk c;
+    int i;
+
+    c.chunk = CHK_POINT_ARRAY;
+    c.size = 8 + 12 * mesh->nvertices;
+    lib3ds_chunk_write(&c, io);
+
+    lib3ds_io_write_word(io, (uint16_t) mesh->nvertices);
+
+    if (lib3ds_matrix_det(mesh->matrix) >= 0.0f) {
+        for (i = 0; i < mesh->nvertices; ++i) {
+            lib3ds_io_write_vector(io, mesh->vertices[i]);
+        }
+    } else {
+        /* Flip X coordinate of vertices if mesh matrix
+           has negative determinant */
+        float inv_matrix[4][4], M[4][4];
+        float tmp[3];
+
+        lib3ds_matrix_copy(inv_matrix, mesh->matrix);
+        lib3ds_matrix_inv(inv_matrix);
+        lib3ds_matrix_copy(M, mesh->matrix);
+        lib3ds_matrix_scale(M, -1.0f, 1.0f, 1.0f);
+        lib3ds_matrix_mult(M, M, inv_matrix);
+
+        for (i = 0; i < mesh->nvertices; ++i) {
+            lib3ds_vector_transform(tmp, M, mesh->vertices[i]);
+            lib3ds_io_write_vector(io, tmp);
+        }
+    }
+}
+
+
+static void
+flag_array_write(Lib3dsMesh *mesh, Lib3dsIo *io) {
+    Lib3dsChunk c;
+    int i;
+
+    if (!mesh->vflags) {
+        return;
+    }
+
+    c.chunk = CHK_POINT_FLAG_ARRAY;
+    c.size = 8 + 2 * mesh->nvertices;
+    lib3ds_chunk_write(&c, io);
+
+    lib3ds_io_write_word(io, (uint16_t) mesh->nvertices);
+    for (i = 0; i < mesh->nvertices; ++i) {
+        lib3ds_io_write_word(io, mesh->vflags[i]);
+    }
+}
+
+
+static void
+face_array_write(Lib3dsFile *file, Lib3dsMesh *mesh, Lib3dsIo *io) {
+    Lib3dsChunk c;
+
+    if (mesh->nfaces == 0) {
+        return;
+    }
+    c.chunk = CHK_FACE_ARRAY;
+    lib3ds_chunk_write_start(&c, io);
+
+    {
+        int i;
+
+        lib3ds_io_write_word(io, (uint16_t) mesh->nfaces);
+        for (i = 0; i < mesh->nfaces; ++i) {
+            lib3ds_io_write_word(io, mesh->faces[i].index[0]);
+            lib3ds_io_write_word(io, mesh->faces[i].index[1]);
+            lib3ds_io_write_word(io, mesh->faces[i].index[2]);
+            lib3ds_io_write_word(io, mesh->faces[i].flags);
+        }
+    }
+
+    {
+        /*---- MSH_CHK_MAT_GROUP ----*/
+        Lib3dsChunk c;
+        int i, j;
+        uint16_t num;
+        char *matf = (char*)calloc(sizeof(char), mesh->nfaces);
+		((Lib3dsIoImpl*)io->impl)->tmp_mem = matf;
+        assert(matf);
+
+        for (i = 0; i < mesh->nfaces; ++i) {
+            if (!matf[i] && (mesh->faces[i].material >= 0) && (mesh->faces[i].material < file->nmaterials)) {
+                matf[i] = 1;
+                num = 1;
+
+                for (j = i + 1; j < mesh->nfaces; ++j) {
+                    if (mesh->faces[i].material == mesh->faces[j].material) ++num;
+                }
+
+                c.chunk = CHK_MSH_MAT_GROUP;
+                c.size = 6 + (uint32_t)strlen(file->materials[mesh->faces[i].material]->name) + 1 + 2 + 2 * num;
+                lib3ds_chunk_write(&c, io);
+                lib3ds_io_write_string(io, file->materials[mesh->faces[i].material]->name);
+                lib3ds_io_write_word(io, num);
+                lib3ds_io_write_word(io, (uint16_t) i);
+
+                for (j = i + 1; j < mesh->nfaces; ++j) {
+                    if (mesh->faces[i].material == mesh->faces[j].material) {
+                        lib3ds_io_write_word(io, (uint16_t) j);
+                        matf[j] = 1;
+                    }
+                }
+            }
+        }
+        ((Lib3dsIoImpl*)io->impl)->tmp_mem = NULL;
+        free(matf);
+    }
+
+    {
+        /*---- SMOOTH_GROUP ----*/
+        Lib3dsChunk c;
+        int i;
+
+        c.chunk = CHK_SMOOTH_GROUP;
+        c.size = 6 + 4 * mesh->nfaces;
+        lib3ds_chunk_write(&c, io);
+
+        for (i = 0; i < mesh->nfaces; ++i) {
+            lib3ds_io_write_dword(io, mesh->faces[i].smoothing_group);
+        }
+    }
+
+    {
+        /*---- MSH_BOXMAP ----*/
+        Lib3dsChunk c;
+
+        if (strlen(mesh->box_front) ||
+            strlen(mesh->box_back) ||
+            strlen(mesh->box_left) ||
+            strlen(mesh->box_right) ||
+            strlen(mesh->box_top) ||
+            strlen(mesh->box_bottom)) {
+
+            c.chunk = CHK_MSH_BOXMAP;
+            lib3ds_chunk_write_start(&c, io);
+
+            lib3ds_io_write_string(io, mesh->box_front);
+            lib3ds_io_write_string(io, mesh->box_back);
+            lib3ds_io_write_string(io, mesh->box_left);
+            lib3ds_io_write_string(io, mesh->box_right);
+            lib3ds_io_write_string(io, mesh->box_top);
+            lib3ds_io_write_string(io, mesh->box_bottom);
+
+            lib3ds_chunk_write_end(&c, io);
+        }
+    }
+
+    lib3ds_chunk_write_end(&c, io);
+}
+
+
+static void
+texco_array_write(Lib3dsMesh *mesh, Lib3dsIo *io) {
+    Lib3dsChunk c;
+    int i;
+
+    if (!mesh->texcos) {
+        return;
+    }
+     
+    c.chunk = CHK_TEX_VERTS;
+    c.size = 8 + 8 * mesh->nvertices;
+    lib3ds_chunk_write(&c, io);
+
+    lib3ds_io_write_word(io, mesh->nvertices);
+    for (i = 0; i < mesh->nvertices; ++i) {
+        lib3ds_io_write_float(io, mesh->texcos[i][0]);
+        lib3ds_io_write_float(io, mesh->texcos[i][1]);
+    }
+}
+
+
+void
+lib3ds_mesh_write(Lib3dsFile *file, Lib3dsMesh *mesh, Lib3dsIo *io) {
+    Lib3dsChunk c;
+
+    c.chunk = CHK_N_TRI_OBJECT;
+    lib3ds_chunk_write_start(&c, io);
+
+    point_array_write(mesh, io);
+    texco_array_write(mesh, io);
+
+    if (mesh->map_type != LIB3DS_MAP_NONE) {   /*---- LIB3DS_MESH_TEXTURE_INFO ----*/
+        Lib3dsChunk c;
+        int i, j;
+
+        c.chunk = CHK_MESH_TEXTURE_INFO;
+        c.size = 92;
+        lib3ds_chunk_write(&c, io);
+
+        lib3ds_io_write_word(io, (uint16_t)mesh->map_type);
+
+        for (i = 0; i < 2; ++i) {
+            lib3ds_io_write_float(io, mesh->map_tile[i]);
+        }
+        lib3ds_io_write_vector(io, mesh->map_pos);
+        lib3ds_io_write_float(io, mesh->map_scale);
+
+        for (i = 0; i < 4; i++) {
+            for (j = 0; j < 3; j++) {
+                lib3ds_io_write_float(io, mesh->map_matrix[i][j]);
+            }
+        }
+        for (i = 0; i < 2; ++i) {
+            lib3ds_io_write_float(io, mesh->map_planar_size[i]);
+        }
+        lib3ds_io_write_float(io, mesh->map_cylinder_height);
+    }
+
+    flag_array_write(mesh, io);
+
+    {
+        /*---- LIB3DS_MESH_MATRIX ----*/
+        Lib3dsChunk c;
+        int i, j;
+
+        c.chunk = CHK_MESH_MATRIX;
+        c.size = 54;
+        lib3ds_chunk_write(&c, io);
+        for (i = 0; i < 4; i++) {
+            for (j = 0; j < 3; j++) {
+                lib3ds_io_write_float(io, mesh->matrix[i][j]);
+            }
+        }
+    }
+
+    if (mesh->color) {   /*---- LIB3DS_MESH_COLOR ----*/
+        Lib3dsChunk c;
+
+        c.chunk = CHK_MESH_COLOR;
+        c.size = 7;
+        lib3ds_chunk_write(&c, io);
+        lib3ds_io_write_byte(io, (uint8_t)mesh->color);
+    }
+    
+    face_array_write(file, mesh, io);
+
+    lib3ds_chunk_write_end(&c, io);
+}
+
Index: /OpenSceneGraph/trunk/src/osgPlugins/3ds/WriterNodeVisitor.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/WriterNodeVisitor.cpp (revision 10853)
+++ /OpenSceneGraph/trunk/src/osgPlugins/3ds/WriterNodeVisitor.cpp (revision 10853)
@@ -0,0 +1,843 @@
+// -*-c++-*-
+
+/*
+ * 3DS reader/writer for Open Scene Graph
+ *
+ * Copyright (C) ???
+ *
+ * Writing support added 2007 by Sukender (Benoit Neil), http://sukender.free.fr,
+ * strongly inspired by the OBJ writer object by Stephan Huber
+ *
+ * The Open Scene Graph (OSG) is a cross platform C++/OpenGL library for
+ * real-time rendering of large 3D photo-realistic models.
+ * The OSG homepage is http://www.openscenegraph.org/
+ */
+
+#include <osg/io_utils>
+#include <osg/CullFace>
+#include "WriterNodeVisitor.h"
+#include <assert.h>
+#include <string.h>
+
+
+void copyOsgMatrixToLib3dsMatrix(Lib3dsMatrix lib3ds_matrix, const osg::Matrix& osg_matrix)
+{
+    for(int row=0; row<4; ++row) {
+        lib3ds_matrix[row][0] = osg_matrix.ptr()[row*4+0];
+        lib3ds_matrix[row][1] = osg_matrix.ptr()[row*4+1];
+        lib3ds_matrix[row][2] = osg_matrix.ptr()[row*4+2];
+        lib3ds_matrix[row][3] = osg_matrix.ptr()[row*4+3];
+    }
+}
+
+inline void copyOsgVectorToLib3dsVector(Lib3dsVector lib3ds_vector, const osg::Vec3f& osg_vector) {
+    lib3ds_vector[0] = osg_vector[0];
+    lib3ds_vector[1] = osg_vector[1];
+    lib3ds_vector[2] = osg_vector[2];
+}
+inline void copyOsgVectorToLib3dsVector(Lib3dsVector lib3ds_vector, const osg::Vec3d& osg_vector) {
+    lib3ds_vector[0] = osg_vector[0];
+    lib3ds_vector[1] = osg_vector[1];
+    lib3ds_vector[2] = osg_vector[2];
+}
+
+inline void copyOsgColorToLib3dsColor(Lib3dsVector lib3ds_vector, const osg::Vec4f& osg_vector) {
+    lib3ds_vector[0] = osg_vector[0];
+    lib3ds_vector[1] = osg_vector[1];
+    lib3ds_vector[2] = osg_vector[2];
+}
+inline void copyOsgColorToLib3dsColor(Lib3dsVector lib3ds_vector, const osg::Vec4d& osg_vector) {
+    lib3ds_vector[0] = osg_vector[0];
+    lib3ds_vector[1] = osg_vector[1];
+    lib3ds_vector[2] = osg_vector[2];
+}
+
+inline void copyOsgQuatToLib3dsQuat(float lib3ds_vector[4], const osg::Quat& osg_quat) {
+    //lib3ds_vector[0] = osg_quat[3];        // Not sure
+    //lib3ds_vector[1] = osg_quat[0];
+    //lib3ds_vector[2] = osg_quat[1];
+    //lib3ds_vector[3] = osg_quat[2];
+    // 3DS seems to store (angle in radians, axis_x, axis_y, axis_z), but it works with (axis_x, axis_y, axis_z, -angle in radians)!
+    osg::Quat::value_type angle, x, y, z;
+    osg_quat.getRotate(angle, x, y, z);
+    lib3ds_vector[0] = static_cast<float>(x);
+    lib3ds_vector[1] = static_cast<float>(y);
+    lib3ds_vector[2] = static_cast<float>(z);
+    lib3ds_vector[3] = static_cast<float>(-angle);
+}
+
+std::string getFileName(const std::string & path) {
+    unsigned int slashPos = path.find_last_of("/\\");
+    if (slashPos == std::string::npos) return path;
+    return path.substr(slashPos+1);
+}
+
+
+/// Checks if a filename (\b not path) is 8.3 (an empty name is never 8.3, and a path is never 8.3).
+bool is83(const std::string & s) {
+    // 012345678901
+    // ABCDEFGH.ABC
+    if (s.find_first_of("/\\") != std::string::npos) return false;            // It should not be a path, but a filename
+    unsigned int len = s.length();
+    if (len > 12 || len == 0) return false;
+    unsigned int pointPos = s.rfind('.');
+    if (pointPos == std::string::npos) return len <= 8;        // Without point
+    // With point
+    if (pointPos > 8) return false;
+    if (len-1 - pointPos > 3) return false;
+    return true;
+}
+
+/// Tests if the given string is a path supported by 3DS format (8.3, 63 chars max).
+bool is3DSpath(const std::string & s) {
+    unsigned int len = s.length();
+    if (len >= 64 || len == 0) return false;
+
+    unsigned int tokenBegin = 0;
+    for (unsigned int tokenEnd=0; tokenEnd != std::string::npos; tokenBegin = tokenEnd+1) {
+        tokenEnd = s.find_first_of("/\\", tokenBegin);
+        if ( !is83(s.substr(tokenBegin, tokenEnd-tokenBegin-1)) ) return false;
+    }
+    return true;
+}
+
+
+
+/** writes all primitives of a primitive-set out to a stream, decomposes quads to triangles, line-strips to lines etc */
+class PrimitiveIndexWriter : public osg::PrimitiveIndexFunctor {
+public:
+      PrimitiveIndexWriter(osg::Geometry  *    geo, 
+                           ListTriangle  &    listTriangles,
+                           unsigned int        drawable_n,
+                           unsigned int        material) : 
+          osg::PrimitiveIndexFunctor(),
+          _drawable_n(drawable_n),
+          _listTriangles(listTriangles),
+          _hasNormalCoords(geo->getNormalArray() != NULL),
+          _hasTexCoords(geo->getTexCoordArray(0) != NULL),
+          _geo(geo),
+          _lastFaceIndex(0),
+          _material(material)
+      {
+      }
+
+      unsigned int getNextFaceIndex() { return _lastFaceIndex; }
+
+      virtual void setVertexArray(unsigned int,const osg::Vec2*) {}
+
+      virtual void setVertexArray(unsigned int count,const osg::Vec3* vecs) {}
+
+      virtual void setVertexArray(unsigned int,const osg::Vec4* ) {}
+
+      virtual void setVertexArray(unsigned int,const osg::Vec2d*) {}
+
+      virtual void setVertexArray(unsigned int ,const osg::Vec3d* ) {}
+      virtual void setVertexArray(unsigned int,const osg::Vec4d* ) {}
+
+
+      // operator for triangles
+      void writeTriangle(unsigned int i1, unsigned int i2, unsigned int i3)
+      {
+          Triangle triangle;
+          triangle.t1 = i1;
+          triangle.t2 = i2;
+          triangle.t3 = i3;
+          triangle.material = _material;
+          _listTriangles.push_back(std::make_pair(triangle, _drawable_n));
+      }
+      virtual void begin(GLenum mode)
+      {
+          _modeCache = mode;
+          _indexCache.clear();
+      }
+
+      virtual void vertex(unsigned int vert)
+      {
+          _indexCache.push_back(vert);
+      }
+
+      virtual void end()
+      {
+          if (!_indexCache.empty())
+          {
+              drawElements(_modeCache,_indexCache.size(),&_indexCache.front());
+          }
+      }
+
+      virtual void drawArrays(GLenum mode,GLint first,GLsizei count);
+
+      virtual void drawElements(GLenum mode,GLsizei count,const GLubyte* indices)
+      {
+          drawElementsImplementation<GLubyte>(mode, count, indices);
+      }
+      virtual void drawElements(GLenum mode,GLsizei count,const GLushort* indices)
+      {
+          drawElementsImplementation<GLushort>(mode, count, indices);
+      }
+
+      virtual void drawElements(GLenum mode,GLsizei count,const GLuint* indices)
+      {
+          drawElementsImplementation<GLuint>(mode, count, indices);
+      }
+
+protected:
+
+    template<typename T>void drawElementsImplementation(GLenum mode, GLsizei count, const T* indices)
+    {
+        if (indices==0 || count==0) return;
+
+        typedef const T* IndexPointer;
+
+        switch(mode)
+        {
+        case(GL_TRIANGLES):
+            {
+                //lib3ds_mesh_resize_faces(_mesh, _lastFaceIndex + count / 3);
+                IndexPointer ilast = &indices[count];
+                for(IndexPointer  iptr=indices;iptr<ilast;iptr+=3)
+                    writeTriangle(*iptr,*(iptr+1),*(iptr+2));
+
+                break;
+            }
+        case(GL_TRIANGLE_STRIP):
+            {
+                //lib3ds_mesh_resize_faces(_mesh, _lastFaceIndex + count -2);
+                IndexPointer iptr = indices;
+                for(GLsizei i=2;i<count;++i,++iptr)
+                {
+                    if ((i%2)) writeTriangle(*(iptr),*(iptr+2),*(iptr+1));
+                    else       writeTriangle(*(iptr),*(iptr+1),*(iptr+2));
+                }
+                break;
+            }
+        case(GL_QUADS):
+            {
+                //lib3ds_mesh_resize_faces(_mesh, _lastFaceIndex + count /2);        // count/4*2
+                IndexPointer iptr = indices;
+                for(GLsizei i=3;i<count;i+=4,iptr+=4)
+                {
+                    writeTriangle(*(iptr),*(iptr+1),*(iptr+2));
+                    writeTriangle(*(iptr),*(iptr+2),*(iptr+3));
+                }
+                break;
+            }
+        case(GL_QUAD_STRIP):
+            {
+                //lib3ds_mesh_resize_faces(_mesh, _lastFaceIndex + (count / 2 -1)*2);
+                IndexPointer iptr = indices;
+                for(GLsizei i=3;i<count;i+=2,iptr+=2)
+                {
+                    writeTriangle(*(iptr),*(iptr+1),*(iptr+2));
+                    writeTriangle(*(iptr+1),*(iptr+3),*(iptr+2));
+                }
+                break;
+            }
+        case(GL_POLYGON): // treat polygons as GL_TRIANGLE_FAN
+        case(GL_TRIANGLE_FAN):
+            {
+                //lib3ds_mesh_resize_faces(_mesh, _lastFaceIndex + count -2);
+                IndexPointer iptr = indices;
+                unsigned int first = *iptr;
+                ++iptr;
+                for(GLsizei i=2;i<count;++i,++iptr)
+                {
+                    writeTriangle(first,*(iptr),*(iptr+1));
+                }
+                break;
+            }
+        case(GL_POINTS):
+        case(GL_LINES):
+        case(GL_LINE_STRIP):
+        case(GL_LINE_LOOP):
+            // Not handled
+            break;
+
+        default:
+            // uhm should never come to this point :)
+            break;
+        }
+    }
+
+private:
+
+    PrimitiveIndexWriter& operator = (const PrimitiveIndexWriter&) { return *this; }
+
+    unsigned int         _drawable_n;
+    ListTriangle    &     _listTriangles;
+    GLenum               _modeCache;
+    std::vector<GLuint>  _indexCache;
+    bool                 _hasNormalCoords, _hasTexCoords;
+    osg::Geometry*       _geo;
+    unsigned int         _lastFaceIndex;
+    unsigned int         _material;
+};
+
+
+void PrimitiveIndexWriter::drawArrays(GLenum mode,GLint first,GLsizei count)
+{
+    switch(mode)
+    {
+    case(GL_TRIANGLES):
+        {
+            unsigned int pos=first;
+            for(GLsizei i=2;i<count;i+=3,pos+=3)
+            {
+                writeTriangle(pos,pos+1,pos+2);
+            }
+            break;
+        }
+    case(GL_TRIANGLE_STRIP):
+        {
+            unsigned int pos=first;
+            for(GLsizei i=2;i<count;++i,++pos)
+            {
+                if ((i%2)) writeTriangle(pos,pos+2,pos+1);
+                else       writeTriangle(pos,pos+1,pos+2);
+            }
+            break;
+        }
+    case(GL_QUADS):
+        {
+            unsigned int pos=first;
+            for(GLsizei i=3;i<count;i+=4,pos+=4)
+            {
+                writeTriangle(pos,pos+1,pos+2);
+                writeTriangle(pos,pos+2,pos+3);
+            }
+            break;
+        }
+    case(GL_QUAD_STRIP):
+        {
+            unsigned int pos=first;
+            for(GLsizei i=3;i<count;i+=2,pos+=2)
+            {
+                writeTriangle(pos,pos+1,pos+2);
+                writeTriangle(pos+1,pos+3,pos+2);
+            }
+            break;
+        }
+    case(GL_POLYGON): // treat polygons as GL_TRIANGLE_FAN
+    case(GL_TRIANGLE_FAN):
+        {
+            unsigned int pos=first+1;
+            for(GLsizei i=2;i<count;++i,++pos)
+            {
+                writeTriangle(first,pos,pos+1);
+            }
+            break;
+        }
+    case(GL_POINTS):
+    case(GL_LINES):
+    case(GL_LINE_STRIP):
+    case(GL_LINE_LOOP):
+        //break;
+    default:
+        osg::notify(osg::WARN) << "WriterNodeVisitor :: can't handle mode " << mode << std::endl;
+        break;
+    }
+}
+
+
+
+WriterNodeVisitor::Material::Material(WriterNodeVisitor & writerNodeVisitor, osg::StateSet * stateset, osg::Material* mat, osg::Texture* tex, int index) :
+    index(index),
+    diffuse(1,1,1,1),
+    ambient(0.2,0.2,0.2,1),
+    specular(0,0,0,1),
+    shininess(0),
+    transparency(0),
+    double_sided(false),
+    image(NULL),
+    texture_transparency(false),
+    texture_no_tile(false)
+{
+    //static unsigned int s_objmaterial_id = 0;
+    //++s_objmaterial_id;
+    if (mat) {
+        assert(stateset);
+        diffuse = mat->getDiffuse(osg::Material::FRONT);
+        ambient = mat->getAmbient(osg::Material::FRONT);
+        specular = mat->getSpecular(osg::Material::FRONT);
+        shininess = mat->getShininess(osg::Material::FRONT);
+        transparency = 1-diffuse.w();
+        name = writerNodeVisitor.getUniqueName(mat->getName(),"mat");
+        osg::StateAttribute * attribute = stateset->getAttribute(osg::StateAttribute::CULLFACE);
+        if (!attribute) {
+            double_sided = true;
+        } else {
+            assert(dynamic_cast<osg::CullFace *>(attribute));
+            osg::CullFace::Mode mode = static_cast<osg::CullFace *>(attribute)->getMode();
+            if (mode == osg::CullFace::BACK) double_sided = false;
+            else if (mode == osg::CullFace::FRONT) {
+                osg::notify(osg::WARN) << "3DS Writer: Reversed face (culled FRONT) not supported yet." << std::endl;
+                double_sided = false;
+            }
+            else {
+                assert(mode == osg::CullFace::FRONT_AND_BACK);
+                osg::notify(osg::WARN) << "3DS Writer: Invisible face (culled FRONT_AND_BACK) not supported yet." << std::endl;
+                double_sided = false;
+            }
+        }
+    }
+    if (tex) {
+        osg::Image* img = tex->getImage(0);
+        if(img)
+        {
+            texture_transparency = (stateset->getMode(GL_BLEND) == osg::StateAttribute::ON);
+            texture_no_tile = (tex->getWrap(osg::Texture2D::WRAP_S) == osg::Texture2D::CLAMP);
+            image = img;
+        }
+    }
+
+    if (name.empty()) {
+        std::stringstream ss;
+        ss << "m" << index;
+        name = ss.str();
+    }
+}
+
+
+/// Creates a unique 3DS name for a given texture, and copies the image file to disk at an appropriate location if necessary.
+//std::string WriterNodeVisitor::export3DSTexture(const osg::Image * image, const std::string & texName) {
+//    std::string extension = osgDB::getFileExtension(texName);
+//    if (is83(texName))
+//    {
+//        std::string newName = texName;
+//        if (extension.empty())
+//            newName += ".rgb";
+//        if (osgDB::Registry::instance()->writeImage(*image, osgDB::concatPaths(_directory, newName), options).status() == 
+//            osgDB::ReaderWriter::WriteResult::ERROR_IN_WRITING_FILE)
+//            failedApply();
+//        return texName;
+//    }
+//    if (extension.empty())
+//    {
+//        extension = "rgb";
+//    }
+//    std::string newName = getUniqueName(texName, "tex");
+//    newName += "." + extension;
+//    osgDB::Registry::instance()->writeImage(*image, osgDB::concatPaths(_directory, newName), options);
+//    return newName;
+//}
+
+std::string
+getPathRelative(const std::string & srcBad,
+                const std::string & dstBad)
+{
+    const std::string & src = osgDB::convertFileNameToNativeStyle(srcBad);
+    const std::string & dst = osgDB::convertFileNameToNativeStyle(dstBad);
+    std::string::const_iterator itDst = dst.begin();
+    std::string::const_iterator itSrc = src.begin();
+
+    std::string result = "";
+
+    while(itDst != dst.end())
+    {
+        if (itSrc != src.end() && *itDst == *itSrc)
+            ++itSrc;
+        else if (!result.empty() || *itDst != '\\')  
+            result += *itDst;
+        ++itDst;
+    }
+    if (itSrc != src.end() || !is3DSpath(result))
+        result = osgDB::getSimpleFileName(dst);
+    return result;
+}
+
+void WriterNodeVisitor::writeMaterials()
+{
+    unsigned int nbMat = _materialMap.size();
+    lib3ds_file_reserve_materials(file3ds, nbMat, 1);
+    // Ugly thing: it seems lib3ds_file_insert_material() doesn't support insertion in a random order (else materials are not assigned the right way)
+    for (unsigned int iMat=0; iMat<nbMat; ++iMat)
+    {
+        bool found = false;
+        for(MaterialMap::iterator itr = _materialMap.begin(); itr != _materialMap.end(); ++itr)
+        {
+            const Material & mat = itr->second;
+            if (mat.index != static_cast<int>(iMat)) continue;        // Ugly thing (2)
+            found = true;
+
+            assert(mat.index>=0 && mat.index < static_cast<int>(_materialMap.size()));
+            Lib3dsMaterial * mat3ds = lib3ds_material_new(getFileName(mat.name).c_str());
+            copyOsgColorToLib3dsColor(mat3ds->ambient,  mat.ambient);
+            copyOsgColorToLib3dsColor(mat3ds->diffuse,  mat.diffuse);
+            copyOsgColorToLib3dsColor(mat3ds->specular, mat.specular);
+            mat3ds->shininess = mat.shininess;
+            mat3ds->transparency = mat.transparency;
+            mat3ds->two_sided = mat.double_sided ? 1 : 0;
+            if (mat.image)
+            {
+                Lib3dsTextureMap & tex = mat3ds->texture1_map;
+                std::string path;
+                if(mat.image->getFileName().empty())
+                {
+                    std::ostringstream oss;
+                    oss << "Image_" << _imageCount++ << ".rgb";
+                    path = oss.str();
+                }
+                else
+                    path = getPathRelative(_srcDirectory, mat.image->getFileName());
+                // if(!is3DSpath(path))
+                    path = osgDB::getSimpleFileName(path);
+
+                strcpy(tex.name, path.c_str());
+                path = osgDB::concatPaths(_directory, path);
+                osgDB::makeDirectoryForFile(path);
+
+                if (mat.image && mat.image->data()) osgDB::Registry::instance()->writeImage(*(mat.image), path, NULL);
+                if (mat.texture_transparency) tex.flags |= LIB3DS_TEXTURE_ALPHA_SOURCE;
+                if (mat.texture_no_tile) tex.flags |= LIB3DS_TEXTURE_NO_TILE;
+            }
+            if (!suceedLastApply())
+                return;
+            lib3ds_file_insert_material(file3ds, mat3ds, itr->second.index);
+            break;        // Ugly thing (3)
+        }
+        if (!found) throw "Implementation error";                // Ugly thing (4)
+    }
+}
+
+
+std::string WriterNodeVisitor::getUniqueName(const std::string& defaultValue, const std::string & _defaultPrefix, bool nameIsPath) {
+    if (_defaultPrefix.length()>=4) throw "Default prefix is too long";            // Arbitrarily defined to 3 chars. You can modify this, but you may have to change the code so that finding a number is okay, even when changing the default prefix length.
+
+    // Tests if default name is valid and unique
+    bool defaultIs83 = is83(defaultValue);
+    bool defaultIsValid = nameIsPath ? is3DSpath(defaultValue) : defaultIs83;
+    if (defaultIsValid && _nameMap.find(defaultValue) == _nameMap.end()) {
+        _nameMap.insert(defaultValue);
+        return defaultValue;
+    }
+
+    std::string defaultPrefix(_defaultPrefix.empty() ? "_" : _defaultPrefix);
+
+    unsigned int max_val = 0;
+    std::string truncDefaultValue = "";
+    for (unsigned int i = 0; i < std::min<unsigned int>(defaultValue.size(), 4); ++i)
+    {
+        if (defaultValue[i] == '.')
+        {
+            truncDefaultValue = defaultValue.substr(0, i);
+            break;
+        }
+    }
+    if (truncDefaultValue.empty())
+        truncDefaultValue = defaultValue.substr(0, std::min<unsigned int>(defaultValue.size(), 4));
+    std::map<std::string, unsigned int>::iterator pairPrefix;
+    defaultIs83 = is83(truncDefaultValue);
+    if (defaultIs83)
+    {
+        max_val = static_cast<unsigned int>(pow(10., 8. - truncDefaultValue.length() - 1)) -1;        // defaultPrefix.length()-1 because we add an underscore ("_")
+        pairPrefix = _mapPrefix.find(truncDefaultValue);
+    }  
+
+    if (defaultIs83 && (_mapPrefix.end() == pairPrefix || pairPrefix->second <= max_val))
+    {
+        defaultPrefix = truncDefaultValue;
+    }
+    else
+    {
+        max_val = static_cast<unsigned int>(pow(10., 8. - defaultPrefix.length() - 1)) -  1;        // defaultPrefix.length()-1 because we add an underscore ("_")
+        pairPrefix = _mapPrefix.find(defaultPrefix);
+    }
+
+    unsigned int searchStart = 0;
+    if (pairPrefix != _mapPrefix.end())
+        searchStart = pairPrefix->second;
+
+    for(unsigned int i = searchStart; i <= max_val; ++i) {
+        std::stringstream ss;
+        ss << defaultPrefix << "_" << i;
+        const std::string & res = ss.str();
+        if (_nameMap.find(res) == _nameMap.end()) {
+            if (pairPrefix != _mapPrefix.end())
+            {
+                pairPrefix->second = i + 1;
+            }
+            else
+            {
+                _mapPrefix.insert(std::make_pair(defaultPrefix, i + 1));
+            }
+            _nameMap.insert(res);
+            return res;
+        }
+    }
+    if (defaultPrefix == "_") _lastGeneratedNumberedName = max_val;
+    throw "No more names available! Is default prefix too long?";
+}
+
+int WriterNodeVisitor::processStateSet(osg::StateSet* ss)
+{
+    MaterialMap::const_iterator itr = _materialMap.find(ss);
+    if (itr != _materialMap.end()) {
+        assert(itr->second.index>=0);
+        return itr->second.index;
+    }
+
+    osg::Material* mat = dynamic_cast<osg::Material*>(ss->getAttribute(osg::StateAttribute::MATERIAL));
+    osg::Texture* tex = dynamic_cast<osg::Texture*>(ss->getTextureAttribute(0, osg::StateAttribute::TEXTURE));
+
+    if (mat || tex)
+    {
+        int matNum = _lastMaterialIndex;
+        _materialMap.insert(std::make_pair(osg::ref_ptr<osg::StateSet>(ss), Material(*this, ss, mat, tex, matNum) ));
+        ++_lastMaterialIndex;
+        return matNum;
+    }
+    return -1;
+}
+
+/** 
+*  Add a vertice to the index and link him with the Triangle index and the drawable.
+*  \param index_vert is the map where the vertice are stored.
+*  \param index is the indice of the vertice's position in the vec3.
+*  \param drawable_n is the number of the drawable.
+*  \return the position of the vertice in the final mesh.
+*/
+unsigned int
+WriterNodeVisitor::getMeshIndexForGeometryIndex(MapIndices & index_vert, 
+                                                unsigned int index,
+                                                unsigned int drawable_n)
+{
+    MapIndices::iterator itIndex = index_vert.find(std::make_pair(index, drawable_n));
+    if (itIndex == index_vert.end()) {
+        unsigned int indexMesh = index_vert.size();
+        index_vert.insert(std::make_pair(std::make_pair(index, drawable_n), indexMesh));
+        return indexMesh;
+    }
+    return itIndex->second;
+}
+
+
+void 
+WriterNodeVisitor::buildMesh(osg::Geode                  &    geo,
+                             MapIndices                  &    index_vert,
+                             bool                        texcoords,
+                             Lib3dsMesh                  *    mesh)
+{
+    osg::notify(osg::DEBUG_INFO) << "Building Mesh" << std::endl;
+
+    if (!mesh) throw "Allocation error";        // TODO
+
+    lib3ds_mesh_resize_vertices(mesh, index_vert.size(), texcoords ? 1 : 0, 0);
+    // Write points
+
+    for(MapIndices::iterator it = index_vert.begin(); it != index_vert.end();++it)
+    {
+        osg::Geometry *g = geo.getDrawable( it->first.second )->asGeometry();
+        assert(g->getVertexArray());
+        if (g->getVertexArray()->getType() != osg::Array::Vec3ArrayType)
+            throw "Vertex array is not Vec3. Not implemented";        // TODO
+        const osg::Vec3Array & vecs= *static_cast<osg::Vec3Array *>(g->getVertexArray());
+        copyOsgVectorToLib3dsVector(mesh->vertices[it->second], vecs[it->first.first]);
+    }
+
+    // Write texture coords (Texture 0 only)
+    if (texcoords)
+    {
+        for(MapIndices::iterator it = index_vert.begin(); it != index_vert.end(); ++it)
+        {
+            osg::Geometry *g = geo.getDrawable( it->first.second )->asGeometry();
+            osg::Array * array = g->getTexCoordArray(0);
+            if(array)
+            {
+                if (g->getTexCoordArray(0)->getType() != osg::Array::Vec2ArrayType)
+                    throw "Texture coords array is not Vec2. Not implemented";        // TODO
+                const osg::Vec2Array & vecs= *static_cast<osg::Vec2Array *>(array);
+                mesh->texcos[it->second][0] = vecs[it->first.first][0];
+                mesh->texcos[it->second][1] = vecs[it->first.first][1];
+            }
+        }
+    }
+    lib3ds_file_insert_mesh(file3ds, mesh, _lastMeshIndex);
+    ++_lastMeshIndex;
+
+    Lib3dsMeshInstanceNode * node3ds = lib3ds_node_new_mesh_instance(mesh, mesh->name, NULL, NULL, NULL);
+    lib3ds_file_append_node(file3ds, reinterpret_cast<Lib3dsNode*>(node3ds), reinterpret_cast<Lib3dsNode*>(_cur3dsNode));
+}
+
+unsigned int 
+WriterNodeVisitor::calcVertices(osg::Geode & geo)
+{
+    unsigned int numVertice = 0;
+    for (unsigned int i = 0; i < geo.getNumDrawables(); ++i)
+    {
+        osg::Geometry *g = geo.getDrawable( i )->asGeometry();
+        assert(g->getVertexArray());
+        if (g->getVertexArray()->getType() != osg::Array::Vec3ArrayType)
+            throw "Vertex array is not Vec3. Not implemented";        // TODO
+        const osg::Vec3Array & vecs= *static_cast<osg::Vec3Array *>(g->getVertexArray());
+        numVertice += vecs.getNumElements();
+    }
+    return numVertice;
+}
+
+
+void
+WriterNodeVisitor::buildFaces(osg::Geode     &    geo,
+                              ListTriangle   &    listTriangles,
+                              bool                texcoords)
+{
+    MapIndices index_vert;
+    unsigned int nbFace = 0;
+    Lib3dsMesh *mesh = lib3ds_mesh_new( getUniqueName(geo.getName().empty() ? geo.className() : geo.getName(), "geo").c_str() );
+    unsigned int nbTriangles = listTriangles.size();
+
+    lib3ds_mesh_resize_faces(mesh, nbTriangles);
+
+    unsigned int nbVertices = calcVertices(geo);
+    if (listTriangles.size() >= MAX_FACES-2 ||
+       ((nbVertices) >= MAX_VERTICES-2))
+    {
+        osg::notify(osg::ALWAYS) << "Sorting elements..." << std::endl;
+        WriterCompareTriangle cmp(geo, nbVertices);
+        std::sort(listTriangles.begin(), listTriangles.end(), cmp);
+    }
+
+    for (ListTriangle::iterator it = listTriangles.begin(); it != listTriangles.end(); ++it) //Go through the triangle list to define meshs
+    {
+        // Using -2 due to the fact that we treat 3 faces in one time (=the algorithm may overrun the limit by 2).
+        if ((index_vert.size() >= MAX_VERTICES-2 ||        // If mesh is full
+            nbFace >= MAX_FACES-2))
+        {
+            // Finnishing mesh
+            lib3ds_mesh_resize_faces(mesh, nbFace);
+            buildMesh(geo, index_vert, texcoords, mesh);
+
+            // Creating a new mesh
+            index_vert.clear();
+            mesh = lib3ds_mesh_new( getUniqueName(geo.getName().empty() ? geo.className() : geo.getName(), "geo").c_str());
+            nbTriangles -= nbFace;
+            nbFace = 0;
+            lib3ds_mesh_resize_faces(mesh, nbTriangles);
+        }
+        Lib3dsFace & face = mesh->faces[nbFace++];
+        face.index[0] = getMeshIndexForGeometryIndex(index_vert, it->first.t1, it->second);
+        face.index[1] = getMeshIndexForGeometryIndex(index_vert, it->first.t2, it->second);
+        face.index[2] = getMeshIndexForGeometryIndex(index_vert, it->first.t3, it->second);
+        face.material = it->first.material;
+    }
+    buildMesh(geo, index_vert, texcoords, mesh); //When a Mesh is completed without restriction of vertices number
+}
+
+void 
+WriterNodeVisitor::createListTriangle(osg::Geometry    *    geo, 
+                                      ListTriangle    &    listTriangles,
+                                      bool            &    texcoords,
+                                      unsigned int    &   drawable_n)
+{
+    unsigned int nbVertices = 0;
+    {
+        if (geo->getVertexArray() && geo->getVertexArray()->getType() != osg::Array::Vec3ArrayType)
+            throw "Vertex array is not Vec3. Not implemented";        // TODO
+        const osg::Vec3Array * vecs = geo->getVertexArray() ? static_cast<osg::Vec3Array *>(geo->getVertexArray()) : NULL;
+        if (vecs) 
+        {
+            nbVertices = geo->getVertexArray()->getNumElements();
+            // Texture coords
+            if (geo->getTexCoordArray(0) && geo->getTexCoordArray(0)->getType() != osg::Array::Vec2ArrayType)
+                throw "Texture coords array is not Vec2. Not implemented";        // TODO
+            const osg::Vec2Array * texvecs = geo->getTexCoordArray(0) ? static_cast<osg::Vec2Array *>(geo->getTexCoordArray(0)) : NULL;
+            if (texvecs) 
+            {
+                unsigned int nb = geo->getTexCoordArray(0)->getNumElements();
+                if (nb != geo->getVertexArray()->getNumElements()) throw "There are more/less texture coords than vertices!";
+                texcoords = true;
+            }
+        }
+    }
+
+    if (nbVertices==0) return;
+
+    int material = processStateSet(_currentStateSet.get());    
+
+    for(unsigned int i = 0; i < geo->getNumPrimitiveSets(); ++i) //Fill the Triangle List
+    {
+        osg::PrimitiveSet* ps = geo->getPrimitiveSet(i);
+        PrimitiveIndexWriter pif(geo, listTriangles, drawable_n, material);
+        ps->accept(pif);
+    }
+}
+
+bool WriterNodeVisitor::suceedLastApply() const
+{
+    return _suceedLastApply;
+}
+
+void WriterNodeVisitor::failedApply()
+{
+    _suceedLastApply = false;
+    osg::notify(osg::NOTICE) << "Error going through node" << std::endl;
+}
+
+void WriterNodeVisitor::apply( osg::Geode &node )
+{
+    pushStateSet(node.getStateSet());
+    //_nameStack.push_back(node.getName());
+    //osg::Matrix m = osg::computeLocalToWorld(getNodePath());
+    unsigned int count = node.getNumDrawables();
+    ListTriangle listTriangles;
+    bool texcoords = false;
+    for ( unsigned int i = 0; i < count; i++ )
+    {
+        osg::Geometry *g = node.getDrawable( i )->asGeometry();
+        if ( g != NULL )
+        {
+            pushStateSet(g->getStateSet());
+            createListTriangle(g, listTriangles, texcoords, i);
+            popStateSet(g->getStateSet());
+        }
+    }
+    if (count > 0)
+    {
+        buildFaces(node, listTriangles, texcoords);
+    }
+    popStateSet(node.getStateSet());
+    //_nameStack.pop_back();
+    if (suceedLastApply())
+        traverse(node);
+}
+
+void WriterNodeVisitor::apply(osg::Group &node)
+{
+    Lib3dsMeshInstanceNode * parent = _cur3dsNode;
+    Lib3dsMeshInstanceNode * node3ds = lib3ds_node_new_mesh_instance(NULL, getUniqueName(node.getName().empty() ? node.className() : getFileName(node.getName()), "grp").c_str(), NULL, NULL, NULL);
+    lib3ds_file_append_node(file3ds, reinterpret_cast<Lib3dsNode*>(node3ds), reinterpret_cast<Lib3dsNode*>(parent));
+    _cur3dsNode = node3ds;
+    if (suceedLastApply())
+        traverse(node);
+    _cur3dsNode = parent;
+}
+
+void WriterNodeVisitor::apply(osg::MatrixTransform &node)
+{
+    Lib3dsMeshInstanceNode * parent = _cur3dsNode;
+
+    const osg::Matrix & m = node.getMatrix();
+    //const osg::Matrix m( osg::computeWorldToLocal(getNodePath()) );        // [NEEDS TESTING!] 3DS matrices always contain world to local transformation (not local transform; ie. from parent)
+
+    // Transform data used to be given to lib3ds_node_new_mesh_instance(), but it seems buggy (pivot problem? bug in conversion?).
+    float pos[3];
+    float scl[3];
+    float rot[4];
+    osg::Vec3 osgScl, osgPos;
+    osg::Quat osgRot, osgSo;
+    m.decompose(osgPos, osgRot, osgScl, osgSo);
+    copyOsgVectorToLib3dsVector(pos, osgPos);
+    copyOsgVectorToLib3dsVector(scl, osgScl);
+    copyOsgQuatToLib3dsQuat(rot, osgRot);
+    Lib3dsMeshInstanceNode * node3ds = lib3ds_node_new_mesh_instance
+        (NULL, getUniqueName(node.getName().empty() ? node.className() : node.getName(), "mtx").c_str(), pos, scl, rot);
+
+    //// Create a mesh instance with no transform and then copy the matrix (doesn't work)
+    //Lib3dsMeshInstanceNode * node3ds = lib3ds_node_new_mesh_instance
+    //    (NULL, getUniqueName(node.getName().empty() ? node.className() : node.getName(), "mtx").c_str(), NULL, NULL, NULL);
+    //    copyOsgMatrixToLib3dsMatrix(node3ds->base.matrix, m);
+
+    lib3ds_file_append_node(file3ds, reinterpret_cast<Lib3dsNode*>(node3ds), reinterpret_cast<Lib3dsNode*>(parent));
+    _cur3dsNode = node3ds;
+    if (suceedLastApply())
+        traverse(node);
+    _cur3dsNode = parent;
+}
Index: /OpenSceneGraph/trunk/src/osgPlugins/3ds/AUTHORS
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/AUTHORS (revision 8)
+++ /OpenSceneGraph/trunk/src/osgPlugins/3ds/AUTHORS (revision 10853)
@@ -1,1 +1,3 @@
 J.E. Hoffmann <je-h@gmx.net>
+Sukender (Benoit Neil) <suky0001 at free dot fr>
+Thibault Caporal <>
Index: /OpenSceneGraph/trunk/src/osgPlugins/3ds/WriterNodeVisitor.h
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/WriterNodeVisitor.h (revision 10853)
+++ /OpenSceneGraph/trunk/src/osgPlugins/3ds/WriterNodeVisitor.h (revision 10853)
@@ -0,0 +1,228 @@
+// -*-c++-*-
+
+/*
+* 3DS reader/writer for Open Scene Graph
+*
+* Copyright (C) ???
+*
+* Writing support added 2007 by Sukender (Benoit Neil), http://sukender.free.fr,
+* strongly inspired by the OBJ writer object by Stephan Huber
+*
+* The Open Scene Graph (OSG) is a cross platform C++/OpenGL library for
+* real-time rendering of large 3D photo-realistic models.
+* The OSG homepage is http://www.openscenegraph.org/
+*/
+
+#ifndef _3DS_WRITER_NODE_VISITOR_HEADER__
+#define _3DS_WRITER_NODE_VISITOR_HEADER__
+
+#include <string>
+#include <stack>
+#include <sstream>
+
+#include <osg/Notify>
+#include <osg/Node>
+#include <osg/MatrixTransform>
+#include <osg/Geode>
+
+#include <osg/Geometry>
+#include <osg/StateSet>
+#include <osg/Material>
+#include <osg/Texture2D>
+#include <osg/TexGen>
+#include <osg/TexMat>
+
+#include <osgDB/Registry>
+#include <osgDB/ReadFile>
+#include <osgDB/FileUtils>
+#include <osgDB/FileNameUtils>
+
+#include <map>
+
+#include "lib3ds/lib3ds.h"
+#include "WriterCompareTriangle.h"
+
+void copyOsgMatrixToLib3dsMatrix(Lib3dsMatrix lib3ds_matrix, const osg::Matrix& osg_matrix);
+
+typedef std::map<std::pair<unsigned int, unsigned int>, unsigned int> MapIndices;
+typedef std::vector<std::pair<Triangle, int> > ListTriangle; //the int is the drawable of the triangle
+
+class WriterNodeVisitor: public osg::NodeVisitor {
+
+    public:
+        static const unsigned int MAX_VERTICES = 65000;
+        static const unsigned int MAX_FACES    = MAX_VERTICES;
+
+        WriterNodeVisitor(Lib3dsFile * file3ds, const std::string & fileName, 
+                        const osgDB::ReaderWriter::Options* options, 
+                        const std::string & srcDirectory) :
+            osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
+            _suceedLastApply(true),
+            _srcDirectory(srcDirectory),
+            file3ds(file3ds),
+            _currentStateSet(new osg::StateSet()),
+            _lastGeneratedNumberedName(0),
+            _lastMaterialIndex(0),
+            _lastMeshIndex(0),
+            _cur3dsNode(NULL),
+            options(options),
+            _imageCount(0)
+        {
+            //supportsOption("flipTexture", "flip texture upside-down");
+            if (!fileName.empty())
+                _directory = options->getDatabasePathList().empty() ? osgDB::getFilePath(fileName) : options->getDatabasePathList().front();
+        }
+
+        bool        suceedLastApply() const;
+        void        failedApply();
+        virtual void apply(osg::Geode &node);
+
+        virtual void apply(osg::Group &node);
+        virtual void apply(osg::MatrixTransform &node);
+
+        void traverse (osg::Node &node)
+        {
+            pushStateSet(node.getStateSet());
+            osg::NodeVisitor::traverse( node );
+            popStateSet(node.getStateSet());
+        }
+
+        void pushStateSet(osg::StateSet* ss)
+        {
+        if (NULL!=ss) {
+            // Save our current stateset
+            _stateSetStack.push(_currentStateSet.get());
+
+            // merge with node stateset
+            _currentStateSet = static_cast<osg::StateSet*>(_currentStateSet->clone(osg::CopyOp::SHALLOW_COPY));
+            _currentStateSet->merge(*ss);
+        }
+        }
+
+
+        void popStateSet(osg::StateSet* ss)
+        {
+            if (NULL!=ss) {
+            // restore the previous stateset
+            _currentStateSet = _stateSetStack.top();
+            _stateSetStack.pop();
+            }
+        }
+
+
+        void writeMaterials();
+
+
+
+        ///\todo Add support for 2nd texture, opacity_map, bump_map, specular_map, shininess_map, self_illum_map, reflection_map.
+        class Material {
+            public:
+                Material(WriterNodeVisitor & writerNodeVisitor, osg::StateSet * stateset, osg::Material* mat, osg::Texture* tex, int index=-1);
+
+                int index;            ///< Index in the 3DS file
+                osg::Vec4 diffuse, ambient, specular;
+                float shininess;
+                float transparency;
+                bool  double_sided;
+                std::string name;
+                osg::ref_ptr<osg::Image> image;
+                bool texture_transparency;
+                bool texture_no_tile;
+            protected:
+                Material() : index(-1) {}
+
+        };
+
+    protected:
+        struct CompareStateSet
+        {
+            bool operator()(const osg::ref_ptr<osg::StateSet>& ss1, const osg::ref_ptr<osg::StateSet>& ss2) const
+            {
+				return *ss1 < *ss2;
+            }
+        };
+
+
+    private:
+        WriterNodeVisitor& operator = (const WriterNodeVisitor&) { return *this; }
+
+        /** 
+        *  Fill the faces field of the mesh and call buildMesh().
+        *  \param geo is the geode who contain vertice and faces.
+        *  \param listTriangles contain all the meshs faces.
+        *  \param texcoords tell us if we have to treat texture coord.
+        */
+        void buildFaces(osg::Geode & geo, ListTriangle & listTriangles, bool texcoords);
+
+        /** 
+        *  Calculate the number of vertices in the geode.
+        *  \return the number of vertices in the geode.
+        */
+        unsigned int 
+        calcVertices(osg::Geode & geo);
+
+        /** 
+        *  Build a mesh
+        *  \param geo is the geode who contain vertice and faces
+        *  \param index_vert is the index used to build the new mesh
+        *  \param texcoords tell us if we have to treat texture coord
+        *  \param mesh is the mesh with faces filled
+        *  \return the place of the box in the vector.
+        *  \sa See cutScene() about the definition of the boxes for faces sorting.
+        */
+        void
+        buildMesh(osg::Geode        &    geo, 
+                  MapIndices        &    index_vert, 
+                  bool                   texcoords,        
+                  Lib3dsMesh             *mesh);
+
+        /** 
+        *  Add a vertice to the index and link him with the Triangle index and the drawable.
+        *  \param index_vert is the map where the vertice are stored.
+        *  \param index is the indice of the vertice's position in the vec3.
+        *  \param drawable_n is the number of the drawable.
+        *  \return the position of the vertice in the final mesh.
+        */
+        unsigned int
+        getMeshIndexForGeometryIndex(MapIndices & index_vert, 
+                                     unsigned int index,
+                                     unsigned int drawable_n);
+        /** 
+        *  Create the list of faces from the geode.
+        *  \param geo is the geode to study.
+        *  \param listTriangles is the list to fill.
+        *  \param texcoords tell us if we have to treat texture coord.
+        *  \param drawable_n tell us which drawable we are building.
+        */ 
+        void createListTriangle(osg::Geometry       *    geo, 
+                                ListTriangle        &    listTriangles,
+                                bool                &    texcoords,
+                                unsigned int        &    drawable_n);
+
+        int processStateSet(osg::StateSet* stateset);
+
+        std::string getUniqueName(const std::string& defaultvalue="", const std::string & defaultPrefix = "", bool nameIsPath = false);
+        std::string export3DSTexture(const osg::Image * image, const std::string & fileName);
+
+        typedef std::stack<osg::ref_ptr<osg::StateSet> > StateSetStack;
+        typedef std::map< osg::ref_ptr<osg::StateSet>, Material, CompareStateSet> MaterialMap;
+
+
+        bool                                _suceedLastApply;
+        std::string                         _directory;
+        std::string                         _srcDirectory;
+        Lib3dsFile *                        file3ds;
+        StateSetStack                       _stateSetStack;
+        osg::ref_ptr<osg::StateSet>         _currentStateSet;
+        std::map<std::string, unsigned int> _mapPrefix;
+        std::set<std::string>                _nameMap;
+        MaterialMap                         _materialMap;
+        unsigned int                        _lastGeneratedNumberedName;
+        unsigned int                        _lastMaterialIndex;
+        unsigned int                        _lastMeshIndex;
+        Lib3dsMeshInstanceNode *            _cur3dsNode;
+        const osgDB::ReaderWriter::Options* options;
+        unsigned int                        _imageCount;
+};
+
+#endif
Index: /OpenSceneGraph/trunk/src/osgPlugins/3ds/ReaderWriter3DS.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/ReaderWriter3DS.cpp (revision 10805)
+++ /OpenSceneGraph/trunk/src/osgPlugins/3ds/ReaderWriter3DS.cpp (revision 10853)
@@ -1,2 +1,4 @@
+#define ENABLE_3DS_WRITER      1            // Enables the 3DS writer (the define should be removed when the writer will be stable and tested enough)
+
 #include <osg/Notify>
 #include <osg/Group>
@@ -19,14 +21,8 @@
 #include <osg/NodeVisitor>
 
-
-#include "file.h"
-#include "mesh.h"
-#include "material.h"
-#include "vector.h"
-#include "matrix.h"
-#include "node.h"
-#include "quat.h"
-#include "readwrite.h"
-
+#ifdef ENABLE_3DS_WRITER
+    #include "WriterNodeVisitor.h"
+#endif
+#include "lib3ds/lib3ds.h"
 #include <stdlib.h>
 #include <string.h>
@@ -36,92 +32,140 @@
 #include <iostream>
 #include <sstream>
+#include <assert.h>
 
 using namespace std;
 using namespace osg;
 
+
+void copyLib3dsMatrixToOsgMatrix(osg::Matrix& osg_matrix, const Lib3dsMatrix lib3ds_matrix)
+{
+    osg_matrix.set(
+        lib3ds_matrix[0][0],lib3ds_matrix[0][1],lib3ds_matrix[0][2],lib3ds_matrix[0][3],
+        lib3ds_matrix[1][0],lib3ds_matrix[1][1],lib3ds_matrix[1][2],lib3ds_matrix[1][3],
+        lib3ds_matrix[2][0],lib3ds_matrix[2][1],lib3ds_matrix[2][2],lib3ds_matrix[2][3],
+        lib3ds_matrix[3][0],lib3ds_matrix[3][1],lib3ds_matrix[3][2],lib3ds_matrix[3][3]);
+}
+
+osg::Matrix copyLib3dsMatrixToOsgMatrix(const Lib3dsMatrix mat)
+{
+    osg::Matrix osgMatrix;
+    copyLib3dsMatrixToOsgMatrix(osgMatrix, mat);
+    return osgMatrix;
+}
+
+void copyLib3dsVec3ToOsgVec3(osg::Vec3f osgVec, const float vertices[3]) {
+    return osgVec.set(vertices[0], vertices[1], vertices[2]);
+}
+
+osg::Vec3f copyLib3dsVec3ToOsgVec3(const float vertices[3]) {
+    return osg::Vec3f(vertices[0], vertices[1], vertices[2]);
+}
+
+osg::Quat copyLib3dsQuatToOsgQuat(const float quat[4]) {
+    return osg::Quat(quat[0], quat[1], quat[2], quat[3]);
+}
+
+
+
 class PrintVisitor : public NodeVisitor
 {
-
-   public:
-   
-        PrintVisitor(std::ostream& out):
-            NodeVisitor(NodeVisitor::TRAVERSE_ALL_CHILDREN),
-            _out(out)
-        {
-            _indent = 0;
-            _step = 4;
-        }
-        
-        inline void moveIn() { _indent += _step; }
-        inline void moveOut() { _indent -= _step; }
-        inline void writeIndent() 
-        {
-            for(int i=0;i<_indent;++i) _out << " ";
-        }
-                
-        virtual void apply(Node& node)
-        {
-            moveIn();
-            writeIndent(); _out << node.className() <<std::endl;
-            traverse(node);
-            moveOut();
-        }
-
-        virtual void apply(Geode& node)         { apply((Node&)node); }
-        virtual void apply(Billboard& node)     { apply((Geode&)node); }
-        virtual void apply(LightSource& node)   { apply((Group&)node); }
-        virtual void apply(ClipNode& node)      { apply((Group&)node); }
-        
-        virtual void apply(Group& node)         { apply((Node&)node); }
-        virtual void apply(Transform& node)     { apply((Group&)node); }
-        virtual void apply(Projection& node)    { apply((Group&)node); }
-        virtual void apply(Switch& node)        { apply((Group&)node); }
-        virtual void apply(LOD& node)           { apply((Group&)node); }
-
-   protected:
-
-        PrintVisitor& operator = (const PrintVisitor&) { return *this; }
-
-        std::ostream& _out;
-        int _indent;
-        int _step;
+public:
+    PrintVisitor(std::ostream& out):
+      NodeVisitor(NodeVisitor::TRAVERSE_ALL_CHILDREN),
+          _out(out)
+      {
+          _indent = 0;
+          _step = 4;
+      }
+
+      inline void moveIn() { _indent += _step; }
+      inline void moveOut() { _indent -= _step; }
+      inline void writeIndent()
+      {
+          for(int i=0;i<_indent;++i) _out << " ";
+      }
+
+      virtual void apply(Node& node)
+      {
+          moveIn();
+          writeIndent(); _out << node.className() <<std::endl;
+          traverse(node);
+          moveOut();
+      }
+
+      virtual void apply(Geode& node)         { apply((Node&)node); }
+      virtual void apply(Billboard& node)     { apply((Geode&)node); }
+      virtual void apply(LightSource& node)   { apply((Group&)node); }
+      virtual void apply(ClipNode& node)      { apply((Group&)node); }
+
+      virtual void apply(Group& node)         { apply((Node&)node); }
+      virtual void apply(Transform& node)     { apply((Group&)node); }
+      virtual void apply(Projection& node)    { apply((Group&)node); }
+      virtual void apply(Switch& node)        { apply((Group&)node); }
+      virtual void apply(LOD& node)           { apply((Group&)node); }
+
+protected:
+
+    PrintVisitor& operator = (const PrintVisitor&) { return *this; }
+
+    std::ostream& _out;
+    int _indent;
+    int _step;
 };
 
+/// Possible options:
+///		- noMatrixTransforms: set the plugin to apply matrices into the mesh vertices ("old behaviour") instead of restoring them ("new behaviour"). You may use this option to avoid a few rounding errors.
+///		- checkForEspilonIdentityMatrices: if noMatrixTransforms is \b not set, then consider "almost identity" matrices to be identity ones (in case of rounding errors).
+///		- restoreMatrixTransformsNoMeshes: makes an exception to the behaviour when 'noMatrixTransforms' is \b not set for mesh instances. When a mesh instance has a transform on it, the reader creates a MatrixTransform above the Geode. If you don't want the hierarchy to be modified, then you can use this option to merge the transform into vertices.
 class ReaderWriter3DS : public osgDB::ReaderWriter
 {
+public:
+
+    ReaderWriter3DS();
+
+    virtual const char* className() const { return "3DS Auto Studio Reader/Writer"; }
+
+    virtual ReadResult readNode(const std::string& file, const osgDB::ReaderWriter::Options* options) const;
+    virtual ReadResult readNode(std::istream& fin, const Options* options) const;
+#if ENABLE_3DS_WRITER
+    virtual WriteResult writeNode(const osg::Node& /*node*/,const std::string& /*fileName*/,const Options* =NULL) const;
+    virtual WriteResult writeNode(const osg::Node& /*node*/,std::ostream& /*fout*/,const Options* =NULL) const;
+#endif
+
+protected:
+    ReadResult constructFrom3dsFile(Lib3dsFile *f,const std::string& filename, const Options* options) const;
+
+#if ENABLE_3DS_WRITER
+    bool createFileObject(const osg::Node& node, Lib3dsFile * file3ds,const std::string& fileName, const osgDB::ReaderWriter::Options* options) const;
+#endif
+
+    class ReaderObject
+    {
     public:
-
-        ReaderWriter3DS();
-
-        virtual const char* className() const { return "3DS Auto Studio Reader"; }
-
-        virtual ReadResult readNode(const std::string& file, const osgDB::ReaderWriter::Options* options) const;
-        virtual ReadResult readNode(std::istream& fin, const Options* options) const;
-
-    protected:
-        ReadResult constructFrom3dsFile(Lib3dsFile *f,const std::string& filename, const Options* options) const;
-
-
-        class ReaderObject
-        {
-        public:
-            ReaderObject();
-        
-            typedef std::map<std::string,osg::StateSet*> StateSetMap;
-            typedef std::vector<int> FaceList;
-            typedef std::map<std::string,osg::StateSet*> GeoStateMap;
-
-            osg::Texture2D* createTexture(Lib3dsTextureMap *texture,const char* label,bool& transparancy, const osgDB::ReaderWriter::Options* options);
-            osg::StateSet* createStateSet(Lib3dsMaterial *materials, const osgDB::ReaderWriter::Options* options);
-            osg::Drawable* createDrawable(Lib3dsMesh *meshes,FaceList& faceList, Lib3dsMatrix* matrix);
-
-            std::string _directory;
-            bool _useSmoothingGroups;
-            bool _usePerVertexNormals;
-
-            // MIKEC
-            osg::Node* processMesh(StateSetMap& drawStateMap,osg::Group* parent,Lib3dsMesh* mesh, Lib3dsMatrix* matrix);
-            osg::Node* processNode(StateSetMap drawStateMap,Lib3dsFile *f,Lib3dsNode *node);
-        };
+        ReaderObject(const osgDB::ReaderWriter::Options* options);
+
+        typedef std::vector<osg::StateSet*> StateSetMap;
+        typedef std::vector<int> FaceList;
+        typedef std::map<std::string,osg::StateSet*> GeoStateMap;
+
+        osg::Texture2D* createTexture(Lib3dsTextureMap *texture,const char* label,bool& transparancy);
+        osg::StateSet* createStateSet(Lib3dsMaterial *materials);
+        osg::Drawable* createDrawable(Lib3dsMesh *meshes,FaceList& faceList, const osg::Matrix * matrix);
+
+        std::string _directory;
+        bool _useSmoothingGroups;
+        bool _usePerVertexNormals;
+
+        // MIKEC
+        osg::Node* processMesh(StateSetMap& drawStateMap,osg::Group* parent,Lib3dsMesh* mesh, const osg::Matrix * matrix);
+        osg::Node* processNode(StateSetMap drawStateMap,Lib3dsFile *f,Lib3dsNode *node);
+    private:
+        const osgDB::ReaderWriter::Options* options;
+        bool noMatrixTransforms;            ///< Should the plugin apply matrices into the mesh vertices ("old behaviour"), instead of restoring matrices ("new behaviour")?
+        bool checkForEspilonIdentityMatrices;
+        bool restoreMatrixTransformsNoMeshes;
+        typedef std::map<unsigned int,FaceList> SmoothingFaceMap;
+        void addDrawableFromFace(osg::Geode * geode, FaceList & faceList, Lib3dsMesh * mesh, const osg::Matrix * matrix, osg::StateSet * stateSet);
+    };
 };
 
@@ -133,5 +177,5 @@
 {
     supportsExtension("3ds","3D Studio model format");
-
+    supportsOption("OutputTextureFiles","Write out the texture images to file");
     setByteOrder();
 
@@ -157,8 +201,23 @@
 }
 
-ReaderWriter3DS::ReaderObject::ReaderObject()
-{
-    _useSmoothingGroups = true;
-    _usePerVertexNormals = true;
+ReaderWriter3DS::ReaderObject::ReaderObject(const osgDB::ReaderWriter::Options* options) :
+    _useSmoothingGroups(true),
+    _usePerVertexNormals(true),
+    options(options),
+    noMatrixTransforms(false),
+    checkForEspilonIdentityMatrices(false),
+    restoreMatrixTransformsNoMeshes(false)
+{
+    std::istringstream iss(options->getOptionString());
+    std::string opt; 
+    while (iss >> opt) 
+    {
+        if (opt == "noMatrixTransforms")
+            noMatrixTransforms = true;
+        if (opt == "checkForEspilonIdentityMatrices")
+            checkForEspilonIdentityMatrices = true;
+        if (opt == "restoreMatrixTransformsNoMeshes")
+            restoreMatrixTransformsNoMeshes = true;
+    }
 }
 
@@ -172,6 +231,5 @@
 void print(Lib3dsMesh *mesh,int level);
 void print(Lib3dsUserData *user,int level);
-void print(Lib3dsNodeData *user,int level);
-void print(Lib3dsObjectData *object,int level);
+void print(Lib3dsMeshInstanceNode *object,int level);
 void print(Lib3dsNode *node, int level);
 
@@ -198,16 +256,8 @@
     }
 }
-void print(Lib3dsNodeData *node,int level) {
-    if (node) {
-        pad(level); cout << "node data:" << endl;
-        // nodedata->object is a union of many types
-        print((Lib3dsObjectData *)&node->object,level+1);
-    } else {
-        pad(level); cout << "no user data" << endl;
-    }
-}
-void print(Lib3dsObjectData *object,int level) {
+
+void print(Lib3dsMeshInstanceNode *object,int level) {
     if (object) {
-        pad(level); cout << "objectdata instance [" << object->instance << "]" << endl;
+        pad(level); cout << "objectdata instance [" << object->instance_name << "]" << endl;
         pad(level); cout << "pivot     " << object->pivot[0] <<" "<< object->pivot[1] <<" "<< object->pivot[2] << endl;
         pad(level); cout << "pos       " << object->pos[0] <<" "<< object->pos[1] <<" "<< object->pos[2] << endl;
@@ -220,13 +270,19 @@
 
 void print(Lib3dsNode *node, int level) {
-    
+
     pad(level); cout << "node name [" << node->name << "]" << endl;
-    pad(level); cout << "node id    " << node->node_id << endl;
-    pad(level); cout << "node parent id " << node->parent_id << endl;
+    pad(level); cout << "node id    " << node->user_id << endl;
+    pad(level); cout << "node parent id " << (node->parent ? static_cast<int>(node->parent->user_id) : -1) << endl;
     pad(level); cout << "node matrix:" << endl;
     print(node->matrix,level+1);
-    print(&node->data,level);
-    print(&node->user,level);
-    
+
+    if (node->type == LIB3DS_NODE_MESH_INSTANCE) {
+        pad(level); cout << "mesh instance data:" << endl;
+        print(reinterpret_cast<Lib3dsMeshInstanceNode *>(node),level+1);
+    } else {
+        pad(level); cout << "node is not a mesh instance (not handled)" << endl;
+    }
+
+    print(&node->user_ptr,level);
 
     for(Lib3dsNode *child=node->childs; child; child=child->next) {
@@ -236,85 +292,100 @@
 }
 
-void copyLib3dsMatrixToOsgMatrix(osg::Matrix& osg_matrix, const Lib3dsMatrix lib3ds_matrix)
-{
-    osg_matrix.set(
-        lib3ds_matrix[0][0],lib3ds_matrix[0][1],lib3ds_matrix[0][2],lib3ds_matrix[0][3],
-        lib3ds_matrix[1][0],lib3ds_matrix[1][1],lib3ds_matrix[1][2],lib3ds_matrix[1][3],
-        lib3ds_matrix[2][0],lib3ds_matrix[2][1],lib3ds_matrix[2][2],lib3ds_matrix[2][3],
-        lib3ds_matrix[3][0],lib3ds_matrix[3][1],lib3ds_matrix[3][2],lib3ds_matrix[3][3]); 
-}
+void ReaderWriter3DS::ReaderObject::addDrawableFromFace(osg::Geode * geode, FaceList & faceList,
+                                                        Lib3dsMesh * mesh,
+                                                        const osg::Matrix * matrix,
+                                                        osg::StateSet * stateSet)
+{
+    if (_useSmoothingGroups)
+    {
+        SmoothingFaceMap smoothingFaceMap;
+        for (FaceList::iterator flitr=faceList.begin();
+            flitr!=faceList.end();
+            ++flitr)
+        {
+            smoothingFaceMap[mesh->faces[*flitr].smoothing_group].push_back(*flitr);
+        }
+
+        for(SmoothingFaceMap::iterator sitr=smoothingFaceMap.begin();
+            sitr!=smoothingFaceMap.end();
+            ++sitr)
+        {
+            // each smoothing group to have its own geom
+            // to ensure the vertices on adjacent groups
+            // don't get shared.
+            FaceList& smoothFaceMap = sitr->second;
+            osg::ref_ptr<osg::Drawable> drawable = createDrawable(mesh,smoothFaceMap,matrix);
+            if (drawable)
+            {
+                if (stateSet)
+                    drawable->setStateSet(stateSet);
+                geode->addDrawable(drawable);
+            }
+        }
+    }
+    else // ignore smoothing groups.
+    {
+        osg::ref_ptr<osg::Drawable> drawable = createDrawable(mesh,faceList,matrix);
+        if (drawable)
+        {
+            if (stateSet)
+                drawable->setStateSet(stateSet);
+            geode->addDrawable(drawable);
+        }
+    }
+}
+
 
 // Transforms points by matrix if 'matrix' is not NULL
 // Creates a Geode and Geometry (as parent,child) and adds the Geode to 'parent' parameter iff 'parent' is non-NULL
 // Returns ptr to the Geode
-osg::Node* ReaderWriter3DS::ReaderObject::processMesh(StateSetMap& drawStateMap,osg::Group* parent,Lib3dsMesh* mesh, Lib3dsMatrix* matrix) {
-    typedef std::vector<int> FaceList;
-    typedef std::map<std::string,FaceList> MaterialFaceMap;
+osg::Node* ReaderWriter3DS::ReaderObject::processMesh(StateSetMap& drawStateMap,osg::Group* parent,Lib3dsMesh* mesh, const osg::Matrix * matrix) {
+    typedef std::vector<FaceList> MaterialFaceMap;
     MaterialFaceMap materialFaceMap;
-    for (unsigned int i=0; i<mesh->faces; ++i)
-    {
-        materialFaceMap[mesh->faceL[i].material].push_back(i);
-    }
-
-    if (materialFaceMap.empty())
+    unsigned int numMaterials = drawStateMap.size();
+    materialFaceMap.insert(materialFaceMap.begin(), numMaterials, FaceList());        // Setup the map
+    FaceList defaultMaterialFaceList;
+    for (unsigned int i=0; i<mesh->nfaces; ++i)
+    {
+        if (mesh->faces[i].material>=0) {
+            //std::stringstream materialStr;
+            //materialStr << mesh->faces[i].material;
+            //materialFaceMap[materialStr.str()].push_back(i);
+            materialFaceMap[mesh->faces[i].material].push_back(i);
+        }
+        else
+            defaultMaterialFaceList.push_back(i);
+    }
+    if (materialFaceMap.empty() && defaultMaterialFaceList.empty())
     {
         osg::notify(osg::NOTICE)<<"Warning : no triangles assigned to mesh '"<<mesh->name<<"'"<< std::endl;
+        //osg::notify(osg::INFO) << "No material assigned to mesh '" << mesh->name << "'" << std::endl;
         return NULL;
     }
     else
     {
-
         osg::Geode* geode = new osg::Geode;
         geode->setName(mesh->name);
-
-        for(MaterialFaceMap::iterator itr=materialFaceMap.begin();
-            itr!=materialFaceMap.end();
-            ++itr)
-        {
-            FaceList& faceList = itr->second;
-            
-            if (_useSmoothingGroups)
-            {
-
-                typedef std::map<int,FaceList> SmoothingFaceMap;
-                SmoothingFaceMap smoothingFaceMap;
-                for (FaceList::iterator flitr=faceList.begin();
-                     flitr!=faceList.end();
-                     ++flitr)
-                {
-                    smoothingFaceMap[mesh->faceL[*flitr].smoothing].push_back(*flitr);
-                }
-
-                for(SmoothingFaceMap::iterator sitr=smoothingFaceMap.begin();
-                    sitr!=smoothingFaceMap.end();
-                    ++sitr)
-                {
-                    // each smoothing group to have its own geom 
-                    // to ensure the vertices on adjacent groups
-                    // don't get shared.
-                    FaceList& smoothFaceMap = sitr->second;
-
-                    osg::Drawable* drawable = createDrawable(mesh,smoothFaceMap,matrix);
-                    if (drawable)
-                    {
-                        drawable->setStateSet(drawStateMap[itr->first]);
-                        geode->addDrawable(drawable);
-                    }
-                }
-            }
-            else // ignore smoothing groups.
-            {
-                osg::Drawable* drawable = createDrawable(mesh,faceList,matrix);
-                if (drawable)
-                {
-                    drawable->setStateSet(drawStateMap[itr->first]);
-                    geode->addDrawable(drawable);
-                }
-            }
-        }
-
+        if (!defaultMaterialFaceList.empty())
+        {
+            addDrawableFromFace(geode, defaultMaterialFaceList, mesh, matrix, NULL);
+        }
+        for(unsigned int imat=0; imat<numMaterials; ++imat)
+        {
+            addDrawableFromFace(geode, materialFaceMap[imat], mesh, matrix, drawStateMap[imat]);
+        }
         if (parent) parent->addChild(geode);
         return geode;
     }
+}
+
+
+/// Returns true if a matrix is 'almost' identity, meaning that the difference between each value and the corresponding identity value is less than an epsilon value.
+bool isIdentityEquivalent(const osg::Matrix & mat, osg::Matrix::value_type epsilon=1e-6)
+{
+    return osg::equivalent(mat(0,0), 1, epsilon) && osg::equivalent(mat(0,1), 0, epsilon) && osg::equivalent(mat(0,2), 0, epsilon) &&  osg::equivalent(mat(0,3), 0, epsilon) &&
+           osg::equivalent(mat(1,0), 0, epsilon) && osg::equivalent(mat(1,1), 1, epsilon) && osg::equivalent(mat(1,2), 0, epsilon) &&  osg::equivalent(mat(1,3), 0, epsilon) &&
+           osg::equivalent(mat(2,0), 0, epsilon) && osg::equivalent(mat(2,1), 0, epsilon) && osg::equivalent(mat(2,2), 1, epsilon) &&  osg::equivalent(mat(2,3), 0, epsilon) &&
+           osg::equivalent(mat(3,0), 0, epsilon) && osg::equivalent(mat(3,1), 0, epsilon) && osg::equivalent(mat(3,2), 0, epsilon) &&  osg::equivalent(mat(3,3), 1, epsilon);
 }
 
@@ -332,107 +403,96 @@
     Transform the node by the node matrix, which does the orientation about the pivot point, (and currently) transforms the object back by a translation to the PP.
 
-  */
-osg::Node* ReaderWriter3DS::ReaderObject::processNode(StateSetMap drawStateMap,Lib3dsFile *f,Lib3dsNode *node) {
-    
-    osg::Group* group=NULL;// created on demand if we find we have children to group together
-    
-
-    // Handle all children of this node for hierarchical assemblies
-    Lib3dsNode *p;
-    for (p=node->childs; p!=0; p=p->next) {
-        if (!group) {
-            group =new osg::Group;
-            if (strcmp(node->name, "$$$DUMMY") == 0) {
-                group->setName(node->data.object.instance);
+*/
+osg::Node* ReaderWriter3DS::ReaderObject::processNode(StateSetMap drawStateMap,Lib3dsFile *f,Lib3dsNode *node)
+{
+    // Get mesh
+    Lib3dsMeshInstanceNode * object = (node->type == LIB3DS_NODE_MESH_INSTANCE) ? reinterpret_cast<Lib3dsMeshInstanceNode *>(node) : NULL;
+    Lib3dsMesh * mesh = lib3ds_file_mesh_for_node(f,node);
+    assert(!(mesh && !object));		// Node must be a LIB3DS_NODE_MESH_INSTANCE if a mesh exists
+
+    // Retreive LOCAL transform
+    static const osg::Matrix::value_type MATRIX_EPSILON = 1e-10;
+    osg::Matrix osgNodeMatrix( copyLib3dsMatrixToOsgMatrix(node->matrix) );
+
+    if (node->parent)
+    {
+        // Matrices evaluated by lib3DS are multiplied by parents' ones
+        osgNodeMatrix *= osg::Matrix::inverse( copyLib3dsMatrixToOsgMatrix(node->parent->matrix) );
+    }
+
+    // Test if we should create an intermediate Group (or MatrixTransform) and which matrix we should apply to the vertices
+    osg::Group* group = NULL;
+
+    // Get pivot point
+    osg::Vec3 pivot( object ? copyLib3dsVec3ToOsgVec3(object->pivot) : osg::Vec3() );
+    bool pivoted = pivot.x()!=0 || pivot.y()!=0 || pivot.z()!=0;
+
+    osg::Matrix meshMat;
+    if (mesh) {
+         if (!noMatrixTransforms) {
+            // There can be a transform directly on a mesh instance (= as if a osg::MatrixTransform and a osg::Geode were merged together) in object->pos/rot/scl
+            if (!pivoted) {
+				meshMat = osg::Matrix::inverse(copyLib3dsMatrixToOsgMatrix(mesh->matrix));
             } else {
-                group->setName(node->name);
+                meshMat = osg::Matrix::inverse(copyLib3dsMatrixToOsgMatrix(mesh->matrix)) * osg::Matrix::translate(-pivot);
             }
         }
-        group->addChild(processNode(drawStateMap,f,p));
-    }
-    
-    // MIKEC: possible BUG - 3ds files APPEAR to enforce unqiue names, so this is OK, but I am not 100% sure
-    // failed to find any alternative way to do it in lib3ds though, and lib3ds player.c application uses this method
-    Lib3dsMesh *mesh=lib3ds_file_mesh_by_name(f,node->name);
+        else {
+			if (pivoted) {
+				meshMat = osg::Matrix::inverse(copyLib3dsMatrixToOsgMatrix(mesh->matrix)) * osg::Matrix::translate(-pivot) * copyLib3dsMatrixToOsgMatrix(node->matrix);
+			} else {
+				meshMat = osg::Matrix::inverse(copyLib3dsMatrixToOsgMatrix(mesh->matrix)) * copyLib3dsMatrixToOsgMatrix(node->matrix);
+			}
+			osgNodeMatrix = osg::Matrix::identity();		// Not sure it's useful, but it's harmless ;)
+        }
+    }
+
+    bool isOsgNodeMatrixIdentity = false;
+    if (osgNodeMatrix.isIdentity() || (checkForEspilonIdentityMatrices && isIdentityEquivalent(osgNodeMatrix, MATRIX_EPSILON))) {
+        isOsgNodeMatrixIdentity = true;
+    }
+
+
+    if (node->childs != NULL || pivoted || (!isOsgNodeMatrixIdentity && !noMatrixTransforms)) {
+        if (isOsgNodeMatrixIdentity || noMatrixTransforms) {
+            group = new osg::Group;
+        } else {
+            group = new osg::MatrixTransform(osgNodeMatrix);
+        }
+    }
+
+    if (group) {
+        if (strcmp(node->name, "$$$DUMMY") == 0) 
+        {
+            if (node->type == LIB3DS_NODE_MESH_INSTANCE)
+                group->setName(reinterpret_cast<Lib3dsMeshInstanceNode *>(node)->instance_name); 
+        }
+        else
+            group->setName(node->name);
+
+        // Handle all children of this node for hierarchical assemblies
+        for (Lib3dsNode *p=node->childs; p!=NULL; p=p->next) {
+            group->addChild(processNode(drawStateMap,f,p));
+        }
+    } else {
+        assert(node->childs == NULL);		// Else we must have a group to put childs into
+    }
+
+    // Handle mesh
     if (mesh) {
-        Lib3dsObjectData* object=&node->data.object;
-        Lib3dsMatrix mesh_inverse;
-        osg::Matrix osgmatrix;
-        
-        lib3ds_matrix_copy(mesh_inverse,mesh->matrix); 
-        lib3ds_matrix_inv(mesh_inverse);
-        
-        Lib3dsMatrix M,N;
-        lib3ds_matrix_identity(M);
-        lib3ds_matrix_identity(N);
-        lib3ds_matrix_copy(M,node->matrix);
-        N[3][0]=-object->pivot[0];
-        N[3][1]=-object->pivot[1];
-        N[3][2]=-object->pivot[2];
-
-        bool pivoted=false;
-        if ( (object->pivot[0]!=0.0) || (object->pivot[1]!=0.0) || (object->pivot[2]!=0.0) ) {
-            pivoted=true; // there is a pivot point, so we must use it
-        }
-
-        /*cout<<"M"<<node->name<<endl;
-        print(M,0);
-        cout<<"N"<<endl;
-        print(N,0);*/
-
-        if (pivoted) {
-            // Transform object's pivot point to the world origin
-            osg::MatrixTransform* T=new osg::MatrixTransform;
-            copyLib3dsMatrixToOsgMatrix(osgmatrix, N);
-            T->setMatrix(osgmatrix);
-            T->setName("3DSPIVOTPOINT: Translate pivotpoint to (world) origin");
-            //cout<<"Translation for "<<node->name<<" is "<<osgmatrix<<endl;
-
-            // rotate about "origin" (after the transform this is the world origin)
-            // BUG this matrix also contains the translation to the pivot point - we should plit that out (maybe)
-            osg::MatrixTransform* R=new osg::MatrixTransform;
-            copyLib3dsMatrixToOsgMatrix(osgmatrix, M);
-            R->setMatrix(osgmatrix);
-            R->setName("3DSPIVOTPOINT: Rotate");
-                
-            /*
-            cout<<"Rotation for "<<node->name<<" is "<<osgmatrix<<endl;
-            osg::Quat quat;
-            quat.set(osgmatrix);
-            osg::Vec3 axis;
-            float angle;
-            quat.getRotate(angle,axis);
-            cout<<"which is "<<osg::RadiansToDegrees(angle)<<" degrees around "<<axis<<endl;
-            */
-            /*
-            printf("%s---------------\n",node->name);
-            printf("mesh matrix :\n");         print(mesh->matrix,1);
-            printf("mesh inverse:\n");         print(mesh_inverse,1);
-            printf("node matrix :\n");         print(matrix,1);
-            printf("pivot=%f,%f,%f pos=%f,%f,%f\n",object->pivot[0],object->pivot[1],object->pivot[2],object->pos[0],object->pos[1],object->pos[2]);
-            */
-
-            if (group) {
-                // Always in reverse order...
-                group->addChild(R); 
-                R->addChild(T);
-                processMesh(drawStateMap,T,mesh,&mesh_inverse); // creates geometry under modifier node
-                return group;
-            } else {
-                // We are a pivoted node with no children
-                R->addChild(T);
-                processMesh(drawStateMap,T,mesh,&mesh_inverse); // creates geometry under modifier node
-                return R;
-            }
+        osg::Matrix * meshAppliedMatPtr = NULL;
+        if (!meshMat.isIdentity() && !(checkForEspilonIdentityMatrices && isIdentityEquivalent(meshMat, MATRIX_EPSILON))) {
+            meshAppliedMatPtr = &meshMat;
+        }
+
+        if(group) {
+            // add our geometry to group (where our children already are)
+            // creates geometry under modifier node
+            processMesh(drawStateMap,group,mesh,meshAppliedMatPtr);
+            return group;
         } else {
-            if(group) {
-                // add our geometry to group (where our children already are)
-                processMesh(drawStateMap,group,mesh,NULL); // creates geometry under modifier node
-                return group;
-            } else {
-                // didnt use group for children
-                // return a ptr directly to the Geode for this mesh
-                return processMesh(drawStateMap,NULL,mesh,NULL); 
-            }    
+            // didnt use group for children
+            // return a ptr directly to the Geode for this mesh
+            return processMesh(drawStateMap,NULL,mesh,meshAppliedMatPtr);
         }
 
@@ -444,4 +504,65 @@
 }
 
+
+static long filei_seek_func(void *self, long offset, Lib3dsIoSeek origin) {
+    std::istream *f = reinterpret_cast<std::istream*>(self);
+    ios_base::seekdir o = ios_base::beg;
+    if (origin == LIB3DS_SEEK_CUR) o = ios_base::cur;
+    else if (origin == LIB3DS_SEEK_END) o = ios_base::end;
+
+    f->seekg(offset, o);
+    return f->fail() ? -1 : 0;
+}
+
+#if ENABLE_3DS_WRITER
+static long fileo_seek_func(void *self, long offset, Lib3dsIoSeek origin) {
+    std::ostream *f = reinterpret_cast<std::ostream*>(self);
+    ios_base::seekdir o = ios_base::beg;
+    if (origin == LIB3DS_SEEK_CUR) o = ios_base::cur;
+    else if (origin == LIB3DS_SEEK_END) o = ios_base::end;
+
+    f->seekp(offset, o);
+    return f->fail() ? -1 : 0;
+}
+#endif
+
+static long filei_tell_func(void *self) {
+    std::istream *f = reinterpret_cast<std::istream*>(self);
+    return f->tellg();
+}
+
+#if ENABLE_3DS_WRITER
+static long fileo_tell_func(void *self) {
+    std::ostream *f = reinterpret_cast<std::ostream*>(self);
+    return f->tellp();
+}
+#endif
+
+
+static size_t filei_read_func(void *self, void *buffer, size_t size) {
+    std::istream *f = reinterpret_cast<std::istream*>(self);
+    f->read(reinterpret_cast<char*>(buffer), size);
+    return f->gcount();
+}
+
+#if ENABLE_3DS_WRITER
+static size_t fileo_write_func(void *self, const void *buffer, size_t size) {
+    std::ostream *f = reinterpret_cast<std::ostream*>(self);
+    f->write(static_cast<const char*>(buffer), size);
+    return f->fail() ? 0 : size;
+}
+#endif
+
+static void fileio_log_func(void *self, Lib3dsLogLevel level, int indent, const char *msg)
+{
+    osg::NotifySeverity l = osg::INFO;
+    if (level == LIB3DS_LOG_ERROR) l = osg::FATAL;
+    else if (level == LIB3DS_LOG_WARN) l = osg::WARN;
+    else if (level == LIB3DS_LOG_INFO) l = osg::INFO;
+    else if (level == LIB3DS_LOG_DEBUG) l = osg::DEBUG_INFO;
+    osg::notify(l) << msg << std::endl;
+}
+
+
 osgDB::ReaderWriter::ReadResult ReaderWriter3DS::readNode(std::istream& fin,  const osgDB::ReaderWriter::Options* options) const
 {
@@ -452,11 +573,21 @@
     {
         optFileName = options->getPluginStringData("STREAM_FILENAME");
-    }
-
-    Lib3dsFile *f = lib3ds_stream_load((iostream *) &fin);
-    if (f)
-    {
-        result = constructFrom3dsFile(f,optFileName,options);
-        lib3ds_file_free(f);
+        if (optFileName.empty()) optFileName = options->getPluginStringData("filename");
+    }
+
+    // Prepare io structure to tell how to read the stream
+    Lib3dsIo io;
+    io.self = &fin;
+    io.seek_func = filei_seek_func;
+    io.tell_func = filei_tell_func;
+    io.read_func = filei_read_func;
+    io.write_func = NULL;
+    io.log_func = fileio_log_func;
+
+    Lib3dsFile * file3ds = lib3ds_file_new();
+    if (lib3ds_file_read(file3ds, &io) != 0)
+    {
+        result = constructFrom3dsFile(file3ds,optFileName,options);
+        lib3ds_file_free(file3ds);
     }
 
@@ -474,5 +605,5 @@
     if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;
 
-    Lib3dsFile *f = lib3ds_file_load(fileName.c_str(),options);
+    Lib3dsFile *f = lib3ds_file_open(fileName.c_str() /*,options*/);
 
     if (f)
@@ -498,18 +629,17 @@
     lib3ds_file_eval(f,0.0f); // second param is time 't' for animated files
 
-    ReaderObject reader;
+    ReaderObject reader(options);
 
     reader._directory = ( options && !options->getDatabasePathList().empty() ) ? options->getDatabasePathList().front() : osgDB::getFilePath(fileName);
 
-    osg::Group* group = new osg::Group;
-    group->setName(fileName);
-
     ReaderObject::StateSetMap drawStateMap;
-
-    for (Lib3dsMaterial *mat=f->materials; mat; mat=mat->next)
-    {
-        drawStateMap[mat->name] = reader.createStateSet(mat, options);
-    }
-    
+    unsigned int numMaterials = f->nmaterials;
+    drawStateMap.insert(drawStateMap.begin(), numMaterials, NULL);        // Setup the map
+    for (unsigned int imat=0; imat<numMaterials; ++imat)
+    {
+        Lib3dsMaterial * mat = f->materials[imat];
+        drawStateMap[imat] = reader.createStateSet(mat);
+    }
+
     if (osg::getNotifyLevel()>=osg::INFO)
     {
@@ -520,6 +650,6 @@
         }
         std::cout << "MESH TRAVERSAL of 3ds file "<<f->name<<std::endl;
-        for(Lib3dsMesh *mesh=f->meshes; mesh; mesh=mesh->next) {
-            print(mesh,level+1);
+        for (int imesh=0; imesh<f->nmeshes; ++imesh) {
+            print(f->meshes[imesh],level+1);
         }
     }
@@ -529,5 +659,5 @@
     // send me the model
     bool traverse_nodes=false;
-    
+
     // MIKEC: have found 3ds files with NO node structure - only meshes, for this case we fall back to the old traverse-by-meshes code
     // Loading and re-exporting these files from 3DS produces a file with correct node structure, so perhaps these are not 100% conformant?
@@ -537,13 +667,24 @@
     }
 
+    osg::Node* group = NULL;
+
     if (traverse_nodes) { // old method
-        for (Lib3dsMesh *mesh=f->meshes; mesh; mesh=mesh->next) {
-            reader.processMesh(drawStateMap,group,mesh,NULL);
+        group = new osg::Group();
+        for (int imesh=0; imesh<f->nmeshes; ++imesh) {
+            reader.processMesh(drawStateMap,group->asGroup(),f->meshes[imesh],NULL);
         }
     } else { // new method
-        for(Lib3dsNode *node=f->nodes; node; node=node->next) {
-            group->addChild(reader.processNode(drawStateMap,f,node));
-        }
-    } 
+        Lib3dsNode *node=f->nodes;
+        if (!node->next)
+            group = reader.processNode(drawStateMap,f,node);
+        else
+        {
+            group = new osg::Group();
+            for(; node; node=node->next) {
+                group->asGroup()->addChild(reader.processNode(drawStateMap,f,node));
+            }
+        }
+    }
+    if (group && group->getName().empty()) group->setName(fileName);
 
     if (osg::getNotifyLevel()>=osg::INFO)
@@ -552,6 +693,6 @@
         PrintVisitor pv(osg::notify(osg::NOTICE));
         group->accept(pv);
-    }    
-    
+    }
+
     return group;
 }
@@ -560,13 +701,13 @@
 use matrix to pretransform geometry, or NULL to do nothing
 */
-osg::Drawable*   ReaderWriter3DS::ReaderObject::createDrawable(Lib3dsMesh *m,FaceList& faceList,Lib3dsMatrix *matrix)
+osg::Drawable* ReaderWriter3DS::ReaderObject::createDrawable(Lib3dsMesh *m,FaceList& faceList, const osg::Matrix * matrix)
 {
 
     osg::Geometry* geom = new osg::Geometry;
-
     unsigned int i;
-    
+
     std::vector<int> orig2NewMapping;
-    for(i=0;i<m->points;++i) orig2NewMapping.push_back(-1);
+    orig2NewMapping.reserve(m->nvertices);
+    for(i=0;i<m->nvertices;++i) orig2NewMapping.push_back(-1);
 
     unsigned int noVertex=0;
@@ -577,25 +718,23 @@
     {
 
-        Lib3dsFace& face = m->faceL[*fitr];
-
-        if (orig2NewMapping[face.points[0]]<0)
-            orig2NewMapping[face.points[0]] = noVertex++;
-
-        if (orig2NewMapping[face.points[1]]<0)
-            orig2NewMapping[face.points[1]] = noVertex++;
-
-        if (orig2NewMapping[face.points[2]]<0)
-            orig2NewMapping[face.points[2]] = noVertex++;
+        Lib3dsFace& face = m->faces[*fitr];
+
+        if (orig2NewMapping[face.index[0]]<0)
+            orig2NewMapping[face.index[0]] = noVertex++;
+
+        if (orig2NewMapping[face.index[1]]<0)
+            orig2NewMapping[face.index[1]] = noVertex++;
+
+        if (orig2NewMapping[face.index[2]]<0)
+            orig2NewMapping[face.index[2]] = noVertex++;
 
     }
 
     // create vertices.
-    
+
     osg::Vec3Array* osg_coords = new osg::Vec3Array(noVertex);
     geom->setVertexArray(osg_coords);
 
-    Lib3dsVector c;
-       
-    for (i=0; i<m->points; ++i)
+    for (i=0; i<m->nvertices; ++i)
     {
         if (orig2NewMapping[i]>=0)
@@ -603,11 +742,10 @@
             if (matrix)
             {
-                lib3ds_vector_transform(c,*matrix, m->pointL[i].pos);
-                (*osg_coords)[orig2NewMapping[i]].set(c[0],c[1],c[2]);
+                (*osg_coords)[orig2NewMapping[i]].set( copyLib3dsVec3ToOsgVec3(m->vertices[i]) * (*matrix) );
             }
             else
             {
                 // original no transform code.
-                (*osg_coords)[orig2NewMapping[i]].set(m->pointL[i].pos[0],m->pointL[i].pos[1],m->pointL[i].pos[2]);
+                (*osg_coords)[orig2NewMapping[i]].set( copyLib3dsVec3ToOsgVec3(m->vertices[i]) );
             }
         }
@@ -615,26 +753,25 @@
 
     // create texture coords if needed.
-    if (m->texels>0)
-    {
-        if (m->texels==m->points)
-        {
-            osg::Vec2Array* osg_tcoords = new osg::Vec2Array(noVertex);
-            geom->setTexCoordArray(0,osg_tcoords);
-            for (i=0; i<m->texels; ++i)
-            {
-                if (orig2NewMapping[i]>=0) (*osg_tcoords)[orig2NewMapping[i]].set(m->texelL[i][0],m->texelL[i][1]);
-            }
-        }
-        else
-        {
-            osg::notify(osg::WARN)<<"Warning: in 3ds loader m->texels ("<<m->texels<<") != m->points ("<<m->points<<")"<< std::endl;
-        }
-    }
-
-    // create normals.
+    if (m->texcos)
+    {
+        osg::Vec2Array* osg_tcoords = new osg::Vec2Array(noVertex);
+        geom->setTexCoordArray(0,osg_tcoords);
+        for (i=0; i<m->nvertices; ++i)
+        {
+            if (orig2NewMapping[i]>=0) (*osg_tcoords)[orig2NewMapping[i]].set(m->texcos[i][0],m->texcos[i][1]);
+        }
+    }
+
+    // create normals
+    // Sukender: 3DS file format doesn't store normals (that is to say they're recomputed each time).
+    // When using per vertex normals, we could use either vertex computation, or face computation (and copy the normal to each vertex). Here we use the latter one.
     if (_usePerVertexNormals)
     {
+        //Lib3dsVector * normals = new Lib3dsVector[m->nfaces*3];
+        //lib3ds_mesh_calculate_vertex_normals(m, normals);
+        Lib3dsVector * normals = new Lib3dsVector[m->nfaces];
+        lib3ds_mesh_calculate_face_normals(m, normals);
         osg::Vec3Array* osg_normals = new osg::Vec3Array(noVertex);
-        
+
         // initialize normal list to zero's.
         for (i=0; i<noVertex; ++i)
@@ -647,26 +784,11 @@
             ++fitr)
         {
-            Lib3dsFace& face = m->faceL[*fitr];
-
-            (*osg_normals)[orig2NewMapping[face.points[0]]] += osg::Vec3(face.normal[0],face.normal[1],face.normal[2]);;
-            (*osg_normals)[orig2NewMapping[face.points[1]]] += osg::Vec3(face.normal[0],face.normal[1],face.normal[2]);;
-            (*osg_normals)[orig2NewMapping[face.points[2]]] += osg::Vec3(face.normal[0],face.normal[1],face.normal[2]);;
-
-        }
-
-        if (matrix)
-        {
-            osg::Matrix osg_matrix;
-            copyLib3dsMatrixToOsgMatrix(osg_matrix, *matrix);
-            for (i=0; i<noVertex; ++i)
-            {
-                (*osg_normals)[i] = osg::Matrix::transform3x3((*osg_normals)[i], osg_matrix);
-            }
-        }
-
-        // normalize the normal list to unit length normals.
-        for (i=0; i<noVertex; ++i)
-        {
-            (*osg_normals)[i].normalize();
+            Lib3dsFace& face = m->faces[*fitr];
+            osg::Vec3f osgNormal( copyLib3dsVec3ToOsgVec3(normals[*fitr]) );
+            if (matrix) osgNormal = osg::Matrix::transform3x3(osgNormal, *matrix);
+            osgNormal.normalize();
+            (*osg_normals)[orig2NewMapping[face.index[0]]] = osgNormal;
+            (*osg_normals)[orig2NewMapping[face.index[1]]] = osgNormal;
+            (*osg_normals)[orig2NewMapping[face.index[2]]] = osgNormal;
         }
 
@@ -675,6 +797,8 @@
 
     }
-    else 
-    {
+    else
+    {
+        Lib3dsVector * normals = new Lib3dsVector[m->nfaces];
+        lib3ds_mesh_calculate_face_normals(m, normals);
         osg::Vec3Array* osg_normals = new osg::Vec3Array(faceList.size());
         osg::Vec3Array::iterator normal_itr = osg_normals->begin();
@@ -683,16 +807,18 @@
             ++fitr)
         {
-            Lib3dsFace& face = m->faceL[*fitr];
-            *(normal_itr++) =  osg::Vec3(face.normal[0],face.normal[1],face.normal[2]);
+            osg::Vec3f osgNormal( copyLib3dsVec3ToOsgVec3(normals[*fitr]) );
+            if (matrix) osgNormal = osg::Matrix::transform3x3(osgNormal, *matrix);
+            osgNormal.normalize();
+            *(normal_itr++) = osgNormal;
         }
         geom->setNormalArray(osg_normals);
         geom->setNormalBinding(osg::Geometry::BIND_PER_PRIMITIVE);
     }
-    
+
     osg::Vec4ubArray* osg_colors = new osg::Vec4ubArray(1);
     (*osg_colors)[0].set(255,255,255,255);
     geom->setColorArray(osg_colors);
     geom->setColorBinding(osg::Geometry::BIND_OVERALL);
-    
+
 
     // create primitives
@@ -705,11 +831,11 @@
         ++fitr)
     {
-        Lib3dsFace& face = m->faceL[*fitr];
-
-        *(index_itr++) = orig2NewMapping[face.points[0]];
-        *(index_itr++) = orig2NewMapping[face.points[1]];
-        *(index_itr++) = orig2NewMapping[face.points[2]];
-    }
-   
+        Lib3dsFace& face = m->faces[*fitr];
+
+        *(index_itr++) = orig2NewMapping[face.index[0]];
+        *(index_itr++) = orig2NewMapping[face.index[1]];
+        *(index_itr++) = orig2NewMapping[face.index[2]];
+    }
+
     geom->addPrimitiveSet(elements);
 
@@ -723,5 +849,5 @@
 
 
-osg::Texture2D*  ReaderWriter3DS::ReaderObject::createTexture(Lib3dsTextureMap *texture,const char* label,bool& transparancy, const osgDB::ReaderWriter::Options* options)
+osg::Texture2D*  ReaderWriter3DS::ReaderObject::createTexture(Lib3dsTextureMap *texture,const char* label,bool& transparancy)
 {
     if (texture && *(texture->name))
@@ -729,10 +855,10 @@
         osg::notify(osg::NOTICE)<<"texture->name="<<texture->name<<", _directory="<<_directory<<std::endl;
 
-
         std::string fileName = osgDB::findFileInDirectory(texture->name,_directory,osgDB::CASE_INSENSITIVE);
-        if (fileName.empty()) 
+        if (fileName.empty())
         {
             // file not found in .3ds file's directory, so we'll look in the datafile path list.
             fileName = osgDB::findDataFile(texture->name,options, osgDB::CASE_INSENSITIVE);
+            osg::notify(osg::NOTICE)<<"texture->name="<<texture->name<<", _directory="<<_directory<<std::endl;
         }
 
@@ -753,15 +879,31 @@
         osg::notify(osg::DEBUG_INFO) << " '"<<texture->name<<"'"<< std::endl;
         osg::notify(osg::DEBUG_INFO) << "    texture flag        "<<texture->flags<< std::endl;
-        osg::notify(osg::DEBUG_INFO) << "    LIB3DS_DECALE       "<<((texture->flags)&LIB3DS_DECALE)<< std::endl;
-        osg::notify(osg::DEBUG_INFO) << "    LIB3DS_MIRROR       "<<((texture->flags)&LIB3DS_MIRROR)<< std::endl;
-        osg::notify(osg::DEBUG_INFO) << "    LIB3DS_NEGATE       "<<((texture->flags)&LIB3DS_NEGATE)<< std::endl;
-        osg::notify(osg::DEBUG_INFO) << "    LIB3DS_NO_TILE      "<<((texture->flags)&LIB3DS_NO_TILE)<< std::endl;
-        osg::notify(osg::DEBUG_INFO) << "    LIB3DS_SUMMED_AREA  "<<((texture->flags)&LIB3DS_SUMMED_AREA)<< std::endl;
-        osg::notify(osg::DEBUG_INFO) << "    LIB3DS_ALPHA_SOURCE "<<((texture->flags)&LIB3DS_ALPHA_SOURCE)<< std::endl;
-        osg::notify(osg::DEBUG_INFO) << "    LIB3DS_TINT         "<<((texture->flags)&LIB3DS_TINT)<< std::endl;
-        osg::notify(osg::DEBUG_INFO) << "    LIB3DS_IGNORE_ALPHA "<<((texture->flags)&LIB3DS_IGNORE_ALPHA)<< std::endl;
-        osg::notify(osg::DEBUG_INFO) << "    LIB3DS_RGB_TINT     "<<((texture->flags)&LIB3DS_RGB_TINT)<< std::endl;
-
-        osg::ref_ptr<osg::Image> osg_image = osgDB::readRefImageFile(fileName.c_str());
+        osg::notify(osg::DEBUG_INFO) << "    LIB3DS_TEXTURE_DECALE       "<<((texture->flags)&LIB3DS_TEXTURE_DECALE)<< std::endl;
+        osg::notify(osg::DEBUG_INFO) << "    LIB3DS_TEXTURE_MIRROR       "<<((texture->flags)&LIB3DS_TEXTURE_MIRROR)<< std::endl;
+        osg::notify(osg::DEBUG_INFO) << "    LIB3DS_TEXTURE_NEGATE       "<<((texture->flags)&LIB3DS_TEXTURE_NEGATE)<< std::endl;
+        osg::notify(osg::DEBUG_INFO) << "    LIB3DS_TEXTURE_NO_TILE      "<<((texture->flags)&LIB3DS_TEXTURE_NO_TILE)<< std::endl;
+        osg::notify(osg::DEBUG_INFO) << "    LIB3DS_TEXTURE_SUMMED_AREA  "<<((texture->flags)&LIB3DS_TEXTURE_SUMMED_AREA)<< std::endl;
+        osg::notify(osg::DEBUG_INFO) << "    LIB3DS_TEXTURE_ALPHA_SOURCE "<<((texture->flags)&LIB3DS_TEXTURE_ALPHA_SOURCE)<< std::endl;
+        osg::notify(osg::DEBUG_INFO) << "    LIB3DS_TEXTURE_TINT         "<<((texture->flags)&LIB3DS_TEXTURE_TINT)<< std::endl;
+        osg::notify(osg::DEBUG_INFO) << "    LIB3DS_TEXTURE_IGNORE_ALPHA "<<((texture->flags)&LIB3DS_TEXTURE_IGNORE_ALPHA)<< std::endl;
+        osg::notify(osg::DEBUG_INFO) << "    LIB3DS_TEXTURE_RGB_TINT     "<<((texture->flags)&LIB3DS_TEXTURE_RGB_TINT)<< std::endl;
+
+        bool noTexture = false;
+        if (options)
+        {
+            std::istringstream iss(options->getOptionString());
+            std::string opt;
+            while (iss >> opt)
+            {
+                if (opt == "noTexture")
+                    noTexture = true;
+            }
+        }
+
+        osg::ref_ptr<osg::Image> osg_image = NULL;
+        if(noTexture)
+            osg_image = new osg::Image();
+        else
+            osg_image = osgDB::readRefImageFile(fileName.c_str(), options); //Absolute Path
         if (!osg_image)
         {
@@ -769,13 +911,14 @@
             return NULL;
         }
-
+        if (osg_image->getFileName().empty()) // it should be done in OSG with osgDB::readRefImageFile(fileName.c_str());
+            osg_image->setFileName(fileName);
         osg::Texture2D* osg_texture = new osg::Texture2D;
         osg_texture->setImage(osg_image.get());
-
+        osg_texture->setName(texture->name);
         // does the texture support transparancy?
-        transparancy = ((texture->flags)&LIB3DS_ALPHA_SOURCE)!=0;
+        transparancy = ((texture->flags)&LIB3DS_TEXTURE_ALPHA_SOURCE)!=0;
 
         // what is the wrap mode of the texture.
-        osg::Texture2D::WrapMode wm = ((texture->flags)&LIB3DS_NO_TILE) ?
+        osg::Texture2D::WrapMode wm = ((texture->flags)&LIB3DS_TEXTURE_NO_TILE) ?
                 osg::Texture2D::CLAMP :
                 osg::Texture2D::REPEAT;
@@ -793,5 +936,5 @@
 
 
-osg::StateSet* ReaderWriter3DS::ReaderObject::createStateSet(Lib3dsMaterial *mat, const osgDB::ReaderWriter::Options* options)
+osg::StateSet* ReaderWriter3DS::ReaderObject::createStateSet(Lib3dsMaterial *mat)
 {
     if (mat==NULL) return NULL;
@@ -819,11 +962,11 @@
 
     bool textureTransparancy=false;
-    osg::Texture2D* texture1_map = createTexture(&(mat->texture1_map),"texture1_map",textureTransparancy, options);
+    osg::Texture2D* texture1_map = createTexture(&(mat->texture1_map),"texture1_map",textureTransparancy);
     if (texture1_map)
     {
         stateset->setTextureAttributeAndModes(0,texture1_map,osg::StateAttribute::ON);
-        
+
         if (!textureTransparancy)
-        {        
+        {
             // from an email from Eric Hamil, September 30, 2003.
             // According to the 3DS spec, and other
@@ -831,5 +974,5 @@
             // a non-white diffuse base color and a 100% opaque bitmap texture, will show the
             // texture with no influence from the base color.
-            
+
             // so we'll override material back to white.
             // and no longer require the decal hack below...
@@ -846,10 +989,10 @@
             material->setDiffuse(osg::Material::FRONT_AND_BACK,osg::Vec4(0.8f,0.8f,0.8f,alpha));
             material->setSpecular(osg::Material::FRONT_AND_BACK,osg::Vec4(0.0f,0.0f,0.0f,alpha));
-#endif            
-        }
-        
-// no longer required...        
+#endif
+        }
+
+// no longer required...
 //         bool decal = false;
-//         
+//
 //         // not sure exactly how to interpret what is best for .3ds
 //         // but the default text env MODULATE doesn't work well, and
@@ -893,2 +1036,96 @@
 }
 
+
+
+#if ENABLE_3DS_WRITER
+osgDB::ReaderWriter::WriteResult ReaderWriter3DS::writeNode(const osg::Node& node,const std::string& fileName,const Options* options) const {
+    std::string ext = osgDB::getLowerCaseFileExtension(fileName);
+    if (!acceptsExtension(ext)) return WriteResult::FILE_NOT_HANDLED;
+
+    //osg::notify(osg::WARN) << "!!WARNING!! 3DS write support is incomplete" << std::endl;
+
+    bool ok = true;
+    Lib3dsFile * file3ds = lib3ds_file_new();
+    if (!file3ds) return WriteResult(WriteResult::ERROR_IN_WRITING_FILE);
+
+    try {
+        osg::ref_ptr<Options> local_opt = options ? static_cast<Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options;
+        local_opt->getDatabasePathList().push_front(osgDB::getFilePath(fileName));
+
+        if (!createFileObject(node, file3ds, fileName, local_opt)) ok = false;
+        if (ok && !lib3ds_file_save(file3ds, fileName.c_str())) ok = false;
+    } catch (...) {
+        lib3ds_file_free(file3ds);
+        throw;
+    }
+    lib3ds_file_free(file3ds);
+
+    return ok ? WriteResult(WriteResult::FILE_SAVED) : WriteResult(WriteResult::ERROR_IN_WRITING_FILE);
+    //return ok ? WriteResult(WriteResult::FILE_SAVED) : WriteResult(WriteResult::FILE_NOT_HANDLED);
+}
+
+
+osgDB::ReaderWriter::WriteResult ReaderWriter3DS::writeNode(const osg::Node& node,std::ostream& fout,const Options* options) const {
+    //osg::notify(osg::WARN) << "!!WARNING!! 3DS write support is incomplete" << std::endl;
+    std::string optFileName = "";
+    if (options)
+    {
+        optFileName = options->getPluginStringData("STREAM_FILENAME");
+    }
+
+    Lib3dsIo io;
+    io.self = &fout;
+    io.seek_func = fileo_seek_func;
+    io.tell_func = fileo_tell_func;
+    io.read_func = NULL;
+    io.write_func = fileo_write_func;
+    io.log_func = fileio_log_func;
+    
+    Lib3dsFile * file3ds = lib3ds_file_new();
+    bool ok = true;
+    try {
+        osg::ref_ptr<Options> local_opt = options ? static_cast<Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options;
+        local_opt->getDatabasePathList().push_front(osgDB::getFilePath(optFileName));
+
+        if (!createFileObject(node, file3ds, optFileName, local_opt)) ok = false;
+        if (ok && !lib3ds_file_write(file3ds, &io)) ok = false;
+        
+    } catch (...) {
+        lib3ds_file_free(file3ds);
+        throw;
+    }
+    lib3ds_file_free(file3ds);
+
+    return ok ? WriteResult(WriteResult::FILE_SAVED) : WriteResult(WriteResult::ERROR_IN_WRITING_FILE);
+    //return ok ? WriteResult(WriteResult::FILE_SAVED) : WriteResult(WriteResult::FILE_NOT_HANDLED);
+}
+
+const std::string getParent(const std::string & pathBad)
+{
+    const std::string & path = osgDB::convertFileNameToNativeStyle(pathBad);
+
+    std::string parent = "";
+    std::string tmp = "";
+    for(std::string::const_iterator itPath = path.begin();; ++itPath)
+    {
+        if (!parent.empty())
+            parent += '\\';
+        parent += tmp;
+        tmp.clear();
+        for(;itPath != path.end() && *itPath != '\\'; ++itPath)
+            tmp += *itPath;
+        if (itPath == path.end())
+            break;
+    }
+    return parent;
+}
+
+bool ReaderWriter3DS::createFileObject(const osg::Node& node, Lib3dsFile * file3ds,const std::string& fileName, const osgDB::ReaderWriter::Options* options) const {
+    WriterNodeVisitor w(file3ds, fileName, options, getParent(node.getName()));
+    const_cast<osg::Node &>(node).accept(w);                // TODO Remove that ugly const_cast<>. Any idea?
+    if (!w.suceedLastApply())
+        return false;
+    w.writeMaterials();
+    return true;	//w.good();
+}
+#endif    // ENABLE_3DS_WRITER
Index: /OpenSceneGraph/trunk/src/osgPlugins/3ds/WriterCompareTriangle.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/WriterCompareTriangle.cpp (revision 10853)
+++ /OpenSceneGraph/trunk/src/osgPlugins/3ds/WriterCompareTriangle.cpp (revision 10853)
@@ -0,0 +1,135 @@
+#include "WriterCompareTriangle.h"
+
+WriterCompareTriangle::WriterCompareTriangle(const osg::Geode & geode, unsigned int nbVertices) : geode(geode) 
+{
+    cutscene(nbVertices, geode.getBoundingBox());
+}
+
+bool 
+WriterCompareTriangle::operator()(const std::pair<Triangle, int> & t1, 
+                                  const std::pair<Triangle, int> & t2) const
+{
+    const osg::Geometry *g = geode.getDrawable( t1.second )->asGeometry();
+
+    const osg::Vec3Array * vecs= static_cast<const osg::Vec3Array *>(g->getVertexArray());
+    const osg::BoundingBox::vec_type v1( (*vecs)[t1.first.t1] );
+
+    if (t1.second != t2.second)
+    {
+        const osg::Geometry *g = geode.getDrawable( t2.second )->asGeometry();
+        vecs = static_cast<const osg::Vec3Array *>(g->getVertexArray());
+    };
+    const osg::BoundingBox::vec_type v2( (*vecs)[t2.first.t1] );
+    int val1 = inWhichBox(v1);
+    int val2 = inWhichBox(v2);
+
+    return (val1 < val2);
+}
+
+void
+WriterCompareTriangle::setMaxMin(unsigned int & nbVerticesX,
+                                 unsigned int & nbVerticesY,
+                                 unsigned int & nbVerticesZ) const    
+{
+    static const unsigned int min = 1;
+    static const unsigned int max = 5;		// Number of blocks used to divide the scene (arbitrary but seems ok)
+	nbVerticesX = osg::clampBetween<unsigned int>(nbVerticesX, min, max);
+	nbVerticesY = osg::clampBetween<unsigned int>(nbVerticesY, min, max);
+	nbVerticesZ = osg::clampBetween<unsigned int>(nbVerticesZ, min, max);
+}
+
+void WriterCompareTriangle::cutscene(int nbVertices, const osg::BoundingBox & sceneBox)
+{
+    osg::BoundingBox::vec_type length = sceneBox._max - sceneBox._min;
+
+    static const float k = 1.3f;		// Arbitrary constant multiplier for density computation ("simulates" non-uniform point distributions)
+	// Computes "density" of points, and thus the number of blocks to divide the mesh into
+    unsigned int nbVerticesX = static_cast<unsigned int>( (nbVertices * k) / (length.z() * length.y()) );
+    unsigned int nbVerticesY = static_cast<unsigned int>( (nbVertices * k) / (length.z() * length.x()) );
+    unsigned int nbVerticesZ = static_cast<unsigned int>( (nbVertices * k) / (length.x() * length.y()) );
+
+    setMaxMin (nbVerticesX, nbVerticesY, nbVerticesZ); // This function prevent from cut scene in too many blocs
+
+    osg::notify(osg::ALWAYS) << "Cutting x by " << nbVerticesX << std::endl
+        << "Cutting y by " << nbVerticesY << std::endl
+        << "Cutting z by " << nbVerticesZ << std::endl;
+
+    osg::BoundingBox::value_type blocX = length.x() / nbVerticesX; //This 3 lines set the size of a bloc in x, y and z
+    osg::BoundingBox::value_type blocY = length.y() / nbVerticesY;
+    osg::BoundingBox::value_type blocZ = length.z() / nbVerticesZ;
+
+    boxList.reserve(nbVerticesX * nbVerticesY * nbVerticesZ);
+    short yinc = 1;
+    short xinc = 1;
+    unsigned int y = 0;
+    unsigned int x = 0;
+    for (unsigned int z = 0; z < nbVerticesZ; ++z)
+    {
+        while (x < nbVerticesX && x >= 0)
+        {
+            while (y < nbVerticesY && y >= 0)
+            {
+                osg::BoundingBox::value_type xMin = sceneBox.xMin() + x * blocX;
+                if (x == 0) //to prevent from mesh with no case
+                    xMin -= 10;
+
+                osg::BoundingBox::value_type yMin = sceneBox.yMin() + y * blocY;
+                if (y == 0) //to prevent from mesh with no case
+                    yMin -= 10;
+
+                osg::BoundingBox::value_type zMin = sceneBox.zMin() + z * blocZ;
+                if (z == 0) //to prevent from mesh with no case
+                    zMin -= 10;
+
+                osg::BoundingBox::value_type xMax = sceneBox.xMin() + (x + 1) * blocX;
+                if (x == nbVerticesX - 1) //to prevent from mesh with no case
+                    xMax += 10;
+
+                osg::BoundingBox::value_type yMax = sceneBox.yMin() + (y + 1) * blocY;
+                if (y == nbVerticesY - 1) //to prevent from mesh with no case
+                    yMax += 10;
+
+                osg::BoundingBox::value_type zMax = sceneBox.zMin() + (z + 1) * blocZ;
+                if (z == nbVerticesZ - 1) //to prevent from mesh with no case
+                    zMax += 10;
+
+                boxList.push_back(osg::BoundingBox(xMin, // Add a bloc to the list
+                    yMin,
+                    zMin,
+                    xMax, 
+                    yMax,
+                    zMax));
+                y += yinc;
+            }
+            yinc = -yinc;
+            y += yinc;
+            x += xinc;
+        }
+        xinc = -xinc;
+        x += xinc;
+    }
+}
+
+int 
+WriterCompareTriangle::inWhichBox(const osg::BoundingBox::value_type x, 
+                                  const osg::BoundingBox::value_type y,
+                                  const osg::BoundingBox::value_type z) const
+{
+    for (unsigned int i = 0; i < boxList.size(); ++i)
+    {
+        if (x >= boxList[i].xMin() && 
+            x < boxList[i].xMax() &&
+            y >= boxList[i].yMin() &&
+            y < boxList[i].yMax() &&
+            z >= boxList[i].zMin() &&
+            z < boxList[i].zMax())
+        {
+            return i;
+        }
+    }
+    throw "Point is not in any blocs";
+}
+
+int WriterCompareTriangle::inWhichBox(const osg::BoundingBox::vec_type & point) const {
+	return inWhichBox(point.x(), point.y(), point.z());
+}
Index: /OpenSceneGraph/trunk/src/osgPlugins/3ds/CMakeLists.txt
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/CMakeLists.txt (revision 9998)
+++ /OpenSceneGraph/trunk/src/osgPlugins/3ds/CMakeLists.txt (revision 10853)
@@ -1,48 +1,40 @@
+# List of C files to be compiled as C++ (else CMake sets ".c" to be compiled as pure C)
+SET(C_FILES
+    lib3ds/lib3ds_io.c        # Modified to support OSG endianness
+)
+
 SET(TARGET_SRC
     ReaderWriter3DS.cpp
-    atmosphere.cpp
-    background.cpp
-    camera.cpp
-    chunk.cpp
-    ease.cpp
-    file.cpp
-    lib3ds_float.cpp
-    light.cpp
-    material.cpp
-    matrix.cpp
-    mesh.cpp
-    node.cpp
-    quat.cpp
-    readwrite.cpp
-    shadow.cpp
-    tcb.cpp
-    tracks.cpp
-    vector.cpp
-    viewport.cpp
+    WriterNodeVisitor.cpp
+    WriterCompareTriangle.cpp
+
+    ${C_FILES}
+    lib3ds/lib3ds_atmosphere.c
+    lib3ds/lib3ds_background.c
+    lib3ds/lib3ds_camera.c
+    lib3ds/lib3ds_chunk.c
+    lib3ds/lib3ds_chunktable.c
+    lib3ds/lib3ds_file.c
+    lib3ds/lib3ds_light.c
+    lib3ds/lib3ds_material.c
+    lib3ds/lib3ds_math.c
+    lib3ds/lib3ds_matrix.c
+    lib3ds/lib3ds_mesh.c
+    lib3ds/lib3ds_node.c
+    lib3ds/lib3ds_quat.c
+    lib3ds/lib3ds_shadow.c
+    lib3ds/lib3ds_track.c
+    lib3ds/lib3ds_util.c
+    lib3ds/lib3ds_vector.c
+    lib3ds/lib3ds_viewport.c
 )
 SET(TARGET_H
-    atmosphere.h
-    background.h
-    camera.h
-    chunk.h
-    chunktable.h
-    config.h
-    ease.h
-    file.h
-    lib3ds_float.h
-    light.h
-    material.h
-    matrix.h
-    mesh.h
-    node.h
-    quat.h
-    readwrite.h
-    shadow.h
-    tcb.h
-    tracks.h
-    types.h
-    vector.h
-    viewport.h
+    WriterNodeVisitor.h
+    WriterCompareTriangle.h
+    lib3ds/lib3ds.h
+    lib3ds/lib3ds_impl.h
 )
 #### end var setup  ###
 SETUP_PLUGIN(3ds)
+ADD_DEFINITIONS( -DLIB3DS_STATIC )        # lib3ds is included, so we need the flag
+SET_SOURCE_FILES_PROPERTIES(${C_FILES} PROPERTIES LANGUAGE "CXX")        # Force some files to be compiled as C++
Index: /enSceneGraph/trunk/src/osgPlugins/3ds/material.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/material.cpp (revision 10076)
+++  (revision )
@@ -1,1038 +1,0 @@
-/*
- * The 3D Studio File Format Library
- * Copyright (C) 1996-2001 by J.E. Hoffmann <je-h@gmx.net>
- * All rights reserved.
- *
- * This program is  free  software;  you can redistribute it and/or modify it
- * under the terms of the  GNU Lesser General Public License  as published by 
- * the  Free Software Foundation;  either version 2.1 of the License,  or (at 
- * your option) any later version.
- *
- * This  program  is  distributed in  the  hope that it will  be useful,  but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or  FITNESS FOR A  PARTICULAR PURPOSE.  See the  GNU Lesser General Public  
- * License for more details.
- *
- * You should  have received  a copy of the GNU Lesser General Public License
- * along with  this program;  if not, write to the  Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id$
- */
-#define LIB3DS_EXPORT
-#include "material.h"
-#include "chunk.h"
-#include "readwrite.h"
-#include <stdlib.h>
-#include <math.h>
-#include <string.h>
-#include "config.h"
-#ifdef WITH_DMALLOC
-#include <dmalloc.h>
-#endif
-
-
-/*!
- * \defgroup material Materials
- *
- * \author J.E. Hoffmann <je-h@gmx.net>
- */
-
-
-/*!
- * \ingroup material
- */
-Lib3dsMaterial*
-lib3ds_material_new()
-{
-  Lib3dsMaterial *material;
-
-  material=(Lib3dsMaterial*)calloc(sizeof(Lib3dsMaterial), 1);
-  if (!material) {
-    return(0);
-  }
-  return(material);
-}
-
-
-/*!
- * \ingroup material
- */
-void
-lib3ds_material_free(Lib3dsMaterial *material)
-{
-  memset(material, 0, sizeof(Lib3dsMaterial));
-  free(material);
-}
-
-
-static Lib3dsBool
-color_read(Lib3dsRgba rgb, iostream *strm)
-{
-  Lib3dsChunk c;
-  Lib3dsWord chunk;
-  Lib3dsBool have_lin=LIB3DS_FALSE;
-
-  if (!lib3ds_chunk_read_start(&c, 0, strm)) {
-    return(LIB3DS_FALSE);
-  }
-
-  while ((chunk=lib3ds_chunk_read_next(&c, strm))!=0) {
-    switch (chunk) {
-      case LIB3DS_LIN_COLOR_24:
-        {
-          int i;
-          for (i=0; i<3; ++i) {
-            rgb[i]=1.0f*lib3ds_byte_read(strm)/255.0f;
-          }
-          rgb[3]=1.0f;
-        }
-        have_lin=LIB3DS_TRUE;
-        break;
-      case LIB3DS_COLOR_24:
-        /* gamma corrected color chunk
-           replaced in 3ds R3 by LIN_COLOR_24 */
-        if (!have_lin) {
-          int i;
-          for (i=0; i<3; ++i) {
-            rgb[i]=1.0f*lib3ds_byte_read(strm)/255.0f;
-          }
-          rgb[3]=1.0f;
-        }
-        break;
-      case LIB3DS_COLOR_F:
-        // sth: this will fix 3ds-files exported from cinema 4d
-        lib3ds_rgb_read(rgb, strm);
-        break;
-      default:
-        lib3ds_chunk_unknown(chunk);
-    }
-  }
-  
-  lib3ds_chunk_read_end(&c, strm);
-  return(LIB3DS_TRUE);
-}
-
-
-static Lib3dsBool
-int_percentage_read(Lib3dsFloat *p, iostream *strm)
-{
-  Lib3dsChunk c;
-  Lib3dsWord chunk;
-
-  if (!lib3ds_chunk_read_start(&c, 0, strm)) {
-    return(LIB3DS_FALSE);
-  }
-
-  while ((chunk=lib3ds_chunk_read_next(&c, strm))!=0) {
-    switch (chunk) {
-      case LIB3DS_INT_PERCENTAGE:
-        {
-          Lib3dsIntw i=lib3ds_intw_read(strm);
-          *p=(Lib3dsFloat)(1.0*i/100.0);
-        }
-        break;
-      default:
-        lib3ds_chunk_unknown(chunk);
-    }
-  }
-  
-  lib3ds_chunk_read_end(&c, strm);
-  return(LIB3DS_TRUE);
-}
-
-
-static Lib3dsBool
-texture_map_read(Lib3dsTextureMap *map, iostream *strm)
-{
-  Lib3dsChunk c;
-  Lib3dsWord chunk;
-
-  if (!lib3ds_chunk_read_start(&c, 0, strm)) {
-    return(LIB3DS_FALSE);
-  }
-
-  while ((chunk=lib3ds_chunk_read_next(&c, strm))!=0) {
-    switch (chunk) {
-      case LIB3DS_INT_PERCENTAGE:
-        {
-          map->percent=1.0f*lib3ds_intw_read(strm)/100.0f;
-        }
-        break;
-      case LIB3DS_MAT_MAPNAME:
-        {
-          if (!lib3ds_string_read(map->name, 64, strm)) {
-            return(LIB3DS_FALSE);
-          }
-          lib3ds_chunk_dump_info("  NAME=%s", map->name);
-        }
-        break;
-      case LIB3DS_MAT_MAP_TILING:
-        {
-          map->flags=lib3ds_word_read(strm);
-        }
-        break;
-      case LIB3DS_MAT_MAP_TEXBLUR:
-        {
-          map->blur=lib3ds_float_read(strm);
-        }
-        break;
-      case LIB3DS_MAT_MAP_USCALE:
-        {
-          map->scale[0]=lib3ds_float_read(strm);
-        }
-        break;
-      case LIB3DS_MAT_MAP_VSCALE:
-        {
-          map->scale[1]=lib3ds_float_read(strm);
-        }
-        break;
-      case LIB3DS_MAT_MAP_UOFFSET:
-        {
-          map->offset[0]=lib3ds_float_read(strm);
-        }
-        break;
-      case LIB3DS_MAT_MAP_VOFFSET:
-        {
-          map->offset[1]=lib3ds_float_read(strm);
-        }
-        break;
-      case LIB3DS_MAT_MAP_ANG:
-        {
-          map->rotation=lib3ds_float_read(strm);
-        }
-        break;
-      case LIB3DS_MAT_MAP_COL1:
-        {
-          map->tint_1[0]=1.0f*lib3ds_byte_read(strm)/255.0f;
-          map->tint_1[1]=1.0f*lib3ds_byte_read(strm)/255.0f;
-          map->tint_1[2]=1.0f*lib3ds_byte_read(strm)/255.0f;
-        }
-        break;
-      case LIB3DS_MAT_MAP_COL2:
-        {
-          map->tint_2[0]=1.0f*lib3ds_byte_read(strm)/255.0f;
-          map->tint_2[1]=1.0f*lib3ds_byte_read(strm)/255.0f;
-          map->tint_2[2]=1.0f*lib3ds_byte_read(strm)/255.0f;
-        }
-        break;
-      case LIB3DS_MAT_MAP_RCOL:
-        {
-          map->tint_r[0]=1.0f*lib3ds_byte_read(strm)/255.0f;
-          map->tint_r[1]=1.0f*lib3ds_byte_read(strm)/255.0f;
-          map->tint_r[2]=1.0f*lib3ds_byte_read(strm)/255.0f;
-        }
-        break;
-      case LIB3DS_MAT_MAP_GCOL:
-        {
-          map->tint_g[0]=1.0f*lib3ds_byte_read(strm)/255.0f;
-          map->tint_g[1]=1.0f*lib3ds_byte_read(strm)/255.0f;
-          map->tint_g[2]=1.0f*lib3ds_byte_read(strm)/255.0f;
-        }
-        break;
-      case LIB3DS_MAT_MAP_BCOL:
-        {
-          map->tint_b[0]=1.0f*lib3ds_byte_read(strm)/255.0f;
-          map->tint_b[1]=1.0f*lib3ds_byte_read(strm)/255.0f;
-          map->tint_b[2]=1.0f*lib3ds_byte_read(strm)/255.0f;
-        }
-        break;
-      default:
-        lib3ds_chunk_unknown(chunk);
-    }
-  }
-  
-  lib3ds_chunk_read_end(&c, strm);
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
- * \ingroup material
- */
-static void
-texture_dump(const char *maptype, Lib3dsTextureMap *texture)
-{
-  ASSERT(texture);
-  if (strlen(texture->name)==0) {
-    return;
-  }
-  printf("  %s:\n", maptype);
-  printf("    name:        %s\n", texture->name);
-  printf("    flags:       %ii\n", static_cast<unsigned int>(texture->flags));
-  printf("    percent:     %f\n", texture->percent);
-  printf("    blur:        %f\n", texture->blur);
-  printf("    scale:       (%f, %f)\n", texture->scale[0], texture->scale[1]);
-  printf("    offset:      (%f, %f)\n", texture->offset[0], texture->offset[1]);
-  printf("    rotation:    %f\n", texture->rotation);
-  printf("    tint_1:      (%f, %f, %f)\n",
-    texture->tint_1[0], texture->tint_1[1], texture->tint_1[2]);
-  printf("    tint_2:      (%f, %f, %f)\n",
-    texture->tint_2[0], texture->tint_2[1], texture->tint_2[2]);
-  printf("    tint_r:      (%f, %f, %f)\n",
-    texture->tint_r[0], texture->tint_r[1], texture->tint_r[2]);
-  printf("    tint_g:      (%f, %f, %f)\n",
-    texture->tint_g[0], texture->tint_g[1], texture->tint_g[2]);
-  printf("    tint_b:      (%f, %f, %f)\n",
-    texture->tint_b[0], texture->tint_b[1], texture->tint_b[2]);
-}
-
-
-/*!
- * \ingroup material
- */
-void
-lib3ds_material_dump(Lib3dsMaterial *material)
-{
-  ASSERT(material);
-  printf("  name:          %s\n", material->name);
-  printf("  ambient:       (%f, %f, %f)\n",
-    material->ambient[0], material->ambient[1], material->ambient[2]);
-  printf("  diffuse:       (%f, %f, %f)\n",
-    material->diffuse[0], material->diffuse[1], material->diffuse[2]);
-  printf("  specular:      (%f, %f, %f)\n",
-    material->specular[0], material->specular[1], material->specular[2]);
-  printf("  shininess:     %f\n", material->shininess);
-  printf("  shin_strength: %f\n", material->shin_strength);
-  printf("  use_blur:      %s\n", material->use_blur ? "yes" : "no");
-  printf("  blur:          %f\n", material->blur);
-  printf("  falloff:       %f\n", material->falloff);
-  printf("  additive:      %s\n", material->additive ? "yes" : "no");
-  printf("  use_falloff:   %s\n", material->use_falloff ? "yes" : "no");
-  printf("  self_illum:    %s\n", material->self_illum ? "yes" : "no");
-  printf("  shading:       %d\n", material->shading);
-  printf("  soften:        %s\n", material->soften ? "yes" : "no");
-  printf("  face_map:      %s\n", material->face_map ? "yes" : "no");
-  printf("  two_sided:     %s\n", material->two_sided ? "yes" : "no");
-  printf("  map_decal:     %s\n", material->map_decal ? "yes" : "no");
-  printf("  use_wire:      %s\n", material->use_wire ? "yes" : "no");
-  printf("  use_wire_abs:  %s\n", material->use_wire_abs ? "yes" : "no");
-  printf("  wire_size:     %f\n", material->wire_size);
-  texture_dump("texture1_map", &material->texture1_map);
-  texture_dump("texture1_mask", &material->texture1_mask);
-  texture_dump("texture2_map", &material->texture2_map);
-  texture_dump("texture2_mask", &material->texture2_mask);
-  texture_dump("opacity_map", &material->opacity_map);
-  texture_dump("opacity_mask", &material->opacity_mask);
-  texture_dump("bump_map", &material->bump_map);
-  texture_dump("bump_mask", &material->bump_mask);
-  texture_dump("specular_map", &material->specular_map);
-  texture_dump("specular_mask", &material->specular_mask);
-  texture_dump("shininess_map", &material->shininess_map);
-  texture_dump("shininess_mask", &material->shininess_mask);
-  texture_dump("self_illum_map", &material->self_illum_map);
-  texture_dump("self_illum_mask", &material->self_illum_mask);
-  texture_dump("reflection_map", &material->reflection_map);
-  texture_dump("reflection_mask", &material->reflection_mask);
-  printf("  autorefl_map:\n");
-  printf("    flags        %X\n", static_cast<int>(material->autorefl_map.flags));
-  printf("    level        %X\n", static_cast<int>(material->autorefl_map.level));
-  printf("    size         %X\n", static_cast<int>(material->autorefl_map.size));
-  printf("    frame_step   %d\n", static_cast<int>(material->autorefl_map.frame_step));
-  printf("\n");
-}
-
-
-/*!
- * \ingroup material
- */
-Lib3dsBool
-lib3ds_material_read(Lib3dsMaterial *material, iostream *strm)
-{
-  Lib3dsChunk c;
-  Lib3dsWord chunk;
-
-  ASSERT(material);
-  if (!lib3ds_chunk_read_start(&c, LIB3DS_MAT_ENTRY, strm)) {
-    return(LIB3DS_FALSE);
-  }
-
-  while ((chunk=lib3ds_chunk_read_next(&c, strm))!=0) {
-    switch (chunk) {
-      case LIB3DS_MAT_NAME:
-        {
-          if (!lib3ds_string_read(material->name, 64, strm)) {
-            return(LIB3DS_FALSE);
-          }
-          lib3ds_chunk_dump_info("  NAME=%s", material->name);
-        }
-        break;
-      case LIB3DS_MAT_AMBIENT:
-        {
-          lib3ds_chunk_read_reset(&c, strm);
-          if (!color_read(material->ambient, strm)) {
-            return(LIB3DS_FALSE);
-          }
-        }
-        break;
-      case LIB3DS_MAT_DIFFUSE:
-        {
-          lib3ds_chunk_read_reset(&c, strm);
-          if (!color_read(material->diffuse, strm)) {
-            return(LIB3DS_FALSE);
-          }
-        }
-        break;
-      case LIB3DS_MAT_SPECULAR:
-        {
-          lib3ds_chunk_read_reset(&c, strm);
-          if (!color_read(material->specular, strm)) {
-            return(LIB3DS_FALSE);
-          }
-        }
-        break;
-      case LIB3DS_MAT_SHININESS:
-        {
-          lib3ds_chunk_read_reset(&c, strm);
-          if (!int_percentage_read(&material->shininess, strm)) {
-            return(LIB3DS_FALSE);
-          }
-        }
-        break;
-      case LIB3DS_MAT_SHIN2PCT:
-        {
-          lib3ds_chunk_read_reset(&c, strm);
-          if (!int_percentage_read(&material->shin_strength, strm)) {
-            return(LIB3DS_FALSE);
-          }
-        }
-        break;
-      case LIB3DS_MAT_TRANSPARENCY:
-        {
-          lib3ds_chunk_read_reset(&c, strm);
-          if (!int_percentage_read(&material->transparency, strm)) {
-            return(LIB3DS_FALSE);
-          }
-        }
-        break;
-      case LIB3DS_MAT_XPFALL:
-        {
-          lib3ds_chunk_read_reset(&c, strm);
-          if (!int_percentage_read(&material->falloff, strm)) {
-            return(LIB3DS_FALSE);
-          }
-        }
-        break;
-      case LIB3DS_MAT_USE_XPFALL:
-        {
-          material->use_falloff=LIB3DS_TRUE;
-        }
-        break;
-      case LIB3DS_MAT_REFBLUR:
-        {
-          lib3ds_chunk_read_reset(&c, strm);
-          if (!int_percentage_read(&material->blur, strm)) {
-            return(LIB3DS_FALSE);
-          }
-        }
-        break;
-      case LIB3DS_MAT_USE_REFBLUR:
-        {
-          material->use_blur=LIB3DS_TRUE;
-        }
-        break;
-      case LIB3DS_MAT_SHADING:
-        {
-          material->shading=lib3ds_intw_read(strm);
-        }
-        break;
-      case LIB3DS_MAT_SELF_ILLUM:
-        {
-          material->self_illum=LIB3DS_TRUE;
-        }
-        break;
-      case LIB3DS_MAT_TWO_SIDE:
-        {
-          material->two_sided=LIB3DS_TRUE;
-        }
-        break;
-      case LIB3DS_MAT_DECAL:
-        {
-          material->map_decal=LIB3DS_TRUE;
-        }
-        break;
-      case LIB3DS_MAT_ADDITIVE:
-        {
-          material->additive=LIB3DS_TRUE;
-        }
-        break;
-      case LIB3DS_MAT_FACEMAP:
-        {
-          material->face_map=LIB3DS_TRUE;
-        }
-        break;
-      case LIB3DS_MAT_PHONGSOFT:
-        {
-          material->soften=LIB3DS_TRUE;
-        }
-        break;
-      case LIB3DS_MAT_WIRE:
-        {
-          material->use_wire=LIB3DS_TRUE;
-        }
-        break;
-      case LIB3DS_MAT_WIREABS:
-        {
-          material->use_wire_abs=LIB3DS_TRUE;
-        }
-        break;
-      case LIB3DS_MAT_WIRE_SIZE:
-        {
-          material->wire_size=lib3ds_float_read(strm);
-        }
-        break;
-      case LIB3DS_MAT_TEXMAP:
-        {
-          lib3ds_chunk_read_reset(&c, strm);
-          if (!texture_map_read(&material->texture1_map, strm)) {
-            return(LIB3DS_FALSE);
-          }
-        }
-        break;
-      case LIB3DS_MAT_TEXMASK:
-        {
-          lib3ds_chunk_read_reset(&c, strm);
-          if (!texture_map_read(&material->texture1_mask, strm)) {
-            return(LIB3DS_FALSE);
-          }
-        }
-        break;
-      case LIB3DS_MAT_TEX2MAP:
-        {
-          lib3ds_chunk_read_reset(&c, strm);
-          if (!texture_map_read(&material->texture2_map, strm)) {
-            return(LIB3DS_FALSE);
-          }
-        }
-        break;
-      case LIB3DS_MAT_TEX2MASK:
-        {
-          lib3ds_chunk_read_reset(&c, strm);
-          if (!texture_map_read(&material->texture2_mask, strm)) {
-            return(LIB3DS_FALSE);
-          }
-        }
-        break;
-      case LIB3DS_MAT_OPACMAP:
-        {
-          lib3ds_chunk_read_reset(&c, strm);
-          if (!texture_map_read(&material->opacity_map, strm)) {
-            return(LIB3DS_FALSE);
-          }
-        }
-        break;
-      case LIB3DS_MAT_OPACMASK:
-        {
-          lib3ds_chunk_read_reset(&c, strm);
-          if (!texture_map_read(&material->opacity_mask, strm)) {
-            return(LIB3DS_FALSE);
-          }
-        }
-        break;
-      case LIB3DS_MAT_BUMPMAP:
-        {
-          lib3ds_chunk_read_reset(&c, strm);
-          if (!texture_map_read(&material->bump_map, strm)) {
-            return(LIB3DS_FALSE);
-          }
-        }
-        break;
-      case LIB3DS_MAT_BUMPMASK:
-        {
-          lib3ds_chunk_read_reset(&c, strm);
-          if (!texture_map_read(&material->bump_mask, strm)) {
-            return(LIB3DS_FALSE);
-          }
-        }
-        break;
-      case LIB3DS_MAT_SPECMAP:
-        {
-          lib3ds_chunk_read_reset(&c, strm);
-          if (!texture_map_read(&material->specular_map, strm)) {
-            return(LIB3DS_FALSE);
-          }
-        }
-        break;
-      case LIB3DS_MAT_SPECMASK:
-        {
-          lib3ds_chunk_read_reset(&c, strm);
-          if (!texture_map_read(&material->specular_mask, strm)) {
-            return(LIB3DS_FALSE);
-          }
-        }
-        break;
-      case LIB3DS_MAT_SHINMAP:
-        {
-          lib3ds_chunk_read_reset(&c, strm);
-          if (!texture_map_read(&material->shininess_map, strm)) {
-            return(LIB3DS_FALSE);
-          }
-        }
-        break;
-      case LIB3DS_MAT_SHINMASK:
-        {
-          lib3ds_chunk_read_reset(&c, strm);
-          if (!texture_map_read(&material->shininess_mask, strm)) {
-            return(LIB3DS_FALSE);
-          }
-        }
-        break;
-      case LIB3DS_MAT_SELFIMAP:
-        {
-          lib3ds_chunk_read_reset(&c, strm);
-          if (!texture_map_read(&material->self_illum_map, strm)) {
-            return(LIB3DS_FALSE);
-          }
-        }
-        break;
-      case LIB3DS_MAT_SELFIMASK:
-        {
-          lib3ds_chunk_read_reset(&c, strm);
-          if (!texture_map_read(&material->self_illum_mask, strm)) {
-            return(LIB3DS_FALSE);
-          }
-        }
-        break;
-      case LIB3DS_MAT_REFLMAP:
-        {
-          lib3ds_chunk_read_reset(&c, strm);
-          if (!texture_map_read(&material->reflection_map, strm)) {
-            return(LIB3DS_FALSE);
-          }
-        }
-        break;
-      case LIB3DS_MAT_REFLMASK:
-        {
-          lib3ds_chunk_read_reset(&c, strm);
-          if (!texture_map_read(&material->reflection_mask, strm)) {
-            return(LIB3DS_FALSE);
-          }
-        }
-        break;
-      case LIB3DS_MAT_ACUBIC:
-        {
-          lib3ds_intb_read(strm);
-          material->autorefl_map.level=lib3ds_intb_read(strm);
-          material->autorefl_map.flags=lib3ds_intw_read(strm);
-          material->autorefl_map.size=lib3ds_intd_read(strm);
-          material->autorefl_map.frame_step=lib3ds_intd_read(strm);
-        }
-        break;
-      default:
-        lib3ds_chunk_unknown(chunk);
-    }
-  }
-
-  lib3ds_chunk_read_end(&c, strm);
-  return(LIB3DS_TRUE);
-}
-
-
-static Lib3dsBool
-color_write(Lib3dsRgba rgb, iostream *strm)
-{
-  Lib3dsChunk c;
-
-  c.chunk=LIB3DS_COLOR_24;
-  c.size=9;
-  lib3ds_chunk_write(&c,strm);
-  lib3ds_byte_write((Lib3dsByte)floor(255.0*rgb[0]+0.5),strm);
-  lib3ds_byte_write((Lib3dsByte)floor(255.0*rgb[1]+0.5),strm);
-  lib3ds_byte_write((Lib3dsByte)floor(255.0*rgb[2]+0.5),strm);
-
-  c.chunk=LIB3DS_LIN_COLOR_24;
-  c.size=9;
-  lib3ds_chunk_write(&c,strm);
-  lib3ds_byte_write((Lib3dsByte)floor(255.0*rgb[0]+0.5),strm);
-  lib3ds_byte_write((Lib3dsByte)floor(255.0*rgb[1]+0.5),strm);
-  lib3ds_byte_write((Lib3dsByte)floor(255.0*rgb[2]+0.5),strm);
-
-  return(LIB3DS_TRUE);
-}
-
-
-static Lib3dsBool
-int_percentage_write(Lib3dsFloat p, iostream *strm)
-{
-  Lib3dsChunk c;
-
-  c.chunk=LIB3DS_INT_PERCENTAGE;
-  c.size=8;
-  lib3ds_chunk_write(&c,strm);
-  lib3ds_intw_write((Lib3dsByte)floor(100.0*p+0.5),strm);
-
-  return(LIB3DS_TRUE);
-}
-
-
-static Lib3dsBool
-texture_map_write(Lib3dsWord chunk, Lib3dsTextureMap *map, iostream *strm)
-{
-  Lib3dsChunk c;
-
-  if (strlen(map->name)==0) {
-    return(LIB3DS_TRUE);
-  }
-  c.chunk=chunk;
-  if (!lib3ds_chunk_write_start(&c,strm)) {
-    return(LIB3DS_FALSE);
-  }
-  
-  int_percentage_write(map->percent,strm);
-
-  { /*---- LIB3DS_MAT_MAPNAME ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_MAT_MAPNAME;
-    c.size=6+strlen(map->name)+1;
-    lib3ds_chunk_write(&c,strm);
-    lib3ds_string_write(map->name,strm);
-  }
-
-  { /*---- LIB3DS_MAT_MAP_TILING ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_MAT_MAP_TILING;
-    c.size=8;
-    lib3ds_chunk_write(&c,strm);
-    lib3ds_word_write((Lib3dsWord)map->flags,strm);
-  }
-  
-  { /*---- LIB3DS_MAT_MAP_TEXBLUR ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_MAT_MAP_TEXBLUR;
-    c.size=10;
-    lib3ds_chunk_write(&c,strm);
-    lib3ds_float_write(map->blur,strm);
-  }
-
-  { /*---- LIB3DS_MAT_MAP_USCALE ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_MAT_MAP_USCALE;
-    c.size=10;
-    lib3ds_chunk_write(&c,strm);
-    lib3ds_float_write(map->scale[0],strm);
-  }
-
-  { /*---- LIB3DS_MAT_MAP_VSCALE ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_MAT_MAP_VSCALE;
-    c.size=10;
-    lib3ds_chunk_write(&c,strm);
-    lib3ds_float_write(map->scale[1],strm);
-  }
-
-  { /*---- LIB3DS_MAT_MAP_UOFFSET ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_MAT_MAP_UOFFSET;
-    c.size=10;
-    lib3ds_chunk_write(&c,strm);
-    lib3ds_float_write(map->offset[0],strm);
-  }
-
-  { /*---- LIB3DS_MAT_MAP_VOFFSET ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_MAT_MAP_VOFFSET;
-    c.size=10;
-    lib3ds_chunk_write(&c,strm);
-    lib3ds_float_write(map->offset[1],strm);
-  }
-
-  { /*---- LIB3DS_MAT_MAP_ANG ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_MAT_MAP_ANG;
-    c.size=10;
-    lib3ds_chunk_write(&c,strm);
-    lib3ds_float_write(map->rotation,strm);
-  }
-
-  { /*---- LIB3DS_MAT_MAP_COL1 ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_MAT_MAP_COL1;
-    c.size=9;
-    lib3ds_chunk_write(&c,strm);
-    lib3ds_byte_write((Lib3dsByte)floor(255.0*map->tint_1[0]+0.5), strm);
-    lib3ds_byte_write((Lib3dsByte)floor(255.0*map->tint_1[1]+0.5), strm);
-    lib3ds_byte_write((Lib3dsByte)floor(255.0*map->tint_1[2]+0.5), strm);
-  }
-
-  { /*---- LIB3DS_MAT_MAP_COL2 ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_MAT_MAP_COL2;
-    c.size=9;
-    lib3ds_chunk_write(&c,strm);
-    lib3ds_byte_write((Lib3dsByte)floor(255.0*map->tint_2[0]+0.5), strm);
-    lib3ds_byte_write((Lib3dsByte)floor(255.0*map->tint_2[1]+0.5), strm);
-    lib3ds_byte_write((Lib3dsByte)floor(255.0*map->tint_2[2]+0.5), strm);
-  }
-  
-  { /*---- LIB3DS_MAT_MAP_RCOL ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_MAT_MAP_RCOL;
-    c.size=9;
-    lib3ds_chunk_write(&c,strm);
-    lib3ds_byte_write((Lib3dsByte)floor(255.0*map->tint_r[0]+0.5), strm);
-    lib3ds_byte_write((Lib3dsByte)floor(255.0*map->tint_r[1]+0.5), strm);
-    lib3ds_byte_write((Lib3dsByte)floor(255.0*map->tint_r[2]+0.5), strm);
-  }
-
-  { /*---- LIB3DS_MAT_MAP_GCOL ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_MAT_MAP_GCOL;
-    c.size=9;
-    lib3ds_chunk_write(&c,strm);
-    lib3ds_byte_write((Lib3dsByte)floor(255.0*map->tint_g[0]+0.5), strm);
-    lib3ds_byte_write((Lib3dsByte)floor(255.0*map->tint_g[1]+0.5), strm);
-    lib3ds_byte_write((Lib3dsByte)floor(255.0*map->tint_g[2]+0.5), strm);
-  }
-  
-  { /*---- LIB3DS_MAT_MAP_BCOL ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_MAT_MAP_BCOL;
-    c.size=9;
-    lib3ds_chunk_write(&c,strm);
-    lib3ds_byte_write((Lib3dsByte)floor(255.0*map->tint_b[0]+0.5), strm);
-    lib3ds_byte_write((Lib3dsByte)floor(255.0*map->tint_b[1]+0.5), strm);
-    lib3ds_byte_write((Lib3dsByte)floor(255.0*map->tint_b[2]+0.5), strm);
-  }
-
-  if (!lib3ds_chunk_write_end(&c,strm)) {
-    return(LIB3DS_FALSE);
-  }
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
- * \ingroup material
- */
-Lib3dsBool
-lib3ds_material_write(Lib3dsMaterial *material, iostream *strm)
-{
-  Lib3dsChunk c;
-
-  c.chunk=LIB3DS_MAT_ENTRY;
-  if (!lib3ds_chunk_write_start(&c,strm)) {
-    return(LIB3DS_FALSE);
-  }
-
-  { /*---- LIB3DS_MAT_NAME ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_MAT_NAME;
-    c.size=6+strlen(material->name)+1;
-    lib3ds_chunk_write(&c,strm);
-    lib3ds_string_write(material->name,strm);
-  }
-
-  { /*---- LIB3DS_MAT_AMBIENT ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_MAT_AMBIENT;
-    c.size=24;
-    lib3ds_chunk_write(&c,strm);
-    color_write(material->ambient,strm);
-  }
-
-  { /*---- LIB3DS_MAT_DIFFUSE ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_MAT_DIFFUSE;
-    c.size=24;
-    lib3ds_chunk_write(&c,strm);
-    color_write(material->diffuse,strm);
-  }
-
-  { /*---- LIB3DS_MAT_SPECULAR ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_MAT_SPECULAR;
-    c.size=24;
-    lib3ds_chunk_write(&c,strm);
-    color_write(material->specular,strm);
-  }
-
-  { /*---- LIB3DS_MAT_SHININESS ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_MAT_SHININESS;
-    c.size=14;
-    lib3ds_chunk_write(&c,strm);
-    int_percentage_write(material->shininess,strm);
-  }
-
-  { /*---- LIB3DS_MAT_SHIN2PCT ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_MAT_SHIN2PCT;
-    c.size=14;
-    lib3ds_chunk_write(&c,strm);
-    int_percentage_write(material->shin_strength,strm);
-  }
-
-  { /*---- LIB3DS_MAT_TRANSPARENCY ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_MAT_TRANSPARENCY;
-    c.size=14;
-    lib3ds_chunk_write(&c,strm);
-    int_percentage_write(material->transparency,strm);
-  }
-
-  { /*---- LIB3DS_MAT_XPFALL ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_MAT_XPFALL;
-    c.size=14;
-    lib3ds_chunk_write(&c,strm);
-    int_percentage_write(material->falloff,strm);
-  }
-
-  if (material->use_falloff) { /*---- LIB3DS_MAT_USE_XPFALL ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_MAT_USE_XPFALL;
-    c.size=6;
-    lib3ds_chunk_write(&c,strm);
-  }
-
-  { /*---- LIB3DS_MAT_SHADING ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_MAT_SHADING;
-    c.size=8;
-    lib3ds_chunk_write(&c,strm);
-    lib3ds_intw_write(material->shading,strm);
-  }
-
-  { /*---- LIB3DS_MAT_REFBLUR ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_MAT_REFBLUR;
-    c.size=14;
-    lib3ds_chunk_write(&c,strm);
-    int_percentage_write(material->blur,strm);
-  }
-
-  if (material->use_blur) { /*---- LIB3DS_MAT_USE_REFBLUR ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_MAT_USE_REFBLUR;
-    c.size=6;
-    lib3ds_chunk_write(&c,strm);
-  }
-
-  if (material->self_illum) { /*---- LIB3DS_MAT_SELF_ILLUM ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_MAT_SELF_ILLUM;
-    c.size=6;
-    lib3ds_chunk_write(&c,strm);
-  }
-
-  if (material->two_sided) { /*---- LIB3DS_MAT_TWO_SIDE ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_MAT_TWO_SIDE;
-    c.size=6;
-    lib3ds_chunk_write(&c,strm);
-  }
-  
-  if (material->map_decal) { /*---- LIB3DS_MAT_DECAL ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_MAT_DECAL;
-    c.size=6;
-    lib3ds_chunk_write(&c,strm);
-  }
-
-  if (material->additive) { /*---- LIB3DS_MAT_ADDITIVE ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_MAT_ADDITIVE;
-    c.size=6;
-    lib3ds_chunk_write(&c,strm);
-  }
-
-  if (material->use_wire) { /*---- LIB3DS_MAT_WIRE ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_MAT_WIRE;
-    c.size=6;
-    lib3ds_chunk_write(&c,strm);
-  }
-
-  if (material->use_wire_abs) { /*---- LIB3DS_MAT_WIREABS ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_MAT_WIREABS;
-    c.size=6;
-    lib3ds_chunk_write(&c,strm);
-  }
-
-  { /*---- LIB3DS_MAT_WIRE_SIZE ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_MAT_WIRE_SIZE;
-    c.size=10;
-    lib3ds_chunk_write(&c,strm);
-    lib3ds_float_write(material->wire_size,strm);
-  }
-
-  if (material->face_map) { /*---- LIB3DS_MAT_FACEMAP ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_MAT_FACEMAP;
-    c.size=6;
-    lib3ds_chunk_write(&c,strm);
-  }
-
-  if (material->soften) { /*---- LIB3DS_MAT_PHONGSOFT ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_MAT_PHONGSOFT;
-    c.size=6;
-    lib3ds_chunk_write(&c,strm);
-  }
-
-  if (!texture_map_write(LIB3DS_MAT_TEXMAP, &material->texture1_map, strm)) {
-    return(LIB3DS_FALSE);
-  }
-  if (!texture_map_write(LIB3DS_MAT_TEXMASK, &material->texture1_mask, strm)) {
-    return(LIB3DS_FALSE);
-  }
-  if (!texture_map_write(LIB3DS_MAT_TEX2MAP, &material->texture2_map, strm)) {
-    return(LIB3DS_FALSE);
-  }
-  if (!texture_map_write(LIB3DS_MAT_TEX2MASK, &material->texture2_mask, strm)) {
-    return(LIB3DS_FALSE);
-  }
-  if (!texture_map_write(LIB3DS_MAT_OPACMAP, &material->opacity_map, strm)) {
-    return(LIB3DS_FALSE);
-  }
-  if (!texture_map_write(LIB3DS_MAT_OPACMASK, &material->opacity_mask, strm)) {
-    return(LIB3DS_FALSE);
-  }
-  if (!texture_map_write(LIB3DS_MAT_BUMPMAP, &material->bump_map, strm)) {
-    return(LIB3DS_FALSE);
-  }
-  if (!texture_map_write(LIB3DS_MAT_BUMPMASK, &material->bump_mask, strm)) {
-    return(LIB3DS_FALSE);
-  }
-  if (!texture_map_write(LIB3DS_MAT_SPECMAP, &material->specular_map, strm)) {
-    return(LIB3DS_FALSE);
-  }
-  if (!texture_map_write(LIB3DS_MAT_SPECMASK, &material->specular_mask, strm)) {
-    return(LIB3DS_FALSE);
-  }
-  if (!texture_map_write(LIB3DS_MAT_SHINMAP, &material->shininess_map, strm)) {
-    return(LIB3DS_FALSE);
-  }
-  if (!texture_map_write(LIB3DS_MAT_SHINMASK, &material->shininess_mask, strm)) {
-    return(LIB3DS_FALSE);
-  }
-  if (!texture_map_write(LIB3DS_MAT_SELFIMAP, &material->self_illum_map, strm)) {
-    return(LIB3DS_FALSE);
-  }
-  if (!texture_map_write(LIB3DS_MAT_SELFIMASK, &material->self_illum_mask, strm)) {
-    return(LIB3DS_FALSE);
-  }
-  if (!texture_map_write(LIB3DS_MAT_REFLMAP,  &material->reflection_map, strm)) {
-    return(LIB3DS_FALSE);
-  }
-  if (!texture_map_write(LIB3DS_MAT_REFLMASK,  &material->reflection_mask, strm)) {
-    return(LIB3DS_FALSE);
-  }
-
-  if (!lib3ds_chunk_write_end(&c,strm)) {
-    return(LIB3DS_FALSE);
-  }
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
-
-\typedef Lib3dsMaterial
-  \ingroup material
-  \sa _Lib3dsMaterial
-
-*/
-
Index: /enSceneGraph/trunk/src/osgPlugins/3ds/mesh.h
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/mesh.h (revision 10076)
+++  (revision )
@@ -1,140 +1,0 @@
-/* -*- c -*- */
-#ifndef INCLUDED_LIB3DS_MESH_H
-#define INCLUDED_LIB3DS_MESH_H
-/*
- * The 3D Studio File Format Library
- * Copyright (C) 1996-2001 by J.E. Hoffmann <je-h@gmx.net>
- * All rights reserved.
- *
- * This program is  free  software;  you can redistribute it and/or modify it
- * under the terms of the  GNU Lesser General Public License  as published by 
- * the  Free Software Foundation;  either version 2.1 of the License,  or (at 
- * your option) any later version.
- *
- * This  program  is  distributed in  the  hope that it will  be useful,  but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or  FITNESS FOR A  PARTICULAR PURPOSE.  See the  GNU Lesser General Public  
- * License for more details.
- *
- * You should  have received  a copy of the GNU Lesser General Public License
- * along with  this program;  if not, write to the  Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id$
- */
-
-#ifndef INCLUDED_LIB3DS_TYPES_H
-#include "types.h"
-#endif
-
-#include <iostream>
-using namespace std;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-
-/*!
- * Triangular mesh point
- * \ingroup mesh
- */
-typedef struct _Lib3dsPoint {
-    Lib3dsVector pos;
-} Lib3dsPoint;
-
-/*!
- * Triangular mesh face
- * \ingroup mesh
- */
-struct _Lib3dsFace {
-    Lib3dsUserData user;
-    char material[64];
-    Lib3dsWord points[3];
-    Lib3dsWord flags;
-    Lib3dsDword smoothing;
-    Lib3dsVector normal;
-};
-
-/*!
- * Triangular mesh box mapping settings
- * \ingroup mesh
- */
-struct _Lib3dsBoxMap {
-    char front[64];
-    char back[64];
-    char left[64];
-    char right[64];
-    char top[64];
-    char bottom[64];
-};
-
-/*!
- * Lib3dsMapData maptype
- * \ingroup tracks
- */
-typedef enum {
-  LIB3DS_MAP_NONE        =0xFFFF,
-  LIB3DS_MAP_PLANAR      =0,
-  LIB3DS_MAP_CYLINDRICAL =1,
-  LIB3DS_MAP_SPHERICAL   =2
-} Lib3dsMapType;
-
-/*!
- * Triangular mesh texture mapping data
- * \ingroup mesh
- */
-struct _Lib3dsMapData {
-    Lib3dsWord maptype;
-    Lib3dsVector pos;
-    Lib3dsMatrix matrix;
-    Lib3dsFloat scale;
-    Lib3dsFloat tile[2];
-    Lib3dsFloat planar_size[2];
-    Lib3dsFloat cylinder_height;
-};
-
-/*!
- * Triangular mesh object
- * \ingroup mesh
- */
-struct _Lib3dsMesh {
-    Lib3dsUserData user;
-    Lib3dsMesh *next;
-    char name[64];
-    Lib3dsByte color;
-    Lib3dsMatrix matrix;
-    Lib3dsDword points;
-    Lib3dsPoint *pointL;
-    Lib3dsDword flags;
-    Lib3dsWord *flagL;
-    Lib3dsDword texels;
-    Lib3dsTexel *texelL;
-    Lib3dsDword faces;
-    Lib3dsFace *faceL;
-    Lib3dsBoxMap box_map;
-    Lib3dsMapData map_data;
-}; 
-
-extern LIB3DSAPI Lib3dsMesh* lib3ds_mesh_new(const char *name);
-extern LIB3DSAPI void lib3ds_mesh_free(Lib3dsMesh *mesh);
-extern LIB3DSAPI Lib3dsBool lib3ds_mesh_new_point_list(Lib3dsMesh *mesh, Lib3dsDword points);
-extern LIB3DSAPI void lib3ds_mesh_free_point_list(Lib3dsMesh *mesh);
-extern LIB3DSAPI Lib3dsBool lib3ds_mesh_new_flag_list(Lib3dsMesh *mesh, Lib3dsDword flags);
-extern LIB3DSAPI void lib3ds_mesh_free_flag_list(Lib3dsMesh *mesh);
-extern LIB3DSAPI Lib3dsBool lib3ds_mesh_new_texel_list(Lib3dsMesh *mesh, Lib3dsDword texels);
-extern LIB3DSAPI void lib3ds_mesh_free_texel_list(Lib3dsMesh *mesh);
-extern LIB3DSAPI Lib3dsBool lib3ds_mesh_new_face_list(Lib3dsMesh *mesh, Lib3dsDword flags);
-extern LIB3DSAPI void lib3ds_mesh_free_face_list(Lib3dsMesh *mesh);
-extern LIB3DSAPI void lib3ds_mesh_bounding_box(Lib3dsMesh *mesh, Lib3dsVector min, Lib3dsVector max);
-extern LIB3DSAPI void lib3ds_mesh_calculate_normals(Lib3dsMesh *mesh, Lib3dsVector *normalL);
-extern LIB3DSAPI void lib3ds_mesh_dump(Lib3dsMesh *mesh);
-extern LIB3DSAPI Lib3dsBool lib3ds_mesh_read(Lib3dsMesh *mesh, iostream *strm);
-extern LIB3DSAPI Lib3dsBool lib3ds_mesh_write(Lib3dsMesh *mesh, iostream *strm);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
-
Index: /enSceneGraph/trunk/src/osgPlugins/3ds/vector.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/vector.cpp (revision 1563)
+++  (revision )
@@ -1,275 +1,0 @@
-/*
- * The 3D Studio File Format Library
- * Copyright (C) 1996-2001 by J.E. Hoffmann <je-h@gmx.net>
- * All rights reserved.
- *
- * This program is  free  software;  you can redistribute it and/or modify it
- * under the terms of the  GNU Lesser General Public License  as published by 
- * the  Free Software Foundation;  either version 2.1 of the License,  or (at 
- * your option) any later version.
- *
- * This  program  is  distributed in  the  hope that it will  be useful,  but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or  FITNESS FOR A  PARTICULAR PURPOSE.  See the  GNU Lesser General Public  
- * License for more details.
- *
- * You should  have received  a copy of the GNU Lesser General Public License
- * along with  this program;  if not, write to the  Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id$
- */
-#define LIB3DS_EXPORT
-#include "vector.h"
-#include <math.h>
-
-
-/*!
- * \defgroup vector Vector Mathematics
- *
- * \author J.E. Hoffmann <je-h@gmx.net>
- */
-/*!
- * \typedef Lib3dsVector
- *   \ingroup vector
- */
-
-
-/*!
- * \ingroup vector
- */
-void
-lib3ds_vector_zero(Lib3dsVector c)
-{
-  int i;
-  for (i=0; i<3; ++i) {
-    c[i]=0.0f;
-  }
-}
-
-
-/*!
- * \ingroup vector
- */
-void
-lib3ds_vector_copy(Lib3dsVector dest, Lib3dsVector src)
-{
-  int i;
-  for (i=0; i<3; ++i) {
-    dest[i]=src[i];
-  }
-}
-
-
-/*!
- * \ingroup vector
- */
-void
-lib3ds_vector_neg(Lib3dsVector c)
-{
-  int i;
-  for (i=0; i<3; ++i) {
-    c[i]=-c[i];
-  }
-}
-
-
-/*!
- * \ingroup vector
- */
-void
-lib3ds_vector_add(Lib3dsVector c, Lib3dsVector a, Lib3dsVector b)
-{
-  int i;
-  for (i=0; i<3; ++i) {
-    c[i]=a[i]+b[i];
-  }
-}
-
-
-/*!
- * \ingroup vector
- */
-void
-lib3ds_vector_sub(Lib3dsVector c, Lib3dsVector a, Lib3dsVector b)
-{
-  int i;
-  for (i=0; i<3; ++i) {
-    c[i]=a[i]-b[i];
-  }
-}
-
-
-/*!
- * \ingroup vector
- */
-void
-lib3ds_vector_scalar(Lib3dsVector c, Lib3dsFloat k)
-{
-  int i;
-  for (i=0; i<3; ++i) {
-    c[i]*=k;
-  }
-}
-
-
-/*!
- * \ingroup vector
- */
-void
-lib3ds_vector_cross(Lib3dsVector c, Lib3dsVector a, Lib3dsVector b)
-{
-  c[0]=a[1]*b[2] - a[2]*b[1];
-  c[1]=a[2]*b[0] - a[0]*b[2];
-  c[2]=a[0]*b[1] - a[1]*b[0];
-}
-
-
-/*!
- * \ingroup vector
- */
-Lib3dsFloat
-lib3ds_vector_dot(Lib3dsVector a, Lib3dsVector b)
-{
-  return(a[0]*b[0] + a[1]*b[1] + a[2]*b[2]);
-}
-
-
-/*!
- * \ingroup vector
- */
-Lib3dsFloat
-lib3ds_vector_squared(Lib3dsVector c)
-{
-  return(c[0]*c[0] + c[1]*c[1] + c[2]*c[2]);
-}
-
-
-/*!
- * \ingroup vector
- */
-Lib3dsFloat
-lib3ds_vector_length(Lib3dsVector c)
-{
-  return((Lib3dsFloat)sqrt(c[0]*c[0] + c[1]*c[1] + c[2]*c[2]));
-}
-
-
-/*!
- * \ingroup vector
- */
-void
-lib3ds_vector_normalize(Lib3dsVector c)
-{
-  Lib3dsFloat l,m;
-
-  l=(Lib3dsFloat)sqrt(c[0]*c[0] + c[1]*c[1] + c[2]*c[2]);
-  if (fabs(l)<LIB3DS_EPSILON) {
-    c[0]=c[1]=c[2]=0.0f;
-    if ((c[0]>=c[1]) && (c[0]>=c[2])) {
-      c[0]=1.0f;
-    }
-    else
-    if (c[1]>=c[2]) {
-      c[1]=1.0f;
-    }
-    else {
-      c[2]=1.0f;
-    }
-  }
-  else {
-    m=1.0f/l;
-    c[0]*=m;
-    c[1]*=m;
-    c[2]*=m;
-  }
-}
-
-
-/*!
- * \ingroup vector
- */
-void
-lib3ds_vector_normal(Lib3dsVector n, Lib3dsVector a, Lib3dsVector b, Lib3dsVector c)
-{
-  Lib3dsVector p,q;
-
-  lib3ds_vector_sub(p,c,b);
-  lib3ds_vector_sub(q,a,b);
-  lib3ds_vector_cross(n,p,q);
-  lib3ds_vector_normalize(n);
-}
-
-
-/*!
- * \ingroup vector
- */
-void
-lib3ds_vector_transform(Lib3dsVector c, Lib3dsMatrix m, Lib3dsVector a)
-{
-  c[0]= m[0][0]*a[0] + m[1][0]*a[1] + m[2][0]*a[2] + m[3][0];
-  c[1]= m[0][1]*a[0] + m[1][1]*a[1] + m[2][1]*a[2] + m[3][1];
-  c[2]= m[0][2]*a[0] + m[1][2]*a[1] + m[2][2]*a[2] + m[3][2];
-}
-
-
-/*!
- * \ingroup vector
- */
-void
-lib3ds_vector_cubic(Lib3dsVector c, Lib3dsVector a, Lib3dsVector p, Lib3dsVector q,
-  Lib3dsVector b, Lib3dsFloat t)
-{
-  Lib3dsDouble x,y,z,w;   
-
-  x=2*t*t*t - 3*t*t + 1;
-  y=-2*t*t*t + 3*t*t;
-  z=t*t*t - 2*t*t + t;
-  w=t*t*t - t*t;
-  c[0]=(Lib3dsFloat)(x*a[0] + y*b[0] + z*p[0] + w*q[0]);
-  c[1]=(Lib3dsFloat)(x*a[1] + y*b[1] + z*p[1] + w*q[1]);
-  c[2]=(Lib3dsFloat)(x*a[2] + y*b[2] + z*p[2] + w*q[2]);
-}
-
-
-/*!
- * c[i] = min(c[i], a[i]);
- * \ingroup vector
- */
-void 
-lib3ds_vector_min(Lib3dsVector c, Lib3dsVector a)
-{
-  int i;
-  for (i=0; i<3; ++i) {
-    if (a[i]<c[i]) {
-      c[i] = a[i];
-    }
-  }
-}
-
-
-/*!
- * c[i] = max(c[i], a[i]);
- * \ingroup vector
- */
-void 
-lib3ds_vector_max(Lib3dsVector c, Lib3dsVector a)
-{
-  int i;
-  for (i=0; i<3; ++i) {
-    if (a[i]>c[i]) {
-      c[i] = a[i];
-    }
-  }
-}
-
-
-/*!
- * \ingroup vector
- */
-void
-lib3ds_vector_dump(Lib3dsVector c)
-{
-  fprintf(stderr, "%f %f %f\n", c[0], c[1], c[2]);
-}
-
Index: /enSceneGraph/trunk/src/osgPlugins/3ds/matrix.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/matrix.cpp (revision 1563)
+++  (revision )
@@ -1,643 +1,0 @@
-/*
- * The 3D Studio File Format Library
- * Copyright (C) 1996-2001 by J.E. Hoffmann <je-h@gmx.net>
- * All rights reserved.
- *
- * This program is  free  software;  you can redistribute it and/or modify it
- * under the terms of the  GNU Lesser General Public License  as published by 
- * the  Free Software Foundation;  either version 2.1 of the License,  or (at 
- * your option) any later version.
- *
- * This  program  is  distributed in  the  hope that it will  be useful,  but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or  FITNESS FOR A  PARTICULAR PURPOSE.  See the  GNU Lesser General Public  
- * License for more details.
- *
- * You should  have received  a copy of the GNU Lesser General Public License
- * along with  this program;  if not, write to the  Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id$
- */
-#define LIB3DS_EXPORT
-#include "matrix.h"
-#include "quat.h"
-#include "vector.h"
-#include <string.h>
-#include <math.h>
-
-
-/*!
- * \defgroup matrix Matrix Mathematics
- *
- * \author J.E. Hoffmann <je-h@gmx.net>
- */
-/*!
- * \typedef Lib3dsMatrix
- *   \ingroup matrix
- */
-
-
-/*!
- * \ingroup matrix
- */
-void
-lib3ds_matrix_zero(Lib3dsMatrix m)
-{
-  int i,j;
-
-  for (i=0; i<4; i++) {
-    for (j=0; j<4; j++) m[i][j]=0.0f;
-  }
-}
-
-
-/*!
- * \ingroup matrix
- */
-void
-lib3ds_matrix_identity(Lib3dsMatrix m)
-{
-  int i,j;
-
-  for (i=0; i<4; i++) {
-    for (j=0; j<4; j++) m[i][j]=0.0;
-  }
-  for (i=0; i<4; i++) m[i][i]=1.0;
-}
-
-
-/*!
- * \ingroup matrix
- */
-void
-lib3ds_matrix_copy(Lib3dsMatrix dest, Lib3dsMatrix src)
-{
-  memcpy(dest, src, sizeof(Lib3dsMatrix)); 
-}
-
-
-/*!
- * \ingroup matrix
- */
-void 
-lib3ds_matrix_neg(Lib3dsMatrix m)
-{
-  int i,j;
-
-  for (j=0; j<4; j++) {
-    for (i=0; i<4; i++) {
-      m[j][i]=-m[j][i];
-    }
-  }
-}
-
-
-/*!
- * \ingroup matrix
- */
-void 
-lib3ds_matrix_abs(Lib3dsMatrix m)
-{
-  int i,j;
-
-  for (j=0; j<4; j++) {
-    for (i=0; i<4; i++) {
-      m[j][i]=(Lib3dsFloat)fabs(m[j][i]);
-    }
-  }
-}
-
-
-/*!
- * \ingroup matrix
- */
-void
-lib3ds_matrix_transpose(Lib3dsMatrix m)
-{
-  int i,j;
-  Lib3dsFloat swp;
-
-  for (j=0; j<4; j++) {
-    for (i=j+1; i<4; i++) {
-      swp=m[j][i];
-      m[j][i]=m[i][j];
-      m[i][j]=swp;
-    }
-  }
-}
-
-
-/*!
- * \ingroup matrix
- */
-void
-lib3ds_matrix_add(Lib3dsMatrix m, Lib3dsMatrix a, Lib3dsMatrix b)
-{
-  int i,j;
-
-  for (j=0; j<4; j++) {
-    for (i=0; i<4; i++) {
-      m[j][i]=a[j][i]+b[j][i];
-    }
-  }
-}
-
-
-/*!
- * \ingroup matrix
- */
-void
-lib3ds_matrix_sub(Lib3dsMatrix m, Lib3dsMatrix a, Lib3dsMatrix b)
-{
-  int i,j;
-
-  for (j=0; j<4; j++) {
-    for (i=0; i<4; i++) {
-      m[j][i]=a[j][i]-b[j][i];
-    }
-  }
-}
-
-
-/*!
- * \ingroup matrix
- */
-void
-lib3ds_matrix_mul(Lib3dsMatrix m, Lib3dsMatrix a, Lib3dsMatrix b)
-{
-  int i,j,k;
-  Lib3dsFloat ab;
-
-  for (j=0; j<4; j++) {
-    for (i=0; i<4; i++) {
-      ab=0.0f;
-      for (k=0; k<4; k++) ab+=a[k][i]*b[j][k];
-      m[j][i]=ab;
-    }
-  }
-}
-
-
-/*!
- * \ingroup matrix
- */
-void
-lib3ds_matrix_scalar(Lib3dsMatrix m, Lib3dsFloat k)
-{
-  int i,j;
-
-  for (j=0; j<4; j++) {
-    for (i=0; i<4; i++) {
-      m[j][i]*=k;
-    }
-  }
-}
-
-
-static Lib3dsFloat
-det2x2(
-  Lib3dsFloat a, Lib3dsFloat b,
-  Lib3dsFloat c, Lib3dsFloat d) 
-{
-  return((a)*(d)-(b)*(c));
-}
-
-
-static Lib3dsFloat
-det3x3(
-  Lib3dsFloat a1, Lib3dsFloat a2, Lib3dsFloat a3,
-  Lib3dsFloat b1, Lib3dsFloat b2, Lib3dsFloat b3,
-  Lib3dsFloat c1, Lib3dsFloat c2, Lib3dsFloat c3)
-{
-  return(
-    a1*det2x2(b2,b3,c2,c3)-
-    b1*det2x2(a2,a3,c2,c3)+
-    c1*det2x2(a2,a3,b2,b3)
-  );
-}
-
-
-/*!
- * \ingroup matrix
- */
-Lib3dsFloat
-lib3ds_matrix_det(Lib3dsMatrix m)
-{
-  Lib3dsFloat a1,a2,a3,a4,b1,b2,b3,b4,c1,c2,c3,c4,d1,d2,d3,d4;
-
-  a1 = m[0][0];
-  b1 = m[1][0];
-  c1 = m[2][0];
-  d1 = m[3][0];
-  a2 = m[0][1];
-  b2 = m[1][1];
-  c2 = m[2][1];
-  d2 = m[3][1];
-  a3 = m[0][2];
-  b3 = m[1][2];
-  c3 = m[2][2];
-  d3 = m[3][2];
-  a4 = m[0][3];
-  b4 = m[1][3];
-  c4 = m[2][3];
-  d4 = m[3][3];
-  return(
-    a1 * det3x3(b2, b3, b4, c2, c3, c4, d2, d3, d4)-
-    b1 * det3x3(a2, a3, a4, c2, c3, c4, d2, d3, d4)+
-    c1 * det3x3(a2, a3, a4, b2, b3, b4, d2, d3, d4)-
-    d1 * det3x3(a2, a3, a4, b2, b3, b4, c2, c3, c4)
-  );
-}
-
-
-/*!
- * \ingroup matrix
- */
-void
-lib3ds_matrix_adjoint(Lib3dsMatrix m)
-{
-  Lib3dsFloat a1,a2,a3,a4,b1,b2,b3,b4,c1,c2,c3,c4,d1,d2,d3,d4;
-
-  a1 = m[0][0];
-  b1 = m[1][0];
-  c1 = m[2][0];
-  d1 = m[3][0];
-  a2 = m[0][1];
-  b2 = m[1][1];
-  c2 = m[2][1];
-  d2 = m[3][1];
-  a3 = m[0][2];
-  b3 = m[1][2];
-  c3 = m[2][2];
-  d3 = m[3][2];
-  a4 = m[0][3];
-  b4 = m[1][3];
-  c4 = m[2][3];
-  d4 = m[3][3];
-  m[0][0]=  det3x3 (b2, b3, b4, c2, c3, c4, d2, d3, d4);
-  m[0][1]= -det3x3 (a2, a3, a4, c2, c3, c4, d2, d3, d4);
-  m[0][2]=  det3x3 (a2, a3, a4, b2, b3, b4, d2, d3, d4);
-  m[0][3]= -det3x3 (a2, a3, a4, b2, b3, b4, c2, c3, c4);
-  m[1][0]= -det3x3 (b1, b3, b4, c1, c3, c4, d1, d3, d4);
-  m[1][1]=  det3x3 (a1, a3, a4, c1, c3, c4, d1, d3, d4);
-  m[1][2]= -det3x3 (a1, a3, a4, b1, b3, b4, d1, d3, d4);
-  m[1][3]=  det3x3 (a1, a3, a4, b1, b3, b4, c1, c3, c4);
-  m[2][0]=  det3x3 (b1, b2, b4, c1, c2, c4, d1, d2, d4);
-  m[2][1]= -det3x3 (a1, a2, a4, c1, c2, c4, d1, d2, d4);
-  m[2][2]=  det3x3 (a1, a2, a4, b1, b2, b4, d1, d2, d4);
-  m[2][3]= -det3x3 (a1, a2, a4, b1, b2, b4, c1, c2, c4);
-  m[3][0]= -det3x3 (b1, b2, b3, c1, c2, c3, d1, d2, d3);
-  m[3][1]=  det3x3 (a1, a2, a3, c1, c2, c3, d1, d2, d3);
-  m[3][2]= -det3x3 (a1, a2, a3, b1, b2, b3, d1, d2, d3);
-  m[3][3]=  det3x3 (a1, a2, a3, b1, b2, b3, c1, c2, c3);
-}
-
-
-/*!
- * \ingroup matrix
- *
- * GGemsII, K.Wu, Fast Matrix Inversion 
- */
-Lib3dsBool
-lib3ds_matrix_inv(Lib3dsMatrix m)
-{                          
-  int i,j,k;               
-  int pvt_i[4], pvt_j[4];            /* Locations of pivot elements */
-  Lib3dsFloat pvt_val;               /* Value of current pivot element */
-  Lib3dsFloat hold;                  /* Temporary storage */
-  Lib3dsFloat determinat;            
-
-  determinat = 1.0f;
-  for (k=0; k<4; k++)  {
-    /* Locate k'th pivot element */
-    pvt_val=m[k][k];            /* Initialize for search */
-    pvt_i[k]=k;
-    pvt_j[k]=k;
-    for (i=k; i<4; i++) {
-      for (j=k; j<4; j++) {
-        if (fabs(m[i][j]) > fabs(pvt_val)) {
-          pvt_i[k]=i;
-          pvt_j[k]=j;
-          pvt_val=m[i][j];
-        }
-      }
-    }
-
-    /* Product of pivots, gives determinant when finished */
-    determinat*=pvt_val;
-    if (fabs(determinat)<LIB3DS_EPSILON) {    
-      return(LIB3DS_FALSE);  /* Matrix is singular (zero determinant) */
-    }
-
-    /* "Interchange" rows (with sign change stuff) */
-    i=pvt_i[k];
-    if (i!=k) {               /* If rows are different */
-      for (j=0; j<4; j++) {
-        hold=-m[k][j];
-        m[k][j]=m[i][j];
-        m[i][j]=hold;
-      }
-    }
-
-    /* "Interchange" columns */
-    j=pvt_j[k];
-    if (j!=k) {              /* If columns are different */
-      for (i=0; i<4; i++) {
-        hold=-m[i][k];
-        m[i][k]=m[i][j];
-        m[i][j]=hold;
-      }
-    }
-    
-    /* Divide column by minus pivot value */
-    for (i=0; i<4; i++) {
-      if (i!=k) m[i][k]/=( -pvt_val) ; 
-    }
-
-    /* Reduce the matrix */
-    for (i=0; i<4; i++) {
-      hold = m[i][k];
-      for (j=0; j<4; j++) {
-        if (i!=k && j!=k) m[i][j]+=hold*m[k][j];
-      }
-    }
-
-    /* Divide row by pivot */
-    for (j=0; j<4; j++) {
-      if (j!=k) m[k][j]/=pvt_val;
-    }
-
-    /* Replace pivot by reciprocal (at last we can touch it). */
-    m[k][k] = 1.0f/pvt_val;
-  }
-
-  /* That was most of the work, one final pass of row/column interchange */
-  /* to finish */
-  for (k=4-2; k>=0; k--) { /* Don't need to work with 1 by 1 corner*/
-    i=pvt_j[k];            /* Rows to swap correspond to pivot COLUMN */
-    if (i!=k) {            /* If rows are different */
-      for(j=0; j<4; j++) {
-        hold = m[k][j];
-        m[k][j]=-m[i][j];
-        m[i][j]=hold;
-      }
-    }
-
-    j=pvt_i[k];           /* Columns to swap correspond to pivot ROW */
-    if (j!=k)             /* If columns are different */
-    for (i=0; i<4; i++) {
-      hold=m[i][k];
-      m[i][k]=-m[i][j];
-      m[i][j]=hold;
-    }
-  }
-  return(LIB3DS_TRUE);                          
-}
-
-
-/*!
- * \ingroup matrix
- */
-void
-lib3ds_matrix_translate_xyz(Lib3dsMatrix m, Lib3dsFloat x, Lib3dsFloat y, Lib3dsFloat z)
-{
-  int i;
-  
-  for (i=0; i<3; i++) {
-    m[3][i]+= m[0][i]*x + m[1][i]*y + m[2][i]*z;
-  }
-}
-
-
-/*!
- * \ingroup matrix
- */
-void
-lib3ds_matrix_translate(Lib3dsMatrix m, Lib3dsVector t)
-{
-  int i;
-  
-  for (i=0; i<3; i++) {
-    m[3][i]+= m[0][i]*t[0] + m[1][i]*t[1] + m[2][i]*t[2];
-  }
-}
-
-
-/*!
- * \ingroup matrix
- */
-void
-lib3ds_matrix_scale_xyz(Lib3dsMatrix m, Lib3dsFloat x, Lib3dsFloat y, Lib3dsFloat z)
-{
-  int i;
-
-  for (i=0; i<4; i++) {
-    m[0][i]*=x;
-    m[1][i]*=y;
-    m[2][i]*=z;
-  }
-}
-
-
-/*!
- * \ingroup matrix
- */
-void
-lib3ds_matrix_scale(Lib3dsMatrix m, Lib3dsVector s)
-{
-  int i;
-
-  for (i=0; i<4; i++) {
-    m[0][i]*=s[0];
-    m[1][i]*=s[1];
-    m[2][i]*=s[2];
-  }
-}
-
-
-/*!
- * \ingroup matrix
- */
-void
-lib3ds_matrix_rotate_x(Lib3dsMatrix m, Lib3dsFloat phi)
-{
-  Lib3dsFloat SinPhi,CosPhi;
-  Lib3dsFloat a1[4],a2[4];
-
-  SinPhi=(Lib3dsFloat)sin(phi);
-  CosPhi=(Lib3dsFloat)cos(phi);
-  memcpy(a1,m[1],4*sizeof(Lib3dsFloat));
-  memcpy(a2,m[2],4*sizeof(Lib3dsFloat));
-  m[1][0]=CosPhi*a1[0]+SinPhi*a2[0];
-  m[1][1]=CosPhi*a1[1]+SinPhi*a2[1];
-  m[1][2]=CosPhi*a1[2]+SinPhi*a2[2];
-  m[1][3]=CosPhi*a1[3]+SinPhi*a2[3];
-  m[2][0]=-SinPhi*a1[0]+CosPhi*a2[0];
-  m[2][1]=-SinPhi*a1[1]+CosPhi*a2[1];
-  m[2][2]=-SinPhi*a1[2]+CosPhi*a2[2];
-  m[2][3]=-SinPhi*a1[3]+CosPhi*a2[3];
-}
-
-
-/*!
- * \ingroup matrix
- */
-void
-lib3ds_matrix_rotate_y(Lib3dsMatrix m, Lib3dsFloat phi)
-{
-  Lib3dsFloat SinPhi,CosPhi;
-  Lib3dsFloat a0[4],a2[4];
-
-  SinPhi=(Lib3dsFloat)sin(phi);
-  CosPhi=(Lib3dsFloat)cos(phi);
-  memcpy(a0,m[0],4*sizeof(Lib3dsFloat));
-  memcpy(a2,m[2],4*sizeof(Lib3dsFloat));
-  m[0][0]=CosPhi*a0[0]-SinPhi*a2[0];
-  m[0][1]=CosPhi*a0[1]-SinPhi*a2[1];
-  m[0][2]=CosPhi*a0[2]-SinPhi*a2[2];
-  m[0][3]=CosPhi*a0[3]-SinPhi*a2[3];
-  m[2][0]=SinPhi*a0[0]+CosPhi*a2[0];
-  m[2][1]=SinPhi*a0[1]+CosPhi*a2[1];
-  m[2][2]=SinPhi*a0[2]+CosPhi*a2[2];
-  m[2][3]=SinPhi*a0[3]+CosPhi*a2[3];
-}
-
-
-/*!
- * \ingroup matrix
- */
-void
-lib3ds_matrix_rotate_z(Lib3dsMatrix m, Lib3dsFloat phi)
-{
-  Lib3dsFloat SinPhi,CosPhi;
-  Lib3dsFloat a0[4],a1[4];
-  
-  SinPhi=(Lib3dsFloat)sin(phi);
-  CosPhi=(Lib3dsFloat)cos(phi);
-  memcpy(a0,m[0],4*sizeof(Lib3dsFloat));
-  memcpy(a1,m[1],4*sizeof(Lib3dsFloat));
-  m[0][0]=CosPhi*a0[0]+SinPhi*a1[0];
-  m[0][1]=CosPhi*a0[1]+SinPhi*a1[1];
-  m[0][2]=CosPhi*a0[2]+SinPhi*a1[2];
-  m[0][3]=CosPhi*a0[3]+SinPhi*a1[3];
-  m[1][0]=-SinPhi*a0[0]+CosPhi*a1[0];
-  m[1][1]=-SinPhi*a0[1]+CosPhi*a1[1];
-  m[1][2]=-SinPhi*a0[2]+CosPhi*a1[2];
-  m[1][3]=-SinPhi*a0[3]+CosPhi*a1[3];
-}
-
-
-/*!
- * \ingroup matrix
- */
-void
-lib3ds_matrix_rotate(Lib3dsMatrix m, Lib3dsQuat q)
-{
-  Lib3dsFloat s,xs,ys,zs,wx,wy,wz,xx,xy,xz,yy,yz,zz,l;
-  Lib3dsMatrix a,b;
-
-  lib3ds_matrix_copy(a, m);
-
-  l=q[0]*q[0] + q[1]*q[1] + q[2]*q[2] + q[3]*q[3];
-  if (fabs(l)<LIB3DS_EPSILON) {
-    s=1.0f;
-  }
-  else {
-    s=2.0f/l;
-  }
-
-  xs = q[0] * s;   ys = q[1] * s;  zs = q[2] * s;
-  wx = q[3] * xs;  wy = q[3] * ys; wz = q[3] * zs;
-  xx = q[0] * xs;  xy = q[0] * ys; xz = q[0] * zs;
-  yy = q[1] * ys;  yz = q[1] * zs; zz = q[2] * zs;
-
-  b[0][0]=1.0f - (yy +zz);
-  b[1][0]=xy - wz;
-  b[2][0]=xz + wy;
-  b[0][1]=xy + wz;
-  b[1][1]=1.0f - (xx +zz);
-  b[2][1]=yz - wx;
-  b[0][2]=xz - wy;
-  b[1][2]=yz + wx;
-  b[2][2]=1.0f - (xx + yy);
-  b[3][0]=b[3][1]=b[3][2]=b[0][3]=b[1][3]=b[2][3]=0.0f;
-  b[3][3]=1.0f;
-
-  lib3ds_matrix_mul(m,a,b);
-}
-
-
-/*!
- * \ingroup matrix
- */
-void
-lib3ds_matrix_rotate_axis(Lib3dsMatrix m, Lib3dsVector axis, Lib3dsFloat angle)
-{
-  Lib3dsQuat q;
-  
-  lib3ds_quat_axis_angle(q,axis,angle);
-  lib3ds_matrix_rotate(m,q);
-}
-
-
-/*!
- * \ingroup matrix
- */
-void
-lib3ds_matrix_camera(Lib3dsMatrix matrix, Lib3dsVector pos,
-  Lib3dsVector tgt, Lib3dsFloat roll)
-{
-  Lib3dsMatrix M,R;
-  Lib3dsVector x, y, z;
-
-  lib3ds_vector_sub(y, tgt, pos);
-  lib3ds_vector_normalize(y);
-  
-  z[0] = 0;
-  z[1] = 0;
-  z[2] = 1.0;
-  
-  lib3ds_vector_cross(x, y, z);
-  lib3ds_vector_cross(z, x, y);
-  lib3ds_vector_normalize(x);
-  lib3ds_vector_normalize(y);
-
-  lib3ds_matrix_identity(M);
-  M[0][0] = x[0];
-  M[1][0] = x[1];
-  M[2][0] = x[2];
-  M[0][1] = y[0];
-  M[1][1] = y[1];
-  M[2][1] = y[2];
-  M[0][2] = z[0];
-  M[1][2] = z[1];
-  M[2][2] = z[2];
-
-  lib3ds_matrix_identity(R);
-  lib3ds_matrix_rotate_y(R, roll);
-  lib3ds_matrix_mul(matrix, R,M);
-  lib3ds_matrix_translate_xyz(matrix, -pos[0],-pos[1],-pos[2]);
-}
-
-
-/*!
- * \ingroup matrix
- */
-void
-lib3ds_matrix_dump(Lib3dsMatrix matrix)
-{
-  int i,j;
-
-  for (i=0; i<4; ++i) {
-    for (j=0; j<3; ++j) {
-      printf("%f ", matrix[j][i]);
-    }
-    printf("%f\n", matrix[j][i]);
-  }
-}
-
-
-
-
-
Index: /enSceneGraph/trunk/src/osgPlugins/3ds/atmosphere.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/atmosphere.cpp (revision 10076)
+++  (revision )
@@ -1,305 +1,0 @@
-/*
- * The 3D Studio File Format Library
- * Copyright (C) 1996-2001 by J.E. Hoffmann <je-h@gmx.net>
- * All rights reserved.
- *
- * This program is  free  software;  you can redistribute it and/or modify it
- * under the terms of the  GNU Lesser General Public License  as published by 
- * the  Free Software Foundation;  either version 2.1 of the License,  or (at 
- * your option) any later version.
- *
- * This  program  is  distributed in  the  hope that it will  be useful,  but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or  FITNESS FOR A  PARTICULAR PURPOSE.  See the  GNU Lesser General Public  
- * License for more details.
- *
- * You should  have received  a copy of the GNU Lesser General Public License
- * along with  this program;  if not, write to the  Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id$
- */
-#define LIB3DS_EXPORT
-#include "atmosphere.h"
-#include "chunk.h"
-#include "readwrite.h"
-
-
-/*!
- * \defgroup atmosphere Atmosphere Settings
- *
- * \author J.E. Hoffmann <je-h@gmx.net>
- */
-
-
-static Lib3dsBool
-fog_read(Lib3dsFog *fog, iostream *strm)
-{
-  Lib3dsChunk c;
-  Lib3dsWord chunk;
-
-  if (!lib3ds_chunk_read_start(&c, LIB3DS_FOG, strm)) {
-    return(LIB3DS_FALSE);
-  }
-  fog->near_plane=lib3ds_float_read(strm);
-  fog->near_density=lib3ds_float_read(strm);
-  fog->far_plane=lib3ds_float_read(strm);
-  fog->far_density=lib3ds_float_read(strm);
-  lib3ds_chunk_read_tell(&c, strm);
-  
-  while ((chunk=lib3ds_chunk_read_next(&c, strm))!=0) {
-    switch (chunk) {
-      case LIB3DS_LIN_COLOR_F:
-        {
-          int i;
-          for (i=0; i<3; ++i) {
-            fog->col[i]=lib3ds_float_read(strm);
-          }
-        }
-        break;
-      case LIB3DS_COLOR_F:
-        break;
-      case LIB3DS_FOG_BGND:
-        {
-          fog->fog_background=LIB3DS_TRUE;
-        }
-        break;
-      default:
-        lib3ds_chunk_unknown(chunk);
-    }
-  }
-  
-  lib3ds_chunk_read_end(&c, strm);
-  return(LIB3DS_TRUE);
-}
-
-
-static Lib3dsBool
-layer_fog_read(Lib3dsLayerFog *fog, iostream *strm)
-{
-  Lib3dsChunk c;
-  Lib3dsWord chunk;
-
-  if (!lib3ds_chunk_read_start(&c, LIB3DS_LAYER_FOG, strm)) {
-    return(LIB3DS_FALSE);
-  }
-  fog->near_y=lib3ds_float_read(strm);
-  fog->far_y=lib3ds_float_read(strm);
-  fog->density=lib3ds_float_read(strm);
-  fog->flags=lib3ds_dword_read(strm);
-  lib3ds_chunk_read_tell(&c, strm);
-  
-  while ((chunk=lib3ds_chunk_read_next(&c, strm))!=0) {
-    switch (chunk) {
-      case LIB3DS_LIN_COLOR_F:
-        lib3ds_rgb_read(fog->col,strm);
-        break;
-      case LIB3DS_COLOR_F:
-        lib3ds_rgb_read(fog->col,strm);
-        break;
-      default:
-        lib3ds_chunk_unknown(chunk);
-    }
-  }
-  
-  lib3ds_chunk_read_end(&c, strm);
-  return(LIB3DS_TRUE);
-}
-
-
-static Lib3dsBool
-distance_cue_read(Lib3dsDistanceCue *cue, iostream *strm)
-{
-  Lib3dsChunk c;
-  Lib3dsWord chunk;
-
-  if (!lib3ds_chunk_read_start(&c, LIB3DS_DISTANCE_CUE, strm)) {
-    return(LIB3DS_FALSE);
-  }
-  cue->near_plane=lib3ds_float_read(strm);
-  cue->near_dimming=lib3ds_float_read(strm);
-  cue->far_plane=lib3ds_float_read(strm);
-  cue->far_dimming=lib3ds_float_read(strm);
-  lib3ds_chunk_read_tell(&c, strm);
-  
-  while ((chunk=lib3ds_chunk_read_next(&c, strm))!=0) {
-    switch (chunk) {
-      case LIB3DS_DCUE_BGND:
-        {
-          cue->cue_background=LIB3DS_TRUE;
-        }
-        break;
-      default:
-        lib3ds_chunk_unknown(chunk);
-    }
-  }
-  
-  lib3ds_chunk_read_end(&c, strm);
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
- * \ingroup atmosphere
- */
-Lib3dsBool
-lib3ds_atmosphere_read(Lib3dsAtmosphere *atmosphere, iostream *strm)
-{
-  Lib3dsChunk c;
-
-  if (!lib3ds_chunk_read(&c, strm)) {
-    return(LIB3DS_FALSE);
-  }
-  
-  switch (c.chunk) {
-      case LIB3DS_FOG:
-        {
-          lib3ds_chunk_read_reset(&c, strm);
-          if (!fog_read(&atmosphere->fog, strm)) {
-            return(LIB3DS_FALSE);
-          }
-        }
-        break;
-      case LIB3DS_LAYER_FOG:
-        {
-          lib3ds_chunk_read_reset(&c, strm);
-          if (!layer_fog_read(&atmosphere->layer_fog, strm)) {
-            return(LIB3DS_FALSE);
-          }
-        }
-        break;
-      case LIB3DS_DISTANCE_CUE:
-        {
-          lib3ds_chunk_read_reset(&c, strm);
-          if (!distance_cue_read(&atmosphere->dist_cue, strm)) {
-            return(LIB3DS_FALSE);
-          }
-        }
-        break;
-      case LIB3DS_USE_FOG:
-        {
-          atmosphere->fog.use=LIB3DS_TRUE;
-        }
-        break;
-      case LIB3DS_USE_LAYER_FOG:
-        {
-          atmosphere->fog.use=LIB3DS_TRUE;
-        }
-        break;
-      case LIB3DS_USE_DISTANCE_CUE:
-        {
-          atmosphere->dist_cue.use=LIB3DS_TRUE;
-        }
-        break;
-  }
-
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
- * \ingroup atmosphere
- */
-Lib3dsBool
-lib3ds_atmosphere_write(Lib3dsAtmosphere *atmosphere, iostream *strm)
-{
-  if (atmosphere->fog.use) { /*---- LIB3DS_FOG ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_FOG;
-    if (!lib3ds_chunk_write_start(&c,strm)) {
-      return(LIB3DS_FALSE);
-    }
-    lib3ds_float_write(atmosphere->fog.near_plane,strm);
-    lib3ds_float_write(atmosphere->fog.near_density,strm);
-    lib3ds_float_write(atmosphere->fog.far_plane,strm);
-    lib3ds_float_write(atmosphere->fog.far_density,strm);
-    {
-      Lib3dsChunk c;
-      c.chunk=LIB3DS_COLOR_F;
-      c.size=18;
-      lib3ds_chunk_write(&c,strm);
-      lib3ds_rgb_write(atmosphere->fog.col,strm);
-    }
-    if (atmosphere->fog.fog_background) {
-      Lib3dsChunk c;
-      c.chunk=LIB3DS_FOG_BGND;
-      c.size=6;
-      lib3ds_chunk_write(&c,strm);
-    }
-    if (!lib3ds_chunk_write_end(&c,strm)) {
-      return(LIB3DS_FALSE);
-    }
-  }
-
-  if (atmosphere->layer_fog.use) { /*---- LIB3DS_LAYER_FOG ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_LAYER_FOG;
-    c.size=40;
-    lib3ds_chunk_write(&c,strm);
-    lib3ds_float_write(atmosphere->layer_fog.near_y,strm);
-    lib3ds_float_write(atmosphere->layer_fog.far_y,strm);
-    lib3ds_float_write(atmosphere->layer_fog.near_y,strm);
-    lib3ds_dword_write(atmosphere->layer_fog.flags,strm);
-    {
-      Lib3dsChunk c;
-      c.chunk=LIB3DS_COLOR_F;
-      c.size=18;
-      lib3ds_chunk_write(&c,strm);
-      lib3ds_rgb_write(atmosphere->fog.col,strm);
-    }
-  }
-
-  if (atmosphere->dist_cue.use) { /*---- LIB3DS_DISTANCE_CUE ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_DISTANCE_CUE;
-    if (!lib3ds_chunk_write_start(&c,strm)) {
-      return(LIB3DS_FALSE);
-    }
-    lib3ds_float_write(atmosphere->dist_cue.near_plane,strm);
-    lib3ds_float_write(atmosphere->dist_cue.near_dimming,strm);
-    lib3ds_float_write(atmosphere->dist_cue.far_plane,strm);
-    lib3ds_float_write(atmosphere->dist_cue.far_dimming,strm);
-    if (atmosphere->dist_cue.cue_background) {
-      Lib3dsChunk c;
-      c.chunk=LIB3DS_DCUE_BGND;
-      c.size=6;
-      lib3ds_chunk_write(&c,strm);
-    }
-    if (!lib3ds_chunk_write_end(&c,strm)) {
-      return(LIB3DS_FALSE);
-    }
-  }
-
-  if (atmosphere->fog.use) { /*---- LIB3DS_USE_FOG ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_USE_FOG;
-    c.size=6;
-    lib3ds_chunk_write(&c,strm);
-  }
-
-  if (atmosphere->layer_fog.use) { /*---- LIB3DS_USE_LAYER_FOG ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_USE_LAYER_FOG;
-    c.size=6;
-    lib3ds_chunk_write(&c,strm);
-  }
-
-  if (atmosphere->dist_cue.use) { /*---- LIB3DS_USE_DISTANCE_CUE ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_USE_V_GRADIENT;
-    c.size=6;
-    lib3ds_chunk_write(&c,strm);
-  }
-  
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
-
-\typedef Lib3dsAtmosphere
-  \ingroup atmosphere
-  \sa _Lib3dsAtmosphere
-
-*/
-
Index: /enSceneGraph/trunk/src/osgPlugins/3ds/chunk.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/chunk.cpp (revision 10076)
+++  (revision )
@@ -1,307 +1,0 @@
-/*
- * The 3D Studio File Format Library
- * Copyright (C) 1996-2001 by J.E. Hoffmann <je-h@gmx.net>
- * All rights reserved.
- *
- * This program is  free  software;  you can redistribute it and/or modify it
- * under the terms of the  GNU Lesser General Public License  as published by 
- * the  Free Software Foundation;  either version 2.1 of the License,  or (at 
- * your option) any later version.
- *
- * This  program  is  distributed in  the  hope that it will  be useful,  but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or  FITNESS FOR A  PARTICULAR PURPOSE.  See the  GNU Lesser General Public  
- * License for more details.
- *
- * You should  have received  a copy of the GNU Lesser General Public License
- * along with  this program;  if not, write to the  Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id$
- */
-#define LIB3DS_EXPORT
-#include "chunk.h"
-#include "readwrite.h"
-#include "chunktable.h"
-#include <string.h>
-#include <stdarg.h>
-
-
-/*#define LIB3DS_CHUNK_DEBUG*/
-/*#define LIB3DS_CHUNK_WARNING*/
-
-
-/*!
- * \defgroup chunk Chunk Handling
- *
- * \author J.E. Hoffmann <je-h@gmx.net>
- */
-
-
-static Lib3dsBool enable_dump=LIB3DS_FALSE;
-static Lib3dsBool enable_unknown=LIB3DS_FALSE;
-static char lib3ds_chunk_level[128]="";
-
-
-static void
-lib3ds_chunk_debug_enter(Lib3dsChunk *)
-{
-  strcat(lib3ds_chunk_level, "  ");
-}
-
-
-static void
-lib3ds_chunk_debug_leave(Lib3dsChunk *)
-{
-  lib3ds_chunk_level[strlen(lib3ds_chunk_level)-2]=0;
-}
-
-
-static void
-lib3ds_chunk_debug_dump(Lib3dsChunk *c)
-{
-  if (enable_dump) {
-    printf("%s%s (0x%X) size=%u\n",
-      lib3ds_chunk_level,
-      lib3ds_chunk_name(c->chunk),
-      c->chunk,
-      c->size
-    );
-  }
-}
-
-
-/*!
- * \ingroup chunk
- */
-void
-lib3ds_chunk_enable_dump(Lib3dsBool enable, Lib3dsBool unknown)
-{
-  enable_dump=enable;
-  enable_unknown=unknown;
-}
-
-
-/*!
- * \ingroup chunk
- *
- * Reads a 3d-Studio chunk header from a little endian file stream.
- *
- * \param c  The chunk to store the data.
- * \param f  The file stream.
- *
- * \return   True on success, False otherwise.
- */
-Lib3dsBool
-lib3ds_chunk_read(Lib3dsChunk *c, iostream *strm)
-{
-  ASSERT(c);
-  ASSERT(strm);
-  c->cur=strm->tellg();           
-  c->chunk=lib3ds_word_read(strm);
-  c->size=lib3ds_dword_read(strm);
-  c->end=c->cur+c->size;
-  c->cur+=6;
-
-  if (strm->fail()||(c->size<6)) {    
-    return(LIB3DS_FALSE);
-  }
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
- * \ingroup chunk
- */
-Lib3dsBool
-lib3ds_chunk_read_start(Lib3dsChunk *c, Lib3dsWord chunk, iostream *strm)
-{
-  ASSERT(c);
-  ASSERT(strm);
-  if (!lib3ds_chunk_read(c, strm)) {
-    return(LIB3DS_FALSE);
-  }
-  lib3ds_chunk_debug_enter(c);
-  return((chunk==0) || (c->chunk==chunk));
-}
-
-
-/*!
- * \ingroup chunk
- */
-void
-lib3ds_chunk_read_tell(Lib3dsChunk *c, iostream *strm)
-{
-    c->cur=strm->tellg();
-}
-
-
-/*!
- * \ingroup chunk
- */
-Lib3dsWord
-lib3ds_chunk_read_next(Lib3dsChunk *c, iostream *strm)
-{
-  Lib3dsChunk d;
-
-  if (c->cur>=c->end) {
-    ASSERT(c->cur==c->end);
-    return(0);
-  }
-
-  strm->seekg((long)c->cur,ios_base::beg);
-  d.chunk=lib3ds_word_read(strm);
-  d.size=lib3ds_dword_read(strm);
-  lib3ds_chunk_debug_dump(&d);
-  c->cur+=d.size;
-  return(d.chunk);
-}
-
-
-/*!
- * \ingroup chunk
- */
-void
-lib3ds_chunk_read_reset(Lib3dsChunk *, iostream *strm)
-{  
-  strm->seekg(-6,ios_base::cur);
-}
-
-
-/*!
- * \ingroup chunk
- */
-void
-lib3ds_chunk_read_end(Lib3dsChunk *c, iostream *strm)
-{
-  lib3ds_chunk_debug_leave(c);
-  strm->seekg(c->end,ios_base::beg);
-}
-
-
-/*!
- * \ingroup chunk
- *
- * Writes a 3d-Studio chunk header into a little endian file stream.
- *
- * \param c  The chunk to be written.
- * \param f  The file stream.
- *
- * \return   True on success, False otherwise.
- */
-Lib3dsBool
-lib3ds_chunk_write(Lib3dsChunk *c, iostream *strm)
-{
-  ASSERT(c);
-  if (!lib3ds_word_write(c->chunk, strm)) {
-    LIB3DS_ERROR_LOG;
-    return(LIB3DS_FALSE);
-  }
-  if (!lib3ds_dword_write(c->size, strm)) {
-    LIB3DS_ERROR_LOG;
-    return(LIB3DS_FALSE);
-  }
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
- * \ingroup chunk
- */
-Lib3dsBool
-lib3ds_chunk_write_start(Lib3dsChunk *c, iostream *strm)
-{
-  ASSERT(c);
-  c->size=0;
-  c->cur=strm->tellp();
-  if (!lib3ds_word_write(c->chunk, strm)) {
-    return(LIB3DS_FALSE);
-  }
-  if (!lib3ds_dword_write(c->size, strm)) {
-    return(LIB3DS_FALSE);
-  }
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
- * \ingroup chunk
- */
-Lib3dsBool
-lib3ds_chunk_write_end(Lib3dsChunk *c, iostream *strm)
-{
-  ASSERT(c);
-  c->size=(Lib3dsDword)(strm->tellp()) - c->cur;
-  strm->seekp(c->cur+2,ios_base::beg);  
-  if (!lib3ds_dword_write(c->size, strm)) {
-    LIB3DS_ERROR_LOG;
-    return(LIB3DS_FALSE);
-  }
-
-  c->cur+=c->size;
-  strm->seekp(c->cur, ios_base::beg);
-  if (strm->fail()) {
-    LIB3DS_ERROR_LOG;
-    return(LIB3DS_FALSE);
-  }
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
- * \ingroup chunk
- */
-const char*
-lib3ds_chunk_name(Lib3dsWord chunk)
-{
-  Lib3dsChunkTable *p;
-
-  for (p=lib3ds_chunk_table; p->name!=0; ++p) {
-    if (p->chunk==chunk) {
-      return(p->name);
-    }
-  }
-  return("***UNKNOWN***");
-}
-
-
-/*!
- * \ingroup chunk
- */
-void
-lib3ds_chunk_unknown(Lib3dsWord chunk)
-{
-  if (enable_unknown) {
-    printf("%s***WARNING*** Unknown Chunk: %s (0x%X)\n",
-      lib3ds_chunk_level,
-      lib3ds_chunk_name(chunk),
-      chunk
-    );
-  }
-}
-
-
-/*!
- * \ingroup chunk
- */
-void 
-lib3ds_chunk_dump_info(const char *format, ...)
-{
-  if (enable_dump) {
-    char s[1024];
-    va_list marker;
-
-    va_start(marker, format);
-    vsprintf(s, format, marker);
-    va_end(marker);
-
-    printf("%s%s\n", lib3ds_chunk_level, s);
-  }
-}
-
-
-
-
-
-
-
Index: /enSceneGraph/trunk/src/osgPlugins/3ds/tcb.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/tcb.cpp (revision 10076)
+++  (revision )
@@ -1,140 +1,0 @@
-/*
- * The 3D Studio File Format Library
- * Copyright (C) 1996-2001 by J.E. Hoffmann <je-h@gmx.net>
- * All rights reserved.
- *
- * This program is  free  software;  you can redistribute it and/or modify it
- * under the terms of the  GNU Lesser General Public License  as published by 
- * the  Free Software Foundation;  either version 2.1 of the License,  or (at 
- * your option) any later version.
- *
- * This  program  is  distributed in  the  hope that it will  be useful,  but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or  FITNESS FOR A  PARTICULAR PURPOSE.  See the  GNU Lesser General Public  
- * License for more details.
- *
- * You should  have received  a copy of the GNU Lesser General Public License
- * along with  this program;  if not, write to the  Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id$
- */
-#define LIB3DS_EXPORT
-#include "tcb.h"
-#include "readwrite.h"
-#include <math.h>
-
-
-/*!
- * \defgroup tcb Tension/Continuity/Bias Splines
- *
- * \author J.E. Hoffmann <je-h@gmx.net>
- */
-
-
-/*!
- * \ingroup tcb 
- */
-void
-lib3ds_tcb(Lib3dsTcb *p, Lib3dsTcb *pc, Lib3dsTcb *c, Lib3dsTcb *nc, Lib3dsTcb *n,
-  Lib3dsFloat *ksm, Lib3dsFloat *ksp, Lib3dsFloat *kdm, Lib3dsFloat *kdp)
-{
-  Lib3dsFloat tm,cm,cp,bm,bp,tmcm,tmcp,cc;
-  Lib3dsFloat dt,fp,fn;
-
-  if (!pc) {
-    pc=c;
-  }
-  if (!nc) {
-    nc=c;
-  }
-  
-  fp=fn=1.0f;
-  if (p&&n) {
-    dt=0.5f*(Lib3dsFloat)(pc->frame-p->frame+n->frame-nc->frame);
-    fp=((Lib3dsFloat)(pc->frame-p->frame))/dt;
-    fn=((Lib3dsFloat)(n->frame-nc->frame))/dt;
-    cc=(Lib3dsFloat)fabs(c->cont);
-    fp=fp+cc-cc*fp;
-    fn=fn+cc-cc*fn;
-  }
-
-  cm=1.0f-c->cont;
-  tm=0.5f*(1.0f-c->tens);
-  cp=2.0f-cm;
-  bm=1.0f-c->bias;
-  bp=2.0f-bm;      
-  tmcm=tm*cm;
-  tmcp=tm*cp;
-  *ksm=tmcm*bp*fp;
-  *ksp=tmcp*bm*fp;
-  *kdm=tmcp*bp*fn;
-  *kdp=tmcm*bm*fn;
-}
-
-
-/*!
- * \ingroup tcb 
- */
-Lib3dsBool
-lib3ds_tcb_read(Lib3dsTcb *tcb, iostream *strm)
-{
-  Lib3dsWord flags;
-  
-  tcb->frame=lib3ds_intd_read(strm);
-  tcb->flags=flags=lib3ds_word_read(strm);
-  if (flags&LIB3DS_USE_TENSION) {
-    tcb->tens=lib3ds_float_read(strm);
-  }
-  if (flags&LIB3DS_USE_CONTINUITY) {
-    tcb->cont=lib3ds_float_read(strm);
-  }
-  if (flags&LIB3DS_USE_BIAS) {
-    tcb->bias=lib3ds_float_read(strm);
-  }
-  if (flags&LIB3DS_USE_EASE_TO) {
-    tcb->ease_to=lib3ds_float_read(strm);
-  }
-  if (flags&LIB3DS_USE_EASE_FROM) {
-    tcb->ease_from=lib3ds_float_read(strm);
-  }
-
-  if (strm->fail()){
-    return(LIB3DS_FALSE);
-  }
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
- * \ingroup tcb 
- */
-Lib3dsBool
-lib3ds_tcb_write(Lib3dsTcb *tcb, iostream *strm)
-{
-  lib3ds_intd_write(tcb->frame,strm);
-  lib3ds_word_write(tcb->flags,strm);
-  if (tcb->flags&LIB3DS_USE_TENSION) {
-    lib3ds_float_write(tcb->tens,strm);
-  }
-  if (tcb->flags&LIB3DS_USE_CONTINUITY) {
-    lib3ds_float_write(tcb->cont,strm);
-  }
-  if (tcb->flags&LIB3DS_USE_BIAS) {
-    lib3ds_float_write(tcb->bias,strm);
-  }
-  if (tcb->flags&LIB3DS_USE_EASE_TO) {
-    lib3ds_float_write(tcb->ease_to,strm);
-  }
-  if (tcb->flags&LIB3DS_USE_EASE_FROM) {
-    lib3ds_float_write(tcb->ease_from,strm);
-  }
-  if (strm->fail()){
-    return(LIB3DS_FALSE);
-  }
-  return(LIB3DS_TRUE);
-}
-
-
-
-
Index: /enSceneGraph/trunk/src/osgPlugins/3ds/types.h
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/types.h (revision 6461)
+++  (revision )
@@ -1,148 +1,0 @@
-/* -*- c -*- */
-#ifndef INCLUDED_LIB3DS_TYPES_H
-#define INCLUDED_LIB3DS_TYPES_H
-/*
- * The 3D Studio File Format Library
- * Copyright (C) 1996-2001 by J.E. Hoffmann <je-h@gmx.net>
- * All rights reserved.
- *
- * This program is  free  software;  you can redistribute it and/or modify it
- * under the terms of the  GNU Lesser General Public License  as published by 
- * the  Free Software Foundation;  either version 2.1 of the License,  or (at 
- * your option) any later version.
- *
- * This  program  is  distributed in  the  hope that it will  be useful,  but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or  FITNESS FOR A  PARTICULAR PURPOSE.  See the  GNU Lesser General Public  
- * License for more details.
- *
- * You should  have received  a copy of the GNU Lesser General Public License
- * along with  this program;  if not, write to the  Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id$
- */
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * #if defined (_LIB3DS_DLL) && defined(_WIN32) && (!defined(__GNUC__))
- * #ifdef LIB3DS_EXPORT
- * #define LIB3DSAPI __declspec(dllexport)
- * #else               
- * #define LIB3DSAPI __declspec(dllimport)
- * #endif           
- * #else
- * #define LIB3DSAPI
- * #endif
- */
-// within the OSG just use the libary inline, no need to export symbols.
-#define LIB3DSAPI
-
-#define LIB3DS_TRUE 1
-#define LIB3DS_FALSE 0
-
-typedef int Lib3dsBool;
-typedef unsigned char Lib3dsByte;
-typedef unsigned short Lib3dsWord;
-typedef unsigned int Lib3dsDword;
-typedef signed char Lib3dsIntb;
-typedef signed short Lib3dsIntw;
-typedef signed int Lib3dsIntd;
-typedef float Lib3dsFloat;
-typedef double Lib3dsDouble;
-
-typedef float Lib3dsVector[3];
-typedef float Lib3dsTexel[2];
-typedef float Lib3dsQuat[4];
-typedef float Lib3dsMatrix[4][4];
-typedef float Lib3dsRgb[3];
-typedef float Lib3dsRgba[4];
-
-#define LIB3DS_EPSILON (1e-8)
-#define LIB3DS_PI 3.14159265358979323846
-#define LIB3DS_TWOPI (2.0*LIB3DS_PI)
-#define LIB3DS_HALFPI (LIB3DS_PI/2.0)
-#define LIB3DS_DEG(x) ((180.0/LIB3DS_PI)*(x))
-#define LIB3DS_RAD(x) ((LIB3DS_PI/180.0)*(x))
-  
-#ifndef INCLUDED_STDIO_H
-#define INCLUDED_STDIO_H
-#include <stdio.h>
-#endif
-
-#ifdef _DEBUG
-  #ifndef ASSERT
-  #include <assert.h>
-  #define ASSERT(__expr) assert(__expr)
-  #endif
-  #define LIB3DS_ERROR_LOG \
-    {printf("\t***LIB3DS_ERROR_LOG*** %s : %d\n", __FILE__, __LINE__);}
-#else 
-  #ifndef ASSERT
-  #define ASSERT(__expr)
-  #endif
-  #define LIB3DS_ERROR_LOG
-#endif
-
-typedef struct _Lib3dsFile Lib3dsFile;
-typedef struct _Lib3dsBackground Lib3dsBackground;
-typedef struct _Lib3dsAtmosphere Lib3dsAtmosphere;
-typedef struct _Lib3dsShadow Lib3dsShadow;
-typedef struct _Lib3dsViewport Lib3dsViewport;
-typedef struct _Lib3dsMaterial Lib3dsMaterial;
-typedef struct _Lib3dsFace Lib3dsFace; 
-typedef struct _Lib3dsBoxMap Lib3dsBoxMap; 
-typedef struct _Lib3dsMapData Lib3dsMapData; 
-typedef struct _Lib3dsMesh Lib3dsMesh;
-typedef struct _Lib3dsCamera Lib3dsCamera;
-typedef struct _Lib3dsLight Lib3dsLight;
-typedef struct _Lib3dsBoolKey Lib3dsBoolKey;
-typedef struct _Lib3dsBoolTrack Lib3dsBoolTrack;
-typedef struct _Lib3dsLin1Key Lib3dsLin1Key;
-typedef struct _Lib3dsLin1Track Lib3dsLin1Track;
-typedef struct _Lib3dsLin3Key Lib3dsLin3Key;
-typedef struct _Lib3dsLin3Track Lib3dsLin3Track;
-typedef struct _Lib3dsQuatKey Lib3dsQuatKey;
-typedef struct _Lib3dsQuatTrack Lib3dsQuatTrack;
-typedef struct _Lib3dsMorphKey Lib3dsMorphKey;
-typedef struct _Lib3dsMorphTrack Lib3dsMorphTrack;
-
-typedef enum _Lib3dsNodeTypes {
-  LIB3DS_UNKNOWN_NODE =0,
-  LIB3DS_AMBIENT_NODE =1,
-  LIB3DS_OBJECT_NODE  =2,
-  LIB3DS_CAMERA_NODE  =3,
-  LIB3DS_TARGET_NODE  =4,
-  LIB3DS_LIGHT_NODE   =5,
-  LIB3DS_SPOT_NODE    =6
-} Lib3dsNodeTypes;
-
-typedef struct _Lib3dsNode Lib3dsNode;
-
-typedef union _Lib3dsUserData {
-    void *p;
-    Lib3dsIntd i;
-    Lib3dsDword d;
-    Lib3dsFloat f;
-    Lib3dsMaterial *material;
-    Lib3dsMesh *mesh;
-    Lib3dsCamera *camera;
-    Lib3dsLight *light;
-    Lib3dsNode *node;
-} Lib3dsUserData;
-
-#ifdef __cplusplus
-}
-#endif
-#endif
-
-
-
-
-
-
-
-
-
Index: /enSceneGraph/trunk/src/osgPlugins/3ds/lib3ds_float.h
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds_float.h (revision 6461)
+++  (revision )
@@ -1,41 +1,0 @@
-/* -*- c -*- */
-#ifndef INCLUDED_LIB3DS_FLOAT_H
-#define INCLUDED_LIB3DS_FLOAT_H
-/*
- * The 3D Studio File Format Library
- * Copyright (C) 1996-2001 by J.E. Hoffmann <je-h@gmx.net>
- * All rights reserved.
- *
- * This program is  free  software;  you can redistribute it and/or modify it
- * under the terms of the  GNU Lesser General Public License  as published by 
- * the  Free Software Foundation;  either version 2.1 of the License,  or (at 
- * your option) any later version.
- *
- * This  program  is  distributed in  the  hope that it will  be useful,  but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or  FITNESS FOR A  PARTICULAR PURPOSE.  See the  GNU Lesser General Public  
- * License for more details.
- *
- * You should  have received  a copy of the GNU Lesser General Public License
- * along with  this program;  if not, write to the  Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id$
- */
-
-#ifndef INCLUDED_LIB3DS_TYPES_H
-#include "types.h"
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern LIB3DSAPI Lib3dsFloat lib3ds_float_cubic(Lib3dsFloat a, Lib3dsFloat p,
-  Lib3dsFloat q, Lib3dsFloat b, Lib3dsFloat t);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
-
Index: /enSceneGraph/trunk/src/osgPlugins/3ds/config.h
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/config.h (revision 153)
+++  (revision )
@@ -1,12 +1,0 @@
-/* config.h.  Generated automatically by configure.  */
-/* config.h.in.  Generated automatically from configure.in by autoheader.  */
-
-/* Name of package */
-#define PACKAGE "lib3ds"
-
-/* Version number of package */
-#define VERSION "1.1.0"
-
-/* Define if using the dmalloc debugging malloc package */
-/* #undef WITH_DMALLOC */
-
Index: /enSceneGraph/trunk/src/osgPlugins/3ds/light.h
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/light.h (revision 10076)
+++  (revision )
@@ -1,82 +1,0 @@
-/* -*- c -*- */
-#ifndef INCLUDED_LIB3DS_LIGHT_H
-#define INCLUDED_LIB3DS_LIGHT_H
-/*
- * The 3D Studio File Format Library
- * Copyright (C) 1996-2001 by J.E. Hoffmann <je-h@gmx.net>
- * All rights reserved.
- *
- * This program is  free  software;  you can redistribute it and/or modify it
- * under the terms of the  GNU Lesser General Public License  as published by 
- * the  Free Software Foundation;  either version 2.1 of the License,  or (at 
- * your option) any later version.
- *
- * This  program  is  distributed in  the  hope that it will  be useful,  but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or  FITNESS FOR A  PARTICULAR PURPOSE.  See the  GNU Lesser General Public  
- * License for more details.
- *
- * You should  have received  a copy of the GNU Lesser General Public License
- * along with  this program;  if not, write to the  Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id$
- */
-
-#ifndef INCLUDED_LIB3DS_TYPES_H
-#include "types.h"
-#endif
-
-#include <iostream>
-using namespace std;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/*!
- * Light
- * \ingroup light
- */
-struct _Lib3dsLight {
-    Lib3dsLight *next;
-    char name[64];
-    Lib3dsBool spot_light;
-    Lib3dsBool see_cone;
-    Lib3dsRgb color;
-    Lib3dsVector position;
-    Lib3dsVector spot;
-    Lib3dsFloat roll;
-    Lib3dsBool off;
-    Lib3dsFloat outer_range;
-    Lib3dsFloat inner_range;
-    Lib3dsFloat multiplier;
-    /*const char** excludes;*/
-    Lib3dsFloat attenuation;
-    Lib3dsBool rectangular_spot;
-    Lib3dsBool shadowed;
-    Lib3dsFloat shadow_bias;
-    Lib3dsFloat shadow_filter;
-    Lib3dsIntw shadow_size;
-    Lib3dsFloat spot_aspect;
-    Lib3dsBool use_projector;
-    char projector[64];
-    Lib3dsIntd spot_overshoot;
-    Lib3dsBool ray_shadows;
-    Lib3dsFloat ray_bias;
-    Lib3dsFloat hot_spot;
-    Lib3dsFloat fall_off;
-}; 
-
-extern LIB3DSAPI Lib3dsLight* lib3ds_light_new(const char *name);
-extern LIB3DSAPI void lib3ds_light_free(Lib3dsLight *mesh);
-extern LIB3DSAPI void lib3ds_light_dump(Lib3dsLight *light);
-extern LIB3DSAPI Lib3dsBool lib3ds_light_read(Lib3dsLight *light, iostream *strm);
-extern LIB3DSAPI Lib3dsBool lib3ds_light_write(Lib3dsLight *light, iostream *strm);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
-
Index: /enSceneGraph/trunk/src/osgPlugins/3ds/ease.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/ease.cpp (revision 1563)
+++  (revision )
@@ -1,65 +1,0 @@
-/*
- * The 3D Studio File Format Library
- * Copyright (C) 1996-2001 by J.E. Hoffmann <je-h@gmx.net>
- * All rights reserved.
- *
- * This program is  free  software;  you can redistribute it and/or modify it
- * under the terms of the  GNU Lesser General Public License  as published by 
- * the  Free Software Foundation;  either version 2.1 of the License,  or (at 
- * your option) any later version.
- *
- * This  program  is  distributed in  the  hope that it will  be useful,  but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or  FITNESS FOR A  PARTICULAR PURPOSE.  See the  GNU Lesser General Public  
- * License for more details.
- *
- * You should  have received  a copy of the GNU Lesser General Public License
- * along with  this program;  if not, write to the  Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id$
- */
-#define LIB3DS_EXPORT
-#include "ease.h"
-
-
-/*!
- * \defgroup ease Ease
- *
- * \author J.E. Hoffmann <je-h@gmx.net>
- */
-
-
-/*!
- * \ingroup ease
- */
-Lib3dsFloat
-lib3ds_ease(Lib3dsFloat fp, Lib3dsFloat fc, Lib3dsFloat fn,
-  Lib3dsFloat ease_from, Lib3dsFloat ease_to)
-{
-  Lib3dsDouble s,step;
-  Lib3dsDouble tofrom;
-  Lib3dsDouble a;
-
-  s=step=(Lib3dsFloat)(fc-fp)/(fn-fp);
-  tofrom=ease_to+ease_from;
-  if (tofrom!=0.0) {
-    if (tofrom>1.0) {
-      ease_to=(Lib3dsFloat)(ease_to/tofrom);
-      ease_from=(Lib3dsFloat)(ease_from/tofrom);
-    }
-    a=1.0/(2.0-(ease_to+ease_from));
-
-    if (step<ease_from) s=a/ease_from*step*step;
-    else {
-      if ((1.0-ease_to)<=step) {
-        step=1.0-step;
-        s=1.0-a/ease_to*step*step;
-      }
-      else {
-        s=((2.0*step)-ease_from)*a;
-      }
-    }
-  }
-  return((Lib3dsFloat)s);
-}
Index: /enSceneGraph/trunk/src/osgPlugins/3ds/quat.h
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/quat.h (revision 6461)
+++  (revision )
@@ -1,61 +1,0 @@
-/* -*- c -*- */
-#ifndef INCLUDED_LIB3DS_QUAT_H
-#define INCLUDED_LIB3DS_QUAT_H
-/*
- * The 3D Studio File Format Library
- * Copyright (C) 1996-2001 by J.E. Hoffmann <je-h@gmx.net>
- * All rights reserved.
- *
- * This program is  free  software;  you can redistribute it and/or modify it
- * under the terms of the  GNU Lesser General Public License  as published by 
- * the  Free Software Foundation;  either version 2.1 of the License,  or (at 
- * your option) any later version.
- *
- * This  program  is  distributed in  the  hope that it will  be useful,  but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or  FITNESS FOR A  PARTICULAR PURPOSE.  See the  GNU Lesser General Public  
- * License for more details.
- *
- * You should  have received  a copy of the GNU Lesser General Public License
- * along with  this program;  if not, write to the  Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id$
- */
-
-#ifndef INCLUDED_LIB3DS_TYPES_H
-#include "types.h"
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern LIB3DSAPI void lib3ds_quat_zero(Lib3dsQuat c);
-extern LIB3DSAPI void lib3ds_quat_identity(Lib3dsQuat c);
-extern LIB3DSAPI void lib3ds_quat_copy(Lib3dsQuat dest, Lib3dsQuat src);
-extern LIB3DSAPI void lib3ds_quat_axis_angle(Lib3dsQuat c, Lib3dsVector axis, Lib3dsFloat angle);
-extern LIB3DSAPI void lib3ds_quat_neg(Lib3dsQuat c);
-extern LIB3DSAPI void lib3ds_quat_abs(Lib3dsQuat c);
-extern LIB3DSAPI void lib3ds_quat_cnj(Lib3dsQuat c);
-extern LIB3DSAPI void lib3ds_quat_mul(Lib3dsQuat c, Lib3dsQuat a, Lib3dsQuat b);
-extern LIB3DSAPI void lib3ds_quat_scalar(Lib3dsQuat c, Lib3dsFloat k);
-extern LIB3DSAPI void lib3ds_quat_normalize(Lib3dsQuat c);
-extern LIB3DSAPI void lib3ds_quat_inv(Lib3dsQuat c);
-extern LIB3DSAPI Lib3dsFloat lib3ds_quat_dot(Lib3dsQuat a, Lib3dsQuat b);
-extern LIB3DSAPI Lib3dsFloat lib3ds_quat_squared(Lib3dsQuat c);
-extern LIB3DSAPI Lib3dsFloat lib3ds_quat_length(Lib3dsQuat c);
-extern LIB3DSAPI void lib3ds_quat_ln(Lib3dsQuat c);
-extern LIB3DSAPI void lib3ds_quat_ln_dif(Lib3dsQuat c, Lib3dsQuat a, Lib3dsQuat b);
-extern LIB3DSAPI void lib3ds_quat_exp(Lib3dsQuat c);
-extern LIB3DSAPI void lib3ds_quat_slerp(Lib3dsQuat c, Lib3dsQuat a, Lib3dsQuat b, Lib3dsFloat t);
-extern LIB3DSAPI void lib3ds_quat_squad(Lib3dsQuat c, Lib3dsQuat a, Lib3dsQuat p, Lib3dsQuat q,
-  Lib3dsQuat b, Lib3dsFloat t);
-extern LIB3DSAPI void lib3ds_quat_tangent(Lib3dsQuat c, Lib3dsQuat p, Lib3dsQuat q, Lib3dsQuat n);
-extern LIB3DSAPI void lib3ds_quat_dump(Lib3dsQuat q);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
-
Index: /enSceneGraph/trunk/src/osgPlugins/3ds/file.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/file.cpp (revision 10076)
+++  (revision )
@@ -1,1562 +1,0 @@
-/*
- * The 3D Studio File Format Library
- * Copyright (C) 1996-2001 by J.E. Hoffmann <je-h@gmx.net>
- * All rights reserved.
- *
- * This program is  free  software;  you can redistribute it and/or modify it
- * under the terms of the  GNU Lesser General Public License  as published by 
- * the  Free Software Foundation;  either version 2.1 of the License,  or (at 
- * your option) any later version.
- *
- * This  program  is  distributed in  the  hope that it will  be useful,  but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or  FITNESS FOR A  PARTICULAR PURPOSE.  See the  GNU Lesser General Public  
- * License for more details.
- *
- * You should  have received  a copy of the GNU Lesser General Public License
- * along with  this program;  if not, write to the  Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id$
- */
-#define LIB3DS_EXPORT
-#include "file.h"
-#include "chunk.h"
-#include "readwrite.h"
-#include "material.h"
-#include "mesh.h"
-#include "camera.h"
-#include "light.h"
-#include "node.h"
-#include "vector.h"
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-#include "config.h"
-#ifdef WITH_DMALLOC
-#include <dmalloc.h>
-#endif
-
-#include <istream>
-#include <stdio.h>
-//#include <strstream>
-#include <sstream>
-#include <fstream>
-
-/*!
- * \defgroup file Files
- *
- * \author J.E. Hoffmann <je-h@gmx.net>
- */
-
-
-/*!
- * Loads a .3DS file from disk into memory.
- *
- * \param filename  The filename of the .3DS file
- *
- * \return   A pointer to the Lib3dsFile structure containing the
- *           data of the .3DS file. 
- *           If the .3DS file can not be loaded NULL is returned.
- *
- * \note     To free the returned pointer use lib3ds_free.
- *
- * \see lib3ds_file_save
- * \see lib3ds_file_new
- * \see lib3ds_file_free
- *
- * \ingroup file
- */
-Lib3dsFile*
-lib3ds_file_load(const char *filename, const osgDB::ReaderWriter::Options* options)
-{
-  Lib3dsFile *file = NULL;
-  std::stringstream bufferedStream;
-  ifstream inputStream(filename,ios::in|ios::binary);
-  if (!inputStream.fail())
-  {
-        bufferedStream.operator<<(inputStream.rdbuf());                
-        bufferedStream.seekp(ios_base::beg);                    
-        file = lib3ds_stream_load(&bufferedStream);
-        inputStream.close();
-  }
-  return(file);
-}
-
-Lib3dsFile*
-lib3ds_stream_load(iostream * strm)
-{
-  Lib3dsFile *file = NULL;
-  if (strm)
-  {    
-    file=lib3ds_file_new();
-    if (file) 
-    {
-        if (!lib3ds_file_read(file,strm)) 
-        {
-            free(file);
-            file = NULL;
-        }
-    }
-    else 
-        file = NULL;
-  }
-  return(file);
-}
-
-
-
-/*!
- * Saves a .3DS file from memory to disk.
- *
- * \param file      A pointer to a Lib3dsFile structure containing the
- *                  the data that should be stored.
- * \param filename  The filename of the .3DS file to store the data in.
- *
- * \return          TRUE on success, FALSE otherwise.
- *
- * \see lib3ds_file_load
- *
- * \ingroup file
- */
-Lib3dsBool
-lib3ds_file_save(Lib3dsFile *file, const char *filename)
-{
-  fstream strm;
-
-  strm.open(filename,ios_base::out | ios_base::binary);
-  if (strm.fail()) return (LIB3DS_FALSE);
-  
-  if (!lib3ds_file_write(file, &strm)) {
-      strm.close();
-    return(LIB3DS_FALSE);
-  }
-  strm.close();
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
- * \ingroup file
- */
-Lib3dsFile*
-lib3ds_file_new()
-{
-  Lib3dsFile *file;
-
-  file=(Lib3dsFile*)calloc(sizeof(Lib3dsFile),1);
-  if (!file) {
-    return(0);
-  }
-  file->mesh_version=3;
-  file->master_scale=1.0f;
-  file->keyf_revision=5;
-  strcpy(file->name, "LIB3DS");
-  return(file);
-}
-
-
-/*!
- * \ingroup file
- */
-void
-lib3ds_file_free(Lib3dsFile* file)
-{
-  ASSERT(file);
-  lib3ds_viewport_set_views(&file->viewport,0);
-  {
-    Lib3dsMaterial *p,*q;
-    
-    for (p=file->materials; p; p=q) {
-      q=p->next;
-      lib3ds_material_free(p);
-    }
-    file->materials=0;
-  }
-  {
-    Lib3dsCamera *p,*q;
-    
-    for (p=file->cameras; p; p=q) {
-      q=p->next;
-      lib3ds_camera_free(p);
-    }
-    file->cameras=0;
-  }
-  {
-    Lib3dsLight *p,*q;
-    
-    for (p=file->lights; p; p=q) {
-      q=p->next;
-      lib3ds_light_free(p);
-    }
-    file->lights=0;
-  }
-  {
-    Lib3dsMesh *p,*q;
-    
-    for (p=file->meshes; p; p=q) {
-      q=p->next;
-      lib3ds_mesh_free(p);
-    }
-    file->meshes=0;
-  }
-  {
-    Lib3dsNode *p,*q;
-  
-    for (p=file->nodes; p; p=q) {
-      q=p->next;
-      lib3ds_node_free(p);
-    }
-  }
-  free(file);
-}
-
-
-/*!
- * \ingroup file
- */
-void
-lib3ds_file_eval(Lib3dsFile *file, Lib3dsFloat t)
-{
-  Lib3dsNode *p;
-
-  for (p=file->nodes; p!=0; p=p->next) {
-    lib3ds_node_eval(p, t);
-  }
-}
-
-
-static Lib3dsBool
-named_object_read(Lib3dsFile *file, iostream *strm)
-{
-  Lib3dsChunk c;
-  char name[64];
-  Lib3dsWord chunk;
-
-  if (!lib3ds_chunk_read_start(&c, LIB3DS_NAMED_OBJECT, strm)) {
-    return(LIB3DS_FALSE);
-  }
-  if (!lib3ds_string_read(name, 64, strm)) {
-    return(LIB3DS_FALSE);
-  }
-  lib3ds_chunk_dump_info("  NAME=%s", name);
-  lib3ds_chunk_read_tell(&c, strm);
-
-  while ((chunk=lib3ds_chunk_read_next(&c, strm))!=0) {
-    switch (chunk) {
-      case LIB3DS_N_TRI_OBJECT:
-        {
-          Lib3dsMesh *mesh;
-
-          mesh=lib3ds_mesh_new(name);
-          if (!mesh) {
-            return(LIB3DS_FALSE);
-          }
-          lib3ds_chunk_read_reset(&c, strm);
-          if (!lib3ds_mesh_read(mesh, strm)) {
-            return(LIB3DS_FALSE);
-          }
-          lib3ds_file_insert_mesh(file, mesh);
-        }
-        break;
-      case LIB3DS_N_CAMERA:
-        {
-          Lib3dsCamera *camera;
-
-          camera=lib3ds_camera_new(name);
-          if (!camera) {
-            return(LIB3DS_FALSE);
-          }
-          lib3ds_chunk_read_reset(&c, strm);
-          if (!lib3ds_camera_read(camera, strm)) {
-            return(LIB3DS_FALSE);
-          }
-          lib3ds_file_insert_camera(file, camera);
-        }
-        break;
-      case LIB3DS_N_DIRECT_LIGHT:
-        {
-          Lib3dsLight *light;
-
-          light=lib3ds_light_new(name);
-          if (!light) {
-            return(LIB3DS_FALSE);
-          }
-          lib3ds_chunk_read_reset(&c, strm);
-          if (!lib3ds_light_read(light, strm)) {
-            return(LIB3DS_FALSE);
-          }
-          lib3ds_file_insert_light(file, light);
-        }
-        break;
-      default:
-        lib3ds_chunk_unknown(chunk);
-    }
-  }
-  
-  lib3ds_chunk_read_end(&c, strm);
-  return(LIB3DS_TRUE);
-}
-
-
-static Lib3dsBool
-ambient_read(Lib3dsFile *file, iostream *strm)
-{
-  Lib3dsChunk c;
-  Lib3dsWord chunk;
-  Lib3dsBool have_lin=LIB3DS_FALSE;
-
-  if (!lib3ds_chunk_read_start(&c, LIB3DS_AMBIENT_LIGHT, strm)) {
-    return(LIB3DS_FALSE);
-  }
-
-  while ((chunk=lib3ds_chunk_read_next(&c, strm))!=0) {
-    switch (chunk) {
-      case LIB3DS_LIN_COLOR_F:
-        {
-          int i;
-          for (i=0; i<3; ++i) {
-            file->ambient[i]=lib3ds_float_read(strm);
-          }
-        }
-        have_lin=LIB3DS_TRUE;
-        break;
-      case LIB3DS_COLOR_F:
-        {
-          /* gamma corrected color chunk
-             replaced in 3ds R3 by LIN_COLOR_24 */
-          if (!have_lin) {
-            int i;
-            for (i=0; i<3; ++i) {
-              file->ambient[i]=lib3ds_float_read(strm);
-            }
-          }
-        }
-        break;
-      default:
-        lib3ds_chunk_unknown(chunk);
-    }
-  }
-  
-  lib3ds_chunk_read_end(&c, strm);
-  return(LIB3DS_TRUE);
-}
-
-
-static Lib3dsBool
-mdata_read(Lib3dsFile *file, iostream *strm)
-{
-  Lib3dsChunk c;
-  Lib3dsWord chunk;
-
-  if (!lib3ds_chunk_read_start(&c, LIB3DS_MDATA, strm)) {
-    return(LIB3DS_FALSE);
-  }
-  
-  while ((chunk=lib3ds_chunk_read_next(&c, strm))!=0) {
-    switch (chunk) {
-      case LIB3DS_MESH_VERSION:
-        {
-          file->mesh_version=lib3ds_intd_read(strm);
-        }
-        break;
-      case LIB3DS_MASTER_SCALE:
-        {
-          file->master_scale=lib3ds_float_read(strm);
-        }
-        break;
-      case LIB3DS_SHADOW_MAP_SIZE:
-      case LIB3DS_LO_SHADOW_BIAS:
-      case LIB3DS_HI_SHADOW_BIAS:
-      case LIB3DS_SHADOW_SAMPLES:
-      case LIB3DS_SHADOW_RANGE:
-      case LIB3DS_SHADOW_FILTER:
-      case LIB3DS_RAY_BIAS:
-        {
-          lib3ds_chunk_read_reset(&c, strm);
-          if (!lib3ds_shadow_read(&file->shadow, strm)) {
-            return(LIB3DS_FALSE);
-          }
-        }
-        break;
-      case LIB3DS_VIEWPORT_LAYOUT:
-      case LIB3DS_DEFAULT_VIEW:
-        {
-          lib3ds_chunk_read_reset(&c, strm);
-          if (!lib3ds_viewport_read(&file->viewport, strm)) {
-            return(LIB3DS_FALSE);
-          }
-        }
-        break;
-      case LIB3DS_O_CONSTS:
-        {
-          int i;
-          for (i=0; i<3; ++i) {
-            file->construction_plane[i]=lib3ds_float_read(strm);
-          }
-        }
-        break;
-      case LIB3DS_AMBIENT_LIGHT:
-        {
-          lib3ds_chunk_read_reset(&c, strm);
-          if (!ambient_read(file, strm)) {
-            return(LIB3DS_FALSE);
-          }
-        }
-        break;
-      case LIB3DS_BIT_MAP:
-      case LIB3DS_SOLID_BGND:
-      case LIB3DS_V_GRADIENT:
-      case LIB3DS_USE_BIT_MAP:
-      case LIB3DS_USE_SOLID_BGND:
-      case LIB3DS_USE_V_GRADIENT:
-        {
-          lib3ds_chunk_read_reset(&c, strm);
-          if (!lib3ds_background_read(&file->background, strm)) {
-            return(LIB3DS_FALSE);
-          }
-        }
-        break;
-      case LIB3DS_FOG:
-      case LIB3DS_LAYER_FOG:
-      case LIB3DS_DISTANCE_CUE:
-      case LIB3DS_USE_FOG:
-      case LIB3DS_USE_LAYER_FOG:
-      case LIB3DS_USE_DISTANCE_CUE:
-        {
-          lib3ds_chunk_read_reset(&c, strm);
-          if (!lib3ds_atmosphere_read(&file->atmosphere, strm)) {
-            return(LIB3DS_FALSE);
-          }
-        }
-        break;
-      case LIB3DS_MAT_ENTRY:
-        {
-          Lib3dsMaterial *material;
-
-          material=lib3ds_material_new();
-          if (!material) {
-            return(LIB3DS_FALSE);
-          }
-          lib3ds_chunk_read_reset(&c, strm);
-          if (!lib3ds_material_read(material, strm)) {
-            return(LIB3DS_FALSE);
-          }
-          lib3ds_file_insert_material(file, material);
-        }
-        break;
-      case LIB3DS_NAMED_OBJECT:
-        {
-          lib3ds_chunk_read_reset(&c, strm);
-          if (!named_object_read(file, strm)) {
-            return(LIB3DS_FALSE);
-          }
-        }
-        break;
-      default:
-        lib3ds_chunk_unknown(chunk);
-    }
-  }
-
-  lib3ds_chunk_read_end(&c, strm);
-  return(LIB3DS_TRUE);
-}
-
-
-static Lib3dsBool
-kfdata_read(Lib3dsFile *file, iostream *strm)
-{
-  Lib3dsChunk c;
-  Lib3dsWord chunk;
-
-  if (!lib3ds_chunk_read_start(&c, LIB3DS_KFDATA, strm)) {
-    return(LIB3DS_FALSE);
-  }
-  
-  while ((chunk=lib3ds_chunk_read_next(&c, strm))!=0) {
-    switch (chunk) {
-      case LIB3DS_KFHDR:
-        {
-          file->keyf_revision=lib3ds_word_read(strm);
-          if (!lib3ds_string_read(file->name, 12+1, strm)) {
-            return(LIB3DS_FALSE);
-          }
-          file->frames=lib3ds_intd_read(strm);
-        }
-        break;
-      case LIB3DS_KFSEG:
-        {
-          file->segment_from=lib3ds_intd_read(strm);
-          file->segment_to=lib3ds_intd_read(strm);
-        }
-        break;
-      case LIB3DS_KFCURTIME:
-        {
-          file->current_frame=lib3ds_intd_read(strm);
-        }
-        break;
-      case LIB3DS_VIEWPORT_LAYOUT:
-      case LIB3DS_DEFAULT_VIEW:
-        {
-          lib3ds_chunk_read_reset(&c, strm);
-          if (!lib3ds_viewport_read(&file->viewport_keyf, strm)) {
-            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, strm);
-          if (!lib3ds_node_read(node, file, strm)) {
-            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, strm);
-          if (!lib3ds_node_read(node, file, strm)) {
-            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, strm);
-          if (!lib3ds_node_read(node, file, strm)) {
-            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, strm);
-          if (!lib3ds_node_read(node, file, strm)) {
-            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, strm);
-          if (!lib3ds_node_read(node, file, strm)) {
-            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, strm);
-          if (!lib3ds_node_read(node, file, strm)) {
-            return(LIB3DS_FALSE);
-          }
-          lib3ds_file_insert_node(file, node);
-        }
-        break;
-      default:
-        lib3ds_chunk_unknown(chunk);
-    }
-  }
-
-  lib3ds_chunk_read_end(&c, strm);
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
- * \ingroup file
- */
-Lib3dsBool
-lib3ds_file_read(Lib3dsFile *file, iostream *strm)
-{
-  Lib3dsChunk c;
-  Lib3dsWord chunk;
-
-  if (!lib3ds_chunk_read_start(&c, 0, strm)) {
-    return(LIB3DS_FALSE);
-  }
-  switch (c.chunk) {
-    case LIB3DS_MDATA:
-      {
-        lib3ds_chunk_read_reset(&c, strm);
-        if (!mdata_read(file, strm)) {
-          return(LIB3DS_FALSE);
-        }
-      }
-      break;
-    case LIB3DS_M3DMAGIC:
-    case LIB3DS_MLIBMAGIC:
-    case LIB3DS_CMAGIC:
-      {
-        while ((chunk=lib3ds_chunk_read_next(&c, strm))!=0) {
-          switch (chunk) {
-            case LIB3DS_M3D_VERSION:
-              {
-                file->mesh_version=lib3ds_dword_read(strm);
-              }
-              break;
-            case LIB3DS_MDATA:
-              {
-                lib3ds_chunk_read_reset(&c, strm);
-                if (!mdata_read(file, strm)) {
-                  return(LIB3DS_FALSE);
-                }
-              }
-              break;
-            case LIB3DS_KFDATA:
-              {
-                lib3ds_chunk_read_reset(&c, strm);
-                if (!kfdata_read(file, strm)) {
-                  return(LIB3DS_FALSE);
-                }
-              }
-              break;
-            default:
-              lib3ds_chunk_unknown(chunk);
-          }
-        }
-      }
-      break;
-    default:
-      lib3ds_chunk_unknown(c.chunk);
-      return(LIB3DS_FALSE);
-  }
-
-  lib3ds_chunk_read_end(&c, strm);
-  return(LIB3DS_TRUE);
-}
-
-
-static Lib3dsBool
-colorf_write(Lib3dsRgba rgb, iostream *strm)
-{
-  Lib3dsChunk c;
-
-  c.chunk=LIB3DS_COLOR_F;
-  c.size=18;
-  lib3ds_chunk_write(&c,strm);
-  lib3ds_rgb_write(rgb,strm);
-
-  c.chunk=LIB3DS_LIN_COLOR_F;
-  c.size=18;
-  lib3ds_chunk_write(&c,strm);
-  lib3ds_rgb_write(rgb,strm);
-  return(LIB3DS_TRUE);
-}
-
-
-static Lib3dsBool
-mdata_write(Lib3dsFile *file, iostream *strm)
-{
-  Lib3dsChunk c;
-
-  c.chunk=LIB3DS_MDATA;
-  if (!lib3ds_chunk_write_start(&c,strm)) {
-    return(LIB3DS_FALSE);
-  }
-
-  { /*---- LIB3DS_MESH_VERSION ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_MESH_VERSION;
-    c.size=10;
-    lib3ds_chunk_write(&c,strm);
-    lib3ds_intd_write(file->mesh_version,strm);
-  }
-  { /*---- LIB3DS_MASTER_SCALE ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_MASTER_SCALE;
-    c.size=10;
-    lib3ds_chunk_write(&c,strm);
-    lib3ds_float_write(file->master_scale,strm);
-  }
-  { /*---- LIB3DS_O_CONSTS ----*/
-    int i;
-    for (i=0; i<3; ++i) {
-      if (fabs(file->construction_plane[i])>LIB3DS_EPSILON) {
-        break;
-      }
-    }
-    if (i<3) {
-      Lib3dsChunk c;
-      c.chunk=LIB3DS_O_CONSTS;
-      c.size=18;
-      lib3ds_chunk_write(&c,strm);
-      lib3ds_vector_write(file->construction_plane,strm);
-    }
-  }
-  
-  { /*---- LIB3DS_AMBIENT_LIGHT ----*/
-    int i;
-    for (i=0; i<3; ++i) {
-      if (fabs(file->ambient[i])>LIB3DS_EPSILON) {
-        break;
-      }
-    }
-    if (i<3) {
-      Lib3dsChunk c;
-      c.chunk=LIB3DS_AMBIENT_LIGHT;
-      c.size=42;
-      lib3ds_chunk_write(&c,strm);
-      colorf_write(file->ambient,strm);
-    }
-  }
-  lib3ds_background_write(&file->background, strm);
-  lib3ds_atmosphere_write(&file->atmosphere, strm);
-  lib3ds_shadow_write(&file->shadow, strm);
-  lib3ds_viewport_write(&file->viewport, strm);
-  {
-    Lib3dsMaterial *p;
-    for (p=file->materials; p!=0; p=p->next) {
-      if (!lib3ds_material_write(p,strm)) {
-        return(LIB3DS_FALSE);
-      }
-    }
-  }
-  {
-    Lib3dsCamera *p;
-    Lib3dsChunk c;
-    
-    for (p=file->cameras; p!=0; p=p->next) {
-      c.chunk=LIB3DS_NAMED_OBJECT;
-      if (!lib3ds_chunk_write_start(&c,strm)) {
-        return(LIB3DS_FALSE);
-      }
-      lib3ds_string_write(p->name,strm);
-      lib3ds_camera_write(p,strm);
-      if (!lib3ds_chunk_write_end(&c,strm)) {
-        return(LIB3DS_FALSE);
-      }
-    }
-  }
-  {
-    Lib3dsLight *p;
-    Lib3dsChunk c;
-    
-    for (p=file->lights; p!=0; p=p->next) {
-      c.chunk=LIB3DS_NAMED_OBJECT;
-      if (!lib3ds_chunk_write_start(&c,strm)) {
-        return(LIB3DS_FALSE);
-      }
-      lib3ds_string_write(p->name,strm);
-      lib3ds_light_write(p,strm);
-      if (!lib3ds_chunk_write_end(&c,strm)) {
-        return(LIB3DS_FALSE);
-      }
-    }
-  }
-  {
-    Lib3dsMesh *p;
-    Lib3dsChunk c;
-    
-    for (p=file->meshes; p!=0; p=p->next) {
-      c.chunk=LIB3DS_NAMED_OBJECT;
-      if (!lib3ds_chunk_write_start(&c,strm)) {
-        return(LIB3DS_FALSE);
-      }
-      lib3ds_string_write(p->name,strm);
-      lib3ds_mesh_write(p,strm);
-      if (!lib3ds_chunk_write_end(&c,strm)) {
-        return(LIB3DS_FALSE);
-      }
-    }
-  }
-
-  if (!lib3ds_chunk_write_end(&c,strm)) {
-    return(LIB3DS_FALSE);
-  }
-  return(LIB3DS_TRUE);
-}
-
-
-
-static Lib3dsBool
-nodes_write(Lib3dsNode *node, Lib3dsFile *file, iostream *strm)
-{
-  {
-    Lib3dsNode *p;
-    for (p=node->childs; p!=0; p=p->next) {
-      if (!lib3ds_node_write(p, file, strm)) {
-        return(LIB3DS_FALSE);
-      }
-      nodes_write(p, file, strm);
-    }
-  }
-  return(LIB3DS_TRUE);
-}
-
-
-static Lib3dsBool
-kfdata_write(Lib3dsFile *file, iostream *strm)
-{
-  Lib3dsChunk c;
-  
-  c.chunk=LIB3DS_KFDATA;
-  if (!lib3ds_chunk_write_start(&c,strm)) {
-    return(LIB3DS_FALSE);
-  }
-  
-  { /*---- LIB3DS_KFHDR ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_KFHDR;
-    c.size=6 + 2 + strlen(file->name)+1 +4;
-    lib3ds_chunk_write(&c,strm);
-    lib3ds_intw_write(file->keyf_revision,strm);
-    lib3ds_string_write(file->name, strm);
-    lib3ds_intd_write(file->frames, strm);
-  }
-  { /*---- LIB3DS_KFSEG ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_KFSEG;
-    c.size=14;
-    lib3ds_chunk_write(&c,strm);
-    lib3ds_intd_write(file->segment_from,strm);
-    lib3ds_intd_write(file->segment_to,strm);
-  }
-  { /*---- LIB3DS_KFCURTIME ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_KFCURTIME;
-    c.size=10;
-    lib3ds_chunk_write(&c,strm);
-    lib3ds_intd_write(file->current_frame,strm);
-  }
-  lib3ds_viewport_write(&file->viewport_keyf, strm);
-  
-  {
-    Lib3dsNode *p;
-    for (p=file->nodes; p!=0; p=p->next) {
-      if (!lib3ds_node_write(p, file, strm)) {
-        return(LIB3DS_FALSE);
-      }
-      if (!nodes_write(p, file, strm)) {
-        return(LIB3DS_FALSE);
-      }
-    }
-  }
-  
-  if (!lib3ds_chunk_write_end(&c,strm)) {
-    return(LIB3DS_FALSE);
-  }
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
- * \ingroup file
- */
-Lib3dsBool
-lib3ds_file_write(Lib3dsFile *file, iostream *strm)
-{
-  Lib3dsChunk c;
-
-  c.chunk=LIB3DS_M3DMAGIC;
-  if (!lib3ds_chunk_write_start(&c,strm)) {
-    LIB3DS_ERROR_LOG;
-    return(LIB3DS_FALSE);
-  }
-
-  { /*---- LIB3DS_M3D_VERSION ----*/
-    Lib3dsChunk c;
-
-    c.chunk=LIB3DS_M3D_VERSION;
-    c.size=10;
-    lib3ds_chunk_write(&c,strm);
-    lib3ds_dword_write(file->mesh_version, strm);
-  }
-
-  if (!mdata_write(file, strm)) {
-    return(LIB3DS_FALSE);
-  }
-  if (!kfdata_write(file, strm)) {
-    return(LIB3DS_FALSE);
-  }
-
-  if (!lib3ds_chunk_write_end(&c,strm)) {
-    return(LIB3DS_FALSE);
-  }
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
- * \ingroup file
- */
-void
-lib3ds_file_insert_material(Lib3dsFile *file, Lib3dsMaterial *material)
-{
-  Lib3dsMaterial *p,*q;
-  
-  ASSERT(file);
-  ASSERT(material);
-  ASSERT(!material->next);
-
-  q=0;
-  for (p=file->materials; p!=0; p=p->next) {
-    if (strcmp(material->name, p->name)<0) {
-      break;
-    }
-    q=p;
-  }
-  if (!q) {
-    material->next=file->materials;
-    file->materials=material;
-  }
-  else {
-    material->next=q->next;
-    q->next=material;
-  }
-}
-
-
-/*!
- * \ingroup file
- */
-void
-lib3ds_file_remove_material(Lib3dsFile *file, Lib3dsMaterial *material)
-{
-  Lib3dsMaterial *p,*q;
-
-  ASSERT(file);
-  ASSERT(material);
-  ASSERT(file->materials);
-  for (p=0,q=file->materials; q; p=q,q=q->next) {
-    if (q==material) {
-      break;
-    }
-  }
-  if (!q) {
-    ASSERT(LIB3DS_FALSE);
-    return;
-  }
-  if (!p) {
-    file->materials=material->next;
-  }
-  else {
-    p->next=q->next;
-  }
-  material->next=0;
-}
-
-
-/*!
- * \ingroup file
- */
-Lib3dsMaterial*
-lib3ds_file_material_by_name(Lib3dsFile *file, const char *name)
-{
-  Lib3dsMaterial *p;
-
-  ASSERT(file);
-  for (p=file->materials; p!=0; p=p->next) {
-    if (strcmp(p->name,name)==0) {
-      return(p);
-    }
-  }
-  return(0);
-}
-
-
-/*!
- * \ingroup file
- */
-void
-lib3ds_file_dump_materials(Lib3dsFile *file)
-{
-  Lib3dsMaterial *p;
-
-  ASSERT(file);
-  for (p=file->materials; p!=0; p=p->next) {
-    lib3ds_material_dump(p);
-  }
-}
-
-
-/*!
- * \ingroup file
- */
-void
-lib3ds_file_insert_mesh(Lib3dsFile *file, Lib3dsMesh *mesh)
-{
-  Lib3dsMesh *p,*q;
-  
-  ASSERT(file);
-  ASSERT(mesh);
-  ASSERT(!mesh->next);
-
-  q=0;
-  for (p=file->meshes; p!=0; p=p->next) {
-    if (strcmp(mesh->name, p->name)<0) {
-      break;
-    }
-    q=p;
-  }
-  if (!q) {
-    mesh->next=file->meshes;
-    file->meshes=mesh;
-  }
-  else {
-    mesh->next=q->next;
-    q->next=mesh;
-  }
-}
-
-
-/*!
- * \ingroup file
- */
-void
-lib3ds_file_remove_mesh(Lib3dsFile *file, Lib3dsMesh *mesh)
-{
-  Lib3dsMesh *p,*q;
-
-  ASSERT(file);
-  ASSERT(mesh);
-  ASSERT(file->meshes);
-  for (p=0,q=file->meshes; q; p=q,q=q->next) {
-    if (q==mesh) {
-      break;
-    }
-  }
-  if (!q) {
-    ASSERT(LIB3DS_FALSE);
-    return;
-  }
-  if (!p) {
-    file->meshes=mesh->next;
-  }
-  else {
-    p->next=q->next;
-  }
-  mesh->next=0;
-}
-
-
-/*!
- * \ingroup file
- */
-Lib3dsMesh*
-lib3ds_file_mesh_by_name(Lib3dsFile *file, const char *name)
-{
-  Lib3dsMesh *p;
-
-  ASSERT(file);
-  for (p=file->meshes; p!=0; p=p->next) {
-    if (strcmp(p->name,name)==0) {
-      return(p);
-    }
-  }
-  return(0);
-}
-
-
-/*!
- * \ingroup file
- */
-void
-lib3ds_file_dump_meshes(Lib3dsFile *file)
-{
-  Lib3dsMesh *p;
-
-  ASSERT(file);
-  for (p=file->meshes; p!=0; p=p->next) {
-    lib3ds_mesh_dump(p);
-  }
-}
-
-
-static void
-dump_instances(Lib3dsNode *node, const char* parent)
-{
-  Lib3dsNode *p;
-  char name[255];
-
-  ASSERT(node);
-  ASSERT(parent);
-  strcpy(name, parent);
-  strcat(name, ".");
-  strcat(name, node->name);
-  if (node->type==LIB3DS_OBJECT_NODE) {
-    printf("  %s : %s\n", name, node->data.object.instance);
-  }
-  for (p=node->childs; p!=0; p=p->next) {
-    dump_instances(p, parent);
-  }
-}
-
-
-/*!
- * \ingroup file
- */
-void
-lib3ds_file_dump_instances(Lib3dsFile *file)
-{
-  Lib3dsNode *p;
-
-  ASSERT(file);
-  for (p=file->nodes; p!=0; p=p->next) {
-    dump_instances(p,"");
-  }
-}
-
-
-/*!
- * \ingroup file
- */
-void
-lib3ds_file_insert_camera(Lib3dsFile *file, Lib3dsCamera *camera)
-{
-  Lib3dsCamera *p,*q;
-  
-  ASSERT(file);
-  ASSERT(camera);
-  ASSERT(!camera->next);
-
-  q=0;
-  for (p=file->cameras; p!=0; p=p->next) {
-    if (strcmp(camera->name, p->name)<0) {
-      break;
-    }
-    q=p;
-  }
-  if (!q) {
-    camera->next=file->cameras;
-    file->cameras=camera;
-  }
-  else {
-    camera->next=q->next;
-    q->next=camera;
-  }
-}
-
-
-/*!
- * \ingroup file
- */
-void
-lib3ds_file_remove_camera(Lib3dsFile *file, Lib3dsCamera *camera)
-{
-  Lib3dsCamera *p,*q;
-
-  ASSERT(file);
-  ASSERT(camera);
-  ASSERT(file->cameras);
-  for (p=0,q=file->cameras; q; p=q,q=q->next) {
-    if (q==camera) {
-      break;
-    }
-  }
-  if (!q) {
-    ASSERT(LIB3DS_FALSE);
-    return;
-  }
-  if (!p) {
-    file->cameras=camera->next;
-  }
-  else {
-    p->next=q->next;
-  }
-  camera->next=0;
-}
-
-
-/*!
- * \ingroup file
- */
-Lib3dsCamera*
-lib3ds_file_camera_by_name(Lib3dsFile *file, const char *name)
-{
-  Lib3dsCamera *p;
-
-  ASSERT(file);
-  for (p=file->cameras; p!=0; p=p->next) {
-    if (strcmp(p->name,name)==0) {
-      return(p);
-    }
-  }
-  return(0);
-}
-
-
-/*!
- * \ingroup file
- */
-void
-lib3ds_file_dump_cameras(Lib3dsFile *file)
-{
-  Lib3dsCamera *p;
-
-  ASSERT(file);
-  for (p=file->cameras; p!=0; p=p->next) {
-    lib3ds_camera_dump(p);
-  }
-}
-
-
-/*!
- * \ingroup file
- */
-void
-lib3ds_file_insert_light(Lib3dsFile *file, Lib3dsLight *light)
-{
-  Lib3dsLight *p,*q;
-  
-  ASSERT(file);
-  ASSERT(light);
-  ASSERT(!light->next);
-
-  q=0;
-  for (p=file->lights; p!=0; p=p->next) {
-    if (strcmp(light->name, p->name)<0) {
-      break;
-    }
-    q=p;
-  }
-  if (!q) {
-    light->next=file->lights;
-    file->lights=light;
-  }
-  else {
-    light->next=q->next;
-    q->next=light;
-  }
-}
-
-
-/*!
- * \ingroup file
- */
-void
-lib3ds_file_remove_light(Lib3dsFile *file, Lib3dsLight *light)
-{
-  Lib3dsLight *p,*q;
-
-  ASSERT(file);
-  ASSERT(light);
-  ASSERT(file->lights);
-  for (p=0,q=file->lights; q; p=q,q=q->next) {
-    if (q==light) {
-      break;
-    }
-  }
-  if (!q) {
-    ASSERT(LIB3DS_FALSE);
-    return;
-  }
-  if (!p) {
-    file->lights=light->next;
-  }
-  else {
-    p->next=q->next;
-  }
-  light->next=0;
-}
-
-
-/*!
- * \ingroup file
- */
-Lib3dsLight*
-lib3ds_file_light_by_name(Lib3dsFile *file, const char *name)
-{
-  Lib3dsLight *p;
-
-  ASSERT(file);
-  for (p=file->lights; p!=0; p=p->next) {
-    if (strcmp(p->name,name)==0) {
-      return(p);
-    }
-  }
-  return(0);
-}
-
-
-/*!
- * \ingroup file
- */
-void
-lib3ds_file_dump_lights(Lib3dsFile *file)
-{
-  Lib3dsLight *p;
-
-  ASSERT(file);
-  for (p=file->lights; p!=0; p=p->next) {
-    lib3ds_light_dump(p);
-  }
-}
-
-
-/*!
- * \ingroup file
- */
-void
-lib3ds_file_bounding_box(Lib3dsFile *file, Lib3dsVector min, Lib3dsVector max)
-{
-  Lib3dsBool init=LIB3DS_FALSE;
-
-  {
-    Lib3dsVector lmin, lmax;
-    Lib3dsMesh *p=file->meshes;
-
-    if (!init && p) {
-      init = LIB3DS_TRUE;
-      lib3ds_mesh_bounding_box(p, min, max);
-      p = p->next;  
-    }
-    while (p) {
-      lib3ds_mesh_bounding_box(p, lmin, lmax);
-      lib3ds_vector_min(min, lmin);
-      lib3ds_vector_max(max, lmax);
-      p=p->next;
-    }
-  }
-  {
-    Lib3dsCamera *p=file->cameras;
-    if (!init && p) {
-      init = LIB3DS_TRUE;
-      lib3ds_vector_copy(min, p->position);
-      lib3ds_vector_copy(max, p->position);
-    }
-
-    while (p) {
-      lib3ds_vector_min(min, p->position);
-      lib3ds_vector_max(max, p->position);
-      lib3ds_vector_min(min, p->target);
-      lib3ds_vector_max(max, p->target);
-      p=p->next;
-    }
-  }
-  {
-    Lib3dsLight *p=file->lights;
-    if (!init && p) {
-      init = LIB3DS_TRUE;
-      lib3ds_vector_copy(min, p->position);
-      lib3ds_vector_copy(max, p->position);
-    }
-
-    while (p) {
-      lib3ds_vector_min(min, p->position);
-      lib3ds_vector_max(max, p->position);
-      if (p->spot_light) {
-        lib3ds_vector_min(min, p->spot);
-        lib3ds_vector_max(max, p->spot);
-      }
-      p=p->next;
-    }
-  }
-}  
-
-
-/*!
- * \ingroup file
- */
-Lib3dsNode*
-lib3ds_file_node_by_name(Lib3dsFile *file, const char* name, Lib3dsNodeTypes type)
-{
-  Lib3dsNode *p,*q;
-
-  ASSERT(file);
-  for (p=file->nodes; p!=0; p=p->next) {
-    if ((p->type==type) && (strcmp(p->name, name)==0)) {
-      return(p);
-    }
-    q=lib3ds_node_by_name(p, name, type);
-    if (q) {
-      return(q);
-    }
-  }
-  return(0);
-}
-
-
-/*!
- * \ingroup file
- */
-Lib3dsNode*
-lib3ds_file_node_by_id(Lib3dsFile *file, Lib3dsWord node_id)
-{
-  Lib3dsNode *p,*q;
-
-  ASSERT(file);
-  for (p=file->nodes; p!=0; p=p->next) {
-    if (p->node_id==node_id) {
-      return(p);
-    }
-    q=lib3ds_node_by_id(p, node_id);
-    if (q) {
-      return(q);
-    }
-  }
-  return(0);
-}
-
-
-/*!
- * \ingroup file
- */
-void
-lib3ds_file_insert_node(Lib3dsFile *file, Lib3dsNode *node)
-{
-  Lib3dsNode *parent,*p,*n;
-  
-  ASSERT(node);
-  ASSERT(!node->next);
-  ASSERT(!node->parent);
-
-  parent=0;
-  if (node->parent_id!=LIB3DS_NO_PARENT) {
-    parent=lib3ds_file_node_by_id(file, node->parent_id);
-  }
-  node->parent=parent;
-  
-  if (!parent) {
-    for (p=0,n=file->nodes; n!=0; p=n,n=n->next) {
-      if (strcmp(n->name, node->name)>0) {
-        break;
-      }
-    }
-    if (!p) {
-      node->next=file->nodes;
-      file->nodes=node;
-    }
-    else {
-      node->next=p->next;
-      p->next=node;
-    }
-  }
-  else {
-    for (p=0,n=parent->childs; n!=0; p=n,n=n->next) {
-      if (strcmp(n->name, node->name)>0) {
-        break;
-      }
-    }
-    if (!p) {
-      node->next=parent->childs;
-      parent->childs=node;
-    }
-    else {
-      node->next=p->next;
-      p->next=node;
-    }
-  }
-
-  if (node->node_id!=LIB3DS_NO_PARENT) {
-    for (n=file->nodes; n!=0; n=p) {
-      p=n->next;
-      if (n->parent_id==node->node_id) {
-        lib3ds_file_remove_node(file, n);
-        lib3ds_file_insert_node(file, n);
-      }
-    }
-  }
-}
-
-
-/*!
- * \ingroup file
- */
-Lib3dsBool
-lib3ds_file_remove_node(Lib3dsFile *file, Lib3dsNode *node)
-{
-  Lib3dsNode *p,*n;
-
-  if (node->parent) {
-    for (p=0,n=node->parent->childs; n; p=n,n=n->next) {
-      if (n==node) {
-        break;
-      }
-    }
-    if (!n) {
-      return(LIB3DS_FALSE);
-    }
-    
-    if (!p) {
-      node->parent->childs=n->next;
-    }
-    else {
-      p->next=n->next;
-    }
-  }
-  else {
-    for (p=0,n=file->nodes; n; p=n,n=n->next) {
-      if (n==node) {
-        break;
-      }
-    }
-    if (!n) {
-      return(LIB3DS_FALSE);
-    }
-    
-    if (!p) {
-      file->nodes=n->next;
-    }
-    else {
-      p->next=n->next;
-    }
-  }
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
- * \ingroup file
- */
-void
-lib3ds_file_dump_nodes(Lib3dsFile *file)
-{
-  Lib3dsNode *p;
-
-  ASSERT(file);
-  for (p=file->nodes; p!=0; p=p->next) {
-    lib3ds_node_dump(p,1);
-  }
-}
-
-
-/*!
-
-\typedef Lib3dsFile
-  \ingroup file
-  \sa _Lib3dsFile
-
-*/
Index: /enSceneGraph/trunk/src/osgPlugins/3ds/viewport.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/viewport.cpp (revision 10076)
+++  (revision )
@@ -1,367 +1,0 @@
-/*
- * The 3D Studio File Format Library
- * Copyright (C) 1996-2001 by J.E. Hoffmann <je-h@gmx.net>
- * All rights reserved.
- *
- * This program is  free  software;  you can redistribute it and/or modify it
- * under the terms of the  GNU Lesser General Public License  as published by 
- * the  Free Software Foundation;  either version 2.1 of the License,  or (at 
- * your option) any later version.
- *
- * This  program  is  distributed in  the  hope that it will  be useful,  but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or  FITNESS FOR A  PARTICULAR PURPOSE.  See the  GNU Lesser General Public  
- * License for more details.
- *
- * You should  have received  a copy of the GNU Lesser General Public License
- * along with  this program;  if not, write to the  Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id$
- */
-#define LIB3DS_EXPORT
-#include "viewport.h"
-#include "chunk.h"
-#include "readwrite.h"
-#include <stdlib.h>
-#include <string.h>
-
-
-/*!
- * \defgroup viewport Viewport and default view settings
- *
- * \author J.E. Hoffmann <je-h@gmx.net>
- */
-
-
-/*!
- * \ingroup viewport 
- */
-Lib3dsBool
-lib3ds_viewport_read(Lib3dsViewport *viewport, iostream *strm)
-{
-  Lib3dsChunk c;
-  Lib3dsWord chunk;
-
-  if (!lib3ds_chunk_read_start(&c, 0, strm)) {
-    return(LIB3DS_FALSE);
-  }
-  
-  switch (c.chunk) {
-    case LIB3DS_VIEWPORT_LAYOUT:
-      {
-        int cur=0;
-        viewport->layout.style=lib3ds_word_read(strm);
-        viewport->layout.active=lib3ds_intw_read(strm);
-        lib3ds_intw_read(strm);
-        viewport->layout.swap=lib3ds_intw_read(strm);
-        lib3ds_intw_read(strm);
-        viewport->layout.swap_prior=lib3ds_intw_read(strm);
-        viewport->layout.swap_view=lib3ds_intw_read(strm);
-        lib3ds_chunk_read_tell(&c, strm);
-        while ((chunk=lib3ds_chunk_read_next(&c, strm))!=0) {
-          switch (chunk) {
-            case LIB3DS_VIEWPORT_SIZE:
-              {
-                viewport->layout.position[0]=lib3ds_word_read(strm);
-                viewport->layout.position[1]=lib3ds_word_read(strm);
-                viewport->layout.size[0]=lib3ds_word_read(strm);
-                viewport->layout.size[1]=lib3ds_word_read(strm);
-              }
-              break;
-            case LIB3DS_VIEWPORT_DATA_3:
-              {
-                lib3ds_viewport_set_views(viewport,cur+1);
-                lib3ds_intw_read(strm);
-                viewport->layout.viewL[cur].axis_lock=lib3ds_word_read(strm);
-                viewport->layout.viewL[cur].position[0]=lib3ds_intw_read(strm);
-                viewport->layout.viewL[cur].position[1]=lib3ds_intw_read(strm);
-                viewport->layout.viewL[cur].size[0]=lib3ds_intw_read(strm);
-                viewport->layout.viewL[cur].size[1]=lib3ds_intw_read(strm);
-                viewport->layout.viewL[cur].type=lib3ds_word_read(strm);
-                viewport->layout.viewL[cur].zoom=lib3ds_float_read(strm);
-                lib3ds_vector_read(viewport->layout.viewL[cur].center,strm);
-                viewport->layout.viewL[cur].horiz_angle=lib3ds_float_read(strm);
-                viewport->layout.viewL[cur].vert_angle=lib3ds_float_read(strm);
-                strm->read(viewport->layout.viewL[cur].camera,11);
-                ++cur;
-              }
-              break;
-            case LIB3DS_VIEWPORT_DATA:
-              /* 3DS R2 & R3 chunk
-                 unsupported */
-              break;
-            default:
-              lib3ds_chunk_unknown(chunk);
-          }
-        }
-      }
-      break;
-    case LIB3DS_DEFAULT_VIEW:
-      {
-        memset(&viewport->default_view,0,sizeof(Lib3dsDefaultView));
-        while ((chunk=lib3ds_chunk_read_next(&c, strm))!=0) {
-          switch (chunk) {
-            case LIB3DS_VIEW_TOP:
-              {
-                viewport->default_view.type=LIB3DS_VIEW_TYPE_TOP;
-                lib3ds_vector_read(viewport->default_view.position,strm);
-                viewport->default_view.width=lib3ds_float_read(strm);
-              }
-              break;
-            case LIB3DS_VIEW_BOTTOM:
-              {
-                viewport->default_view.type=LIB3DS_VIEW_TYPE_BOTTOM;
-                lib3ds_vector_read(viewport->default_view.position,strm);
-                viewport->default_view.width=lib3ds_float_read(strm);
-              }
-              break;
-            case LIB3DS_VIEW_LEFT:
-              {
-                viewport->default_view.type=LIB3DS_VIEW_TYPE_LEFT;
-                lib3ds_vector_read(viewport->default_view.position,strm);
-                viewport->default_view.width=lib3ds_float_read(strm);
-              }
-              break;
-            case LIB3DS_VIEW_RIGHT:
-              {
-                viewport->default_view.type=LIB3DS_VIEW_TYPE_RIGHT;
-                lib3ds_vector_read(viewport->default_view.position,strm);
-                viewport->default_view.width=lib3ds_float_read(strm);
-              }
-              break;
-            case LIB3DS_VIEW_FRONT:
-              {
-                viewport->default_view.type=LIB3DS_VIEW_TYPE_FRONT;
-                lib3ds_vector_read(viewport->default_view.position,strm);
-                viewport->default_view.width=lib3ds_float_read(strm);
-              }
-              break;
-            case LIB3DS_VIEW_BACK:
-              {
-                viewport->default_view.type=LIB3DS_VIEW_TYPE_BACK;
-                lib3ds_vector_read(viewport->default_view.position,strm);
-                viewport->default_view.width=lib3ds_float_read(strm);
-              }
-              break;
-            case LIB3DS_VIEW_USER:
-              {
-                viewport->default_view.type=LIB3DS_VIEW_TYPE_USER;
-                lib3ds_vector_read(viewport->default_view.position,strm);
-                viewport->default_view.width=lib3ds_float_read(strm);
-                viewport->default_view.horiz_angle=lib3ds_float_read(strm);
-                viewport->default_view.vert_angle=lib3ds_float_read(strm);
-                viewport->default_view.roll_angle=lib3ds_float_read(strm);
-              }
-              break;
-            case LIB3DS_VIEW_CAMERA:
-              {
-                viewport->default_view.type=LIB3DS_VIEW_TYPE_CAMERA;
-                strm->read(viewport->default_view.camera,11);
-              }
-              break;
-            default:
-              lib3ds_chunk_unknown(chunk);
-          }
-        }
-      }
-      break;
-  }
-
-  lib3ds_chunk_read_end(&c, strm);
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
- * \ingroup viewport 
- */
-void
-lib3ds_viewport_set_views(Lib3dsViewport *viewport, Lib3dsDword views)
-{
-  ASSERT(viewport);
-  if (viewport->layout.views) {
-    if (views) {
-      viewport->layout.views=views;
-      viewport->layout.viewL=(Lib3dsView*)realloc(viewport->layout.viewL, sizeof(Lib3dsView)*views);
-    }
-    else {
-      free(viewport->layout.viewL);
-      viewport->layout.views=0;
-      viewport->layout.viewL=0;
-    }
-  }
-  else {
-    viewport->layout.views=views;
-    viewport->layout.viewL= views ? (Lib3dsView*)calloc(sizeof(Lib3dsView),views) : 0;
-  }
-}
-
-
-/*!
- * \ingroup viewport 
- */
-Lib3dsBool
-lib3ds_viewport_write(Lib3dsViewport *viewport, iostream *strm)
-{
-  if (viewport->layout.views) {
-    Lib3dsChunk c;
-    unsigned i;
-
-    c.chunk=LIB3DS_VIEWPORT_LAYOUT;
-    if (!lib3ds_chunk_write_start(&c,strm)) {
-      return(LIB3DS_FALSE);
-    }
-
-    lib3ds_word_write(viewport->layout.style,strm);
-    lib3ds_intw_write(viewport->layout.active,strm);
-    lib3ds_intw_write(0,strm);
-    lib3ds_intw_write(viewport->layout.swap,strm);
-    lib3ds_intw_write(0,strm);
-    lib3ds_intw_write(viewport->layout.swap_prior,strm);
-    lib3ds_intw_write(viewport->layout.swap_view,strm);
-    
-    {
-      Lib3dsChunk c;
-      c.chunk=LIB3DS_VIEWPORT_SIZE;
-      c.size=14;
-      lib3ds_chunk_write(&c,strm);
-      lib3ds_intw_write(viewport->layout.position[0],strm);
-      lib3ds_intw_write(viewport->layout.position[1],strm);
-      lib3ds_intw_write(viewport->layout.size[0],strm);
-      lib3ds_intw_write(viewport->layout.size[1],strm);
-    }
-
-    for (i=0; i<viewport->layout.views; ++i) {
-      Lib3dsChunk c;
-      c.chunk=LIB3DS_VIEWPORT_DATA_3;
-      c.size=55;
-      lib3ds_chunk_write(&c,strm);
-
-      lib3ds_intw_write(0,strm);
-      lib3ds_word_write(viewport->layout.viewL[i].axis_lock,strm);
-      lib3ds_intw_write(viewport->layout.viewL[i].position[0],strm);
-      lib3ds_intw_write(viewport->layout.viewL[i].position[1],strm);
-      lib3ds_intw_write(viewport->layout.viewL[i].size[0],strm);
-      lib3ds_intw_write(viewport->layout.viewL[i].size[1],strm);
-      lib3ds_word_write(viewport->layout.viewL[i].type,strm);
-      lib3ds_float_write(viewport->layout.viewL[i].zoom,strm);
-      lib3ds_vector_write(viewport->layout.viewL[i].center,strm);
-      lib3ds_float_write(viewport->layout.viewL[i].horiz_angle,strm);
-      lib3ds_float_write(viewport->layout.viewL[i].vert_angle,strm);
-      strm->write(viewport->layout.viewL[i].camera,11);
-    }
-
-    if (!lib3ds_chunk_write_end(&c,strm)) {
-      return(LIB3DS_FALSE);
-    }
-  }
-
-  if (viewport->default_view.type) {
-    Lib3dsChunk c;
-
-    c.chunk=LIB3DS_DEFAULT_VIEW;
-    if (!lib3ds_chunk_write_start(&c,strm)) {
-      return(LIB3DS_FALSE);
-    }
-
-    switch (viewport->default_view.type) {
-      case LIB3DS_VIEW_TYPE_TOP:
-        {
-          Lib3dsChunk c;
-          c.chunk=LIB3DS_VIEW_TOP;
-          c.size=22;
-          lib3ds_chunk_write(&c,strm);
-          lib3ds_vector_write(viewport->default_view.position,strm);
-          lib3ds_float_write(viewport->default_view.width,strm);
-        }
-        break;
-      case LIB3DS_VIEW_TYPE_BOTTOM:
-        {
-          Lib3dsChunk c;
-          c.chunk=LIB3DS_VIEW_BOTTOM;
-          c.size=22;
-          lib3ds_chunk_write(&c,strm);
-          lib3ds_vector_write(viewport->default_view.position,strm);
-          lib3ds_float_write(viewport->default_view.width,strm);
-        }
-        break;
-      case LIB3DS_VIEW_TYPE_LEFT:
-        {
-          Lib3dsChunk c;
-          c.chunk=LIB3DS_VIEW_LEFT;
-          c.size=22;
-          lib3ds_chunk_write(&c,strm);
-          lib3ds_vector_write(viewport->default_view.position,strm);
-          lib3ds_float_write(viewport->default_view.width,strm);
-        }
-        break;
-      case LIB3DS_VIEW_TYPE_RIGHT:
-        {
-          Lib3dsChunk c;
-          c.chunk=LIB3DS_VIEW_RIGHT;
-          c.size=22;
-          lib3ds_chunk_write(&c,strm);
-          lib3ds_vector_write(viewport->default_view.position,strm);
-          lib3ds_float_write(viewport->default_view.width,strm);
-        }
-        break;
-      case LIB3DS_VIEW_TYPE_FRONT:
-        {
-          Lib3dsChunk c;
-          c.chunk=LIB3DS_VIEW_FRONT;
-          c.size=22;
-          lib3ds_chunk_write(&c,strm);
-          lib3ds_vector_write(viewport->default_view.position,strm);
-          lib3ds_float_write(viewport->default_view.width,strm);
-        }
-        break;
-      case LIB3DS_VIEW_TYPE_BACK:
-        {
-          Lib3dsChunk c;
-          c.chunk=LIB3DS_VIEW_BACK;
-          c.size=22;
-          lib3ds_chunk_write(&c,strm);
-          lib3ds_vector_write(viewport->default_view.position,strm);
-          lib3ds_float_write(viewport->default_view.width,strm);
-        }
-        break;
-      case LIB3DS_VIEW_TYPE_USER:
-        {
-          Lib3dsChunk c;
-          c.chunk=LIB3DS_VIEW_USER;
-          c.size=34;
-          lib3ds_chunk_write(&c,strm);
-          lib3ds_vector_write(viewport->default_view.position,strm);
-          lib3ds_float_write(viewport->default_view.width,strm);
-          lib3ds_float_write(viewport->default_view.horiz_angle,strm);
-          lib3ds_float_write(viewport->default_view.vert_angle,strm);
-          lib3ds_float_write(viewport->default_view.roll_angle,strm);
-        }
-        break;
-      case LIB3DS_VIEW_TYPE_CAMERA:
-        {
-          Lib3dsChunk c;
-          c.chunk=LIB3DS_VIEW_CAMERA;
-          c.size=17;
-          lib3ds_chunk_write(&c,strm);
-          strm->write(viewport->default_view.camera,11); // NAH Potential issue here
-        }
-        break;
-    }
-
-    if (!lib3ds_chunk_write_end(&c,strm)) {
-      return(LIB3DS_FALSE);
-    }
-  }
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
-
-\typedef Lib3dsViewport
-  \ingroup viewport
-  \sa _Lib3dsViewport
-
-*/
Index: /enSceneGraph/trunk/src/osgPlugins/3ds/background.h
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/background.h (revision 10076)
+++  (revision )
@@ -1,88 +1,0 @@
-/* -*- c -*- */
-#ifndef INCLUDED_LIB3DS_BACKGROUND_H
-#define INCLUDED_LIB3DS_BACKGROUND_H
-/*
- * The 3D Studio File Format Library
- * Copyright (C) 1996-2001 by J.E. Hoffmann <je-h@gmx.net>
- * All rights reserved.
- *
- * This program is  free  software;  you can redistribute it and/or modify it
- * under the terms of the  GNU Lesser General Public License  as published by 
- * the  Free Software Foundation;  either version 2.1 of the License,  or (at 
- * your option) any later version.
- *
- * This  program  is  distributed in  the  hope that it will  be useful,  but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or  FITNESS FOR A  PARTICULAR PURPOSE.  See the  GNU Lesser General Public  
- * License for more details.
- *
- * You should  have received  a copy of the GNU Lesser General Public License
- * along with  this program;  if not, write to the  Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id$
- */
-
-#ifndef INCLUDED_LIB3DS_TYPES_H
-#include "types.h"
-#endif
-
-#include <iostream>
-using namespace std;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*!
- * Bitmap background settings
- * \ingroup background
- */
-typedef struct _Lib3dsBitmap {
-    Lib3dsBool use;
-    char name[64];
-} Lib3dsBitmap;
-
-/*!
- * Solid color background settings
- * \ingroup background
- */
-typedef struct _Lib3dsSolid {
-    Lib3dsBool use;
-    Lib3dsRgb col;
-} Lib3dsSolid;
-
-/*!
- * Gradient background settings
- * \ingroup background
- */
-typedef struct _Lib3dsGradient {
-    Lib3dsBool use;
-    Lib3dsFloat percent;
-    Lib3dsRgb top;
-    Lib3dsRgb middle;
-    Lib3dsRgb bottom;
-} Lib3dsGradient;
-
-/*!
- * Background settings
- * \ingroup background
- */
-struct _Lib3dsBackground {
-    Lib3dsBitmap bitmap;
-    Lib3dsSolid solid;
-    Lib3dsGradient gradient;
-};
-
-extern LIB3DSAPI Lib3dsBool lib3ds_background_read(Lib3dsBackground *background, iostream *strm);
-extern LIB3DSAPI Lib3dsBool lib3ds_background_write(Lib3dsBackground *background, iostream *strm);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
-
-
-
-
-
Index: /enSceneGraph/trunk/src/osgPlugins/3ds/shadow.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/shadow.cpp (revision 10076)
+++  (revision )
@@ -1,160 +1,0 @@
-/*
- * The 3D Studio File Format Library
- * Copyright (C) 1996-2001 by J.E. Hoffmann <je-h@gmx.net>
- * All rights reserved.
- *
- * This program is  free  software;  you can redistribute it and/or modify it
- * under the terms of the  GNU Lesser General Public License  as published by 
- * the  Free Software Foundation;  either version 2.1 of the License,  or (at 
- * your option) any later version.
- *
- * This  program  is  distributed in  the  hope that it will  be useful,  but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or  FITNESS FOR A  PARTICULAR PURPOSE.  See the  GNU Lesser General Public  
- * License for more details.
- *
- * You should  have received  a copy of the GNU Lesser General Public License
- * along with  this program;  if not, write to the  Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id$
- */
-#define LIB3DS_EXPORT
-#include "shadow.h"
-#include "chunk.h"
-#include "readwrite.h"
-#include <math.h>
-
-
-/*!
- * \defgroup shadow Shadow Map Settings
- *
- * \author J.E. Hoffmann <je-h@gmx.net>
- */
-
-
-/*!
- * \ingroup shadow 
- */
-Lib3dsBool
-lib3ds_shadow_read(Lib3dsShadow *shadow, iostream *strm)
-{
-  Lib3dsChunk c;
-
-  if (!lib3ds_chunk_read(&c, strm)) {
-    return(LIB3DS_FALSE);
-  }
-  
-  switch (c.chunk) {
-    case LIB3DS_SHADOW_MAP_SIZE:
-      {
-        shadow->map_size=lib3ds_intw_read(strm);
-      }
-      break;
-    case LIB3DS_LO_SHADOW_BIAS:
-      {
-          shadow->lo_bias=lib3ds_float_read(strm);
-      }
-      break;
-    case LIB3DS_HI_SHADOW_BIAS:
-      {
-        shadow->hi_bias=lib3ds_float_read(strm);
-      }
-      break;
-    case LIB3DS_SHADOW_SAMPLES:
-      {
-        shadow->samples=lib3ds_intw_read(strm);
-      }
-      break;
-    case LIB3DS_SHADOW_RANGE:
-      {
-        shadow->range=lib3ds_intd_read(strm);
-      }
-      break;
-    case LIB3DS_SHADOW_FILTER:
-      {
-        shadow->filter=lib3ds_float_read(strm);
-      }
-      break;
-    case LIB3DS_RAY_BIAS:
-      {
-        shadow->ray_bias=lib3ds_float_read(strm);
-      }
-      break;
-  }
-  
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
- * \ingroup shadow 
- */
-Lib3dsBool
-lib3ds_shadow_write(Lib3dsShadow *shadow, iostream *strm)
-{
-  if (fabs(shadow->lo_bias)>LIB3DS_EPSILON) { /*---- LIB3DS_LO_SHADOW_BIAS ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_LO_SHADOW_BIAS;
-    c.size=10;
-    lib3ds_chunk_write(&c,strm);
-    lib3ds_float_write(shadow->lo_bias,strm);
-  }
-
-  if (fabs(shadow->hi_bias)>LIB3DS_EPSILON) { /*---- LIB3DS_HI_SHADOW_BIAS ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_HI_SHADOW_BIAS;
-    c.size=10;
-    lib3ds_chunk_write(&c,strm);
-    lib3ds_float_write(shadow->hi_bias,strm);
-  }
-
-  if (shadow->map_size) { /*---- LIB3DS_SHADOW_MAP_SIZE ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_SHADOW_MAP_SIZE;
-    c.size=8;
-    lib3ds_chunk_write(&c,strm);
-    lib3ds_intw_write(shadow->map_size,strm);
-  }
-  
-  if (shadow->samples) { /*---- LIB3DS_SHADOW_SAMPLES ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_SHADOW_SAMPLES;
-    c.size=8;
-    lib3ds_chunk_write(&c,strm);
-    lib3ds_intw_write(shadow->samples,strm);
-  }
-
-  if (shadow->range) { /*---- LIB3DS_SHADOW_RANGE ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_SHADOW_RANGE;
-    c.size=10;
-    lib3ds_chunk_write(&c,strm);
-    lib3ds_intd_write(shadow->range,strm);
-  }
-
-  if (fabs(shadow->filter)>LIB3DS_EPSILON) { /*---- LIB3DS_SHADOW_FILTER ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_SHADOW_FILTER;
-    c.size=10;
-    lib3ds_chunk_write(&c,strm);
-    lib3ds_float_write(shadow->filter,strm);
-  }
-  if (fabs(shadow->ray_bias)>LIB3DS_EPSILON) { /*---- LIB3DS_RAY_BIAS ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_RAY_BIAS;
-    c.size=10;
-    lib3ds_chunk_write(&c,strm);
-    lib3ds_float_write(shadow->ray_bias,strm);
-  }
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
-
-\typedef Lib3dsShadow
-  \ingroup shadow
-  \sa _Lib3dsShadow
-
-*/
Index: /enSceneGraph/trunk/src/osgPlugins/3ds/node.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/node.cpp (revision 10076)
+++  (revision )
@@ -1,1095 +1,0 @@
-/*
- * The 3D Studio File Format Library
- * Copyright (C) 1996-2001 by J.E. Hoffmann <je-h@gmx.net>
- * All rights reserved.
- *
- * This program is  free  software;  you can redistribute it and/or modify it
- * under the terms of the  GNU Lesser General Public License  as published by 
- * the  Free Software Foundation;  either version 2.1 of the License,  or (at 
- * your option) any later version.
- *
- * This  program  is  distributed in  the  hope that it will  be useful,  but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or  FITNESS FOR A  PARTICULAR PURPOSE.  See the  GNU Lesser General Public  
- * License for more details.
- *
- * You should  have received  a copy of the GNU Lesser General Public License
- * along with  this program;  if not, write to the  Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id$
- */
-#define LIB3DS_EXPORT
-#include "node.h"
-#include "file.h"
-#include "readwrite.h"
-#include "chunk.h"
-#include "matrix.h"
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-#include "config.h"
-#ifdef WITH_DMALLOC
-#include <dmalloc.h>
-#endif
-
-
-/*!
- * \defgroup node Animation Nodes
- *
- * \author J.E. Hoffmann <je-h@gmx.net>
- */
-
-
-/*!
- * \ingroup node
- */
-Lib3dsNode*
-lib3ds_node_new_ambient()
-{
-  Lib3dsNode *node=(Lib3dsNode*)calloc(sizeof(Lib3dsNode), 1);
-  node->type=LIB3DS_AMBIENT_NODE;
-  lib3ds_matrix_identity(node->matrix);
-  return(node);
-}
-
-
-/*!
- * \ingroup node
- */
-Lib3dsNode*
-lib3ds_node_new_object()
-{
-  Lib3dsNode *node=(Lib3dsNode*)calloc(sizeof(Lib3dsNode), 1);
-  node->type=LIB3DS_OBJECT_NODE;
-  lib3ds_matrix_identity(node->matrix);
-  return(node);
-}
-
-
-/*!
- * \ingroup node
- */
-Lib3dsNode*
-lib3ds_node_new_camera()
-{
-  Lib3dsNode *node=(Lib3dsNode*)calloc(sizeof(Lib3dsNode), 1);
-  node->type=LIB3DS_CAMERA_NODE;
-  lib3ds_matrix_identity(node->matrix);
-  return(node);
-}
-
-
-/*!
- * \ingroup node
- */
-Lib3dsNode*
-lib3ds_node_new_target()
-{
-  Lib3dsNode *node=(Lib3dsNode*)calloc(sizeof(Lib3dsNode), 1);
-  node->type=LIB3DS_TARGET_NODE;
-  lib3ds_matrix_identity(node->matrix);
-  return(node);
-}
-
-
-/*!
- * \ingroup node
- */
-Lib3dsNode*
-lib3ds_node_new_light()
-{
-  Lib3dsNode *node=(Lib3dsNode*)calloc(sizeof(Lib3dsNode), 1);
-  node->type=LIB3DS_LIGHT_NODE;
-  lib3ds_matrix_identity(node->matrix);
-  return(node);
-}
-
-
-/*!
- * \ingroup node
- */
-Lib3dsNode*
-lib3ds_node_new_spot()
-{
-  Lib3dsNode *node=(Lib3dsNode*)calloc(sizeof(Lib3dsNode), 1);
-  node->type=LIB3DS_SPOT_NODE;
-  lib3ds_matrix_identity(node->matrix);
-  return(node);
-}
-
-
-static void
-free_node_and_childs(Lib3dsNode *node)
-{
-  ASSERT(node);
-  switch (node->type) {
-    case LIB3DS_UNKNOWN_NODE:
-      break;
-    case LIB3DS_AMBIENT_NODE:
-      {
-        Lib3dsAmbientData *n=&node->data.ambient;
-        lib3ds_lin3_track_free_keys(&n->col_track);
-      }
-      break;
-    case LIB3DS_OBJECT_NODE:
-      {
-        Lib3dsObjectData *n=&node->data.object;
-
-        lib3ds_lin3_track_free_keys(&n->pos_track);
-        lib3ds_quat_track_free_keys(&n->rot_track);
-        lib3ds_lin3_track_free_keys(&n->scl_track);
-        lib3ds_bool_track_free_keys(&n->hide_track);
-        lib3ds_morph_track_free_keys(&n->morph_track);
-      }
-      break;
-    case LIB3DS_CAMERA_NODE:
-      {
-        Lib3dsCameraData *n=&node->data.camera;
-        lib3ds_lin3_track_free_keys(&n->pos_track);
-        lib3ds_lin1_track_free_keys(&n->fov_track);
-        lib3ds_lin1_track_free_keys(&n->roll_track);
-      }
-      break;
-    case LIB3DS_TARGET_NODE:
-      {
-        Lib3dsTargetData *n=&node->data.target;
-        lib3ds_lin3_track_free_keys(&n->pos_track);
-      }
-      break;
-    case LIB3DS_LIGHT_NODE:
-      {
-        Lib3dsLightData *n=&node->data.light;
-        lib3ds_lin3_track_free_keys(&n->pos_track);
-        lib3ds_lin3_track_free_keys(&n->col_track);
-        lib3ds_lin1_track_free_keys(&n->hotspot_track);
-        lib3ds_lin1_track_free_keys(&n->falloff_track);
-        lib3ds_lin1_track_free_keys(&n->roll_track);
-      }
-      break;
-    case LIB3DS_SPOT_NODE:
-      {
-        Lib3dsSpotData *n=&node->data.spot;
-        lib3ds_lin3_track_free_keys(&n->pos_track);
-      }
-      break;
-  }
-  {
-    Lib3dsNode *p,*q;
-    for (p=node->childs; p; p=q) {
-      q=p->next;
-      free_node_and_childs(p);
-    }
-  }
-  node->type=LIB3DS_UNKNOWN_NODE;
-  free(node);
-}
-
-
-/*!
- * \ingroup node
- */
-void
-lib3ds_node_free(Lib3dsNode *node)
-{
-  ASSERT(node);
-  free_node_and_childs(node);
-}
-
-
-/*!
- * \ingroup node
- */
-void
-lib3ds_node_eval(Lib3dsNode *node, Lib3dsFloat t)
-{
-  ASSERT(node);
-  switch (node->type) {
-    case LIB3DS_UNKNOWN_NODE:
-      {
-        ASSERT(LIB3DS_FALSE);
-      }
-      break;
-    case LIB3DS_AMBIENT_NODE:
-      {
-        Lib3dsAmbientData *n=&node->data.ambient;
-        if (node->parent) {
-          lib3ds_matrix_copy(node->matrix, node->parent->matrix);
-        }
-        else {
-          lib3ds_matrix_identity(node->matrix);
-        }
-        lib3ds_lin3_track_eval(&n->col_track, n->col, t);
-      }
-      break;
-    case LIB3DS_OBJECT_NODE:
-      {
-        Lib3dsMatrix M;
-        Lib3dsObjectData *n=&node->data.object;
-
-        lib3ds_lin3_track_eval(&n->pos_track, n->pos, t);
-        lib3ds_quat_track_eval(&n->rot_track, n->rot, t);
-        lib3ds_lin3_track_eval(&n->scl_track, n->scl, t);
-        lib3ds_bool_track_eval(&n->hide_track, &n->hide, t);
-        lib3ds_morph_track_eval(&n->morph_track, n->morph, t);
-
-        lib3ds_matrix_identity(M);
-        lib3ds_matrix_translate(M, n->pos);
-        lib3ds_matrix_rotate(M, n->rot);
-        lib3ds_matrix_scale(M, n->scl);
-        
-        if (node->parent) {
-          lib3ds_matrix_mul(node->matrix, node->parent->matrix, M);
-        }
-        else {
-          lib3ds_matrix_copy(node->matrix, M);
-        }
-      }
-      break;
-    case LIB3DS_CAMERA_NODE:
-      {
-        Lib3dsCameraData *n=&node->data.camera;
-        lib3ds_lin3_track_eval(&n->pos_track, n->pos, t);
-        lib3ds_lin1_track_eval(&n->fov_track, &n->fov, t);
-        lib3ds_lin1_track_eval(&n->roll_track, &n->roll, t);
-        if (node->parent) {
-          lib3ds_matrix_copy(node->matrix, node->parent->matrix);
-        }
-        else {
-          lib3ds_matrix_identity(node->matrix);
-        }
-        lib3ds_matrix_translate(node->matrix, n->pos);
-      }
-      break;
-    case LIB3DS_TARGET_NODE:
-      {
-        Lib3dsTargetData *n=&node->data.target;
-        lib3ds_lin3_track_eval(&n->pos_track, n->pos, t);
-        if (node->parent) {
-          lib3ds_matrix_copy(node->matrix, node->parent->matrix);
-        }
-        else {
-          lib3ds_matrix_identity(node->matrix);
-        }
-        lib3ds_matrix_translate(node->matrix, n->pos);
-      }
-      break;
-    case LIB3DS_LIGHT_NODE:
-      {
-        Lib3dsLightData *n=&node->data.light;
-        lib3ds_lin3_track_eval(&n->pos_track, n->pos, t);
-        lib3ds_lin3_track_eval(&n->col_track, n->col, t);
-        lib3ds_lin1_track_eval(&n->hotspot_track, &n->hotspot, t);
-        lib3ds_lin1_track_eval(&n->falloff_track, &n->falloff, t);
-        lib3ds_lin1_track_eval(&n->roll_track, &n->roll, t);
-        if (node->parent) {
-          lib3ds_matrix_copy(node->matrix, node->parent->matrix);
-        }
-        else {
-          lib3ds_matrix_identity(node->matrix);
-        }
-        lib3ds_matrix_translate(node->matrix, n->pos);
-      }
-      break;
-    case LIB3DS_SPOT_NODE:
-      {
-        Lib3dsSpotData *n=&node->data.spot;
-        lib3ds_lin3_track_eval(&n->pos_track, n->pos, t);
-        if (node->parent) {
-          lib3ds_matrix_copy(node->matrix, node->parent->matrix);
-        }
-        else {
-          lib3ds_matrix_identity(node->matrix);
-        }
-        lib3ds_matrix_translate(node->matrix, n->pos);
-      }
-      break;
-  }
-  {
-    Lib3dsNode *p;
-
-    for (p=node->childs; p!=0; p=p->next) {
-      lib3ds_node_eval(p, t);
-    }
-  }
-}
-
-
-/*!
- * \ingroup node
- */
-Lib3dsNode*
-lib3ds_node_by_name(Lib3dsNode *node, const char* name, Lib3dsNodeTypes type)
-{
-  Lib3dsNode *p,*q;
-
-  for (p=node->childs; p!=0; p=p->next) {
-    if ((p->type==type) && (strcmp(p->name, name)==0)) {
-      return(p);
-    }
-    q=lib3ds_node_by_name(p, name, type);
-    if (q) {
-      return(q);
-    }
-  }
-  return(0);
-}
-
-
-/*!
- * \ingroup node
- */
-Lib3dsNode*
-lib3ds_node_by_id(Lib3dsNode *node, Lib3dsWord node_id)
-{
-  Lib3dsNode *p,*q;
-
-  for (p=node->childs; p!=0; p=p->next) {
-    if (p->node_id==node_id) {
-      return(p);
-    }
-    q=lib3ds_node_by_id(p, node_id);
-    if (q) {
-      return(q);
-    }
-  }
-  return(0);
-}
-
-
-static const char* node_names_table[]= {
-  "***Unknown***",
-  "Ambient",
-  "Object",
-  "Camera",
-  "Target",
-  "Light",
-  "Spot"
-};
-
-
-/*!
- * \ingroup node
- */
-void
-lib3ds_node_dump(Lib3dsNode *node, Lib3dsIntd level)
-{
-  Lib3dsNode *p;
-  char l[128];
-
-  ASSERT(node);
-  memset(l, ' ', 2*level);
-  l[2*level]=0;
-
-  if (node->type==LIB3DS_OBJECT_NODE) {
-    printf("%s%s [%s] (%s)\n",
-      l,
-      node->name,
-      node->data.object.instance,
-      node_names_table[node->type]
-    );
-  }
-  else {
-    printf("%s%s (%s)\n",
-      l,
-      node->name,
-      node_names_table[node->type]
-    );
-  }
-  
-  for (p=node->childs; p!=0; p=p->next) {
-    lib3ds_node_dump(p, level+1);
-  }
-}
-
-
-/*!
- * \ingroup node
- */
-Lib3dsBool
-lib3ds_node_read(Lib3dsNode *node, Lib3dsFile *, iostream *strm)
-{
-  Lib3dsChunk c;
-  Lib3dsWord chunk;
-
-  ASSERT(node);
-  if (!lib3ds_chunk_read_start(&c, 0, strm)) {
-    return(LIB3DS_FALSE);
-  }
-  switch (c.chunk) {
-    case LIB3DS_AMBIENT_NODE_TAG:
-    case LIB3DS_OBJECT_NODE_TAG:
-    case LIB3DS_CAMERA_NODE_TAG:
-    case LIB3DS_TARGET_NODE_TAG:
-    case LIB3DS_LIGHT_NODE_TAG:
-    case LIB3DS_SPOTLIGHT_NODE_TAG:
-    case LIB3DS_L_TARGET_NODE_TAG:
-      break;
-    default:
-      return(LIB3DS_FALSE);
-  }
-
-  while ((chunk=lib3ds_chunk_read_next(&c, strm))!=0) {
-    switch (chunk) {
-      case LIB3DS_NODE_ID:
-        {
-          node->node_id=lib3ds_word_read(strm);
-          lib3ds_chunk_dump_info("  ID = %d", (short)node->node_id);
-        }
-        break;
-      case LIB3DS_NODE_HDR:
-        {
-          if (!lib3ds_string_read(node->name, 64, strm)) {
-            return(LIB3DS_FALSE);
-          }
-          node->flags1=lib3ds_word_read(strm);
-          node->flags2=lib3ds_word_read(strm);
-          node->parent_id=lib3ds_word_read(strm);
-          lib3ds_chunk_dump_info("  NAME =%s", node->name);
-          lib3ds_chunk_dump_info("  PARENT=%d", (short)node->parent_id);
-        }
-        break;
-      case LIB3DS_PIVOT:
-        {
-          if (node->type==LIB3DS_OBJECT_NODE) {
-            int i;
-            for (i=0; i<3; ++i) {
-              node->data.object.pivot[i]=lib3ds_float_read(strm);
-            }
-          }
-          else {
-            lib3ds_chunk_unknown(chunk);
-          }
-        }
-        break;
-      case LIB3DS_INSTANCE_NAME:
-        {
-          if (node->type==LIB3DS_OBJECT_NODE) {
-            if (!lib3ds_string_read(node->data.object.instance, 64, strm)) {
-              return(LIB3DS_FALSE);
-            }
-          }
-          else {
-            lib3ds_chunk_unknown(chunk);
-          }
-        }
-        break;
-      case LIB3DS_BOUNDBOX:
-        {
-          if (node->type==LIB3DS_OBJECT_NODE) {
-            int i;
-            for (i=0; i<3; ++i) {
-              node->data.object.bbox_min[i]=lib3ds_float_read(strm);
-            }
-            for (i=0; i<3; ++i) {
-              node->data.object.bbox_max[i]=lib3ds_float_read(strm);
-            }
-          }
-          else {
-            lib3ds_chunk_unknown(chunk);
-          }
-        }
-        break;
-      case LIB3DS_COL_TRACK_TAG:
-        {
-          Lib3dsBool result=LIB3DS_TRUE;
-          
-          switch (node->type) {
-            case LIB3DS_AMBIENT_NODE:
-              result=lib3ds_lin3_track_read(&node->data.ambient.col_track, strm);
-              break;
-            case LIB3DS_LIGHT_NODE:
-              result=lib3ds_lin3_track_read(&node->data.light.col_track, strm);
-              break;
-            default:
-              lib3ds_chunk_unknown(chunk);
-          }
-          if (!result) {
-            return(LIB3DS_FALSE);
-          }
-        }
-        break;
-      case LIB3DS_POS_TRACK_TAG:
-        {
-          Lib3dsBool result=LIB3DS_TRUE;
-
-          switch (node->type) {
-            case LIB3DS_OBJECT_NODE:
-              result=lib3ds_lin3_track_read(&node->data.object.pos_track, strm);
-              break;
-            case LIB3DS_CAMERA_NODE:
-              result=lib3ds_lin3_track_read(&node->data.camera.pos_track, strm);
-              break;
-            case LIB3DS_TARGET_NODE:
-              result=lib3ds_lin3_track_read(&node->data.target.pos_track, strm);
-              break;
-            case LIB3DS_LIGHT_NODE:
-              result=lib3ds_lin3_track_read(&node->data.light.pos_track, strm);
-              break;
-            case LIB3DS_SPOT_NODE:
-              result=lib3ds_lin3_track_read(&node->data.spot.pos_track, strm);
-              break;
-            default:
-              lib3ds_chunk_unknown(chunk);
-          }
-          if (!result) {
-            return(LIB3DS_FALSE);
-          }
-        }
-        break;
-      case LIB3DS_ROT_TRACK_TAG:
-        {
-          if (node->type==LIB3DS_OBJECT_NODE) {
-            if (!lib3ds_quat_track_read(&node->data.object.rot_track, strm)) {
-              return(LIB3DS_FALSE);
-            }
-          }
-          else {
-            lib3ds_chunk_unknown(chunk);
-          }
-        }
-        break;
-      case LIB3DS_SCL_TRACK_TAG:
-        {
-          if (node->type==LIB3DS_OBJECT_NODE) {
-            if (!lib3ds_lin3_track_read(&node->data.object.scl_track, strm)) {
-              return(LIB3DS_FALSE);
-            }
-          }
-          else {
-            lib3ds_chunk_unknown(chunk);
-          }
-        }
-        break;
-      case LIB3DS_FOV_TRACK_TAG:
-        {
-          if (node->type==LIB3DS_CAMERA_NODE) {
-            if (!lib3ds_lin1_track_read(&node->data.camera.fov_track, strm)) {
-              return(LIB3DS_FALSE);
-            }
-          }
-          else {
-            lib3ds_chunk_unknown(chunk);
-          }
-        }
-        break;
-      case LIB3DS_HOT_TRACK_TAG:
-        {
-          if (node->type==LIB3DS_LIGHT_NODE) {
-            if (!lib3ds_lin1_track_read(&node->data.light.hotspot_track, strm)) {
-              return(LIB3DS_FALSE);
-            }
-          }
-          else {
-            lib3ds_chunk_unknown(chunk);
-          }
-        }
-        break;
-      case LIB3DS_FALL_TRACK_TAG:
-        {
-          if (node->type==LIB3DS_LIGHT_NODE) {
-            if (!lib3ds_lin1_track_read(&node->data.light.falloff_track, strm)) {
-              return(LIB3DS_FALSE);
-            }
-          }
-          else {
-            lib3ds_chunk_unknown(chunk);
-          }
-        }
-        break;
-      case LIB3DS_ROLL_TRACK_TAG:
-        {
-          Lib3dsBool result=LIB3DS_TRUE;
-
-          switch (node->type) {
-            case LIB3DS_CAMERA_NODE:
-              result=lib3ds_lin1_track_read(&node->data.camera.roll_track, strm);
-              break;
-            case LIB3DS_LIGHT_NODE:
-              result=lib3ds_lin1_track_read(&node->data.light.roll_track, strm);
-              break;
-            default:
-              lib3ds_chunk_unknown(chunk);
-          }
-          if (!result) {
-            return(LIB3DS_FALSE);
-          }
-        }
-        break;
-      case LIB3DS_HIDE_TRACK_TAG:
-        {
-          if (node->type==LIB3DS_OBJECT_NODE) {
-            if (!lib3ds_bool_track_read(&node->data.object.hide_track, strm)) {
-              return(LIB3DS_FALSE);
-            }
-          }
-          else {
-            lib3ds_chunk_unknown(chunk);
-          }
-        }
-        break;
-      case LIB3DS_MORPH_SMOOTH:
-        {
-          if (node->type==LIB3DS_OBJECT_NODE) {
-            node->data.object.morph_smooth=lib3ds_float_read(strm);
-          }
-          else {
-            lib3ds_chunk_unknown(chunk);
-          }
-        }
-        break;
-      case LIB3DS_MORPH_TRACK_TAG:
-        {
-          if (node->type==LIB3DS_OBJECT_NODE) {
-            if (!lib3ds_morph_track_read(&node->data.object.morph_track, strm)) {
-              return(LIB3DS_FALSE);
-            }
-          }
-          else {
-            lib3ds_chunk_unknown(chunk);
-          }
-        }
-        break;
-      default:
-        lib3ds_chunk_unknown(chunk);
-    }
-  }
-
-  lib3ds_chunk_read_end(&c, strm);
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
- * \ingroup node
- */
-Lib3dsBool
-lib3ds_node_write(Lib3dsNode *node, Lib3dsFile *file, iostream *strm)
-{
-  Lib3dsChunk c;
-
-  switch (node->type) {
-    case LIB3DS_AMBIENT_NODE:
-      c.chunk=LIB3DS_AMBIENT_NODE_TAG;
-      break;
-    case LIB3DS_OBJECT_NODE:
-      c.chunk=LIB3DS_OBJECT_NODE_TAG;
-      break;
-    case LIB3DS_CAMERA_NODE:
-      c.chunk=LIB3DS_CAMERA_NODE_TAG;
-      break;
-    case LIB3DS_TARGET_NODE:
-      c.chunk=LIB3DS_TARGET_NODE_TAG;
-      break;
-    case LIB3DS_LIGHT_NODE:
-      if (lib3ds_file_node_by_name(file, node->name, LIB3DS_SPOT_NODE)) {
-        c.chunk=LIB3DS_SPOTLIGHT_NODE_TAG;
-      }
-      else {
-        c.chunk=LIB3DS_LIGHT_NODE_TAG;
-      }
-      break;
-    case LIB3DS_SPOT_NODE:
-      c.chunk=LIB3DS_L_TARGET_NODE_TAG;
-      break;
-    default:
-      return(LIB3DS_FALSE);
-  }
-  if (!lib3ds_chunk_write_start(&c,strm)) {
-    return(LIB3DS_FALSE);
-  }
-
-  { /*---- LIB3DS_NODE_ID ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_NODE_ID;
-    c.size=8;
-    lib3ds_chunk_write(&c,strm);
-    lib3ds_intw_write(node->node_id,strm);
-  }
-
-  { /*---- LIB3DS_NODE_HDR ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_NODE_HDR;
-    c.size=6+ 1+strlen(node->name) +2+2+2;
-    lib3ds_chunk_write(&c,strm);
-    lib3ds_string_write(node->name,strm);
-    lib3ds_word_write(node->flags1,strm);
-    lib3ds_word_write(node->flags2,strm);
-    lib3ds_word_write(node->parent_id,strm);
-  }
-
-  switch (c.chunk) {
-    case LIB3DS_AMBIENT_NODE_TAG:
-      { /*---- LIB3DS_COL_TRACK_TAG ----*/
-        Lib3dsChunk c;
-        c.chunk=LIB3DS_COL_TRACK_TAG;
-        if (!lib3ds_chunk_write_start(&c,strm)) {
-          return(LIB3DS_FALSE);
-        }
-        if (!lib3ds_lin3_track_write(&node->data.ambient.col_track,strm)) {
-          return(LIB3DS_FALSE);
-        }
-        if (!lib3ds_chunk_write_end(&c,strm)) {
-          return(LIB3DS_FALSE);
-        }
-      }
-      break;
-    case LIB3DS_OBJECT_NODE_TAG:
-      { /*---- LIB3DS_PIVOT ----*/
-        Lib3dsChunk c;
-        c.chunk=LIB3DS_PIVOT;
-        c.size=18;
-        lib3ds_chunk_write(&c,strm);
-        lib3ds_vector_write(node->data.object.pivot,strm);
-      }
-      { /*---- LIB3DS_INSTANCE_NAME ----*/
-        Lib3dsChunk c;
-        const char *name;
-        if (strlen(node->data.object.instance)) {
-          name=node->data.object.instance;
-
-          c.chunk=LIB3DS_INSTANCE_NAME;
-          c.size=6+1+strlen(name);
-          lib3ds_chunk_write(&c,strm);
-          lib3ds_string_write(name,strm);
-        }
-      }
-      {
-        int i;
-        for (i=0; i<3; ++i) {
-          if ((fabs(node->data.object.bbox_min[i])>LIB3DS_EPSILON) ||
-            (fabs(node->data.object.bbox_max[i])>LIB3DS_EPSILON)) {
-            break;
-          }
-        }
-        
-        if (i<3) { /*---- LIB3DS_BOUNDBOX ----*/
-          Lib3dsChunk c;
-          c.chunk=LIB3DS_BOUNDBOX;
-          c.size=30;
-          lib3ds_chunk_write(&c,strm);
-          lib3ds_vector_write(node->data.object.bbox_min, strm);
-          lib3ds_vector_write(node->data.object.bbox_max, strm);
-        }
-      }
-      { /*---- LIB3DS_POS_TRACK_TAG ----*/
-        Lib3dsChunk c;
-        c.chunk=LIB3DS_POS_TRACK_TAG;
-        if (!lib3ds_chunk_write_start(&c,strm)) {
-          return(LIB3DS_FALSE);
-        }
-        if (!lib3ds_lin3_track_write(&node->data.object.pos_track,strm)) {
-          return(LIB3DS_FALSE);
-        }
-        if (!lib3ds_chunk_write_end(&c,strm)) {
-          return(LIB3DS_FALSE);
-        }
-      }
-      { /*---- LIB3DS_ROT_TRACK_TAG ----*/
-        Lib3dsChunk c;
-        c.chunk=LIB3DS_ROT_TRACK_TAG;
-        if (!lib3ds_chunk_write_start(&c,strm)) {
-          return(LIB3DS_FALSE);
-        }
-        if (!lib3ds_quat_track_write(&node->data.object.rot_track,strm)) {
-          return(LIB3DS_FALSE);
-        }
-        if (!lib3ds_chunk_write_end(&c,strm)) {
-          return(LIB3DS_FALSE);
-        }
-      }
-      { /*---- LIB3DS_SCL_TRACK_TAG ----*/
-        Lib3dsChunk c;
-        c.chunk=LIB3DS_SCL_TRACK_TAG;
-        if (!lib3ds_chunk_write_start(&c,strm)) {
-          return(LIB3DS_FALSE);
-        }
-        if (!lib3ds_lin3_track_write(&node->data.object.scl_track,strm)) {
-          return(LIB3DS_FALSE);
-        }
-        if (!lib3ds_chunk_write_end(&c,strm)) {
-          return(LIB3DS_FALSE);
-        }
-      }
-      if (node->data.object.hide_track.keyL) { /*---- LIB3DS_HIDE_TRACK_TAG ----*/
-        Lib3dsChunk c;
-        c.chunk=LIB3DS_HIDE_TRACK_TAG;
-        if (!lib3ds_chunk_write_start(&c,strm)) {
-          return(LIB3DS_FALSE);
-        }
-        if (!lib3ds_bool_track_write(&node->data.object.hide_track,strm)) {
-          return(LIB3DS_FALSE);
-        }
-        if (!lib3ds_chunk_write_end(&c,strm)) {
-          return(LIB3DS_FALSE);
-        }
-      }
-      if (fabs(node->data.object.morph_smooth)>LIB3DS_EPSILON){ /*---- LIB3DS_MORPH_SMOOTH ----*/
-        Lib3dsChunk c;
-        c.chunk=LIB3DS_MORPH_SMOOTH;
-        c.size=10;
-        lib3ds_chunk_write(&c,strm);
-        lib3ds_float_write(node->data.object.morph_smooth,strm);
-      }
-      break;
-    case LIB3DS_CAMERA_NODE_TAG:
-      { /*---- LIB3DS_POS_TRACK_TAG ----*/
-        Lib3dsChunk c;
-        c.chunk=LIB3DS_POS_TRACK_TAG;
-        if (!lib3ds_chunk_write_start(&c,strm)) {
-          return(LIB3DS_FALSE);
-        }
-        if (!lib3ds_lin3_track_write(&node->data.camera.pos_track,strm)) {
-          return(LIB3DS_FALSE);
-        }
-        if (!lib3ds_chunk_write_end(&c,strm)) {
-          return(LIB3DS_FALSE);
-        }
-      }
-      { /*---- LIB3DS_FOV_TRACK_TAG ----*/
-        Lib3dsChunk c;
-        c.chunk=LIB3DS_FOV_TRACK_TAG;
-        if (!lib3ds_chunk_write_start(&c,strm)) {
-          return(LIB3DS_FALSE);
-        }
-        if (!lib3ds_lin1_track_write(&node->data.camera.fov_track,strm)) {
-          return(LIB3DS_FALSE);
-        }
-        if (!lib3ds_chunk_write_end(&c,strm)) {
-          return(LIB3DS_FALSE);
-        }
-      }
-      { /*---- LIB3DS_ROLL_TRACK_TAG ----*/
-        Lib3dsChunk c;
-        c.chunk=LIB3DS_ROLL_TRACK_TAG;
-        if (!lib3ds_chunk_write_start(&c,strm)) {
-          return(LIB3DS_FALSE);
-        }
-        if (!lib3ds_lin1_track_write(&node->data.camera.roll_track,strm)) {
-          return(LIB3DS_FALSE);
-        }
-        if (!lib3ds_chunk_write_end(&c,strm)) {
-          return(LIB3DS_FALSE);
-        }
-      }
-      break;
-    case LIB3DS_TARGET_NODE_TAG:
-      { /*---- LIB3DS_POS_TRACK_TAG ----*/
-        Lib3dsChunk c;
-        c.chunk=LIB3DS_POS_TRACK_TAG;
-        if (!lib3ds_chunk_write_start(&c,strm)) {
-          return(LIB3DS_FALSE);
-        }
-        if (!lib3ds_lin3_track_write(&node->data.target.pos_track,strm)) {
-          return(LIB3DS_FALSE);
-        }
-        if (!lib3ds_chunk_write_end(&c,strm)) {
-          return(LIB3DS_FALSE);
-        }
-      }
-      break;
-    case LIB3DS_LIGHT_NODE_TAG:
-      { /*---- LIB3DS_POS_TRACK_TAG ----*/
-        Lib3dsChunk c;
-        c.chunk=LIB3DS_POS_TRACK_TAG;
-        if (!lib3ds_chunk_write_start(&c,strm)) {
-          return(LIB3DS_FALSE);
-        }
-        if (!lib3ds_lin3_track_write(&node->data.light.pos_track,strm)) {
-          return(LIB3DS_FALSE);
-        }
-        if (!lib3ds_chunk_write_end(&c,strm)) {
-          return(LIB3DS_FALSE);
-        }
-      }
-      { /*---- LIB3DS_COL_TRACK_TAG ----*/
-        Lib3dsChunk c;
-        c.chunk=LIB3DS_COL_TRACK_TAG;
-        if (!lib3ds_chunk_write_start(&c,strm)) {
-          return(LIB3DS_FALSE);
-        }
-        if (!lib3ds_lin3_track_write(&node->data.light.col_track,strm)) {
-          return(LIB3DS_FALSE);
-        }
-        if (!lib3ds_chunk_write_end(&c,strm)) {
-          return(LIB3DS_FALSE);
-        }
-      }
-      break;
-    case LIB3DS_SPOTLIGHT_NODE_TAG:
-      { /*---- LIB3DS_POS_TRACK_TAG ----*/
-        Lib3dsChunk c;
-        c.chunk=LIB3DS_POS_TRACK_TAG;
-        if (!lib3ds_chunk_write_start(&c,strm)) {
-          return(LIB3DS_FALSE);
-        }
-        if (!lib3ds_lin3_track_write(&node->data.light.pos_track,strm)) {
-          return(LIB3DS_FALSE);
-        }
-        if (!lib3ds_chunk_write_end(&c,strm)) {
-          return(LIB3DS_FALSE);
-        }
-      }
-      { /*---- LIB3DS_COL_TRACK_TAG ----*/
-        Lib3dsChunk c;
-        c.chunk=LIB3DS_COL_TRACK_TAG;
-        if (!lib3ds_chunk_write_start(&c,strm)) {
-          return(LIB3DS_FALSE);
-        }
-        if (!lib3ds_lin3_track_write(&node->data.light.col_track,strm)) {
-          return(LIB3DS_FALSE);
-        }
-        if (!lib3ds_chunk_write_end(&c,strm)) {
-          return(LIB3DS_FALSE);
-        }
-      }
-      { /*---- LIB3DS_HOT_TRACK_TAG ----*/
-        Lib3dsChunk c;
-        c.chunk=LIB3DS_HOT_TRACK_TAG;
-        if (!lib3ds_chunk_write_start(&c,strm)) {
-          return(LIB3DS_FALSE);
-        }
-        if (!lib3ds_lin1_track_write(&node->data.light.hotspot_track,strm)) {
-          return(LIB3DS_FALSE);
-        }
-        if (!lib3ds_chunk_write_end(&c,strm)) {
-          return(LIB3DS_FALSE);
-        }
-      }
-      { /*---- LIB3DS_FALL_TRACK_TAG ----*/
-        Lib3dsChunk c;
-        c.chunk=LIB3DS_FALL_TRACK_TAG;
-        if (!lib3ds_chunk_write_start(&c,strm)) {
-          return(LIB3DS_FALSE);
-        }
-        if (!lib3ds_lin1_track_write(&node->data.light.falloff_track,strm)) {
-          return(LIB3DS_FALSE);
-        }
-        if (!lib3ds_chunk_write_end(&c,strm)) {
-          return(LIB3DS_FALSE);
-        }
-      }
-      { /*---- LIB3DS_ROLL_TRACK_TAG ----*/
-        Lib3dsChunk c;
-        c.chunk=LIB3DS_ROLL_TRACK_TAG;
-        if (!lib3ds_chunk_write_start(&c,strm)) {
-          return(LIB3DS_FALSE);
-        }
-        if (!lib3ds_lin1_track_write(&node->data.light.roll_track,strm)) {
-          return(LIB3DS_FALSE);
-        }
-        if (!lib3ds_chunk_write_end(&c,strm)) {
-          return(LIB3DS_FALSE);
-        }
-      }
-      break;
-    case LIB3DS_L_TARGET_NODE_TAG:
-      { /*---- LIB3DS_POS_TRACK_TAG ----*/
-        Lib3dsChunk c;
-        c.chunk=LIB3DS_POS_TRACK_TAG;
-        if (!lib3ds_chunk_write_start(&c,strm)) {
-          return(LIB3DS_FALSE);
-        }
-        if (!lib3ds_lin3_track_write(&node->data.spot.pos_track,strm)) {
-          return(LIB3DS_FALSE);
-        }
-        if (!lib3ds_chunk_write_end(&c,strm)) {
-          return(LIB3DS_FALSE);
-        }
-      }
-      break;
-    default:
-      return(LIB3DS_FALSE);
-  }
-
-  if (!lib3ds_chunk_write_end(&c,strm)) {
-    return(LIB3DS_FALSE);
-  }
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
-
-\typedef Lib3dsNodeTypes
-  \ingroup node
-
-*/
-/*!
-
-\enum _Lib3dsNodeTypes
-  \ingroup node
-
-*/
-/*!
-
-\typedef Lib3dsBoolKey
-  \ingroup node
-  \sa _Lib3dsBoolKey
-
-*/
-/*!
-
-\typedef Lib3dsBoolTrack
-  \ingroup node
-  \sa _Lib3dsBoolTrack
-
-*/
-/*!
-
-\typedef Lib3dsLin1Key
-  \ingroup node
-  \sa _Lib3dsLin1Key
-
-*/
-/*!
-
-\typedef Lib3dsLin1Track
-  \ingroup node
-  \sa _Lib3dsLin1Track
-
-*/
-/*!
-
-\typedef Lib3dsLin3Key
-  \ingroup node
-  \sa _Lib3dsLin3Key
-
-*/
-/*!
-
-\typedef Lib3dsLin3Track
-  \ingroup node
-  \sa _Lib3dsLin3Track
-
-*/
-/*!
-
-\typedef Lib3dsQuatKey
-  \ingroup node
-  \sa _Lib3dsQuatKey
-
-*/
-/*!
-
-\typedef Lib3dsQuatTrack
-  \ingroup node
-  \sa _Lib3dsLin3Key
-
-*/
-/*!
-
-\typedef Lib3dsMorphKey
-  \ingroup node
-  \sa _Lib3dsMorphKey
-
-*/
-/*!
-
-\typedef Lib3dsMorphTrack
-  \ingroup node
-  \sa _Lib3dsMorphTrack
-
-*/
-
-
Index: /enSceneGraph/trunk/src/osgPlugins/3ds/readwrite.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/readwrite.cpp (revision 10128)
+++  (revision )
@@ -1,546 +1,0 @@
-/*
- * The 3D Studio File Format Library
- * Copyright (C) 1996-2001 by J.E. Hoffmann <je-h@gmx.net>
- * All rights reserved.
- *
- * This program is  free  software;  you can redistribute it and/or modify it
- * under the terms of the  GNU Lesser General Public License  as published by 
- * the  Free Software Foundation;  either version 2.1 of the License,  or (at 
- * your option) any later version.
- *
- * This  program  is  distributed in  the  hope that it will  be useful,  but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or  FITNESS FOR A  PARTICULAR PURPOSE.  See the  GNU Lesser General Public  
- * License for more details.
- *
- * You should  have received  a copy of the GNU Lesser General Public License
- * along with  this program;  if not, write to the  Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id$
- */
-#define LIB3DS_EXPORT
-#include "readwrite.h"
-#include <osg/Endian>
-
-
-/*!
- * \defgroup readwrite Portable Binary Input/Ouput
- *
- * \author J.E. Hoffmann <je-h@gmx.net>
- */
-
-static bool s_requiresByteSwap = false;
-
-extern LIB3DSAPI void setByteOrder()
-{
-    s_requiresByteSwap = osg::getCpuByteOrder()==osg::BigEndian;
-}
-
-
-
-/*!
- * \ingroup readwrite
- *
- * Read a byte from a file stream.  
- *
- * \param f  Input file stream. 
- *
- * \return The byte read. 
- */
-Lib3dsByte
-lib3ds_byte_read(iostream *strm)
-{
-  Lib3dsByte b;
-
-  ASSERT(strm);
-  strm->read((char*)&b,1);
-  return(b);
-}
-
-
-/**
- * Read a word from a file stream in little endian format.   
- *
- * \param f  Input file stream. 
- *
- * \return The word read. 
- */
-Lib3dsWord
-lib3ds_word_read(iostream *strm)
-{
-  Lib3dsByte b[2];
-  Lib3dsWord w;
-
-  ASSERT(strm);  
-  strm->read((char*)&b,2);
-  w=((Lib3dsWord)b[1] << 8) |
-    ((Lib3dsWord)b[0]);
-  return(w);
-}
-
-
-/*!
- * \ingroup readwrite
- *
- * Read a dword from file a stream in little endian format.   
- *
- * \param f  Input file stream. 
- *
- * \return The dword read. 
- */
-Lib3dsDword
-lib3ds_dword_read(iostream *strm)
-{
-  Lib3dsByte b[4];
-  Lib3dsDword d;        
-                         
-  ASSERT(strm);  
-  strm->read((char*)&b,4);
-  d=((Lib3dsDword)b[3] << 24) |
-    ((Lib3dsDword)b[2] << 16) |
-    ((Lib3dsDword)b[1] << 8) |
-    ((Lib3dsDword)b[0]);
-  return(d);
-}
-
-
-/*!
- * \ingroup readwrite
- *
- * Read a signed byte from a file stream.   
- *
- * \param f  Input file stream. 
- *
- * \return The signed byte read. 
- */
-Lib3dsIntb
-lib3ds_intb_read(iostream *strm)
-{
-  Lib3dsIntb b;
-
-  ASSERT(strm);  
-  strm->read((char*)&b,1);
-  return(b);
-}
-
-
-/*!
- * \ingroup readwrite
- *
- * Read a signed word from a file stream in little endian format.   
- *
- * \param f  Input file stream. 
- *
- * \return The signed word read. 
- */
-Lib3dsIntw
-lib3ds_intw_read(iostream *strm)
-{
-  Lib3dsByte b[2];
-
-  ASSERT(strm);
-  strm->read((char*)&b,2);
-
-  if (s_requiresByteSwap)
-  {
-    osg::swapBytes2((char*)b);
-  }
-
-  return (*((Lib3dsIntw*)b));
-}
-
-
-/*!
- * \ingroup readwrite
- *
- * Read a signed dword a from file stream in little endian format.   
- *
- * \param f  Input file stream. 
- *
- * \return The signed dword read. 
- */
-Lib3dsIntd
-lib3ds_intd_read(iostream *strm)
-{
-  Lib3dsByte b[4];     
-                         
-  ASSERT(strm);
-  strm->read((char*)&b,4);
-
-  if (s_requiresByteSwap)
-  {
-    osg::swapBytes4((char*)b);
-  }
-
-  return (*((Lib3dsIntd*)b));
-
-}
-
-
-/*!
- * \ingroup readwrite
- *
- * Read a float from a file stream in little endian format.   
- *
- * \param f  Input file stream. 
- *
- * \return The float read. 
- */
-Lib3dsFloat
-lib3ds_float_read(iostream *strm)
-{
-  Lib3dsByte b[4];
-
-  ASSERT(strm);
-  b[0]=b[1]=b[2]=b[3]=0;
-  strm->read((char*)&b,4);  
-
-  if (s_requiresByteSwap)
-  {
-    osg::swapBytes4((char*)b);
-  }
-
-  return (*((Lib3dsFloat*)b));
-}
-
-
-/*!
- * \ingroup readwrite
- * \ingroup vector
- *
- * Read a vector from a file stream in little endian format.   
- *
- * \param v  The vector to store the data. 
- * \param f  Input file stream. 
- *
- * \return The float read. 
- */
-Lib3dsBool
-lib3ds_vector_read(Lib3dsVector v, iostream *strm)
-{
-  v[0]=lib3ds_float_read(strm);
-  v[1]=lib3ds_float_read(strm);
-  v[2]=lib3ds_float_read(strm);
-
-  if (strm->fail()) {
-    return(LIB3DS_FALSE);
-  }
-
-  /*printf("lib3ds_vector_read %f %f %f\n",v[0],v[1],v[2]);*/
-
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
- * \ingroup readwrite
- */
-Lib3dsBool
-lib3ds_rgb_read(Lib3dsRgb rgb, iostream *strm)
-{
-  rgb[0]=lib3ds_float_read(strm);
-  rgb[1]=lib3ds_float_read(strm);
-  rgb[2]=lib3ds_float_read(strm);
-
-  if (strm->fail()) {
-    return(LIB3DS_FALSE);
-  }
-  /*printf("lib3ds_rgb_read %f %f %f\n",rgb[0],rgb[1],rgb[2]);*/
-
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
- * \ingroup readwrite
- *
- * Read a zero-terminated string from a file stream.
- *
- * \param s       The buffer to store the read string.
- * \param buflen  Buffer length.
- * \param f       The input file stream.
- *
- * \return        True on success, False otherwise.
- */
-Lib3dsBool
-lib3ds_string_read(char *s, int buflen, iostream *strm)
-{
-  int k=0;
-  ASSERT(s);
-  s--;
-  do
-  {
-      s++;
-      k++;
-      strm->read(s,1);
-  } while ((*s!=0) && (k<buflen));
-
-  if (strm->fail()) {
-    return(LIB3DS_FALSE);
-  }
-  return(LIB3DS_TRUE);
-}
-
-/*!
- * \ingroup readwrite
- *
- * Writes a byte into a file stream.
- *
- * \param b  The byte to write to the file stream.
- * \param f  The input file stream.
- *
- * \return   True on success, False otherwise.
- */
-Lib3dsBool
-lib3ds_byte_write(Lib3dsByte b, iostream *strm)
-{
-  ASSERT(strm);
-  strm->write((char*)&b,1);
-  if (strm->fail()) {
-    return(LIB3DS_FALSE);
-  }
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
- * \ingroup readwrite
- *
- * Writes a word into a little endian file stream.
- *
- * \param w  The word to write to the file stream.
- * \param f  The input file stream.
- *
- * \return   True on success, False otherwise.
- */
-Lib3dsBool
-lib3ds_word_write(Lib3dsWord w, iostream *strm)
-{
-  Lib3dsByte b[2];
-
-  ASSERT(strm);
-  b[1]=(Lib3dsByte)(((Lib3dsWord)w & 0xFF00) >> 8);
-  b[0]=(Lib3dsByte)((Lib3dsWord)w & 0x00FF);
-  strm->write((char*)b,2);
-  if (strm->fail()) {
-    return(LIB3DS_FALSE);
-  }
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
- * \ingroup readwrite
- *
- * Writes a dword into a little endian file stream.
- *
- * \param d  The dword to write to the file stream.
- * \param f  The input file stream.
- *
- * \return   True on success, False otherwise.
- */
-Lib3dsBool
-lib3ds_dword_write(Lib3dsDword d, iostream *strm)
-{
-  Lib3dsByte b[4];
-
-  ASSERT(strm);
-  b[3]=(Lib3dsByte)(((Lib3dsDword)d & 0xFF000000) >> 24);
-  b[2]=(Lib3dsByte)(((Lib3dsDword)d & 0x00FF0000) >> 16);
-  b[1]=(Lib3dsByte)(((Lib3dsDword)d & 0x0000FF00) >> 8);
-  b[0]=(Lib3dsByte)(((Lib3dsDword)d & 0x000000FF));
-
-  strm->write((char*)b,4);
-  if (strm->fail()) {
-    return(LIB3DS_FALSE);
-  }
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
- * \ingroup readwrite
- *
- * Writes a signed byte in a file stream.
- *
- * \param b  The signed byte to write to the file stream.
- * \param f  The input file stream.
- *
- * \return   True on success, False otherwise.
- */
-Lib3dsBool
-lib3ds_intb_write(Lib3dsIntb b, iostream *strm)
-{
-  ASSERT(strm);
-  strm->write((const char*)&b,1);
-  if (strm->fail()) {
-    return(LIB3DS_FALSE);
-  }
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
- * \ingroup readwrite
- *
- * Writes a signed word into a little endian file stream.
- *
- * \param w  The signed word to write to the file stream.
- * \param f  The input file stream.
- *
- * \return   True on success, False otherwise.
- */
-Lib3dsBool
-lib3ds_intw_write(Lib3dsIntw w, iostream *strm)
-{
-  Lib3dsByte b[2];
-
-  ASSERT(strm);
-  b[1]=(Lib3dsByte)(((Lib3dsWord)w & 0xFF00) >> 8);
-  b[0]=(Lib3dsByte)((Lib3dsWord)w & 0x00FF);
-
-  strm->write((const char*)b,2);
-  if (strm->fail()) {
-    return(LIB3DS_FALSE);
-  }
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
- * \ingroup readwrite
- *
- * Writes a signed dword into a little endian file stream.
- *
- * \param d  The signed dword to write to the file stream.
- * \param f  The input file stream.
- *
- * \return   True on success, False otherwise.
- */
-Lib3dsBool
-lib3ds_intd_write(Lib3dsIntd d, iostream *strm)
-{
-  Lib3dsByte b[4];
-
-  ASSERT(strm);
-  b[3]=(Lib3dsByte)(((Lib3dsDword)d & 0xFF000000) >> 24);
-  b[2]=(Lib3dsByte)(((Lib3dsDword)d & 0x00FF0000) >> 16);
-  b[1]=(Lib3dsByte)(((Lib3dsDword)d & 0x0000FF00) >> 8);
-  b[0]=(Lib3dsByte)(((Lib3dsDword)d & 0x000000FF));
-
-  strm->write((const char*)b,4);
-  if (strm->fail()) {
-    return(LIB3DS_FALSE);
-  }
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
- * \ingroup readwrite
- *
- * Writes a float into a little endian file stream.
- *
- * \param f  The float to write to the file stream.
- * \param f  The input file stream.
- *
- * \return   True on success, False otherwise.
- */
-Lib3dsBool
-lib3ds_float_write(Lib3dsFloat l, iostream *strm)
-{
-  ASSERT(strm);
-
-  Lib3dsByte b[4];
-  Lib3dsByte* ptr = (Lib3dsByte*) (&l);
-
-  if (s_requiresByteSwap)
-  {
-      b[3] = *ptr++;
-      b[2] = *ptr++;
-      b[1] = *ptr++;
-      b[0] = *ptr++;
-  }
-  else
-  {
-      b[0] = *ptr++;
-      b[1] = *ptr++;
-      b[2] = *ptr++;
-      b[3] = *ptr++;
-  }
-
-  strm->write((char*)b,4);
-  if (strm->fail()) {
-    return(LIB3DS_FALSE);
-  }
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
- * \ingroup readwrite
- * \ingroup vector
- *
- * Writes a vector into a file stream in little endian format.   
- *
- * \param v  The vector to write to the file stream. 
- * \param f  Input file stream. 
- */
-Lib3dsBool
-lib3ds_vector_write(Lib3dsVector v, iostream *strm)
-{
-  if (!lib3ds_float_write(v[0], strm)) {
-    return(LIB3DS_FALSE);
-  }
-  if (!lib3ds_float_write(v[1], strm)) {
-    return(LIB3DS_FALSE);
-  }
-  if (!lib3ds_float_write(v[2], strm)) {
-    return(LIB3DS_FALSE);
-  }
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
- * \ingroup readwrite
- */
-Lib3dsBool
-lib3ds_rgb_write(Lib3dsRgb rgb, iostream *strm)
-{
-  if (!lib3ds_float_write(rgb[0], strm)) {
-    return(LIB3DS_FALSE);
-  }
-  if (!lib3ds_float_write(rgb[1], strm)) {
-    return(LIB3DS_FALSE);
-  }
-  if (!lib3ds_float_write(rgb[2], strm)) {
-    return(LIB3DS_FALSE);
-  }
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
- * \ingroup readwrite
- *
- * Writes a zero-terminated string into a file stream.
- *
- * \param f  The float to write to the file stream.
- * \param f  The input file stream.
- *
- * \return   True on success, False otherwise.
- */
-Lib3dsBool
-lib3ds_string_write(const char *s, iostream *strm)
-{
-  ASSERT(s);
-  ASSERT(strm);
-  do strm->write(s,1); while (*s++);
-  if (strm->fail()) {
-    return(LIB3DS_FALSE);
-  }
-  return(LIB3DS_TRUE);
-}
-
Index: /enSceneGraph/trunk/src/osgPlugins/3ds/camera.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/camera.cpp (revision 10076)
+++  (revision )
@@ -1,203 +1,0 @@
-/*
- * The 3D Studio File Format Library
- * Copyright (C) 1996-2001 by J.E. Hoffmann <je-h@gmx.net>
- * All rights reserved.
- *
- * This program is  free  software;  you can redistribute it and/or modify it
- * under the terms of the  GNU Lesser General Public License  as published by 
- * the  Free Software Foundation;  either version 2.1 of the License,  or (at 
- * your option) any later version.
- *
- * This  program  is  distributed in  the  hope that it will  be useful,  but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or  FITNESS FOR A  PARTICULAR PURPOSE.  See the  GNU Lesser General Public  
- * License for more details.
- *
- * You should  have received  a copy of the GNU Lesser General Public License
- * along with  this program;  if not, write to the  Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id$
- */
-#define LIB3DS_EXPORT
-#include "camera.h"
-#include "chunk.h"
-#include "readwrite.h"
-#include <stdlib.h>
-#include <math.h>
-#include <string.h>
-#include "config.h"
-#ifdef WITH_DMALLOC
-#include <dmalloc.h>
-#endif
-
-
-/*!
- * \defgroup camera Cameras
- *
- * \author J.E. Hoffmann <je-h@gmx.net>
- */
-
-
-/*!
- * \ingroup camera
- */
-Lib3dsCamera*
-lib3ds_camera_new(const char *name)
-{
-  Lib3dsCamera *camera;
-
-  ASSERT(name);
-  ASSERT(strlen(name)<64);
-  
-  camera=(Lib3dsCamera*)calloc(sizeof(Lib3dsCamera), 1);
-  if (!camera) {
-    return(0);
-  }
-  strcpy(camera->name, name);
-  camera->fov=45.0f;
-  return(camera);
-}
-
-
-/*!
- * \ingroup camera 
- */
-void
-lib3ds_camera_free(Lib3dsCamera *camera)
-{
-  memset(camera, 0, sizeof(Lib3dsCamera));
-  free(camera);
-}
-
-
-/*!
- * \ingroup camera
- */
-void
-lib3ds_camera_dump(Lib3dsCamera *camera)
-{
-  ASSERT(camera);
-  printf("  name:       %s\n", camera->name);
-  printf("  position:   (%f, %f, %f)\n", 
-    camera->position[0], camera->position[1], camera->position[2]);
-  printf("  target      (%f, %f, %f)\n", 
-    camera->target[0], camera->target[1], camera->target[2]);
-  printf("  roll:       %f\n", camera->roll);
-  printf("  fov:        %f\n", camera->fov);
-  printf("  see_cone:   %s\n", camera->see_cone ? "yes" : "no");
-  printf("  near_range: %f\n", camera->near_range);
-  printf("  far_range:  %f\n", camera->near_range);
-  printf("\n");
-}
-
-
-/*!
- * \ingroup camera
- */
-Lib3dsBool
-lib3ds_camera_read(Lib3dsCamera *camera, iostream *strm)
-{
-  Lib3dsChunk c;
-  Lib3dsWord chunk;
-
-  if (!lib3ds_chunk_read_start(&c, LIB3DS_N_CAMERA, strm)) {
-    return(LIB3DS_FALSE);
-  }
-  {
-    int i;
-    for (i=0; i<3; ++i) {
-      camera->position[i]=lib3ds_float_read(strm);
-    }
-    for (i=0; i<3; ++i) {
-      camera->target[i]=lib3ds_float_read(strm);
-    }
-  }
-  camera->roll=lib3ds_float_read(strm);
-  {
-    float s;
-    s=lib3ds_float_read(strm);
-    if (fabs(s)<LIB3DS_EPSILON) {
-      camera->fov=45.0;
-    }
-    else {
-      camera->fov=2400.0f/s;
-    }
-  }
-  lib3ds_chunk_read_tell(&c, strm);
-  
-  while ((chunk=lib3ds_chunk_read_next(&c, strm))!=0) {
-    switch (chunk) {
-      case LIB3DS_CAM_SEE_CONE:
-        {
-          camera->see_cone=LIB3DS_TRUE;
-        }
-        break;
-      case LIB3DS_CAM_RANGES:
-        {
-          camera->near_range=lib3ds_float_read(strm);
-          camera->far_range=lib3ds_float_read(strm);
-        }
-        break;
-      default:
-        lib3ds_chunk_unknown(chunk);
-    }
-  }
-  
-  lib3ds_chunk_read_end(&c, strm);
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
- * \ingroup camera
- */
-Lib3dsBool
-lib3ds_camera_write(Lib3dsCamera *camera, iostream *strm)
-{
-  Lib3dsChunk c;
-
-  c.chunk=LIB3DS_N_CAMERA;
-  if (!lib3ds_chunk_write_start(&c,strm)) {
-    return(LIB3DS_FALSE);
-  }
-
-  lib3ds_vector_write(camera->position, strm);
-  lib3ds_vector_write(camera->target, strm);
-  lib3ds_float_write(camera->roll, strm);
-  if (fabs(camera->fov)<LIB3DS_EPSILON) {
-    lib3ds_float_write(2400.0f/45.0f, strm);
-  }
-  else {
-    lib3ds_float_write(2400.0f/camera->fov, strm);
-  }
-
-  if (camera->see_cone) {
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_CAM_SEE_CONE;
-    c.size=6;
-    lib3ds_chunk_write(&c, strm);
-  }
-  {
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_CAM_RANGES;
-    c.size=14;
-    lib3ds_chunk_write(&c, strm);
-    lib3ds_float_write(camera->near_range, strm);
-    lib3ds_float_write(camera->far_range, strm);
-  }
-
-  if (!lib3ds_chunk_write_end(&c,strm)) {
-    return(LIB3DS_FALSE);
-  }
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
-
-\typedef Lib3dsCamera
-  \ingroup camera
-  \sa _Lib3dsCamera
-
-*/
Index: /enSceneGraph/trunk/src/osgPlugins/3ds/tracks.h
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/tracks.h (revision 10076)
+++  (revision )
@@ -1,209 +1,0 @@
-/* -*- c -*- */
-#ifndef INCLUDED_LIB3DS_TRACKS_H
-#define INCLUDED_LIB3DS_TRACKS_H
-/*
- * The 3D Studio File Format Library
- * Copyright (C) 1996-2001 by J.E. Hoffmann <je-h@gmx.net>
- * All rights reserved.
- *
- * This program is  free  software;  you can redistribute it and/or modify it
- * under the terms of the  GNU Lesser General Public License  as published by 
- * the  Free Software Foundation;  either version 2.1 of the License,  or (at 
- * your option) any later version.
- *
- * This  program  is  distributed in  the  hope that it will  be useful,  but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or  FITNESS FOR A  PARTICULAR PURPOSE.  See the  GNU Lesser General Public  
- * License for more details.
- *
- * You should  have received  a copy of the GNU Lesser General Public License
- * along with  this program;  if not, write to the  Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id$
- */
-
-#ifndef INCLUDED_LIB3DS_TCB_H
-#include "tcb.h"
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*!
- * Track flags
- * \ingroup tracks
- */
-typedef enum {
-  LIB3DS_REPEAT    =0x0001,
-  LIB3DS_SMOOTH    =0x0002,
-  LIB3DS_LOCK_X    =0x0008,
-  LIB3DS_LOCK_Y    =0x0010,
-  LIB3DS_LOCK_Z    =0x0020,
-  LIB3DS_UNLINK_X  =0x0100,
-  LIB3DS_UNLINK_Y  =0x0200,
-  LIB3DS_UNLINK_Z  =0x0400
-} Lib3dsTrackFlags;
-
-/*!
- * Boolean track key
- * \ingroup tracks
- */
-struct _Lib3dsBoolKey {
-    Lib3dsTcb tcb;
-    Lib3dsBoolKey *next;
-};
-
-/*!
- * Boolean track
- * \ingroup tracks
- */
-struct _Lib3dsBoolTrack {
-    Lib3dsDword flags;
-    Lib3dsBoolKey *keyL;
-};
-
-/*!
- * Floating-point track key
- * \ingroup tracks
- */
-struct _Lib3dsLin1Key {
-    Lib3dsTcb tcb;
-    Lib3dsLin1Key *next;
-    Lib3dsFloat value;
-    Lib3dsFloat dd;
-    Lib3dsFloat ds;
-};
-  
-/*!
- * Floating-point track
- * \ingroup tracks
- */
-struct _Lib3dsLin1Track {
-    Lib3dsDword flags;
-    Lib3dsLin1Key *keyL;
-};
-
-/*!
- * Vector track key
- * \ingroup tracks
- */
-struct _Lib3dsLin3Key {
-    Lib3dsTcb tcb;
-    Lib3dsLin3Key *next;  
-    Lib3dsVector value;
-    Lib3dsVector dd;
-    Lib3dsVector ds;
-};
-  
-/*!
- * Vector track
- * \ingroup tracks
- */
-struct _Lib3dsLin3Track {
-    Lib3dsDword flags;
-    Lib3dsLin3Key *keyL;
-};
-
-/*!
- * Rotation track key
- * \ingroup tracks
- */
-struct _Lib3dsQuatKey {
-    Lib3dsTcb tcb;
-    Lib3dsQuatKey *next;  
-    Lib3dsVector axis;
-    Lib3dsFloat angle;
-    Lib3dsQuat q;
-    Lib3dsQuat dd;
-    Lib3dsQuat ds;
-};
-  
-/*!
- * Rotation track 
- * \ingroup tracks
- */
-struct _Lib3dsQuatTrack {
-    Lib3dsDword flags;
-    Lib3dsQuatKey *keyL;
-};
-
-/*!
- * Morph track key
- * \ingroup tracks
- */
-struct _Lib3dsMorphKey {
-    Lib3dsTcb tcb;
-    Lib3dsMorphKey *next;  
-    char name[64];
-};
-  
-/*!
- * Morph track
- * \ingroup tracks
- */
-struct _Lib3dsMorphTrack {
-    Lib3dsDword flags;
-    Lib3dsMorphKey *keyL;
-};
-
-extern LIB3DSAPI Lib3dsBoolKey* lib3ds_bool_key_new();
-extern LIB3DSAPI void lib3ds_bool_key_free(Lib3dsBoolKey* key);
-extern LIB3DSAPI void lib3ds_bool_track_free_keys(Lib3dsBoolTrack *track);
-extern LIB3DSAPI void lib3ds_bool_track_insert(Lib3dsBoolTrack *track, Lib3dsBoolKey* key);
-extern LIB3DSAPI void lib3ds_bool_track_remove(Lib3dsBoolTrack *track, Lib3dsIntd frame);
-extern LIB3DSAPI void lib3ds_bool_track_eval(Lib3dsBoolTrack *track, Lib3dsBool *p, Lib3dsFloat t);
-extern LIB3DSAPI Lib3dsBool lib3ds_bool_track_read(Lib3dsBoolTrack *track, iostream *strm);
-extern LIB3DSAPI Lib3dsBool lib3ds_bool_track_write(Lib3dsBoolTrack *track, iostream *strm);
-
-extern LIB3DSAPI Lib3dsLin1Key* lib3ds_lin1_key_new();
-extern LIB3DSAPI void lib3ds_lin1_key_free(Lib3dsLin1Key* key);
-extern LIB3DSAPI void lib3ds_lin1_track_free_keys(Lib3dsLin1Track *track);
-extern LIB3DSAPI void lib3ds_lin1_key_setup(Lib3dsLin1Key *p, Lib3dsLin1Key *cp, Lib3dsLin1Key *c,
-  Lib3dsLin1Key *cn, Lib3dsLin1Key *n);
-extern LIB3DSAPI void lib3ds_lin1_track_setup(Lib3dsLin1Track *track);
-extern LIB3DSAPI void lib3ds_lin1_track_insert(Lib3dsLin1Track *track, Lib3dsLin1Key *key);
-extern LIB3DSAPI void lib3ds_lin1_track_remove(Lib3dsLin1Track *track, Lib3dsIntd frame);
-extern LIB3DSAPI void lib3ds_lin1_track_eval(Lib3dsLin1Track *track, Lib3dsFloat *p, Lib3dsFloat t);
-extern LIB3DSAPI Lib3dsBool lib3ds_lin1_track_read(Lib3dsLin1Track *track, iostream *strm);
-extern LIB3DSAPI Lib3dsBool lib3ds_lin1_track_write(Lib3dsLin1Track *track, iostream *strm);
-
-extern LIB3DSAPI Lib3dsLin3Key* lib3ds_lin3_key_new();
-extern LIB3DSAPI void lib3ds_lin3_key_free(Lib3dsLin3Key* key);
-extern LIB3DSAPI void lib3ds_lin3_track_free_keys(Lib3dsLin3Track *track);
-extern LIB3DSAPI void lib3ds_lin3_key_setup(Lib3dsLin3Key *p, Lib3dsLin3Key *cp, Lib3dsLin3Key *c,
-  Lib3dsLin3Key *cn, Lib3dsLin3Key *n);
-extern LIB3DSAPI void lib3ds_lin3_track_setup(Lib3dsLin3Track *track);
-extern LIB3DSAPI void lib3ds_lin3_track_insert(Lib3dsLin3Track *track, Lib3dsLin3Key *key);
-extern LIB3DSAPI void lib3ds_lin3_track_remove(Lib3dsLin3Track *track, Lib3dsIntd frame);
-extern LIB3DSAPI void lib3ds_lin3_track_eval(Lib3dsLin3Track *track, Lib3dsVector p, Lib3dsFloat t);
-extern LIB3DSAPI Lib3dsBool lib3ds_lin3_track_read(Lib3dsLin3Track *track, iostream *strm);
-extern LIB3DSAPI Lib3dsBool lib3ds_lin3_track_write(Lib3dsLin3Track *track, iostream *strm);
-
-extern LIB3DSAPI Lib3dsQuatKey* lib3ds_quat_key_new();
-extern LIB3DSAPI void lib3ds_quat_key_free(Lib3dsQuatKey* key);
-extern LIB3DSAPI void lib3ds_quat_track_free_keys(Lib3dsQuatTrack *track);
-extern LIB3DSAPI void lib3ds_quat_key_setup(Lib3dsQuatKey *p, Lib3dsQuatKey *cp, Lib3dsQuatKey *c,
-  Lib3dsQuatKey *cn, Lib3dsQuatKey *n);
-extern LIB3DSAPI void lib3ds_quat_track_setup(Lib3dsQuatTrack *track);
-extern LIB3DSAPI void lib3ds_quat_track_insert(Lib3dsQuatTrack *track, Lib3dsQuatKey *key);
-extern LIB3DSAPI void lib3ds_quat_track_remove(Lib3dsQuatTrack *track, Lib3dsIntd frame);
-extern LIB3DSAPI void lib3ds_quat_track_eval(Lib3dsQuatTrack *track, Lib3dsQuat p, Lib3dsFloat t);
-extern LIB3DSAPI Lib3dsBool lib3ds_quat_track_read(Lib3dsQuatTrack *track, iostream *strm);
-extern LIB3DSAPI Lib3dsBool lib3ds_quat_track_write(Lib3dsQuatTrack *track, iostream *strm);
-
-extern LIB3DSAPI Lib3dsMorphKey* lib3ds_morph_key_new();
-extern LIB3DSAPI void lib3ds_morph_key_free(Lib3dsMorphKey* key);
-extern LIB3DSAPI void lib3ds_morph_track_free_keys(Lib3dsMorphTrack *track);
-extern LIB3DSAPI void lib3ds_morph_track_insert(Lib3dsMorphTrack *track, Lib3dsMorphKey *key);
-extern LIB3DSAPI void lib3ds_morph_track_remove(Lib3dsMorphTrack *track, Lib3dsIntd frame);
-extern LIB3DSAPI void lib3ds_morph_track_eval(Lib3dsMorphTrack *track, char *p, Lib3dsFloat t);
-extern LIB3DSAPI Lib3dsBool lib3ds_morph_track_read(Lib3dsMorphTrack *track, iostream *strm);
-extern LIB3DSAPI Lib3dsBool lib3ds_morph_track_write(Lib3dsMorphTrack *track, iostream *strm);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
-
Index: /enSceneGraph/trunk/src/osgPlugins/3ds/mesh.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/mesh.cpp (revision 10076)
+++  (revision )
@@ -1,967 +1,0 @@
-/*
- * The 3D Studio File Format Library
- * Copyright (C) 1996-2001 by J.E. Hoffmann <je-h@gmx.net>
- * All rights reserved.
- *
- * This program is  free  software;  you can redistribute it and/or modify it
- * under the terms of the  GNU Lesser General Public License  as published by 
- * the  Free Software Foundation;  either version 2.1 of the License,  or (at 
- * your option) any later version.
- *
- * This  program  is  distributed in  the  hope that it will  be useful,  but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or  FITNESS FOR A  PARTICULAR PURPOSE.  See the  GNU Lesser General Public  
- * License for more details.
- *
- * You should  have received  a copy of the GNU Lesser General Public License
- * along with  this program;  if not, write to the  Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id$
- */
-#define LIB3DS_EXPORT
-#include "mesh.h"
-#include "readwrite.h"
-#include "chunk.h"
-#include "vector.h"
-#include "matrix.h"
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-#include "config.h"
-#ifdef WITH_DMALLOC
-#include <dmalloc.h>
-#endif
-
-
-/*!
- * \defgroup mesh Meshes
- *
- * \author J.E. Hoffmann <je-h@gmx.net>
- */
-
-
-static Lib3dsBool
-face_array_read(Lib3dsMesh *mesh, iostream *strm)
-{
-  Lib3dsChunk c;
-  Lib3dsWord chunk;
-  int i;
-  int faces;
-
-  if (!lib3ds_chunk_read_start(&c, LIB3DS_FACE_ARRAY, strm)) {
-    return(LIB3DS_FALSE);
-  }
-  lib3ds_mesh_free_face_list(mesh);
-  
-  faces=lib3ds_word_read(strm);
-  if (faces) {
-    if (!lib3ds_mesh_new_face_list(mesh, faces)) {
-      LIB3DS_ERROR_LOG;
-      return(LIB3DS_FALSE);
-    }
-    for (i=0; i<faces; ++i) {
-      strcpy(mesh->faceL[i].material, "");
-      mesh->faceL[i].points[0]=lib3ds_word_read(strm);
-      mesh->faceL[i].points[1]=lib3ds_word_read(strm);
-      mesh->faceL[i].points[2]=lib3ds_word_read(strm);
-      mesh->faceL[i].flags=lib3ds_word_read(strm);
-    }
-    lib3ds_chunk_read_tell(&c, strm);
-
-    while ((chunk=lib3ds_chunk_read_next(&c, strm))!=0) {
-      switch (chunk) {
-        case LIB3DS_SMOOTH_GROUP:
-          {
-            unsigned i;
-
-            for (i=0; i<mesh->faces; ++i) {
-              mesh->faceL[i].smoothing=lib3ds_dword_read(strm);
-            }
-          }
-          break;
-        case LIB3DS_MSH_MAT_GROUP:
-          {
-            char name[64];
-            unsigned faces;
-            unsigned i;
-            unsigned index;
-
-            if (!lib3ds_string_read(name, 64, strm)) {
-              return(LIB3DS_FALSE);
-            }
-            faces=lib3ds_word_read(strm);
-            for (i=0; i<faces; ++i) {
-              index=lib3ds_word_read(strm);
-              ASSERT(index<mesh->faces);
-              strcpy(mesh->faceL[index].material, name);
-            }
-          }
-          break;
-        case LIB3DS_MSH_BOXMAP:
-          {
-            char name[64];
-
-            if (!lib3ds_string_read(name, 64, strm)) {
-              return(LIB3DS_FALSE);
-            }
-            strcpy(mesh->box_map.front, name);
-            if (!lib3ds_string_read(name, 64, strm)) {
-              return(LIB3DS_FALSE);
-            }
-            strcpy(mesh->box_map.back, name);
-            if (!lib3ds_string_read(name, 64, strm)) {
-              return(LIB3DS_FALSE);
-            }
-            strcpy(mesh->box_map.left, name);
-            if (!lib3ds_string_read(name, 64, strm)) {
-              return(LIB3DS_FALSE);
-            }
-            strcpy(mesh->box_map.right, name);
-            if (!lib3ds_string_read(name, 64, strm)) {
-              return(LIB3DS_FALSE);
-            }
-            strcpy(mesh->box_map.top, name);
-            if (!lib3ds_string_read(name, 64, strm)) {
-              return(LIB3DS_FALSE);
-            }
-            strcpy(mesh->box_map.bottom, name);
-          }
-          break;
-        default:
-          lib3ds_chunk_unknown(chunk);
-      }
-    }
-    
-  }
-  lib3ds_chunk_read_end(&c, strm);
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
- * \ingroup mesh
- */
-Lib3dsMesh*
-lib3ds_mesh_new(const char *name)
-{
-  Lib3dsMesh *mesh;
-
-  ASSERT(name);
-  ASSERT(strlen(name)<64);
-  
-  mesh=(Lib3dsMesh*)calloc(sizeof(Lib3dsMesh), 1);
-  if (!mesh) {
-    return(0);
-  }
-  strcpy(mesh->name, name);
-  lib3ds_matrix_identity(mesh->matrix);
-  mesh->map_data.maptype=LIB3DS_MAP_NONE;
-  return(mesh);
-}
-
-
-/*!
- * \ingroup mesh
- */
-void
-lib3ds_mesh_free(Lib3dsMesh *mesh)
-{
-  lib3ds_mesh_free_point_list(mesh);
-  lib3ds_mesh_free_flag_list(mesh);
-  lib3ds_mesh_free_texel_list(mesh);
-  lib3ds_mesh_free_face_list(mesh);
-  memset(mesh, 0, sizeof(Lib3dsMesh));
-  free(mesh);
-}
-
-
-/*!
- * \ingroup mesh
- */
-Lib3dsBool
-lib3ds_mesh_new_point_list(Lib3dsMesh *mesh, Lib3dsDword points)
-{
-  ASSERT(mesh);
-  if (mesh->pointL) {
-    ASSERT(mesh->points);
-    lib3ds_mesh_free_point_list(mesh);
-  }
-  ASSERT(!mesh->pointL && !mesh->points);
-  mesh->points=0;
-  mesh->pointL=(Lib3dsPoint*)calloc(sizeof(Lib3dsPoint)*points,1);
-  if (!mesh->pointL) {
-    LIB3DS_ERROR_LOG;
-    return(LIB3DS_FALSE);
-  }
-  mesh->points=points;
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
- * \ingroup mesh
- */
-void
-lib3ds_mesh_free_point_list(Lib3dsMesh *mesh)
-{
-  ASSERT(mesh);
-  if (mesh->pointL) {
-    ASSERT(mesh->points);
-    free(mesh->pointL);
-    mesh->pointL=0;
-    mesh->points=0;
-  }
-  else {
-    ASSERT(!mesh->points);
-  }
-}
-
-
-/*!
- * \ingroup mesh
- */
-Lib3dsBool
-lib3ds_mesh_new_flag_list(Lib3dsMesh *mesh, Lib3dsDword flags)
-{
-  ASSERT(mesh);
-  if (mesh->flagL) {
-    ASSERT(mesh->flags);
-    lib3ds_mesh_free_flag_list(mesh);
-  }
-  ASSERT(!mesh->flagL && !mesh->flags);
-  mesh->flags=0;
-  mesh->flagL=(Lib3dsWord*)calloc(sizeof(Lib3dsWord)*flags,1);
-  if (!mesh->flagL) {
-    LIB3DS_ERROR_LOG;
-    return(LIB3DS_FALSE);
-  }
-  mesh->flags=flags;
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
- * \ingroup mesh
- */
-void
-lib3ds_mesh_free_flag_list(Lib3dsMesh *mesh)
-{
-  ASSERT(mesh);
-  if (mesh->flagL) {
-    ASSERT(mesh->flags);
-    free(mesh->flagL);
-    mesh->flagL=0;
-    mesh->flags=0;
-  }
-  else {
-    ASSERT(!mesh->flags);
-  }
-}
-
-
-/*!
- * \ingroup mesh
- */
-Lib3dsBool
-lib3ds_mesh_new_texel_list(Lib3dsMesh *mesh, Lib3dsDword texels)
-{
-  ASSERT(mesh);
-  if (mesh->texelL) {
-    ASSERT(mesh->texels);
-    lib3ds_mesh_free_texel_list(mesh);
-  }
-  ASSERT(!mesh->texelL && !mesh->texels);
-  mesh->texels=0;
-  mesh->texelL=(Lib3dsTexel*) calloc(sizeof(Lib3dsTexel)*texels,1);
-  if (!mesh->texelL) {
-    LIB3DS_ERROR_LOG;
-    return(LIB3DS_FALSE);
-  }
-  mesh->texels=texels;
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
- * \ingroup mesh
- */
-void
-lib3ds_mesh_free_texel_list(Lib3dsMesh *mesh)
-{
-  ASSERT(mesh);
-  if (mesh->texelL) {
-    ASSERT(mesh->texels);
-    free(mesh->texelL);
-    mesh->texelL=0;
-    mesh->texels=0;
-  }
-  else {
-    ASSERT(!mesh->texels);
-  }
-}
-
-
-/*!
- * \ingroup mesh
- */
-Lib3dsBool
-lib3ds_mesh_new_face_list(Lib3dsMesh *mesh, Lib3dsDword faces)
-{
-  ASSERT(mesh);
-  if (mesh->faceL) {
-    ASSERT(mesh->faces);
-    lib3ds_mesh_free_face_list(mesh);
-  }
-  ASSERT(!mesh->faceL && !mesh->faces);
-  mesh->faces=0;
-  mesh->faceL=(Lib3dsFace*)calloc(sizeof(Lib3dsFace)*faces,1);
-  if (!mesh->faceL) {
-    LIB3DS_ERROR_LOG;
-    return(LIB3DS_FALSE);
-  }
-  mesh->faces=faces;
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
- * \ingroup mesh
- */
-void
-lib3ds_mesh_free_face_list(Lib3dsMesh *mesh)
-{
-  ASSERT(mesh);
-  if (mesh->faceL) {
-    ASSERT(mesh->faces);
-    free(mesh->faceL);
-    mesh->faceL=0;
-    mesh->faces=0;
-  }
-  else {
-    ASSERT(!mesh->faces);
-  }
-}
-
-
-typedef struct _Lib3dsFaces Lib3dsFaces; 
-
-struct _Lib3dsFaces {
-  Lib3dsFaces *next;
-  Lib3dsFace *face;
-};
-
-
-
-
-/*!
- * \ingroup mesh
- */
-void
-lib3ds_mesh_bounding_box(Lib3dsMesh *mesh, Lib3dsVector min, Lib3dsVector max)
-{
-  unsigned i,j;
-  Lib3dsFloat v;
-
-  if (!mesh->points) {
-    lib3ds_vector_zero(min);
-    lib3ds_vector_zero(max);
-    return;
-  }
- 
-  lib3ds_vector_copy(min, mesh->pointL[0].pos);
-  lib3ds_vector_copy(max, mesh->pointL[0].pos);
-  for (i=1; i<mesh->points; ++i) {
-    for (j=0; j<3; ++j) {
-      v=mesh->pointL[i].pos[j];
-      if (v<min[j]) {
-        min[j]=v;
-      }
-      if (v>max[j]) {
-        max[j]=v;
-      }
-    }
-  };
-}
-
-
-/*!
- * Calculates the vertex normals corresponding to the smoothing group
- * settings for each face of a mesh.
- *
- * \param mesh      A pointer to the mesh to calculate the normals for.
- * \param normalL   A pointer to a buffer to store the calculated
- *                  normals. The buffer must have the size:
- *                  3*sizeof(Lib3dsVector)*mesh->faces. 
- *
- * To allocate the normal buffer do for example the following:
- * \code
- *  Lib3dsVector *normalL = malloc(3*sizeof(Lib3dsVector)*mesh->faces);
- * \endcode
- *
- * To access the normal of the i-th vertex of the j-th face do the 
- * following:
- * \code
- *   normalL[3*j+i]
- * \endcode
- */
-void
-lib3ds_mesh_calculate_normals(Lib3dsMesh *mesh, Lib3dsVector *normalL)
-{
-  Lib3dsFaces **fl; 
-  Lib3dsFaces *fa; 
-  unsigned i,j,k;
-
-  if (!mesh->faces) {
-    return;
-  }
-
-  fl=(Lib3dsFaces**)calloc(sizeof(Lib3dsFaces*),mesh->points);
-  ASSERT(fl);
-  fa=(Lib3dsFaces*)calloc(sizeof(Lib3dsFaces),3*mesh->faces);
-  ASSERT(fa);
-  k=0;
-  for (i=0; i<mesh->faces; ++i) {
-    Lib3dsFace *f=&mesh->faceL[i];
-    for (j=0; j<3; ++j) {
-      Lib3dsFaces* l=&fa[k++];
-      ASSERT(f->points[j]<mesh->points);
-      l->face=f;
-      l->next=fl[f->points[j]];
-      fl[f->points[j]]=l;
-    }
-  }
-  
-  for (i=0; i<mesh->faces; ++i) {
-    Lib3dsFace *f=&mesh->faceL[i];
-    for (j=0; j<3; ++j) {
-      Lib3dsVector n,N[32];
-      Lib3dsFaces *p;
-      int k,l;
-      int found;
-
-      ASSERT(f->points[j]<mesh->points);
-
-      if (f->smoothing) {
-        lib3ds_vector_zero(n);
-        k=0;
-        for (p=fl[f->points[j]]; p; p=p->next) {
-          found=0;
-          for (l=0; l<k; ++l) {
-            if (fabs(lib3ds_vector_dot(N[l], p->face->normal)-1.0)<1e-5) {
-              found=1;
-              break;
-            }
-          }
-          if (!found) {
-            if (f->smoothing & p->face->smoothing) {
-              lib3ds_vector_add(n,n, p->face->normal);
-              lib3ds_vector_copy(N[k], p->face->normal);
-              ++k;
-            }
-          }
-        }
-      } 
-      else {
-        lib3ds_vector_copy(n, f->normal);
-      }
-      lib3ds_vector_normalize(n);
-
-      lib3ds_vector_copy(normalL[3*i+j], n);
-    }
-  }
-
-  free(fa);
-  free(fl);
-}
-
-
-/*!
- * This function prints data associated with the specified mesh such as
- * vertex and point lists.
- *
- * \param mesh  Points to a mesh that you wish to view the data for.
- *
- * \return None
- *
- * \warning WIN32: Should only be used in a console window not in a GUI.
- *
- * \ingroup mesh
- */
-void
-lib3ds_mesh_dump(Lib3dsMesh *mesh)
-{
-  unsigned i;
-  Lib3dsVector p;
-
-  ASSERT(mesh);
-  printf("  %s vertices=%d faces=%d\n",
-    mesh->name,
-    mesh->points,
-    mesh->faces
-  );
-  printf("  matrix:\n");
-  lib3ds_matrix_dump(mesh->matrix);
-  printf("  point list:\n");
-  for (i=0; i<mesh->points; ++i) {
-    lib3ds_vector_copy(p, mesh->pointL[i].pos);
-    printf ("    %8f %8f %8f\n", p[0], p[1], p[2]);
-  }
-  printf("  facelist:\n");
-  for (i=0; i<mesh->points; ++i) {
-    printf ("    %4d %4d %4d  smoothing:%X\n",
-      mesh->faceL[i].points[0],
-      mesh->faceL[i].points[1],
-      mesh->faceL[i].points[2],
-      static_cast<int>(mesh->faceL[i].smoothing)
-    );
-  }
-}
-
-
-/*!
- * \ingroup mesh
- */
-Lib3dsBool
-lib3ds_mesh_read(Lib3dsMesh *mesh, iostream *strm)
-{
-  Lib3dsChunk c;
-  Lib3dsWord chunk;
-
-  if (!lib3ds_chunk_read_start(&c, LIB3DS_N_TRI_OBJECT, strm)) {
-    return(LIB3DS_FALSE);
-  }
-
-  while ((chunk=lib3ds_chunk_read_next(&c, strm))!=0) {
-    switch (chunk) {
-      case LIB3DS_MESH_MATRIX:
-        {
-          int i,j;
-          
-          lib3ds_matrix_identity(mesh->matrix);
-          for (i=0; i<4; i++) {
-            for (j=0; j<3; j++) {
-              mesh->matrix[i][j]=lib3ds_float_read(strm);
-            }
-          }
-        }
-        break;
-      case LIB3DS_MESH_COLOR:
-        {
-          mesh->color=lib3ds_byte_read(strm);
-        }
-        break;
-      case LIB3DS_POINT_ARRAY:
-        {
-          unsigned i,j;
-          unsigned points;
-          
-          lib3ds_mesh_free_point_list(mesh);
-          points=lib3ds_word_read(strm);
-          if (points) {
-            if (!lib3ds_mesh_new_point_list(mesh, points)) {
-              LIB3DS_ERROR_LOG;
-              return(LIB3DS_FALSE);
-            }
-            for (i=0; i<mesh->points; ++i) {
-              for (j=0; j<3; ++j) {
-                mesh->pointL[i].pos[j]=lib3ds_float_read(strm);
-              }
-            }
-            ASSERT((!mesh->flags) || (mesh->points==mesh->flags));
-            ASSERT((!mesh->texels) || (mesh->points==mesh->texels));
-          }
-        }
-        break;
-      case LIB3DS_POINT_FLAG_ARRAY:
-        {
-          unsigned i;
-          unsigned flags;
-          
-          lib3ds_mesh_free_flag_list(mesh);
-          flags=lib3ds_word_read(strm);
-          if (flags) {
-            if (!lib3ds_mesh_new_flag_list(mesh, flags)) {
-              LIB3DS_ERROR_LOG;
-              return(LIB3DS_FALSE);
-            }
-            for (i=0; i<mesh->flags; ++i) {
-              mesh->flagL[i]=lib3ds_word_read(strm);
-            }
-            ASSERT((!mesh->points) || (mesh->flags==mesh->points));
-            ASSERT((!mesh->texels) || (mesh->flags==mesh->texels));
-          }
-        }
-        break;
-      case LIB3DS_FACE_ARRAY:
-        {
-          lib3ds_chunk_read_reset(&c, strm);
-          if (!face_array_read(mesh, strm)) {
-            return(LIB3DS_FALSE);
-          }
-        }
-        break;
-      case LIB3DS_MESH_TEXTURE_INFO:
-        {
-          int i,j;
-
-          for (i=0; i<2; ++i) {
-            mesh->map_data.tile[i]=lib3ds_float_read(strm);
-          }
-          for (i=0; i<3; ++i) {
-            mesh->map_data.pos[i]=lib3ds_float_read(strm);
-          }
-          mesh->map_data.scale=lib3ds_float_read(strm);
-
-          lib3ds_matrix_identity(mesh->map_data.matrix);
-          for (i=0; i<4; i++) {
-            for (j=0; j<3; j++) {
-              mesh->map_data.matrix[i][j]=lib3ds_float_read(strm);
-            }
-          }
-          for (i=0; i<2; ++i) {
-            mesh->map_data.planar_size[i]=lib3ds_float_read(strm);
-          }
-          mesh->map_data.cylinder_height=lib3ds_float_read(strm);
-        }
-        break;
-      case LIB3DS_TEX_VERTS:
-        {
-          unsigned i;
-          unsigned texels;
-          
-          lib3ds_mesh_free_texel_list(mesh);
-          texels=lib3ds_word_read(strm);
-          if (texels) {
-            if (!lib3ds_mesh_new_texel_list(mesh, texels)) {
-              LIB3DS_ERROR_LOG;
-              return(LIB3DS_FALSE);
-            }
-            for (i=0; i<mesh->texels; ++i) {
-              mesh->texelL[i][0]=lib3ds_float_read(strm);
-              mesh->texelL[i][1]=lib3ds_float_read(strm);
-            }
-            ASSERT((!mesh->points) || (mesh->texels==mesh->points));
-            ASSERT((!mesh->flags) || (mesh->texels==mesh->flags));
-          }
-        }
-        break;
-      default:
-        lib3ds_chunk_unknown(chunk);
-    }
-  }
-  {
-    unsigned j;
-
-    for (j=0; j<mesh->faces; ++j) {
-      ASSERT(mesh->faceL[j].points[0]<mesh->points);
-      ASSERT(mesh->faceL[j].points[1]<mesh->points);
-      ASSERT(mesh->faceL[j].points[2]<mesh->points);
-      lib3ds_vector_normal(
-        mesh->faceL[j].normal,
-        mesh->pointL[mesh->faceL[j].points[0]].pos,
-        mesh->pointL[mesh->faceL[j].points[1]].pos,
-        mesh->pointL[mesh->faceL[j].points[2]].pos
-      );
-    }
-  }
-  
-  lib3ds_chunk_read_end(&c, strm);
-  return(LIB3DS_TRUE);
-}
-
-
-static Lib3dsBool
-point_array_write(Lib3dsMesh *mesh, iostream *strm)
-{
-  Lib3dsChunk c;
-  unsigned i;
-
-  if (!mesh->points || !mesh->pointL) {
-    return(LIB3DS_TRUE);
-  }
-  ASSERT(mesh->points<0x10000);
-  c.chunk=LIB3DS_POINT_ARRAY;
-  c.size=8+12*mesh->points;
-  lib3ds_chunk_write(&c, strm);
-  
-  lib3ds_word_write((Lib3dsWord)mesh->points, strm);
-  for (i=0; i<mesh->points; ++i) {
-    lib3ds_vector_write(mesh->pointL[i].pos, strm);
-  }
-  return(LIB3DS_TRUE);
-}
-
-
-static Lib3dsBool
-flag_array_write(Lib3dsMesh *mesh, iostream *strm)
-{
-  Lib3dsChunk c;
-  unsigned i;
-  
-  if (!mesh->flags || !mesh->flagL) {
-    return(LIB3DS_TRUE);
-  }
-  ASSERT(mesh->flags<0x10000);
-  c.chunk=LIB3DS_POINT_FLAG_ARRAY;
-  c.size=8+2*mesh->flags;
-  lib3ds_chunk_write(&c, strm);
-  
-  lib3ds_word_write((Lib3dsWord)mesh->flags, strm);
-  for (i=0; i<mesh->flags; ++i) {
-    lib3ds_word_write(mesh->flagL[i], strm);
-  }
-  return(LIB3DS_TRUE);
-}
-
-
-static Lib3dsBool
-face_array_write(Lib3dsMesh *mesh, iostream *strm)
-{
-  Lib3dsChunk c;
-  
-  if (!mesh->faces || !mesh->faceL) {
-    return(LIB3DS_TRUE);
-  }
-  ASSERT(mesh->faces<0x10000);
-  c.chunk=LIB3DS_FACE_ARRAY;
-  if (!lib3ds_chunk_write_start(&c, strm)) {
-    return(LIB3DS_FALSE);
-  }
-  {
-    unsigned i;
-
-    lib3ds_word_write((Lib3dsWord)mesh->faces, strm);
-    for (i=0; i<mesh->faces; ++i) {
-      lib3ds_word_write(mesh->faceL[i].points[0], strm);
-      lib3ds_word_write(mesh->faceL[i].points[1], strm);
-      lib3ds_word_write(mesh->faceL[i].points[2], strm);
-      lib3ds_word_write(mesh->faceL[i].flags, strm);
-    }
-  }
-
-  { /*---- MSH_MAT_GROUP ----*/
-    Lib3dsChunk c;
-    unsigned i,j;
-    Lib3dsWord num;
-    char *matf=(char*)calloc(sizeof(char), mesh->faces);
-    if (!matf) {
-      return(LIB3DS_FALSE);
-    }
-    
-    for (i=0; i<mesh->faces; ++i) {
-      if (!matf[i] && strlen(mesh->faceL[i].material)) {
-        matf[i]=1;
-        num=1;
-        
-        for (j=i+1; j<mesh->faces; ++j) {
-          if (strcmp(mesh->faceL[i].material, mesh->faceL[j].material)==0) ++num;
-        }
-        
-        c.chunk=LIB3DS_MSH_MAT_GROUP;
-        c.size=6+ strlen(mesh->faceL[i].material)+1 +2+2*num;
-        lib3ds_chunk_write(&c, strm);
-        lib3ds_string_write(mesh->faceL[i].material, strm);
-        lib3ds_word_write(num, strm);
-        lib3ds_word_write((Lib3dsWord)i, strm);
-        
-        for (j=i+1; j<mesh->faces; ++j) {
-          if (strcmp(mesh->faceL[i].material, mesh->faceL[j].material)==0) {
-            lib3ds_word_write((Lib3dsWord)j, strm);
-            matf[j]=1;
-          }
-        }
-      }      
-    }
-    free(matf);
-  }
-
-  { /*---- SMOOTH_GROUP ----*/
-    Lib3dsChunk c;
-    unsigned i;
-    
-    c.chunk=LIB3DS_SMOOTH_GROUP;
-    c.size=6+4*mesh->faces;
-    lib3ds_chunk_write(&c, strm);
-    
-    for (i=0; i<mesh->faces; ++i) {
-      lib3ds_dword_write(mesh->faceL[i].smoothing, strm);
-    }
-  }
-  
-  { /*---- MSH_BOXMAP ----*/
-    Lib3dsChunk c;
-
-    if (strlen(mesh->box_map.front) ||
-      strlen(mesh->box_map.back) ||
-      strlen(mesh->box_map.left) ||
-      strlen(mesh->box_map.right) ||
-      strlen(mesh->box_map.top) ||
-      strlen(mesh->box_map.bottom)) {
-    
-      c.chunk=LIB3DS_MSH_BOXMAP;
-      if (!lib3ds_chunk_write_start(&c, strm)) {
-        return(LIB3DS_FALSE);
-      }
-      
-      lib3ds_string_write(mesh->box_map.front, strm);
-      lib3ds_string_write(mesh->box_map.back, strm);
-      lib3ds_string_write(mesh->box_map.left, strm);
-      lib3ds_string_write(mesh->box_map.right, strm);
-      lib3ds_string_write(mesh->box_map.top, strm);
-      lib3ds_string_write(mesh->box_map.bottom, strm);
-      
-      if (!lib3ds_chunk_write_end(&c, strm)) {
-        return(LIB3DS_FALSE);
-      }
-    }
-  }
-
-  if (!lib3ds_chunk_write_end(&c, strm)) {
-    return(LIB3DS_FALSE);
-  }
-  return(LIB3DS_TRUE);
-}
-
-
-static Lib3dsBool
-texel_array_write(Lib3dsMesh *mesh, iostream *strm)
-{
-  Lib3dsChunk c;
-  unsigned i;
-  
-  if (!mesh->texels || !mesh->texelL) {
-    return(LIB3DS_TRUE);
-  }
-  ASSERT(mesh->texels<0x10000);
-  c.chunk=LIB3DS_TEX_VERTS;
-  c.size=8+8*mesh->texels;
-  lib3ds_chunk_write(&c, strm);
-  
-  lib3ds_word_write((Lib3dsWord)mesh->texels, strm);
-  for (i=0; i<mesh->texels; ++i) {
-    lib3ds_float_write(mesh->texelL[i][0], strm);
-    lib3ds_float_write(mesh->texelL[i][1], strm);
-  }
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
- * \ingroup mesh
- */
-Lib3dsBool
-lib3ds_mesh_write(Lib3dsMesh *mesh, iostream *strm)
-{
-  Lib3dsChunk c;
-
-  c.chunk=LIB3DS_N_TRI_OBJECT;
-  if (!lib3ds_chunk_write_start(&c,strm)) {
-    return(LIB3DS_FALSE);
-  }
-  if (!point_array_write(mesh, strm)) {
-    return(LIB3DS_FALSE);
-  }
-  if (!texel_array_write(mesh, strm)) {
-    return(LIB3DS_FALSE);
-  }
-
-  if (mesh->map_data.maptype!=LIB3DS_MAP_NONE) { /*---- LIB3DS_MESH_TEXTURE_INFO ----*/
-    Lib3dsChunk c;
-    int i,j;
-    
-    c.chunk=LIB3DS_MESH_TEXTURE_INFO;
-    c.size=92;
-    if (!lib3ds_chunk_write(&c,strm)) {
-      return(LIB3DS_FALSE);
-    }
-
-    lib3ds_word_write(mesh->map_data.maptype, strm);
-
-    for (i=0; i<2; ++i) {
-      lib3ds_float_write(mesh->map_data.tile[i], strm);
-    }
-    for (i=0; i<3; ++i) {
-      lib3ds_float_write(mesh->map_data.pos[i], strm);
-    }
-    lib3ds_float_write(mesh->map_data.scale, strm);
-
-    for (i=0; i<4; i++) {
-      for (j=0; j<3; j++) {
-        lib3ds_float_write(mesh->map_data.matrix[i][j], strm);
-      }
-    }
-    for (i=0; i<2; ++i) {
-      lib3ds_float_write(mesh->map_data.planar_size[i], strm);
-    }
-    lib3ds_float_write(mesh->map_data.cylinder_height, strm);
-  }
-
-  if (!flag_array_write(mesh, strm)) {
-    return(LIB3DS_FALSE);
-  }
-  { /*---- LIB3DS_MESH_MATRIX ----*/
-    Lib3dsChunk c;
-    int i,j;
-
-    c.chunk=LIB3DS_MESH_MATRIX;
-    c.size=54;
-    if (!lib3ds_chunk_write(&c,strm)) {
-      return(LIB3DS_FALSE);
-    }
-    for (i=0; i<4; i++) {
-      for (j=0; j<3; j++) {
-        lib3ds_float_write(mesh->matrix[i][j], strm);
-      }
-    }
-  }
-
-  if (mesh->color) { /*---- LIB3DS_MESH_COLOR ----*/
-    Lib3dsChunk c;
-    
-    c.chunk=LIB3DS_MESH_COLOR;
-    c.size=7;
-    if (!lib3ds_chunk_write(&c,strm)) {
-      return(LIB3DS_FALSE);
-    }
-    lib3ds_byte_write(mesh->color, strm);
-  }
-  if (!face_array_write(mesh, strm)) {
-    return(LIB3DS_FALSE);
-  }
-
-  if (!lib3ds_chunk_write_end(&c,strm)) {
-    return(LIB3DS_FALSE);
-  }
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
-
-\typedef Lib3dsFace
-  \ingroup mesh
-  \sa _Lib3dsFace
-
-*/
-/*!
-
-\typedef Lib3dsBoxMap
-  \ingroup mesh
-  \sa _Lib3dsBoxMap
-
-*/
-/*!
-
-\typedef Lib3dsMapData
-  \ingroup mesh
-  \sa _Lib3dsMapData
-
-*/
-/*!
-
-\typedef Lib3dsMesh
-  \ingroup mesh
-  \sa _Lib3dsMesh
-
-*/
Index: /enSceneGraph/trunk/src/osgPlugins/3ds/material.h
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/material.h (revision 10076)
+++  (revision )
@@ -1,171 +1,0 @@
-/* -*- c -*- */
-#ifndef INCLUDED_LIB3DS_MATERIAL_H
-#define INCLUDED_LIB3DS_MATERIAL_H
-/*
- * The 3D Studio File Format Library
- * Copyright (C) 1996-2001 by J.E. Hoffmann <je-h@gmx.net>
- * All rights reserved.
- *
- * This program is  free  software;  you can redistribute it and/or modify it
- * under the terms of the  GNU Lesser General Public License  as published by 
- * the  Free Software Foundation;  either version 2.1 of the License,  or (at 
- * your option) any later version.
- *
- * This  program  is  distributed in  the  hope that it will  be useful,  but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or  FITNESS FOR A  PARTICULAR PURPOSE.  See the  GNU Lesser General Public  
- * License for more details.
- *
- * You should  have received  a copy of the GNU Lesser General Public License
- * along with  this program;  if not, write to the  Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id$
- */
-
-#ifndef INCLUDED_LIB3DS_TYPES_H
-#include "types.h"
-#endif
-
-#include <iostream>
-using namespace std;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*!
- * \ingroup material 
- */
-typedef enum _Lib3dsTextureMapFlags {
-  LIB3DS_DECALE       =0x0001,
-  LIB3DS_MIRROR       =0x0002,
-  LIB3DS_NEGATE       =0x0004,
-  LIB3DS_NO_TILE      =0x0008,
-  LIB3DS_SUMMED_AREA  =0x0010,
-  LIB3DS_ALPHA_SOURCE =0x0020,
-  LIB3DS_TINT         =0x0040,
-  LIB3DS_IGNORE_ALPHA =0x0080,
-  LIB3DS_RGB_TINT     =0x0100
-} Lib3dsTextureMapFlags;
-
-/*!
- * Mateial texture map
- * \ingroup material 
- */
-typedef struct _Lib3dsTextureMap {
-    char name[64];
-    Lib3dsDword flags;
-    Lib3dsFloat percent;
-    Lib3dsFloat blur;
-    Lib3dsFloat scale[2];
-    Lib3dsFloat offset[2];
-    Lib3dsFloat rotation;
-    Lib3dsRgb tint_1;
-    Lib3dsRgb tint_2;
-    Lib3dsRgb tint_r;
-    Lib3dsRgb tint_g;
-    Lib3dsRgb tint_b;
-} Lib3dsTextureMap;
-
-/*!
- * \ingroup material 
- */
-typedef enum _Lib3dsAutoReflMapFlags {
-  LIB3DS_USE_REFL_MAP          =0x0001,
-  LIB3DS_READ_FIRST_FRAME_ONLY =0x0004,
-  LIB3DS_FLAT_MIRROR           =0x0008 
-} Lib3dsAutoReflectionMapFlags;
-
-/*!
- * \ingroup material 
- */
-typedef enum _Lib3dsAutoReflMapAntiAliasLevel {
-  LIB3DS_ANTI_ALIAS_NONE   =0,
-  LIB3DS_ANTI_ALIAS_LOW    =1,
-  LIB3DS_ANTI_ALIAS_MEDIUM =2,
-  LIB3DS_ANTI_ALIAS_HIGH   =3
-} Lib3dsAutoReflMapAntiAliasLevel;
-
-/*!
- * Auto reflection map settings
- * \ingroup material 
- */
-typedef struct _Lib3dsAutoReflMap {
-    Lib3dsDword flags;
-    Lib3dsIntd level;
-    Lib3dsIntd size;
-    Lib3dsIntd frame_step;
-} Lib3dsAutoReflMap;
-
-/*!
- * \ingroup material 
- */
-typedef enum _Lib3dsMaterialShading {
-  LIB3DS_WIRE_FRAME =0,
-  LIB3DS_FLAT       =1, 
-  LIB3DS_GOURAUD    =2, 
-  LIB3DS_PHONG      =3, 
-  LIB3DS_METAL      =4
-} Lib3dsMaterialShading; 
-
-/*!
- * Material
- * \ingroup material 
- */
-struct _Lib3dsMaterial {
-    Lib3dsUserData user;
-    Lib3dsMaterial *next;
-    char name[64];
-    Lib3dsRgba ambient;
-    Lib3dsRgba diffuse;
-    Lib3dsRgba specular;
-    Lib3dsFloat shininess;
-    Lib3dsFloat shin_strength;
-    Lib3dsBool use_blur;
-    Lib3dsFloat blur;
-    Lib3dsFloat transparency;
-    Lib3dsFloat falloff;
-    Lib3dsBool additive;
-    Lib3dsBool use_falloff;
-    Lib3dsBool self_illum;
-    Lib3dsIntw shading;
-    Lib3dsBool soften;
-    Lib3dsBool face_map;
-    Lib3dsBool two_sided;
-    Lib3dsBool map_decal;
-    Lib3dsBool use_wire;
-    Lib3dsBool use_wire_abs;
-    Lib3dsFloat wire_size;
-    Lib3dsTextureMap texture1_map;
-    Lib3dsTextureMap texture1_mask;
-    Lib3dsTextureMap texture2_map;
-    Lib3dsTextureMap texture2_mask;
-    Lib3dsTextureMap opacity_map;
-    Lib3dsTextureMap opacity_mask;
-    Lib3dsTextureMap bump_map;
-    Lib3dsTextureMap bump_mask;
-    Lib3dsTextureMap specular_map;
-    Lib3dsTextureMap specular_mask;
-    Lib3dsTextureMap shininess_map;
-    Lib3dsTextureMap shininess_mask;
-    Lib3dsTextureMap self_illum_map;
-    Lib3dsTextureMap self_illum_mask;
-    Lib3dsTextureMap reflection_map;
-    Lib3dsTextureMap reflection_mask;
-    Lib3dsAutoReflMap autorefl_map;
-};
-
-extern LIB3DSAPI Lib3dsMaterial* lib3ds_material_new();
-extern LIB3DSAPI void lib3ds_material_free(Lib3dsMaterial *material);
-extern LIB3DSAPI void lib3ds_material_dump(Lib3dsMaterial *material);
-extern LIB3DSAPI Lib3dsBool lib3ds_material_read(Lib3dsMaterial *material, iostream *strm);
-extern LIB3DSAPI Lib3dsBool lib3ds_material_write(Lib3dsMaterial *material, iostream *strm);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
-
-
-
Index: /enSceneGraph/trunk/src/osgPlugins/3ds/lib3ds_float.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds_float.cpp (revision 1563)
+++  (revision )
@@ -1,47 +1,0 @@
-/*
- * The 3D Studio File Format Library
- * Copyright (C) 1996-2001 by J.E. Hoffmann <je-h@gmx.net>
- * All rights reserved.
- *
- * This program is  free  software;  you can redistribute it and/or modify it
- * under the terms of the  GNU Lesser General Public License  as published by 
- * the  Free Software Foundation;  either version 2.1 of the License,  or (at 
- * your option) any later version.
- *
- * This  program  is  distributed in  the  hope that it will  be useful,  but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or  FITNESS FOR A  PARTICULAR PURPOSE.  See the  GNU Lesser General Public  
- * License for more details.
- *
- * You should  have received  a copy of the GNU Lesser General Public License
- * along with  this program;  if not, write to the  Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id$
- */
-#define LIB3DS_EXPORT
-#include "lib3ds_float.h"
-
-
-/*!
- * \defgroup float Floating Point Mathematics
- *
- * \author J.E. Hoffmann <je-h@gmx.net>
- */
-
-
-/*!
- * \ingroup float
- */
-Lib3dsFloat
-lib3ds_float_cubic(Lib3dsFloat a, Lib3dsFloat p, Lib3dsFloat q, Lib3dsFloat b, Lib3dsFloat t)
-{
-  Lib3dsDouble x,y,z,w;   
-
-  x=2*t*t*t - 3*t*t + 1;
-  y=-2*t*t*t + 3*t*t;
-  z=t*t*t - 2*t*t + t;
-  w=t*t*t - t*t;
-  return((Lib3dsFloat)(x*a + y*b + z*p + w*q));
-}
-
Index: /enSceneGraph/trunk/src/osgPlugins/3ds/vector.h
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/vector.h (revision 6461)
+++  (revision )
@@ -1,58 +1,0 @@
-/* -*- c -*- */
-#ifndef INCLUDED_LIB3DS_VECTOR_H
-#define INCLUDED_LIB3DS_VECTOR_H
-/*
- * The 3D Studio File Format Library
- * Copyright (C) 1996-2001 by J.E. Hoffmann <je-h@gmx.net>
- * All rights reserved.
- *
- * This program is  free  software;  you can redistribute it and/or modify it
- * under the terms of the  GNU Lesser General Public License  as published by 
- * the  Free Software Foundation;  either version 2.1 of the License,  or (at 
- * your option) any later version.
- *
- * This  program  is  distributed in  the  hope that it will  be useful,  but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or  FITNESS FOR A  PARTICULAR PURPOSE.  See the  GNU Lesser General Public  
- * License for more details.
- *
- * You should  have received  a copy of the GNU Lesser General Public License
- * along with  this program;  if not, write to the  Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id$
- */
-
-#ifndef INCLUDED_LIB3DS_TYPES_H
-#include "types.h"
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern LIB3DSAPI void lib3ds_vector_zero(Lib3dsVector c);
-extern LIB3DSAPI void lib3ds_vector_copy(Lib3dsVector dest, Lib3dsVector src);
-extern LIB3DSAPI void lib3ds_vector_neg(Lib3dsVector c);
-extern LIB3DSAPI void lib3ds_vector_add(Lib3dsVector c, Lib3dsVector a, Lib3dsVector b);
-extern LIB3DSAPI void lib3ds_vector_sub(Lib3dsVector c, Lib3dsVector a, Lib3dsVector b);
-extern LIB3DSAPI void lib3ds_vector_scalar(Lib3dsVector c, Lib3dsFloat k);
-extern LIB3DSAPI void lib3ds_vector_cross(Lib3dsVector c, Lib3dsVector a, Lib3dsVector b);
-extern LIB3DSAPI Lib3dsFloat lib3ds_vector_dot(Lib3dsVector a, Lib3dsVector b);
-extern LIB3DSAPI Lib3dsFloat lib3ds_vector_squared(Lib3dsVector c);
-extern LIB3DSAPI Lib3dsFloat lib3ds_vector_length(Lib3dsVector c);
-extern LIB3DSAPI void lib3ds_vector_normalize(Lib3dsVector c);
-extern LIB3DSAPI void lib3ds_vector_normal(Lib3dsVector n, Lib3dsVector a,
-  Lib3dsVector b, Lib3dsVector c);
-extern LIB3DSAPI void lib3ds_vector_transform(Lib3dsVector c, Lib3dsMatrix m, Lib3dsVector a);
-extern LIB3DSAPI void lib3ds_vector_cubic(Lib3dsVector c, Lib3dsVector a, Lib3dsVector p,
-  Lib3dsVector q, Lib3dsVector b, Lib3dsFloat t);
-extern LIB3DSAPI void lib3ds_vector_min(Lib3dsVector c, Lib3dsVector a);
-extern LIB3DSAPI void lib3ds_vector_max(Lib3dsVector c, Lib3dsVector a);
-extern LIB3DSAPI void lib3ds_vector_dump(Lib3dsVector c);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
-
Index: /enSceneGraph/trunk/src/osgPlugins/3ds/light.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/light.cpp (revision 10076)
+++  (revision )
@@ -1,429 +1,0 @@
-/*
- * The 3D Studio File Format Library
- * Copyright (C) 1996-2001 by J.E. Hoffmann <je-h@gmx.net>
- * All rights reserved.
- *
- * This program is  free  software;  you can redistribute it and/or modify it
- * under the terms of the  GNU Lesser General Public License  as published by 
- * the  Free Software Foundation;  either version 2.1 of the License,  or (at 
- * your option) any later version.
- *
- * This  program  is  distributed in  the  hope that it will  be useful,  but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or  FITNESS FOR A  PARTICULAR PURPOSE.  See the  GNU Lesser General Public  
- * License for more details.
- *
- * You should  have received  a copy of the GNU Lesser General Public License
- * along with  this program;  if not, write to the  Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id$
- */
-#define LIB3DS_EXPORT
-#include "light.h"
-#include "chunk.h"
-#include "readwrite.h"
-#include <stdlib.h>
-#include <math.h>
-#include <string.h>
-#include "config.h"
-#ifdef WITH_DMALLOC
-#include <dmalloc.h>
-#endif
-
-
-/*!
- * \defgroup light Lights
- *
- * \author J.E. Hoffmann <je-h@gmx.net>
- */
-/*!
-
-\typedef Lib3dsLight
-  \ingroup light
-  \sa _Lib3dsLight
-
-*/
-
-
-
-/*!
- * \ingroup light
- */
-Lib3dsLight*
-lib3ds_light_new(const char *name)
-{
-  Lib3dsLight *light;
-
-  ASSERT(name);
-  ASSERT(strlen(name)<64);
-  
-  light=(Lib3dsLight*)calloc(sizeof(Lib3dsLight), 1);
-  if (!light) {
-    return(0);
-  }
-  strcpy(light->name, name);
-  return(light);
-}
-
-
-/*!
- * \ingroup light
- */
-void
-lib3ds_light_free(Lib3dsLight *light)
-{
-  memset(light, 0, sizeof(Lib3dsLight));
-  free(light);
-}
-
-
-/*!
- * \ingroup light
- */
-void
-lib3ds_light_dump(Lib3dsLight *light)
-{
-  ASSERT(light);
-  printf("  name:             %s\n", light->name);
-  printf("  spot_light:       %s\n", light->spot_light ? "yes" : "no");
-  printf("  see_cone:         %s\n", light->see_cone ? "yes" : "no");
-  printf("  color:            (%f, %f, %f)\n", 
-    light->color[0], light->color[1], light->color[2]);
-  printf("  position          (%f, %f, %f)\n", 
-    light->position[0], light->position[1], light->position[2]);
-  printf("  spot              (%f, %f, %f)\n", 
-    light->spot[0], light->spot[1], light->spot[2]);
-  printf("  roll:             %f\n", light->roll);
-  printf("  off:              %s\n", light->off ? "yes" : "no");
-  printf("  outer_range:      %f\n", light->outer_range);
-  printf("  inner_range:      %f\n", light->inner_range);
-  printf("  multiplier:       %f\n", light->multiplier);
-  printf("  attenuation:      %f\n", light->attenuation);
-  printf("  rectangular_spot: %s\n", light->rectangular_spot ? "yes" : "no");
-  printf("  shadowed:         %s\n", light->shadowed ? "yes" : "no");
-  printf("  shadow_bias:      %f\n", light->shadow_bias);
-  printf("  shadow_filter:    %f\n", light->shadow_filter);
-  printf("  shadow_size:      %d\n", light->shadow_size);
-  printf("  spot_aspect:      %f\n", light->spot_aspect);
-  printf("  use_projector:    %s\n", light->use_projector ? "yes" : "no");
-  printf("  projector:        %s\n", light->projector);
-  printf("  spot_overshoot:   %i\n", static_cast<int>(light->spot_overshoot));
-  printf("  ray_shadows:      %s\n", light->ray_shadows ? "yes" : "no");
-  printf("  ray_bias:         %f\n", light->ray_bias);
-  printf("  hot_spot:         %f\n", light->hot_spot);
-  printf("  fall_off:         %f\n", light->fall_off);
-  printf("\n");
-}
-
-
-/*!
- * \ingroup light
- */
-static Lib3dsBool
-spotlight_read(Lib3dsLight *light, iostream *strm)
-{
-  Lib3dsChunk c;
-  Lib3dsWord chunk;
-  int i;
-
-  if (!lib3ds_chunk_read_start(&c, LIB3DS_DL_SPOTLIGHT, strm)) {
-    return(LIB3DS_FALSE);
-  }
-  light->spot_light=LIB3DS_TRUE;
-  for (i=0; i<3; ++i) {
-    light->spot[i]=lib3ds_float_read(strm);
-  }
-  light->hot_spot = lib3ds_float_read(strm);
-  light->fall_off = lib3ds_float_read(strm);
-  lib3ds_chunk_read_tell(&c, strm);
-  
-  while ((chunk=lib3ds_chunk_read_next(&c, strm))!=0) {
-    switch (chunk) {
-      case LIB3DS_DL_SPOT_ROLL:
-        {
-          light->roll=lib3ds_float_read(strm);
-        }
-        break;
-      case LIB3DS_DL_SHADOWED:
-        {
-          light->shadowed=LIB3DS_TRUE;
-        }
-        break;
-      case LIB3DS_DL_LOCAL_SHADOW2:
-        {
-          light->shadow_bias=lib3ds_float_read(strm);
-          light->shadow_filter=lib3ds_float_read(strm);
-          light->shadow_size=lib3ds_intw_read(strm);
-        }
-        break;
-      case LIB3DS_DL_SEE_CONE:
-        {
-          light->see_cone=LIB3DS_TRUE;
-        }
-        break;
-      case LIB3DS_DL_SPOT_RECTANGULAR:
-        {
-          light->rectangular_spot=LIB3DS_TRUE;
-        }
-        break;
-      case LIB3DS_DL_SPOT_ASPECT:
-        {
-          light->spot_aspect=lib3ds_float_read(strm);
-        }
-        break;
-      case LIB3DS_DL_SPOT_PROJECTOR:
-        {
-          light->use_projector=LIB3DS_TRUE;
-          if (!lib3ds_string_read(light->projector, 64, strm)) {
-            return(LIB3DS_FALSE);
-          }
-        }
-      case LIB3DS_DL_SPOT_OVERSHOOT:
-        {
-          light->spot_overshoot=LIB3DS_TRUE;
-        }
-        break;
-      case LIB3DS_DL_RAY_BIAS:
-        {
-          light->ray_bias=lib3ds_float_read(strm);
-        }
-        break;
-      case LIB3DS_DL_RAYSHAD:
-        {
-          light->ray_shadows=LIB3DS_TRUE;
-        }
-        break;
-      default:
-        lib3ds_chunk_unknown(chunk);
-    }
-  }
-  
-  lib3ds_chunk_read_end(&c, strm);
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
- * \ingroup light
- */
-Lib3dsBool
-lib3ds_light_read(Lib3dsLight *light, iostream * strm)
-{
-  Lib3dsChunk c;
-  Lib3dsWord chunk;
-
-  if (!lib3ds_chunk_read_start(&c, LIB3DS_N_DIRECT_LIGHT, strm)) {
-    return(LIB3DS_FALSE);
-  }
-  {
-    int i;
-    for (i=0; i<3; ++i) {
-      light->position[i]=lib3ds_float_read(strm);
-    }
-  }
-  lib3ds_chunk_read_tell(&c, strm);
-  
-  while ((chunk=lib3ds_chunk_read_next(&c, strm))!=0) {
-    switch (chunk) {
-      case LIB3DS_COLOR_F:
-        {
-          int i;
-          for (i=0; i<3; ++i) {
-            light->color[i]=lib3ds_float_read(strm);
-          }
-        }
-        break;
-      case LIB3DS_DL_OFF:
-        {
-          light->off=LIB3DS_TRUE;
-        }
-        break;
-      case LIB3DS_DL_OUTER_RANGE:
-        {
-          light->outer_range=lib3ds_float_read(strm);
-        }
-        break;
-      case LIB3DS_DL_INNER_RANGE:
-        {
-          light->inner_range=lib3ds_float_read(strm);
-        }
-        break;
-      case LIB3DS_DL_MULTIPLIER:
-        {
-          light->multiplier=lib3ds_float_read(strm);
-        }
-        break;
-      case LIB3DS_DL_EXCLUDE:
-        {
-          /* FIXME: */
-          lib3ds_chunk_unknown(chunk);
-        }
-      case LIB3DS_DL_ATTENUATE:
-        {
-          light->attenuation=lib3ds_float_read(strm);
-        }
-        break;
-      case LIB3DS_DL_SPOTLIGHT:
-        {
-          lib3ds_chunk_read_reset(&c, strm);
-          if (!spotlight_read(light, strm)) {
-            return(LIB3DS_FALSE);
-          }
-        }
-        break;
-      default:
-        lib3ds_chunk_unknown(chunk);
-    }
-  }
-  
-  lib3ds_chunk_read_end(&c, strm);
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
- * \ingroup light
- */
-Lib3dsBool
-lib3ds_light_write(Lib3dsLight *light, iostream *strm)
-{
-  Lib3dsChunk c;
-
-  c.chunk=LIB3DS_N_DIRECT_LIGHT;
-  if (!lib3ds_chunk_write_start(&c,strm)) {
-    return(LIB3DS_FALSE);
-  }
-  lib3ds_vector_write(light->position, strm);
-  { /*---- LIB3DS_COLOR_F ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_COLOR_F;
-    c.size=18;
-    lib3ds_chunk_write(&c, strm);
-    lib3ds_rgb_write(light->color,strm);
-  }
-  if (light->off) { /*---- LIB3DS_DL_OFF ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_DL_OFF;
-    c.size=6;
-    lib3ds_chunk_write(&c, strm);
-  }
-  { /*---- LIB3DS_DL_OUTER_RANGE ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_DL_OUTER_RANGE;
-    c.size=10;
-    lib3ds_chunk_write(&c, strm);
-    lib3ds_float_write(light->outer_range,strm);
-  }
-  { /*---- LIB3DS_DL_INNER_RANGE ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_DL_INNER_RANGE;
-    c.size=10;
-    lib3ds_chunk_write(&c, strm);
-    lib3ds_float_write(light->inner_range,strm);
-  }
-  { /*---- LIB3DS_DL_MULTIPLIER ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_DL_MULTIPLIER;
-    c.size=10;
-    lib3ds_chunk_write(&c, strm);
-    lib3ds_float_write(light->multiplier, strm);
-  }
-  if (light->attenuation) { /*---- LIB3DS_DL_ATTENUATE ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_DL_ATTENUATE;
-    c.size=6;
-    lib3ds_chunk_write(&c, strm);
-  }
-
-  if (light->spot_light) {
-    Lib3dsChunk c;
-
-    c.chunk=LIB3DS_DL_SPOTLIGHT;
-    if (!lib3ds_chunk_write_start(&c,strm)) {
-      return(LIB3DS_FALSE);
-    }
-    lib3ds_vector_write(light->spot, strm);
-    lib3ds_float_write(light->hot_spot, strm);
-    lib3ds_float_write(light->fall_off, strm);
-    
-    { /*---- LIB3DS_DL_SPOT_ROLL ----*/
-      Lib3dsChunk c;
-      c.chunk=LIB3DS_DL_SPOT_ROLL;
-      c.size=10;
-      lib3ds_chunk_write(&c, strm);
-      lib3ds_float_write(light->roll,strm);
-    }
-    if (light->shadowed) { /*---- LIB3DS_DL_SHADOWED ----*/
-      Lib3dsChunk c;
-      c.chunk=LIB3DS_DL_SHADOWED;
-      c.size=6;
-      lib3ds_chunk_write(&c, strm);
-    }
-    if ((fabs(light->shadow_bias)>LIB3DS_EPSILON) ||
-      (fabs(light->shadow_filter)>LIB3DS_EPSILON) ||
-      (light->shadow_size!=0)) { /*---- LIB3DS_DL_LOCAL_SHADOW2 ----*/
-      Lib3dsChunk c;
-      c.chunk=LIB3DS_DL_LOCAL_SHADOW2;
-      c.size=16;
-      lib3ds_chunk_write(&c, strm);
-      lib3ds_float_write(light->shadow_bias,strm);
-      lib3ds_float_write(light->shadow_filter,strm);
-      lib3ds_intw_write(light->shadow_size,strm);
-    }
-    if (light->see_cone) { /*---- LIB3DS_DL_SEE_CONE ----*/
-      Lib3dsChunk c;
-      c.chunk=LIB3DS_DL_SEE_CONE;
-      c.size=6;
-      lib3ds_chunk_write(&c, strm);
-    }
-    if (light->rectangular_spot) { /*---- LIB3DS_DL_SPOT_RECTANGULAR ----*/
-      Lib3dsChunk c;
-      c.chunk=LIB3DS_DL_SPOT_RECTANGULAR;
-      c.size=6;
-      lib3ds_chunk_write(&c, strm);
-    }
-    if (fabs(light->spot_aspect)>LIB3DS_EPSILON) { /*---- LIB3DS_DL_SPOT_ASPECT ----*/
-      Lib3dsChunk c;
-      c.chunk=LIB3DS_DL_SPOT_ASPECT;
-      c.size=10;
-      lib3ds_chunk_write(&c, strm);
-      lib3ds_float_write(light->spot_aspect,strm);
-    }
-    if (light->use_projector) { /*---- LIB3DS_DL_SPOT_PROJECTOR ----*/
-      Lib3dsChunk c;
-      c.chunk=LIB3DS_DL_SPOT_PROJECTOR;
-      c.size=10;
-      lib3ds_chunk_write(&c, strm);
-      lib3ds_string_write(light->projector,strm);
-    }
-    if (light->spot_overshoot) { /*---- LIB3DS_DL_SPOT_OVERSHOOT ----*/
-      Lib3dsChunk c;
-      c.chunk=LIB3DS_DL_SPOT_OVERSHOOT;
-      c.size=6;
-      lib3ds_chunk_write(&c, strm);
-    }
-    if (fabs(light->ray_bias)>LIB3DS_EPSILON) { /*---- LIB3DS_DL_RAY_BIAS ----*/
-      Lib3dsChunk c;
-      c.chunk=LIB3DS_DL_RAY_BIAS;
-      c.size=10;
-      lib3ds_chunk_write(&c, strm);
-      lib3ds_float_write(light->ray_bias,strm);
-    }
-    if (light->ray_shadows) { /*---- LIB3DS_DL_RAYSHAD ----*/
-      Lib3dsChunk c;
-      c.chunk=LIB3DS_DL_RAYSHAD;
-      c.size=6;
-      lib3ds_chunk_write(&c, strm);
-    }
-    if (!lib3ds_chunk_write_end(&c,strm)) {
-      return(LIB3DS_FALSE);
-    }
-  }
-  if (!lib3ds_chunk_write_end(&c,strm)) {
-    return(LIB3DS_FALSE);
-  }
-  return(LIB3DS_TRUE);
-}
-
-
Index: /enSceneGraph/trunk/src/osgPlugins/3ds/matrix.h
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/matrix.h (revision 6461)
+++  (revision )
@@ -1,67 +1,0 @@
-/* -*- c -*- */
-#ifndef INCLUDED_LIB3DS_MATRIX_H
-#define INCLUDED_LIB3DS_MATRIX_H
-/*
- * The 3D Studio File Format Library
- * Copyright (C) 1996-2001 by J.E. Hoffmann <je-h@gmx.net>
- * All rights reserved.
- *
- * This program is  free  software;  you can redistribute it and/or modify it
- * under the terms of the  GNU Lesser General Public License  as published by 
- * the  Free Software Foundation;  either version 2.1 of the License,  or (at 
- * your option) any later version.
- *
- * This  program  is  distributed in  the  hope that it will  be useful,  but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or  FITNESS FOR A  PARTICULAR PURPOSE.  See the  GNU Lesser General Public  
- * License for more details.
- *
- * You should  have received  a copy of the GNU Lesser General Public License
- * along with  this program;  if not, write to the  Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id$
- */
-
-#ifndef INCLUDED_LIB3DS_TYPES_H
-#include "types.h"
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern LIB3DSAPI void lib3ds_matrix_zero(Lib3dsMatrix m);
-extern LIB3DSAPI void lib3ds_matrix_identity(Lib3dsMatrix m);
-extern LIB3DSAPI void lib3ds_matrix_copy(Lib3dsMatrix dest, Lib3dsMatrix src);
-extern LIB3DSAPI void lib3ds_matrix_neg(Lib3dsMatrix m);
-extern LIB3DSAPI void lib3ds_matrix_abs(Lib3dsMatrix m);
-extern LIB3DSAPI void lib3ds_matrix_transpose(Lib3dsMatrix m);
-extern LIB3DSAPI void lib3ds_matrix_add(Lib3dsMatrix m, Lib3dsMatrix a, Lib3dsMatrix b);
-extern LIB3DSAPI void lib3ds_matrix_sub(Lib3dsMatrix m, Lib3dsMatrix a, Lib3dsMatrix b);
-extern LIB3DSAPI void lib3ds_matrix_mul(Lib3dsMatrix m, Lib3dsMatrix a, Lib3dsMatrix b);
-extern LIB3DSAPI void lib3ds_matrix_scalar(Lib3dsMatrix m, Lib3dsFloat k);
-extern LIB3DSAPI Lib3dsFloat lib3ds_matrix_det(Lib3dsMatrix m);
-extern LIB3DSAPI void lib3ds_matrix_adjoint(Lib3dsMatrix m);
-extern LIB3DSAPI Lib3dsBool lib3ds_matrix_inv(Lib3dsMatrix m);
-void lib3ds_matrix_translate_xyz(Lib3dsMatrix m, Lib3dsFloat x,
-  Lib3dsFloat y, Lib3dsFloat z);
-extern LIB3DSAPI void lib3ds_matrix_translate(Lib3dsMatrix m, Lib3dsVector t);
-extern LIB3DSAPI void lib3ds_matrix_scale_xyz(Lib3dsMatrix m, Lib3dsFloat x,
-  Lib3dsFloat y, Lib3dsFloat z);
-extern LIB3DSAPI void lib3ds_matrix_scale(Lib3dsMatrix m, Lib3dsVector s);
-extern LIB3DSAPI void lib3ds_matrix_rotate_x(Lib3dsMatrix m, Lib3dsFloat phi);
-extern LIB3DSAPI void lib3ds_matrix_rotate_y(Lib3dsMatrix m, Lib3dsFloat phi);
-extern LIB3DSAPI void lib3ds_matrix_rotate_z(Lib3dsMatrix m, Lib3dsFloat phi);
-extern LIB3DSAPI void lib3ds_matrix_rotate(Lib3dsMatrix m, Lib3dsQuat q);
-extern LIB3DSAPI void lib3ds_matrix_rotate_axis(Lib3dsMatrix m,
-  Lib3dsVector axis, Lib3dsFloat angle);
-extern LIB3DSAPI void lib3ds_matrix_camera(Lib3dsMatrix matrix, Lib3dsVector pos,
-  Lib3dsVector tgt, Lib3dsFloat roll);
-extern LIB3DSAPI void lib3ds_matrix_dump(Lib3dsMatrix matrix);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
-
Index: /enSceneGraph/trunk/src/osgPlugins/3ds/quat.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/quat.cpp (revision 1563)
+++  (revision )
@@ -1,392 +1,0 @@
-/*
- * The 3D Studio File Format Library
- * Copyright (C) 1996-2001 by J.E. Hoffmann <je-h@gmx.net>
- * All rights reserved.
- *
- * This program is  free  software;  you can redistribute it and/or modify it
- * under the terms of the  GNU Lesser General Public License  as published by 
- * the  Free Software Foundation;  either version 2.1 of the License,  or (at 
- * your option) any later version.
- *
- * This  program  is  distributed in  the  hope that it will  be useful,  but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or  FITNESS FOR A  PARTICULAR PURPOSE.  See the  GNU Lesser General Public  
- * License for more details.
- *
- * You should  have received  a copy of the GNU Lesser General Public License
- * along with  this program;  if not, write to the  Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id$
- */
-#define LIB3DS_EXPORT
-#include "quat.h"
-#include <math.h>
-
-
-/*!
- * \defgroup quat Quaternion Mathematics
- *
- * \author J.E. Hoffmann <je-h@gmx.net>
- */
-/*!
- * \typedef Lib3dsQuat
- *   \ingroup quat
- */
-
-
-/*!
- * \ingroup quat
- */
-void
-lib3ds_quat_zero(Lib3dsQuat c)
-{
-  c[0]=c[1]=c[2]=c[3]=0.0f;
-}
-
-
-/*!
- * \ingroup quat
- */
-void
-lib3ds_quat_identity(Lib3dsQuat c)
-{
-  c[0]=c[1]=c[2]=0.0f;
-  c[3]=1.0f;
-}
-
-
-/*!
- * \ingroup quat
- */
-void 
-lib3ds_quat_copy(Lib3dsQuat dest, Lib3dsQuat src)
-{
-  int i;
-  for (i=0; i<4; ++i) {
-    dest[i]=src[i];
-  }
-}
-
-
-/*!
- * \ingroup quat
- */
-void
-lib3ds_quat_axis_angle(Lib3dsQuat c, Lib3dsVector axis, Lib3dsFloat angle)
-{
-  Lib3dsDouble omega,s;
-  Lib3dsDouble l;
-
-  l=sqrt(axis[0]*axis[0] + axis[1]*axis[1] + axis[2]*axis[2]);
-  if (l<LIB3DS_EPSILON) {
-    c[0]=c[1]=c[2]=0.0f;
-    c[3]=1.0f;
-  }
-  else {
-    omega=-0.5*angle;
-    s=sin(omega)/l;
-    c[0]=(Lib3dsFloat)s*axis[0];
-    c[1]=(Lib3dsFloat)s*axis[1];
-    c[2]=(Lib3dsFloat)s*axis[2];
-    c[3]=(Lib3dsFloat)cos(omega);
-  }
-}
-
-
-/*!
- * \ingroup quat
- */
-void
-lib3ds_quat_neg(Lib3dsQuat c)
-{
-  int i;
-  for (i=0; i<4; ++i) {
-    c[i]=-c[i];
-  }
-}
-
-
-/*!
- * \ingroup quat
- */
-void
-lib3ds_quat_abs(Lib3dsQuat c)
-{
-  int i;
-  for (i=0; i<4; ++i) {
-    c[i]=(Lib3dsFloat)fabs(c[i]);
-  }
-}
-
-
-/*!
- * \ingroup quat
- */
-void
-lib3ds_quat_cnj(Lib3dsQuat c)
-{
-  int i;
-  for (i=0; i<3; ++i) {
-    c[i]=-c[i];
-  }
-}
-
-
-/*!
- * \ingroup quat
- */
-void
-lib3ds_quat_mul(Lib3dsQuat c, Lib3dsQuat a, Lib3dsQuat b)
-{
-  c[0]=a[3]*b[0] + a[0]*b[3] + a[1]*b[2] - a[2]*b[1];
-  c[1]=a[3]*b[1] + a[1]*b[3] + a[2]*b[0] - a[0]*b[2];
-  c[2]=a[3]*b[2] + a[2]*b[3] + a[0]*b[1] - a[1]*b[0];
-  c[3]=a[3]*b[3] - a[0]*b[0] - a[1]*b[1] - a[2]*b[2];
-}
-
-
-/*!
- * \ingroup quat
- */
-void
-lib3ds_quat_scalar(Lib3dsQuat c, Lib3dsFloat k)
-{
-  int i;
-  for (i=0; i<4; ++i) {
-    c[i]*=k;
-  }
-}
-
-
-/*!
- * \ingroup quat
- */
-void
-lib3ds_quat_normalize(Lib3dsQuat c)
-{
-  Lib3dsDouble l,m;
-
-  l=sqrt(c[0]*c[0] + c[1]*c[1] + c[2]*c[2] + c[3]*c[3]);
-  if (fabs(l)<LIB3DS_EPSILON) {
-    c[0]=c[1]=c[2]=0.0f;
-    c[3]=1.0f; 
-  }
-  else {  
-    int i;
-    m=1.0f/l;
-    for (i=0; i<4; ++i) {
-      c[i]=(Lib3dsFloat)(c[i]*m);
-    }
-  }
-}
-
-
-/*!
- * \ingroup quat
- */
-void
-lib3ds_quat_inv(Lib3dsQuat c)
-{
-  Lib3dsDouble l,m;
-
-  l=sqrt(c[0]*c[0] + c[1]*c[1] + c[2]*c[2] + c[3]*c[3]);
-  if (fabs(l)<LIB3DS_EPSILON) {
-    c[0]=c[1]=c[2]=0.0f;
-    c[3]=1.0f; 
-  }
-  else {  
-    m=1.0f/l;
-    c[0]=(Lib3dsFloat)(-c[0]*m);
-    c[1]=(Lib3dsFloat)(-c[1]*m);
-    c[2]=(Lib3dsFloat)(-c[2]*m);
-    c[3]=(Lib3dsFloat)(c[3]*m);
-  }
-}
-
-
-/*!
- * \ingroup quat
- */
-Lib3dsFloat
-lib3ds_quat_dot(Lib3dsQuat a, Lib3dsQuat b)
-{
-  return(a[0]*b[0] + a[1]*b[1] + a[2]*b[2] + a[3]*b[3]);
-}
-
-
-/*!
- * \ingroup quat
- */
-Lib3dsFloat
-lib3ds_quat_squared(Lib3dsQuat c)
-{
-  return(c[0]*c[0] + c[1]*c[1] + c[2]*c[2] + c[3]*c[3]);
-}
-
-
-/*!
- * \ingroup quat
- */
-Lib3dsFloat
-lib3ds_quat_length(Lib3dsQuat c)
-{
-  return((Lib3dsFloat)sqrt(c[0]*c[0] + c[1]*c[1] + c[2]*c[2] + c[3]*c[3]));
-}
-
-
-/*!
- * \ingroup quat
- */
-void
-lib3ds_quat_ln(Lib3dsQuat c)
-{
-  Lib3dsDouble om,s,t;
-
-  s=sqrt(c[0]*c[0] + c[1]*c[1] + c[2]*c[2]);
-  om=atan2(s,(Lib3dsDouble)c[3]);
-  if (fabs(s)<LIB3DS_EPSILON) {
-    t=0.0f;
-  }
-  else {
-    t=om/s;
-  }
-  {
-    int i;
-    for (i=0; i<3; ++i) {
-      c[i]=(Lib3dsFloat)(c[i]*t);
-    }
-    c[3]=0.0f;
-  }
-}
-
-
-/*!
- * \ingroup quat
- */
-void
-lib3ds_quat_ln_dif(Lib3dsQuat c, Lib3dsQuat a, Lib3dsQuat b)
-{
-  Lib3dsQuat invp;
-
-  lib3ds_quat_copy(invp, a);
-  lib3ds_quat_inv(invp);
-  lib3ds_quat_mul(c, invp, b);
-  lib3ds_quat_ln(c);
-}
-
-
-/*!
- * \ingroup quat
- */
-void
-lib3ds_quat_exp(Lib3dsQuat c)
-{
-  Lib3dsDouble om,sinom;
-
-  om=sqrt(c[0]*c[0] + c[1]*c[1] + c[2]*c[2]);
-  if (fabs(om)<LIB3DS_EPSILON) {
-    sinom=1.0f;
-  }
-  else {
-    sinom=sin(om)/om;
-  }
-  {
-    int i;
-    for (i=0; i<3; ++i) {
-      c[i]=(Lib3dsFloat)(c[i]*sinom);
-    }
-    c[3]=(Lib3dsFloat)cos(om);
-  }
-}
-
-
-/*!
- * \ingroup quat
- */
-void
-lib3ds_quat_slerp(Lib3dsQuat c, Lib3dsQuat a, Lib3dsQuat b, Lib3dsFloat t)
-{
-  Lib3dsDouble l;
-  Lib3dsDouble om,sinom;
-  Lib3dsDouble sp,sq;
-  Lib3dsQuat q;
-
-  l=a[0]*b[0] + a[1]*b[1] + a[2]*b[2] + a[3]*b[3];
-  if ((1.0+l)>LIB3DS_EPSILON) {
-    if (fabs(l)>1.0f) l/=fabs(l);
-    om=acos(l);
-    sinom=sin(om);
-    if (fabs(sinom)>LIB3DS_EPSILON) {
-      sp=sin((1.0f-t)*om)/sinom;
-      sq=sin(t*om)/sinom;
-    }
-    else {
-      sp=1.0f-t;
-      sq=t;
-    }
-    c[0]=(Lib3dsFloat)(sp*a[0] + sq*b[0]);
-    c[1]=(Lib3dsFloat)(sp*a[1] + sq*b[1]);
-    c[2]=(Lib3dsFloat)(sp*a[2] + sq*b[2]);
-    c[3]=(Lib3dsFloat)(sp*a[3] + sq*b[3]);
-  }
-  else {
-    q[0]=-a[1];
-    q[1]=a[0];
-    q[2]=-a[3];
-    q[3]=a[2];
-    sp=sin((1.0-t)*LIB3DS_HALFPI);
-    sq=sin(t*LIB3DS_HALFPI);
-    c[0]=(Lib3dsFloat)(sp*a[0] + sq*q[0]);
-    c[1]=(Lib3dsFloat)(sp*a[1] + sq*q[1]);
-    c[2]=(Lib3dsFloat)(sp*a[2] + sq*q[2]);
-    c[3]=(Lib3dsFloat)(sp*a[3] + sq*q[3]);
-  }
-}
-
-
-/*!
- * \ingroup quat
- */
-void
-lib3ds_quat_squad(Lib3dsQuat c, Lib3dsQuat a, Lib3dsQuat p, Lib3dsQuat q,
-  Lib3dsQuat b, Lib3dsFloat t)
-{
-  Lib3dsQuat ab;
-  Lib3dsQuat pq;
-
-  lib3ds_quat_slerp(ab,a,b,t);
-  lib3ds_quat_slerp(pq,p,q,t);
-  lib3ds_quat_slerp(c,ab,pq,2*t*(1-t));
-}
-
-
-/*!
- * \ingroup quat
- */
-void
-lib3ds_quat_tangent(Lib3dsQuat c, Lib3dsQuat p, Lib3dsQuat q, Lib3dsQuat n)
-{
-  Lib3dsQuat dn,dp,x;
-  int i;
-
-  lib3ds_quat_ln_dif(dn, q, n);
-  lib3ds_quat_ln_dif(dp, q, p);
-
-  for (i=0; i<4; i++) {
-    x[i]=-1.0f/4.0f*(dn[i]+dp[i]);
-  }
-  lib3ds_quat_exp(x);
-  lib3ds_quat_mul(c,q,x);
-}
-
-
-/*!
- * \ingroup quat
- */
-void
-lib3ds_quat_dump(Lib3dsQuat q)
-{
-  printf("%f %f %f %f\n", q[0], q[1], q[2], q[3]);
-}
-
Index: /enSceneGraph/trunk/src/osgPlugins/3ds/atmosphere.h
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/atmosphere.h (revision 10076)
+++  (revision )
@@ -1,103 +1,0 @@
-/* -*- c -*- */
-#ifndef INCLUDED_LIB3DS_ATMOSPHERE_H
-#define INCLUDED_LIB3DS_ATMOSPHERE_H
-/*
- * The 3D Studio File Format Library
- * Copyright (C) 1996-2001 by J.E. Hoffmann <je-h@gmx.net>
- * All rights reserved.
- *
- * This program is  free  software;  you can redistribute it and/or modify it
- * under the terms of the  GNU Lesser General Public License  as published by 
- * the  Free Software Foundation;  either version 2.1 of the License,  or (at 
- * your option) any later version.
- *
- * This  program  is  distributed in  the  hope that it will  be useful,  but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or  FITNESS FOR A  PARTICULAR PURPOSE.  See the  GNU Lesser General Public  
- * License for more details.
- *
- * You should  have received  a copy of the GNU Lesser General Public License
- * along with  this program;  if not, write to the  Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id$
- */
-
-#ifndef INCLUDED_LIB3DS_TYPES_H
-#include "types.h"
-#endif
-
-#include <iostream>
-using namespace std;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*!
- * Fog atmosphere settings
- * \ingroup atmosphere
- */
-typedef struct _Lib3dsFog {
-    Lib3dsBool use;
-    Lib3dsRgb col;
-    Lib3dsBool fog_background;
-    Lib3dsFloat near_plane;
-    Lib3dsFloat near_density;
-    Lib3dsFloat far_plane;
-    Lib3dsFloat far_density;
-} Lib3dsFog;
-
-/*!
- * Layer fog atmosphere flags
- * \ingroup atmosphere
- */
-typedef enum _Lib3dsLayerFogFlags {
-  LIB3DS_BOTTOM_FALL_OFF =0x00000001,
-  LIB3DS_TOP_FALL_OFF    =0x00000002,
-  LIB3DS_FOG_BACKGROUND  =0x00100000
-} Lib3dsLayerFogFlags;
-
-/*!
- * Layer fog atmosphere settings
- * \ingroup atmosphere
- */
-typedef struct _Lib3dsLayerFog {
-    Lib3dsBool use;
-    Lib3dsDword flags;
-    Lib3dsRgb col;
-    Lib3dsFloat near_y;
-    Lib3dsFloat far_y;
-    Lib3dsFloat density;
-} Lib3dsLayerFog;
-
-/*!
- * Distance cue atmosphere settings
- * \ingroup atmosphere
- */
-typedef struct _Lib3dsDistanceCue {
-    Lib3dsBool use;
-    Lib3dsBool cue_background;
-    Lib3dsFloat near_plane;
-    Lib3dsFloat near_dimming;
-    Lib3dsFloat far_plane;
-    Lib3dsFloat far_dimming;
-} Lib3dsDistanceCue;
-
-/*!
- * Atmosphere settings
- * \ingroup atmosphere
- */
-struct _Lib3dsAtmosphere {
-    Lib3dsFog fog;
-    Lib3dsLayerFog layer_fog;
-    Lib3dsDistanceCue dist_cue;
-};
-
-extern LIB3DSAPI Lib3dsBool lib3ds_atmosphere_read(Lib3dsAtmosphere *atmosphere, iostream *strm);
-extern LIB3DSAPI Lib3dsBool lib3ds_atmosphere_write(Lib3dsAtmosphere *atmosphere, iostream *strm);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
Index: /enSceneGraph/trunk/src/osgPlugins/3ds/chunk.h
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/chunk.h (revision 10076)
+++  (revision )
@@ -1,292 +1,0 @@
-/* -*- c -*- */
-#ifndef INCLUDED_LIB3DS_CHUNK_H
-#define INCLUDED_LIB3DS_CHUNK_H
-/*
- * The 3D Studio File Format Library
- * Copyright (C) 1996-2001 by J.E. Hoffmann <je-h@gmx.net>
- * All rights reserved.
- *
- * This program is  free  software;  you can redistribute it and/or modify it
- * under the terms of the  GNU Lesser General Public License  as published by 
- * the  Free Software Foundation;  either version 2.1 of the License,  or (at 
- * your option) any later version.
- *
- * This  program  is  distributed in  the  hope that it will  be useful,  but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or  FITNESS FOR A  PARTICULAR PURPOSE.  See the  GNU Lesser General Public  
- * License for more details.
- *
- * You should  have received  a copy of the GNU Lesser General Public License
- * along with  this program;  if not, write to the  Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id$
- */
-
-#ifndef INCLUDED_LIB3DS_TYPES_H
-#include "types.h"
-#endif
-
-#include <iostream>
-using namespace std;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-typedef enum _Lib3dsChunks {
-  LIB3DS_NULL_CHUNK             =0x0000,
-  LIB3DS_M3DMAGIC               =0x4D4D,    /*3DS file*/
-  LIB3DS_SMAGIC                 =0x2D2D,    
-  LIB3DS_LMAGIC                 =0x2D3D,    
-  LIB3DS_MLIBMAGIC              =0x3DAA,    /*MLI file*/
-  LIB3DS_MATMAGIC               =0x3DFF,    
-  LIB3DS_CMAGIC                 =0xC23D,    /*PRJ file*/
-  LIB3DS_M3D_VERSION            =0x0002,
-  LIB3DS_M3D_KFVERSION          =0x0005,
-
-  LIB3DS_COLOR_F                =0x0010,
-  LIB3DS_COLOR_24               =0x0011,
-  LIB3DS_LIN_COLOR_24           =0x0012,
-  LIB3DS_LIN_COLOR_F            =0x0013,
-  LIB3DS_INT_PERCENTAGE         =0x0030,
-  LIB3DS_FLOAT_PERCENTAGE       =0x0031,
-
-  LIB3DS_MDATA                  =0x3D3D,
-  LIB3DS_MESH_VERSION           =0x3D3E,
-  LIB3DS_MASTER_SCALE           =0x0100,
-  LIB3DS_LO_SHADOW_BIAS         =0x1400,
-  LIB3DS_HI_SHADOW_BIAS         =0x1410,
-  LIB3DS_SHADOW_MAP_SIZE        =0x1420,
-  LIB3DS_SHADOW_SAMPLES         =0x1430,
-  LIB3DS_SHADOW_RANGE           =0x1440,
-  LIB3DS_SHADOW_FILTER          =0x1450,
-  LIB3DS_RAY_BIAS               =0x1460,
-  LIB3DS_O_CONSTS               =0x1500,
-  LIB3DS_AMBIENT_LIGHT          =0x2100,
-  LIB3DS_BIT_MAP                =0x1100,
-  LIB3DS_SOLID_BGND             =0x1200,
-  LIB3DS_V_GRADIENT             =0x1300,
-  LIB3DS_USE_BIT_MAP            =0x1101,
-  LIB3DS_USE_SOLID_BGND         =0x1201,
-  LIB3DS_USE_V_GRADIENT         =0x1301,
-  LIB3DS_FOG                    =0x2200,
-  LIB3DS_FOG_BGND               =0x2210,
-  LIB3DS_LAYER_FOG              =0x2302,
-  LIB3DS_DISTANCE_CUE           =0x2300,
-  LIB3DS_DCUE_BGND              =0x2310,
-  LIB3DS_USE_FOG                =0x2201,
-  LIB3DS_USE_LAYER_FOG          =0x2303,
-  LIB3DS_USE_DISTANCE_CUE       =0x2301,
-
-  LIB3DS_MAT_ENTRY              =0xAFFF,
-  LIB3DS_MAT_NAME               =0xA000,
-  LIB3DS_MAT_AMBIENT            =0xA010,
-  LIB3DS_MAT_DIFFUSE            =0xA020,
-  LIB3DS_MAT_SPECULAR           =0xA030,
-  LIB3DS_MAT_SHININESS          =0xA040,
-  LIB3DS_MAT_SHIN2PCT           =0xA041,
-  LIB3DS_MAT_TRANSPARENCY       =0xA050,
-  LIB3DS_MAT_XPFALL             =0xA052,
-  LIB3DS_MAT_USE_XPFALL         =0xA240,
-  LIB3DS_MAT_REFBLUR            =0xA053,
-  LIB3DS_MAT_SHADING            =0xA100,
-  LIB3DS_MAT_USE_REFBLUR        =0xA250,
-  LIB3DS_MAT_SELF_ILLUM         =0xA080,
-  LIB3DS_MAT_TWO_SIDE           =0xA081,
-  LIB3DS_MAT_DECAL              =0xA082,
-  LIB3DS_MAT_ADDITIVE           =0xA083,
-  LIB3DS_MAT_WIRE               =0xA085,
-  LIB3DS_MAT_FACEMAP            =0xA088,
-  LIB3DS_MAT_PHONGSOFT          =0xA08C,
-  LIB3DS_MAT_WIREABS            =0xA08E,
-  LIB3DS_MAT_WIRE_SIZE          =0xA087,
-  LIB3DS_MAT_TEXMAP             =0xA200,
-  LIB3DS_MAT_SXP_TEXT_DATA      =0xA320,
-  LIB3DS_MAT_TEXMASK            =0xA33E,
-  LIB3DS_MAT_SXP_TEXTMASK_DATA  =0xA32A,
-  LIB3DS_MAT_TEX2MAP            =0xA33A,
-  LIB3DS_MAT_SXP_TEXT2_DATA     =0xA321,
-  LIB3DS_MAT_TEX2MASK           =0xA340,
-  LIB3DS_MAT_SXP_TEXT2MASK_DATA =0xA32C,
-  LIB3DS_MAT_OPACMAP            =0xA210,
-  LIB3DS_MAT_SXP_OPAC_DATA      =0xA322,
-  LIB3DS_MAT_OPACMASK           =0xA342,
-  LIB3DS_MAT_SXP_OPACMASK_DATA  =0xA32E,
-  LIB3DS_MAT_BUMPMAP            =0xA230,
-  LIB3DS_MAT_SXP_BUMP_DATA      =0xA324,
-  LIB3DS_MAT_BUMPMASK           =0xA344,
-  LIB3DS_MAT_SXP_BUMPMASK_DATA  =0xA330,
-  LIB3DS_MAT_SPECMAP            =0xA204,
-  LIB3DS_MAT_SXP_SPEC_DATA      =0xA325,
-  LIB3DS_MAT_SPECMASK           =0xA348,
-  LIB3DS_MAT_SXP_SPECMASK_DATA  =0xA332,
-  LIB3DS_MAT_SHINMAP            =0xA33C,
-  LIB3DS_MAT_SXP_SHIN_DATA      =0xA326,
-  LIB3DS_MAT_SHINMASK           =0xA346,
-  LIB3DS_MAT_SXP_SHINMASK_DATA  =0xA334,
-  LIB3DS_MAT_SELFIMAP           =0xA33D,
-  LIB3DS_MAT_SXP_SELFI_DATA     =0xA328,
-  LIB3DS_MAT_SELFIMASK          =0xA34A,
-  LIB3DS_MAT_SXP_SELFIMASK_DATA =0xA336,
-  LIB3DS_MAT_REFLMAP            =0xA220,
-  LIB3DS_MAT_REFLMASK           =0xA34C,
-  LIB3DS_MAT_SXP_REFLMASK_DATA  =0xA338,
-  LIB3DS_MAT_ACUBIC             =0xA310,
-  LIB3DS_MAT_MAPNAME            =0xA300,
-  LIB3DS_MAT_MAP_TILING         =0xA351,
-  LIB3DS_MAT_MAP_TEXBLUR        =0xA353,
-  LIB3DS_MAT_MAP_USCALE         =0xA354,
-  LIB3DS_MAT_MAP_VSCALE         =0xA356,
-  LIB3DS_MAT_MAP_UOFFSET        =0xA358,
-  LIB3DS_MAT_MAP_VOFFSET        =0xA35A,
-  LIB3DS_MAT_MAP_ANG            =0xA35C,
-  LIB3DS_MAT_MAP_COL1           =0xA360,
-  LIB3DS_MAT_MAP_COL2           =0xA362,
-  LIB3DS_MAT_MAP_RCOL           =0xA364,
-  LIB3DS_MAT_MAP_GCOL           =0xA366,
-  LIB3DS_MAT_MAP_BCOL           =0xA368,
-
-  LIB3DS_NAMED_OBJECT           =0x4000,
-  LIB3DS_N_DIRECT_LIGHT         =0x4600,
-  LIB3DS_DL_OFF                 =0x4620,
-  LIB3DS_DL_OUTER_RANGE         =0x465A,
-  LIB3DS_DL_INNER_RANGE         =0x4659,
-  LIB3DS_DL_MULTIPLIER          =0x465B,
-  LIB3DS_DL_EXCLUDE             =0x4654,
-  LIB3DS_DL_ATTENUATE           =0x4625,
-  LIB3DS_DL_SPOTLIGHT           =0x4610,
-  LIB3DS_DL_SPOT_ROLL           =0x4656,
-  LIB3DS_DL_SHADOWED            =0x4630,
-  LIB3DS_DL_LOCAL_SHADOW2       =0x4641,
-  LIB3DS_DL_SEE_CONE            =0x4650,
-  LIB3DS_DL_SPOT_RECTANGULAR    =0x4651,
-  LIB3DS_DL_SPOT_ASPECT         =0x4657,
-  LIB3DS_DL_SPOT_PROJECTOR      =0x4653,
-  LIB3DS_DL_SPOT_OVERSHOOT      =0x4652,
-  LIB3DS_DL_RAY_BIAS            =0x4658,
-  LIB3DS_DL_RAYSHAD             =0x4627,
-  LIB3DS_N_CAMERA               =0x4700,
-  LIB3DS_CAM_SEE_CONE           =0x4710,
-  LIB3DS_CAM_RANGES             =0x4720,
-  LIB3DS_OBJ_HIDDEN             =0x4010,
-  LIB3DS_OBJ_VIS_LOFTER         =0x4011,
-  LIB3DS_OBJ_DOESNT_CAST        =0x4012,
-  LIB3DS_OBJ_DONT_RECVSHADOW    =0x4017,
-  LIB3DS_OBJ_MATTE              =0x4013,
-  LIB3DS_OBJ_FAST               =0x4014,
-  LIB3DS_OBJ_PROCEDURAL         =0x4015,
-  LIB3DS_OBJ_FROZEN             =0x4016,
-  LIB3DS_N_TRI_OBJECT           =0x4100,
-  LIB3DS_POINT_ARRAY            =0x4110,
-  LIB3DS_POINT_FLAG_ARRAY       =0x4111,
-  LIB3DS_FACE_ARRAY             =0x4120,
-  LIB3DS_MSH_MAT_GROUP          =0x4130,
-  LIB3DS_SMOOTH_GROUP           =0x4150,
-  LIB3DS_MSH_BOXMAP             =0x4190,
-  LIB3DS_TEX_VERTS              =0x4140,
-  LIB3DS_MESH_MATRIX            =0x4160,
-  LIB3DS_MESH_COLOR             =0x4165,
-  LIB3DS_MESH_TEXTURE_INFO      =0x4170,
-
-  LIB3DS_KFDATA                 =0xB000,
-  LIB3DS_KFHDR                  =0xB00A,
-  LIB3DS_KFSEG                  =0xB008,
-  LIB3DS_KFCURTIME              =0xB009,
-  LIB3DS_AMBIENT_NODE_TAG       =0xB001,
-  LIB3DS_OBJECT_NODE_TAG        =0xB002,
-  LIB3DS_CAMERA_NODE_TAG        =0xB003,
-  LIB3DS_TARGET_NODE_TAG        =0xB004,
-  LIB3DS_LIGHT_NODE_TAG         =0xB005,
-  LIB3DS_L_TARGET_NODE_TAG      =0xB006,
-  LIB3DS_SPOTLIGHT_NODE_TAG     =0xB007,
-  LIB3DS_NODE_ID                =0xB030,
-  LIB3DS_NODE_HDR               =0xB010,
-  LIB3DS_PIVOT                  =0xB013,
-  LIB3DS_INSTANCE_NAME          =0xB011,
-  LIB3DS_MORPH_SMOOTH           =0xB015,
-  LIB3DS_BOUNDBOX               =0xB014,
-  LIB3DS_POS_TRACK_TAG          =0xB020,
-  LIB3DS_COL_TRACK_TAG          =0xB025,
-  LIB3DS_ROT_TRACK_TAG          =0xB021,
-  LIB3DS_SCL_TRACK_TAG          =0xB022,
-  LIB3DS_MORPH_TRACK_TAG        =0xB026,
-  LIB3DS_FOV_TRACK_TAG          =0xB023,
-  LIB3DS_ROLL_TRACK_TAG         =0xB024,
-  LIB3DS_HOT_TRACK_TAG          =0xB027,
-  LIB3DS_FALL_TRACK_TAG         =0xB028,
-  LIB3DS_HIDE_TRACK_TAG         =0xB029,
-
-  LIB3DS_POLY_2D                = 0x5000,
-  LIB3DS_SHAPE_OK               = 0x5010,
-  LIB3DS_SHAPE_NOT_OK           = 0x5011,
-  LIB3DS_SHAPE_HOOK             = 0x5020,
-  LIB3DS_PATH_3D                = 0x6000,
-  LIB3DS_PATH_MATRIX            = 0x6005,
-  LIB3DS_SHAPE_2D               = 0x6010,
-  LIB3DS_M_SCALE                = 0x6020,
-  LIB3DS_M_TWIST                = 0x6030,
-  LIB3DS_M_TEETER               = 0x6040,
-  LIB3DS_M_FIT                  = 0x6050,
-  LIB3DS_M_BEVEL                = 0x6060,
-  LIB3DS_XZ_CURVE               = 0x6070,
-  LIB3DS_YZ_CURVE               = 0x6080,
-  LIB3DS_INTERPCT               = 0x6090,
-  LIB3DS_DEFORM_LIMIT           = 0x60A0,
-
-  LIB3DS_USE_CONTOUR            = 0x6100,
-  LIB3DS_USE_TWEEN              = 0x6110,
-  LIB3DS_USE_SCALE              = 0x6120,
-  LIB3DS_USE_TWIST              = 0x6130,
-  LIB3DS_USE_TEETER             = 0x6140,
-  LIB3DS_USE_FIT                = 0x6150,
-  LIB3DS_USE_BEVEL              = 0x6160,
-
-  LIB3DS_DEFAULT_VIEW           = 0x3000,
-  LIB3DS_VIEW_TOP               = 0x3010,
-  LIB3DS_VIEW_BOTTOM            = 0x3020,
-  LIB3DS_VIEW_LEFT              = 0x3030,
-  LIB3DS_VIEW_RIGHT             = 0x3040,
-  LIB3DS_VIEW_FRONT             = 0x3050,
-  LIB3DS_VIEW_BACK              = 0x3060,
-  LIB3DS_VIEW_USER              = 0x3070,
-  LIB3DS_VIEW_CAMERA            = 0x3080,
-  LIB3DS_VIEW_WINDOW            = 0x3090,
-
-  LIB3DS_VIEWPORT_LAYOUT_OLD    = 0x7000,
-  LIB3DS_VIEWPORT_DATA_OLD      = 0x7010,
-  LIB3DS_VIEWPORT_LAYOUT        = 0x7001,
-  LIB3DS_VIEWPORT_DATA          = 0x7011,
-  LIB3DS_VIEWPORT_DATA_3        = 0x7012,
-  LIB3DS_VIEWPORT_SIZE          = 0x7020,
-  LIB3DS_NETWORK_VIEW           = 0x7030
-} Lib3dsChunks;
-
-typedef struct _Lib3dsChunk {
-    Lib3dsWord chunk;
-    Lib3dsDword size;
-    Lib3dsDword end;
-    Lib3dsDword cur;
-} Lib3dsChunk; 
-
-extern LIB3DSAPI void lib3ds_chunk_enable_dump(Lib3dsBool enable, Lib3dsBool unknown);
-extern LIB3DSAPI Lib3dsBool lib3ds_chunk_read(Lib3dsChunk *c, iostream *strm);
-extern LIB3DSAPI Lib3dsBool lib3ds_chunk_read_start(Lib3dsChunk *c, Lib3dsWord chunk, iostream *strm);
-extern LIB3DSAPI void lib3ds_chunk_read_tell(Lib3dsChunk *c, iostream *strm);
-extern LIB3DSAPI Lib3dsWord lib3ds_chunk_read_next(Lib3dsChunk *c, iostream *strm);
-extern LIB3DSAPI void lib3ds_chunk_read_reset(Lib3dsChunk *c, iostream *strm);
-extern LIB3DSAPI void lib3ds_chunk_read_end(Lib3dsChunk *c, iostream *strm);
-extern LIB3DSAPI Lib3dsBool lib3ds_chunk_write(Lib3dsChunk *c, iostream *strm);
-extern LIB3DSAPI Lib3dsBool lib3ds_chunk_write_start(Lib3dsChunk *c, iostream *strm);
-extern LIB3DSAPI Lib3dsBool lib3ds_chunk_write_end(Lib3dsChunk *c, iostream *strm);
-extern LIB3DSAPI const char* lib3ds_chunk_name(Lib3dsWord chunk);
-extern LIB3DSAPI void lib3ds_chunk_unknown(Lib3dsWord chunk);
-extern LIB3DSAPI void lib3ds_chunk_dump_info(const char *format, ...);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
-
-
Index: /enSceneGraph/trunk/src/osgPlugins/3ds/tcb.h
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/tcb.h (revision 10076)
+++  (revision )
@@ -1,67 +1,0 @@
-/* -*- c -*- */
-#ifndef INCLUDED_LIB3DS_TCB_H
-#define INCLUDED_LIB3DS_TCB_H
-/*
- * The 3D Studio File Format Library
- * Copyright (C) 1996-2001 by J.E. Hoffmann <je-h@gmx.net>
- * All rights reserved.
- *
- * This program is  free  software;  you can redistribute it and/or modify it
- * under the terms of the  GNU Lesser General Public License  as published by 
- * the  Free Software Foundation;  either version 2.1 of the License,  or (at 
- * your option) any later version.
- *
- * This  program  is  distributed in  the  hope that it will  be useful,  but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or  FITNESS FOR A  PARTICULAR PURPOSE.  See the  GNU Lesser General Public  
- * License for more details.
- *
- * You should  have received  a copy of the GNU Lesser General Public License
- * along with  this program;  if not, write to the  Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id$
- */
-
-#ifndef INCLUDED_LIB3DS_TYPES_H
-#include "types.h"
-#endif
-
-#include <iostream>
-using namespace std;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-
-typedef enum _Lib3dsTcbFlags{
-  LIB3DS_USE_TENSION    =0x0001,
-  LIB3DS_USE_CONTINUITY =0x0002,
-  LIB3DS_USE_BIAS       =0x0004,
-  LIB3DS_USE_EASE_TO    =0x0008,
-  LIB3DS_USE_EASE_FROM  =0x0010
-} Lib3dsTcbFlags;
-
-typedef struct _Lib3dsTcb {
-    Lib3dsIntd frame;
-    Lib3dsWord flags;
-    Lib3dsFloat tens;
-    Lib3dsFloat cont;
-    Lib3dsFloat bias;
-    Lib3dsFloat ease_to;
-    Lib3dsFloat ease_from;
-} Lib3dsTcb;
-
-extern LIB3DSAPI void lib3ds_tcb(Lib3dsTcb *p, Lib3dsTcb *pc, Lib3dsTcb *c,
-  Lib3dsTcb *nc, Lib3dsTcb *n, Lib3dsFloat *ksm, Lib3dsFloat *ksp,
-  Lib3dsFloat *kdm, Lib3dsFloat *kdp);
-extern LIB3DSAPI Lib3dsBool lib3ds_tcb_read(Lib3dsTcb *tcb, iostream *strm);
-extern LIB3DSAPI Lib3dsBool lib3ds_tcb_write(Lib3dsTcb *tcb, iostream *strm);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
-
Index: /enSceneGraph/trunk/src/osgPlugins/3ds/background.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/background.cpp (revision 10076)
+++  (revision )
@@ -1,264 +1,0 @@
-/*
- * The 3D Studio File Format Library
- * Copyright (C) 1996-2001 by J.E. Hoffmann <je-h@gmx.net>
- * All rights reserved.
- *
- * This program is  free  software;  you can redistribute it and/or modify it
- * under the terms of the  GNU Lesser General Public License  as published by 
- * the  Free Software Foundation;  either version 2.1 of the License,  or (at 
- * your option) any later version.
- *
- * This  program  is  distributed in  the  hope that it will  be useful,  but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or  FITNESS FOR A  PARTICULAR PURPOSE.  See the  GNU Lesser General Public  
- * License for more details.
- *
- * You should  have received  a copy of the GNU Lesser General Public License
- * along with  this program;  if not, write to the  Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id$
- */
-#define LIB3DS_EXPORT
-#include "background.h"
-#include "chunk.h"
-#include "readwrite.h"
-#include <string.h>
-#include <math.h>
-
-
-/*!
- * \defgroup background Background Settings
- *
- * \author J.E. Hoffmann <je-h@gmx.net>
- */
-
-
-static Lib3dsBool
-solid_bgnd_read(Lib3dsBackground *background, iostream *strm)
-{
-  Lib3dsChunk c;
-  Lib3dsWord chunk;
-          
-  if (!lib3ds_chunk_read_start(&c, LIB3DS_SOLID_BGND, strm)) {
-    return(LIB3DS_FALSE);
-  }
-
-  while ((chunk=lib3ds_chunk_read_next(&c, strm))!=0) {
-    switch (chunk) {
-      case LIB3DS_LIN_COLOR_F:
-        lib3ds_rgb_read(background->solid.col, strm);
-        break;
-      case LIB3DS_COLOR_F:
-        lib3ds_rgb_read(background->solid.col, strm);
-        break;
-      default:
-        lib3ds_chunk_unknown(chunk);
-    }
-  }
-  
-  lib3ds_chunk_read_end(&c, strm);
-  return(LIB3DS_TRUE);
-}
-
-
-static Lib3dsBool
-v_gradient_read(Lib3dsBackground *background, iostream *strm)
-{
-  Lib3dsChunk c;
-  Lib3dsWord chunk;
-  int index[2];
-  Lib3dsRgb col[2][3];
-  int have_lin=0;
-  
-
-  if (!lib3ds_chunk_read_start(&c, LIB3DS_V_GRADIENT, strm)) {
-    return(LIB3DS_FALSE);
-  }
-  background->gradient.percent=lib3ds_float_read(strm);
-  lib3ds_chunk_read_tell(&c, strm);
-
-  index[0]=index[1]=0;
-  while ((chunk=lib3ds_chunk_read_next(&c, strm))!=0) {
-    switch (chunk) {
-      case LIB3DS_COLOR_F:
-        lib3ds_rgb_read(col[0][index[0]],strm);
-        index[0]++;
-        break;
-      case LIB3DS_LIN_COLOR_F:
-        lib3ds_rgb_read(col[1][index[1]],strm);
-        index[1]++;
-        have_lin=1;
-        break;
-      default:
-        lib3ds_chunk_unknown(chunk);
-    }
-  }
-  {
-    int i;
-    for (i=0; i<3; ++i) {
-      background->gradient.top[i]=col[have_lin][0][i];
-      background->gradient.middle[i]=col[have_lin][1][i];
-      background->gradient.bottom[i]=col[have_lin][2][i];
-    }
-  }
-  lib3ds_chunk_read_end(&c, strm);
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
- * \ingroup background
- */
-Lib3dsBool
-lib3ds_background_read(Lib3dsBackground *background, iostream *strm)
-{
-  Lib3dsChunk c;
-
-  if (!lib3ds_chunk_read(&c, strm)) {
-    return(LIB3DS_FALSE);
-  }
-  
-  switch (c.chunk) {
-    case LIB3DS_BIT_MAP:
-      {
-        if (!lib3ds_string_read(background->bitmap.name, 64, strm)) {
-            return(LIB3DS_FALSE);
-        }
-      }
-        break;
-      case LIB3DS_SOLID_BGND:
-        {
-          lib3ds_chunk_read_reset(&c, strm);
-          if (!solid_bgnd_read(background, strm)) {
-            return(LIB3DS_FALSE);
-          }
-        }
-        break;
-      case LIB3DS_V_GRADIENT:
-        {
-          lib3ds_chunk_read_reset(&c, strm);
-          if (!v_gradient_read(background, strm)) {
-            return(LIB3DS_FALSE);
-          }
-        }
-        break;
-      case LIB3DS_USE_BIT_MAP:
-        {
-          background->bitmap.use=LIB3DS_TRUE;
-        }
-        break;
-      case LIB3DS_USE_SOLID_BGND:
-        {
-          background->solid.use=LIB3DS_TRUE;
-        }
-        break;
-      case LIB3DS_USE_V_GRADIENT:
-        {
-          background->gradient.use=LIB3DS_TRUE;
-        }
-        break;
-  }
-  
-  return(LIB3DS_TRUE);
-}
-
-
-static Lib3dsBool
-colorf_write(Lib3dsRgba rgb, iostream *strm)
-{
-  Lib3dsChunk c;
-
-  c.chunk=LIB3DS_COLOR_F;
-  c.size=18;
-  lib3ds_chunk_write(&c,strm);
-  lib3ds_rgb_write(rgb,strm);
-
-  c.chunk=LIB3DS_LIN_COLOR_F;
-  c.size=18;
-  lib3ds_chunk_write(&c,strm);
-  lib3ds_rgb_write(rgb,strm);
-  return(LIB3DS_TRUE);
-}
-
-
-static Lib3dsBool
-colorf_defined(Lib3dsRgba rgb)
-{
-  int i;
-  for (i=0; i<3; ++i) {
-    if (fabs(rgb[i])>LIB3DS_EPSILON) {
-      break;
-    }
-  }
-  return(i<3);
-}
-
-
-/*!
- * \ingroup background
- */
-Lib3dsBool
-lib3ds_background_write(Lib3dsBackground *background, iostream *strm)
-{
-  if (strlen(background->bitmap.name)) { /*---- LIB3DS_BIT_MAP ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_BIT_MAP;
-    c.size=6+1+strlen(background->bitmap.name);
-    lib3ds_chunk_write(&c,strm);
-    lib3ds_string_write(background->bitmap.name, strm);
-  }
-
-  if (colorf_defined(background->solid.col)) { /*---- LIB3DS_SOLID_BGND ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_SOLID_BGND;
-    c.size=42;
-    lib3ds_chunk_write(&c,strm);
-    colorf_write(background->solid.col,strm);
-  }
-
-  if (colorf_defined(background->gradient.top) ||
-    colorf_defined(background->gradient.middle) ||
-    colorf_defined(background->gradient.bottom)) { /*---- LIB3DS_V_GRADIENT ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_V_GRADIENT;
-    c.size=118;
-    lib3ds_chunk_write(&c,strm);
-    lib3ds_float_write(background->gradient.percent,strm);
-    colorf_write(background->gradient.top,strm);
-    colorf_write(background->gradient.middle,strm);
-    colorf_write(background->gradient.bottom,strm);
-  }
-
-  if (background->bitmap.use) { /*---- LIB3DS_USE_BIT_MAP ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_USE_BIT_MAP;
-    c.size=6;
-    lib3ds_chunk_write(&c,strm);
-  }
-
-  if (background->solid.use) { /*---- LIB3DS_USE_SOLID_BGND ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_USE_SOLID_BGND;
-    c.size=6;
-    lib3ds_chunk_write(&c,strm);
-  }
-
-  if (background->gradient.use) { /*---- LIB3DS_USE_V_GRADIENT ----*/
-    Lib3dsChunk c;
-    c.chunk=LIB3DS_USE_V_GRADIENT;
-    c.size=6;
-    lib3ds_chunk_write(&c,strm);
-  }
-  
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
-
-\typedef Lib3dsBackground
-  \ingroup background
-  \sa _Lib3dsBackground
-
-*/
Index: /enSceneGraph/trunk/src/osgPlugins/3ds/ease.h
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/ease.h (revision 6461)
+++  (revision )
@@ -1,41 +1,0 @@
-/* -*- c -*- */
-#ifndef INCLUDED_LIB3DS_EASE_H
-#define INCLUDED_LIB3DS_EASE_H
-/*
- * The 3D Studio File Format Library
- * Copyright (C) 1996-2001 by J.E. Hoffmann <je-h@gmx.net>
- * All rights reserved.
- *
- * This program is  free  software;  you can redistribute it and/or modify it
- * under the terms of the  GNU Lesser General Public License  as published by 
- * the  Free Software Foundation;  either version 2.1 of the License,  or (at 
- * your option) any later version.
- *
- * This  program  is  distributed in  the  hope that it will  be useful,  but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or  FITNESS FOR A  PARTICULAR PURPOSE.  See the  GNU Lesser General Public  
- * License for more details.
- *
- * You should  have received  a copy of the GNU Lesser General Public License
- * along with  this program;  if not, write to the  Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id$
- */
-
-#ifndef INCLUDED_LIB3DS_TYPES_H
-#include "types.h"
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern LIB3DSAPI Lib3dsFloat lib3ds_ease(Lib3dsFloat fp, Lib3dsFloat fc, 
-  Lib3dsFloat fn, Lib3dsFloat ease_from, Lib3dsFloat ease_to);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
-
Index: /enSceneGraph/trunk/src/osgPlugins/3ds/file.h
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/file.h (revision 10076)
+++  (revision )
@@ -1,111 +1,0 @@
-/* -*- c -*- */
-#ifndef INCLUDED_LIB3DS_FILE_H
-#define INCLUDED_LIB3DS_FILE_H
-/*
- * The 3D Studio File Format Library
- * Copyright (C) 1996-2001 by J.E. Hoffmann <je-h@gmx.net>
- * All rights reserved.
- *
- * This program is  free  software;  you can redistribute it and/or modify it
- * under the terms of the  GNU Lesser General Public License  as published by 
- * the  Free Software Foundation;  either version 2.1 of the License,  or (at 
- * your option) any later version.
- *
- * This  program  is  distributed in  the  hope that it will  be useful,  but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or  FITNESS FOR A  PARTICULAR PURPOSE.  See the  GNU Lesser General Public  
- * License for more details.
- *
- * You should  have received  a copy of the GNU Lesser General Public License
- * along with  this program;  if not, write to the  Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id$
- */
-
-#ifndef INCLUDED_LIB3DS_BACKGROUND_H
-#include "background.h"
-#endif
-#ifndef INCLUDED_LIB3DS_ATMOSPHERE_H
-#include "atmosphere.h"
-#endif
-#ifndef INCLUDED_LIB3DS_SHADOW_H
-#include "shadow.h"
-#endif
-#ifndef INCLUDED_LIB3DS_VIEWPORT_H
-#include "viewport.h"
-#endif
-#include <osgDB/Registry>
-#include <iostream>
-using namespace std;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-
-/*!
- * 3ds file structure
- * \ingroup file
- */
-struct _Lib3dsFile {
-    Lib3dsDword mesh_version;
-    Lib3dsWord keyf_revision;
-    char name[12+1];
-    Lib3dsFloat master_scale;
-    Lib3dsVector construction_plane;
-    Lib3dsRgb ambient;
-    Lib3dsShadow shadow;
-    Lib3dsBackground background;
-    Lib3dsAtmosphere atmosphere;
-    Lib3dsViewport viewport;
-    Lib3dsViewport viewport_keyf;
-    Lib3dsIntd frames;
-    Lib3dsIntd segment_from;
-    Lib3dsIntd segment_to;
-    Lib3dsIntd current_frame;
-    Lib3dsMaterial *materials;
-    Lib3dsMesh *meshes;
-    Lib3dsCamera *cameras;
-    Lib3dsLight *lights;
-    Lib3dsNode *nodes;
-}; 
-
-extern LIB3DSAPI Lib3dsFile* lib3ds_file_load(const char *filename, const osgDB::ReaderWriter::Options* options);
-extern LIB3DSAPI Lib3dsFile* lib3ds_stream_load(iostream * strm);
-extern LIB3DSAPI Lib3dsBool lib3ds_file_save(Lib3dsFile *file, const char *filename);
-extern LIB3DSAPI Lib3dsFile* lib3ds_file_new();
-extern LIB3DSAPI void lib3ds_file_free(Lib3dsFile *file);
-extern LIB3DSAPI void lib3ds_file_eval(Lib3dsFile *file, Lib3dsFloat t);
-extern LIB3DSAPI Lib3dsBool lib3ds_file_read(Lib3dsFile *file, iostream *strm);
-extern LIB3DSAPI Lib3dsBool lib3ds_file_write(Lib3dsFile *file, iostream *strm);
-extern LIB3DSAPI void lib3ds_file_insert_material(Lib3dsFile *file, Lib3dsMaterial *material);
-extern LIB3DSAPI void lib3ds_file_remove_material(Lib3dsFile *file, Lib3dsMaterial *material);
-extern LIB3DSAPI Lib3dsMaterial* lib3ds_file_material_by_name(Lib3dsFile *file, const char *name);
-extern LIB3DSAPI void lib3ds_file_dump_materials(Lib3dsFile *file);
-extern LIB3DSAPI void lib3ds_file_insert_mesh(Lib3dsFile *file, Lib3dsMesh *mesh);
-extern LIB3DSAPI void lib3ds_file_remove_mesh(Lib3dsFile *file, Lib3dsMesh *mesh);
-extern LIB3DSAPI Lib3dsMesh* lib3ds_file_mesh_by_name(Lib3dsFile *file, const char *name);
-extern LIB3DSAPI void lib3ds_file_dump_meshes(Lib3dsFile *file);
-extern LIB3DSAPI void lib3ds_file_dump_instances(Lib3dsFile *file);
-extern LIB3DSAPI void lib3ds_file_insert_camera(Lib3dsFile *file, Lib3dsCamera *camera);
-extern LIB3DSAPI void lib3ds_file_remove_camera(Lib3dsFile *file, Lib3dsCamera *camera);
-extern LIB3DSAPI Lib3dsCamera* lib3ds_file_camera_by_name(Lib3dsFile *file, const char *name);
-extern LIB3DSAPI void lib3ds_file_dump_cameras(Lib3dsFile *file);
-extern LIB3DSAPI void lib3ds_file_insert_light(Lib3dsFile *file, Lib3dsLight *light);
-extern LIB3DSAPI void lib3ds_file_remove_light(Lib3dsFile *file, Lib3dsLight *light);
-extern LIB3DSAPI Lib3dsLight* lib3ds_file_light_by_name(Lib3dsFile *file, const char *name);
-extern LIB3DSAPI void lib3ds_file_dump_lights(Lib3dsFile *file);
-extern LIB3DSAPI Lib3dsNode* lib3ds_file_node_by_name(Lib3dsFile *file, const char* name,
-  Lib3dsNodeTypes type);
-extern LIB3DSAPI Lib3dsNode* lib3ds_file_node_by_id(Lib3dsFile *file, Lib3dsWord node_id);
-extern LIB3DSAPI void lib3ds_file_insert_node(Lib3dsFile *file, Lib3dsNode *node);
-extern LIB3DSAPI Lib3dsBool lib3ds_file_remove_node(Lib3dsFile *file, Lib3dsNode *node);
-extern LIB3DSAPI void lib3ds_file_dump_nodes(Lib3dsFile *file);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
-
Index: /enSceneGraph/trunk/src/osgPlugins/3ds/viewport.h
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/viewport.h (revision 10076)
+++  (revision )
@@ -1,139 +1,0 @@
-/* -*- c -*- */
-#ifndef INCLUDED_LIB3DS_VIEWPORT_H
-#define INCLUDED_LIB3DS_VIEWPORT_H
-/*
- * The 3D Studio File Format Library
- * Copyright (C) 1996-2001 by J.E. Hoffmann <je-h@gmx.net>
- * All rights reserved.
- *
- * This program is  free  software;  you can redistribute it and/or modify it
- * under the terms of the  GNU Lesser General Public License  as published by 
- * the  Free Software Foundation;  either version 2.1 of the License,  or (at 
- * your option) any later version.
- *
- * This  program  is  distributed in  the  hope that it will  be useful,  but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or  FITNESS FOR A  PARTICULAR PURPOSE.  See the  GNU Lesser General Public  
- * License for more details.
- *
- * You should  have received  a copy of the GNU Lesser General Public License
- * along with  this program;  if not, write to the  Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id$
- */
-
-#ifndef INCLUDED_LIB3DS_TYPES_H
-#include "types.h"
-#endif
-
-#include <iostream>
-using namespace std;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*!
- * Layout view types
- * \ingroup viewport
- */
-typedef enum _Lib3dsViewType {
-  LIB3DS_VIEW_TYPE_NOT_USED  =0,
-  LIB3DS_VIEW_TYPE_TOP       =1,
-  LIB3DS_VIEW_TYPE_BOTTOM    =2,
-  LIB3DS_VIEW_TYPE_LEFT      =3,
-  LIB3DS_VIEW_TYPE_RIGHT     =4,
-  LIB3DS_VIEW_TYPE_FRONT     =5,
-  LIB3DS_VIEW_TYPE_BACK      =6,
-  LIB3DS_VIEW_TYPE_USER      =7,
-  LIB3DS_VIEW_TYPE_SPOTLIGHT =18,
-  LIB3DS_VIEW_TYPE_CAMERA    =65535
-} Lib3dsViewType;
-
-/*!
- * Layout view settings
- * \ingroup viewport
- */
-typedef struct _Lib3dsView {
-    Lib3dsWord type;
-    Lib3dsWord axis_lock;
-    Lib3dsIntw position[2];
-    Lib3dsIntw size[2];
-    Lib3dsFloat zoom;
-    Lib3dsVector center;
-    Lib3dsFloat horiz_angle;
-    Lib3dsFloat vert_angle;
-    char camera[11];
-} Lib3dsView;
-
-/*!
- * Layout styles
- * \ingroup viewport
- */
-typedef enum _Lib3dsLayoutStyle {
-  LIB3DS_LAYOUT_SINGLE                  =0,
-  LIB3DS_LAYOUT_TWO_PANE_VERT_SPLIT     =1,
-  LIB3DS_LAYOUT_TWO_PANE_HORIZ_SPLIT    =2,
-  LIB3DS_LAYOUT_FOUR_PANE               =3,
-  LIB3DS_LAYOUT_THREE_PANE_LEFT_SPLIT   =4,
-  LIB3DS_LAYOUT_THREE_PANE_BOTTOM_SPLIT =5,
-  LIB3DS_LAYOUT_THREE_PANE_RIGHT_SPLIT  =6,
-  LIB3DS_LAYOUT_THREE_PANE_TOP_SPLIT    =7,
-  LIB3DS_LAYOUT_THREE_PANE_VERT_SPLIT   =8,
-  LIB3DS_LAYOUT_THREE_PANE_HORIZ_SPLIT  =9,
-  LIB3DS_LAYOUT_FOUR_PANE_LEFT_SPLIT    =10,
-  LIB3DS_LAYOUT_FOUR_PANE_RIGHT_SPLIT   =11
-} Lib3dsLayoutStyle;
-
-/*!
- * Viewport layout settings
- * \ingroup viewport
- */
-typedef struct _Lib3dsLayout {
-    Lib3dsWord style;
-    Lib3dsIntw active;
-    Lib3dsIntw swap;
-    Lib3dsIntw swap_prior;
-    Lib3dsIntw swap_view;
-    Lib3dsWord position[2];
-    Lib3dsWord size[2];
-    Lib3dsDword views;
-    Lib3dsView *viewL;
-} Lib3dsLayout;
-
-/*!
- * Default view settings
- * \ingroup viewport
- */
-typedef struct _Lib3dsDefaultView {
-    Lib3dsWord type;
-    Lib3dsVector position;
-    Lib3dsFloat width;
-    Lib3dsFloat horiz_angle;
-    Lib3dsFloat vert_angle;
-    Lib3dsFloat roll_angle;
-    char camera[64];
-} Lib3dsDefaultView;
-
-/*!
- * Viewport and default view settings
- * \ingroup viewport
- */
-struct _Lib3dsViewport {
-    Lib3dsLayout layout;
-    Lib3dsDefaultView default_view;
-};
-
-extern LIB3DSAPI Lib3dsBool lib3ds_viewport_read(Lib3dsViewport *viewport, iostream *strm);
-extern LIB3DSAPI void lib3ds_viewport_set_views(Lib3dsViewport *viewport, Lib3dsDword views);
-extern LIB3DSAPI Lib3dsBool lib3ds_viewport_write(Lib3dsViewport *viewport, iostream *strm);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
-
-
-
-
Index: /enSceneGraph/trunk/src/osgPlugins/3ds/chunktable.h
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/chunktable.h (revision 6461)
+++  (revision )
@@ -1,263 +1,0 @@
-/* -*- c -*- */
-#ifndef INCLUDED_LIB3DS_CHUNKTABLE_H
-#define INCLUDED_LIB3DS_CHUNKTABLE_H
-/*
- * The 3D Studio File Format Library
- * Copyright (C) 1996-2001 by J.E. Hoffmann <je-h@gmx.net>
- * All rights reserved.
- *
- * This program is  free  software;  you can redistribute it and/or modify it
- * under the terms of the  GNU Lesser General Public License  as published by
- * the  Free Software Foundation;  either version 2.1 of the License,  or (at
- * your option) any later version.
- *
- * This  program  is  distributed in  the  hope that it will  be useful,  but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or  FITNESS FOR A  PARTICULAR PURPOSE.  See the  GNU Lesser General Public
- * License for more details.
- *
- * You should  have received  a copy of the GNU Lesser General Public License
- * along with  this program;  if not, write to the  Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id$
- */
-
-#ifndef INCLUDED_LIB3DS_CHUNK_H
-#include "chunk.h"
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct _Lib3dsChunkTable {
-    Lib3dsDword chunk;
-    const char* name;
-} Lib3dsChunkTable;
-
-static Lib3dsChunkTable lib3ds_chunk_table[]={
-  {LIB3DS_NULL_CHUNK, "LIB3DS_NULL_CHUNK"},
-  {LIB3DS_M3DMAGIC, "LIB3DS_M3DMAGIC"},
-  {LIB3DS_SMAGIC, "LIB3DS_SMAGIC"},
-  {LIB3DS_LMAGIC, "LIB3DS_LMAGIC"},
-  {LIB3DS_MLIBMAGIC, "LIB3DS_MLIBMAGIC"},
-  {LIB3DS_MATMAGIC, "LIB3DS_MATMAGIC"},
-  {LIB3DS_CMAGIC, "LIB3DS_CMAGIC"},
-  {LIB3DS_M3D_VERSION, "LIB3DS_M3D_VERSION"},
-  {LIB3DS_M3D_KFVERSION, "LIB3DS_M3D_KFVERSION"},
-  {LIB3DS_COLOR_F, "LIB3DS_COLOR_F"},
-  {LIB3DS_COLOR_24, "LIB3DS_COLOR_24"},
-  {LIB3DS_LIN_COLOR_24, "LIB3DS_LIN_COLOR_24"},
-  {LIB3DS_LIN_COLOR_F, "LIB3DS_LIN_COLOR_F"},
-  {LIB3DS_INT_PERCENTAGE, "LIB3DS_INT_PERCENTAGE"},
-  {LIB3DS_FLOAT_PERCENTAGE, "LIB3DS_FLOAT_PERCENTAGE"},
-  {LIB3DS_MDATA, "LIB3DS_MDATA"},
-  {LIB3DS_MESH_VERSION, "LIB3DS_MESH_VERSION"},
-  {LIB3DS_MASTER_SCALE, "LIB3DS_MASTER_SCALE"},
-  {LIB3DS_LO_SHADOW_BIAS, "LIB3DS_LO_SHADOW_BIAS"},
-  {LIB3DS_HI_SHADOW_BIAS, "LIB3DS_HI_SHADOW_BIAS"},
-  {LIB3DS_SHADOW_MAP_SIZE, "LIB3DS_SHADOW_MAP_SIZE"},
-  {LIB3DS_SHADOW_SAMPLES, "LIB3DS_SHADOW_SAMPLES"},
-  {LIB3DS_SHADOW_RANGE, "LIB3DS_SHADOW_RANGE"},
-  {LIB3DS_SHADOW_FILTER, "LIB3DS_SHADOW_FILTER"},
-  {LIB3DS_RAY_BIAS, "LIB3DS_RAY_BIAS"},
-  {LIB3DS_O_CONSTS, "LIB3DS_O_CONSTS"},
-  {LIB3DS_AMBIENT_LIGHT, "LIB3DS_AMBIENT_LIGHT"},
-  {LIB3DS_BIT_MAP, "LIB3DS_BIT_MAP"},
-  {LIB3DS_SOLID_BGND, "LIB3DS_SOLID_BGND"},
-  {LIB3DS_V_GRADIENT, "LIB3DS_V_GRADIENT"},
-  {LIB3DS_USE_BIT_MAP, "LIB3DS_USE_BIT_MAP"},
-  {LIB3DS_USE_SOLID_BGND, "LIB3DS_USE_SOLID_BGND"},
-  {LIB3DS_USE_V_GRADIENT, "LIB3DS_USE_V_GRADIENT"},
-  {LIB3DS_FOG, "LIB3DS_FOG"},
-  {LIB3DS_FOG_BGND, "LIB3DS_FOG_BGND"},
-  {LIB3DS_LAYER_FOG, "LIB3DS_LAYER_FOG"},
-  {LIB3DS_DISTANCE_CUE, "LIB3DS_DISTANCE_CUE"},
-  {LIB3DS_DCUE_BGND, "LIB3DS_DCUE_BGND"},
-  {LIB3DS_USE_FOG, "LIB3DS_USE_FOG"},
-  {LIB3DS_USE_LAYER_FOG, "LIB3DS_USE_LAYER_FOG"},
-  {LIB3DS_USE_DISTANCE_CUE, "LIB3DS_USE_DISTANCE_CUE"},
-  {LIB3DS_MAT_ENTRY, "LIB3DS_MAT_ENTRY"},
-  {LIB3DS_MAT_NAME, "LIB3DS_MAT_NAME"},
-  {LIB3DS_MAT_AMBIENT, "LIB3DS_MAT_AMBIENT"},
-  {LIB3DS_MAT_DIFFUSE, "LIB3DS_MAT_DIFFUSE"},
-  {LIB3DS_MAT_SPECULAR, "LIB3DS_MAT_SPECULAR"},
-  {LIB3DS_MAT_SHININESS, "LIB3DS_MAT_SHININESS"},
-  {LIB3DS_MAT_SHIN2PCT, "LIB3DS_MAT_SHIN2PCT"},
-  {LIB3DS_MAT_TRANSPARENCY, "LIB3DS_MAT_TRANSPARENCY"},
-  {LIB3DS_MAT_XPFALL, "LIB3DS_MAT_XPFALL"},
-  {LIB3DS_MAT_USE_XPFALL, "LIB3DS_MAT_USE_XPFALL"},
-  {LIB3DS_MAT_REFBLUR, "LIB3DS_MAT_REFBLUR"},
-  {LIB3DS_MAT_SHADING, "LIB3DS_MAT_SHADING"},
-  {LIB3DS_MAT_USE_REFBLUR, "LIB3DS_MAT_USE_REFBLUR"},
-  {LIB3DS_MAT_SELF_ILLUM, "LIB3DS_MAT_SELF_ILLUM"},
-  {LIB3DS_MAT_TWO_SIDE, "LIB3DS_MAT_TWO_SIDE"},
-  {LIB3DS_MAT_DECAL, "LIB3DS_MAT_DECAL"},
-  {LIB3DS_MAT_ADDITIVE, "LIB3DS_MAT_ADDITIVE"},
-  {LIB3DS_MAT_WIRE, "LIB3DS_MAT_WIRE"},
-  {LIB3DS_MAT_FACEMAP, "LIB3DS_MAT_FACEMAP"},
-  {LIB3DS_MAT_PHONGSOFT, "LIB3DS_MAT_PHONGSOFT"},
-  {LIB3DS_MAT_WIREABS, "LIB3DS_MAT_WIREABS"},
-  {LIB3DS_MAT_WIRE_SIZE, "LIB3DS_MAT_WIRE_SIZE"},
-  {LIB3DS_MAT_TEXMAP, "LIB3DS_MAT_TEXMAP"},
-  {LIB3DS_MAT_SXP_TEXT_DATA, "LIB3DS_MAT_SXP_TEXT_DATA"},
-  {LIB3DS_MAT_TEXMASK, "LIB3DS_MAT_TEXMASK"},
-  {LIB3DS_MAT_SXP_TEXTMASK_DATA, "LIB3DS_MAT_SXP_TEXTMASK_DATA"},
-  {LIB3DS_MAT_TEX2MAP, "LIB3DS_MAT_TEX2MAP"},
-  {LIB3DS_MAT_SXP_TEXT2_DATA, "LIB3DS_MAT_SXP_TEXT2_DATA"},
-  {LIB3DS_MAT_TEX2MASK, "LIB3DS_MAT_TEX2MASK"},
-  {LIB3DS_MAT_SXP_TEXT2MASK_DATA, "LIB3DS_MAT_SXP_TEXT2MASK_DATA"},
-  {LIB3DS_MAT_OPACMAP, "LIB3DS_MAT_OPACMAP"},
-  {LIB3DS_MAT_SXP_OPAC_DATA, "LIB3DS_MAT_SXP_OPAC_DATA"},
-  {LIB3DS_MAT_OPACMASK, "LIB3DS_MAT_OPACMASK"},
-  {LIB3DS_MAT_SXP_OPACMASK_DATA, "LIB3DS_MAT_SXP_OPACMASK_DATA"},
-  {LIB3DS_MAT_BUMPMAP, "LIB3DS_MAT_BUMPMAP"},
-  {LIB3DS_MAT_SXP_BUMP_DATA, "LIB3DS_MAT_SXP_BUMP_DATA"},
-  {LIB3DS_MAT_BUMPMASK, "LIB3DS_MAT_BUMPMASK"},
-  {LIB3DS_MAT_SXP_BUMPMASK_DATA, "LIB3DS_MAT_SXP_BUMPMASK_DATA"},
-  {LIB3DS_MAT_SPECMAP, "LIB3DS_MAT_SPECMAP"},
-  {LIB3DS_MAT_SXP_SPEC_DATA, "LIB3DS_MAT_SXP_SPEC_DATA"},
-  {LIB3DS_MAT_SPECMASK, "LIB3DS_MAT_SPECMASK"},
-  {LIB3DS_MAT_SXP_SPECMASK_DATA, "LIB3DS_MAT_SXP_SPECMASK_DATA"},
-  {LIB3DS_MAT_SHINMAP, "LIB3DS_MAT_SHINMAP"},
-  {LIB3DS_MAT_SXP_SHIN_DATA, "LIB3DS_MAT_SXP_SHIN_DATA"},
-  {LIB3DS_MAT_SHINMASK, "LIB3DS_MAT_SHINMASK"},
-  {LIB3DS_MAT_SXP_SHINMASK_DATA, "LIB3DS_MAT_SXP_SHINMASK_DATA"},
-  {LIB3DS_MAT_SELFIMAP, "LIB3DS_MAT_SELFIMAP"},
-  {LIB3DS_MAT_SXP_SELFI_DATA, "LIB3DS_MAT_SXP_SELFI_DATA"},
-  {LIB3DS_MAT_SELFIMASK, "LIB3DS_MAT_SELFIMASK"},
-  {LIB3DS_MAT_SXP_SELFIMASK_DATA, "LIB3DS_MAT_SXP_SELFIMASK_DATA"},
-  {LIB3DS_MAT_REFLMAP, "LIB3DS_MAT_REFLMAP"},
-  {LIB3DS_MAT_REFLMASK, "LIB3DS_MAT_REFLMASK"},
-  {LIB3DS_MAT_SXP_REFLMASK_DATA, "LIB3DS_MAT_SXP_REFLMASK_DATA"},
-  {LIB3DS_MAT_ACUBIC, "LIB3DS_MAT_ACUBIC"},
-  {LIB3DS_MAT_MAPNAME, "LIB3DS_MAT_MAPNAME"},
-  {LIB3DS_MAT_MAP_TILING, "LIB3DS_MAT_MAP_TILING"},
-  {LIB3DS_MAT_MAP_TEXBLUR, "LIB3DS_MAT_MAP_TEXBLUR"},
-  {LIB3DS_MAT_MAP_USCALE, "LIB3DS_MAT_MAP_USCALE"},
-  {LIB3DS_MAT_MAP_VSCALE, "LIB3DS_MAT_MAP_VSCALE"},
-  {LIB3DS_MAT_MAP_UOFFSET, "LIB3DS_MAT_MAP_UOFFSET"},
-  {LIB3DS_MAT_MAP_VOFFSET, "LIB3DS_MAT_MAP_VOFFSET"},
-  {LIB3DS_MAT_MAP_ANG, "LIB3DS_MAT_MAP_ANG"},
-  {LIB3DS_MAT_MAP_COL1, "LIB3DS_MAT_MAP_COL1"},
-  {LIB3DS_MAT_MAP_COL2, "LIB3DS_MAT_MAP_COL2"},
-  {LIB3DS_MAT_MAP_RCOL, "LIB3DS_MAT_MAP_RCOL"},
-  {LIB3DS_MAT_MAP_GCOL, "LIB3DS_MAT_MAP_GCOL"},
-  {LIB3DS_MAT_MAP_BCOL, "LIB3DS_MAT_MAP_BCOL"},
-  {LIB3DS_NAMED_OBJECT, "LIB3DS_NAMED_OBJECT"},
-  {LIB3DS_N_DIRECT_LIGHT, "LIB3DS_N_DIRECT_LIGHT"},
-  {LIB3DS_DL_OFF, "LIB3DS_DL_OFF"},
-  {LIB3DS_DL_OUTER_RANGE, "LIB3DS_DL_OUTER_RANGE"},
-  {LIB3DS_DL_INNER_RANGE, "LIB3DS_DL_INNER_RANGE"},
-  {LIB3DS_DL_MULTIPLIER, "LIB3DS_DL_MULTIPLIER"},
-  {LIB3DS_DL_EXCLUDE, "LIB3DS_DL_EXCLUDE"},
-  {LIB3DS_DL_ATTENUATE, "LIB3DS_DL_ATTENUATE"},
-  {LIB3DS_DL_SPOTLIGHT, "LIB3DS_DL_SPOTLIGHT"},
-  {LIB3DS_DL_SPOT_ROLL, "LIB3DS_DL_SPOT_ROLL"},
-  {LIB3DS_DL_SHADOWED, "LIB3DS_DL_SHADOWED"},
-  {LIB3DS_DL_LOCAL_SHADOW2, "LIB3DS_DL_LOCAL_SHADOW2"},
-  {LIB3DS_DL_SEE_CONE, "LIB3DS_DL_SEE_CONE"},
-  {LIB3DS_DL_SPOT_RECTANGULAR, "LIB3DS_DL_SPOT_RECTANGULAR"},
-  {LIB3DS_DL_SPOT_ASPECT, "LIB3DS_DL_SPOT_ASPECT"},
-  {LIB3DS_DL_SPOT_PROJECTOR, "LIB3DS_DL_SPOT_PROJECTOR"},
-  {LIB3DS_DL_SPOT_OVERSHOOT, "LIB3DS_DL_SPOT_OVERSHOOT"},
-  {LIB3DS_DL_RAY_BIAS, "LIB3DS_DL_RAY_BIAS"},
-  {LIB3DS_DL_RAYSHAD, "LIB3DS_DL_RAYSHAD"},
-  {LIB3DS_N_CAMERA, "LIB3DS_N_CAMERA"},
-  {LIB3DS_CAM_SEE_CONE, "LIB3DS_CAM_SEE_CONE"},
-  {LIB3DS_CAM_RANGES, "LIB3DS_CAM_RANGES"},
-  {LIB3DS_OBJ_HIDDEN, "LIB3DS_OBJ_HIDDEN"},
-  {LIB3DS_OBJ_VIS_LOFTER, "LIB3DS_OBJ_VIS_LOFTER"},
-  {LIB3DS_OBJ_DOESNT_CAST, "LIB3DS_OBJ_DOESNT_CAST"},
-  {LIB3DS_OBJ_DONT_RECVSHADOW, "LIB3DS_OBJ_DONT_RECVSHADOW"},
-  {LIB3DS_OBJ_MATTE, "LIB3DS_OBJ_MATTE"},
-  {LIB3DS_OBJ_FAST, "LIB3DS_OBJ_FAST"},
-  {LIB3DS_OBJ_PROCEDURAL, "LIB3DS_OBJ_PROCEDURAL"},
-  {LIB3DS_OBJ_FROZEN, "LIB3DS_OBJ_FROZEN"},
-  {LIB3DS_N_TRI_OBJECT, "LIB3DS_N_TRI_OBJECT"},
-  {LIB3DS_POINT_ARRAY, "LIB3DS_POINT_ARRAY"},
-  {LIB3DS_POINT_FLAG_ARRAY, "LIB3DS_POINT_FLAG_ARRAY"},
-  {LIB3DS_FACE_ARRAY, "LIB3DS_FACE_ARRAY"},
-  {LIB3DS_MSH_MAT_GROUP, "LIB3DS_MSH_MAT_GROUP"},
-  {LIB3DS_SMOOTH_GROUP, "LIB3DS_SMOOTH_GROUP"},
-  {LIB3DS_MSH_BOXMAP, "LIB3DS_MSH_BOXMAP"},
-  {LIB3DS_TEX_VERTS, "LIB3DS_TEX_VERTS"},
-  {LIB3DS_MESH_MATRIX, "LIB3DS_MESH_MATRIX"},
-  {LIB3DS_MESH_COLOR, "LIB3DS_MESH_COLOR"},
-  {LIB3DS_MESH_TEXTURE_INFO, "LIB3DS_MESH_TEXTURE_INFO"},
-  {LIB3DS_KFDATA, "LIB3DS_KFDATA"},
-  {LIB3DS_KFHDR, "LIB3DS_KFHDR"},
-  {LIB3DS_KFSEG, "LIB3DS_KFSEG"},
-  {LIB3DS_KFCURTIME, "LIB3DS_KFCURTIME"},
-  {LIB3DS_AMBIENT_NODE_TAG, "LIB3DS_AMBIENT_NODE_TAG"},
-  {LIB3DS_OBJECT_NODE_TAG, "LIB3DS_OBJECT_NODE_TAG"},
-  {LIB3DS_CAMERA_NODE_TAG, "LIB3DS_CAMERA_NODE_TAG"},
-  {LIB3DS_TARGET_NODE_TAG, "LIB3DS_TARGET_NODE_TAG"},
-  {LIB3DS_LIGHT_NODE_TAG, "LIB3DS_LIGHT_NODE_TAG"},
-  {LIB3DS_L_TARGET_NODE_TAG, "LIB3DS_L_TARGET_NODE_TAG"},
-  {LIB3DS_SPOTLIGHT_NODE_TAG, "LIB3DS_SPOTLIGHT_NODE_TAG"},
-  {LIB3DS_NODE_ID, "LIB3DS_NODE_ID"},
-  {LIB3DS_NODE_HDR, "LIB3DS_NODE_HDR"},
-  {LIB3DS_PIVOT, "LIB3DS_PIVOT"},
-  {LIB3DS_INSTANCE_NAME, "LIB3DS_INSTANCE_NAME"},
-  {LIB3DS_MORPH_SMOOTH, "LIB3DS_MORPH_SMOOTH"},
-  {LIB3DS_BOUNDBOX, "LIB3DS_BOUNDBOX"},
-  {LIB3DS_POS_TRACK_TAG, "LIB3DS_POS_TRACK_TAG"},
-  {LIB3DS_COL_TRACK_TAG, "LIB3DS_COL_TRACK_TAG"},
-  {LIB3DS_ROT_TRACK_TAG, "LIB3DS_ROT_TRACK_TAG"},
-  {LIB3DS_SCL_TRACK_TAG, "LIB3DS_SCL_TRACK_TAG"},
-  {LIB3DS_MORPH_TRACK_TAG, "LIB3DS_MORPH_TRACK_TAG"},
-  {LIB3DS_FOV_TRACK_TAG, "LIB3DS_FOV_TRACK_TAG"},
-  {LIB3DS_ROLL_TRACK_TAG, "LIB3DS_ROLL_TRACK_TAG"},
-  {LIB3DS_HOT_TRACK_TAG, "LIB3DS_HOT_TRACK_TAG"},
-  {LIB3DS_FALL_TRACK_TAG, "LIB3DS_FALL_TRACK_TAG"},
-  {LIB3DS_HIDE_TRACK_TAG, "LIB3DS_HIDE_TRACK_TAG"},
-  {LIB3DS_POLY_2D, "LIB3DS_POLY_2D"},
-  {LIB3DS_SHAPE_OK, "LIB3DS_SHAPE_OK"},
-  {LIB3DS_SHAPE_NOT_OK, "LIB3DS_SHAPE_NOT_OK"},
-  {LIB3DS_SHAPE_HOOK, "LIB3DS_SHAPE_HOOK"},
-  {LIB3DS_PATH_3D, "LIB3DS_PATH_3D"},
-  {LIB3DS_PATH_MATRIX, "LIB3DS_PATH_MATRIX"},
-  {LIB3DS_SHAPE_2D, "LIB3DS_SHAPE_2D"},
-  {LIB3DS_M_SCALE, "LIB3DS_M_SCALE"},
-  {LIB3DS_M_TWIST, "LIB3DS_M_TWIST"},
-  {LIB3DS_M_TEETER, "LIB3DS_M_TEETER"},
-  {LIB3DS_M_FIT, "LIB3DS_M_FIT"},
-  {LIB3DS_M_BEVEL, "LIB3DS_M_BEVEL"},
-  {LIB3DS_XZ_CURVE, "LIB3DS_XZ_CURVE"},
-  {LIB3DS_YZ_CURVE, "LIB3DS_YZ_CURVE"},
-  {LIB3DS_INTERPCT, "LIB3DS_INTERPCT"},
-  {LIB3DS_DEFORM_LIMIT, "LIB3DS_DEFORM_LIMIT"},
-  {LIB3DS_USE_CONTOUR, "LIB3DS_USE_CONTOUR"},
-  {LIB3DS_USE_TWEEN, "LIB3DS_USE_TWEEN"},
-  {LIB3DS_USE_SCALE, "LIB3DS_USE_SCALE"},
-  {LIB3DS_USE_TWIST, "LIB3DS_USE_TWIST"},
-  {LIB3DS_USE_TEETER, "LIB3DS_USE_TEETER"},
-  {LIB3DS_USE_FIT, "LIB3DS_USE_FIT"},
-  {LIB3DS_USE_BEVEL, "LIB3DS_USE_BEVEL"},
-  {LIB3DS_DEFAULT_VIEW, "LIB3DS_DEFAULT_VIEW"},
-  {LIB3DS_VIEW_TOP, "LIB3DS_VIEW_TOP"},
-  {LIB3DS_VIEW_BOTTOM, "LIB3DS_VIEW_BOTTOM"},
-  {LIB3DS_VIEW_LEFT, "LIB3DS_VIEW_LEFT"},
-  {LIB3DS_VIEW_RIGHT, "LIB3DS_VIEW_RIGHT"},
-  {LIB3DS_VIEW_FRONT, "LIB3DS_VIEW_FRONT"},
-  {LIB3DS_VIEW_BACK, "LIB3DS_VIEW_BACK"},
-  {LIB3DS_VIEW_USER, "LIB3DS_VIEW_USER"},
-  {LIB3DS_VIEW_CAMERA, "LIB3DS_VIEW_CAMERA"},
-  {LIB3DS_VIEW_WINDOW, "LIB3DS_VIEW_WINDOW"},
-  {LIB3DS_VIEWPORT_LAYOUT_OLD, "LIB3DS_VIEWPORT_LAYOUT_OLD"},
-  {LIB3DS_VIEWPORT_DATA_OLD, "LIB3DS_VIEWPORT_DATA_OLD"},
-  {LIB3DS_VIEWPORT_LAYOUT, "LIB3DS_VIEWPORT_LAYOUT"},
-  {LIB3DS_VIEWPORT_DATA, "LIB3DS_VIEWPORT_DATA"},
-  {LIB3DS_VIEWPORT_DATA_3, "LIB3DS_VIEWPORT_DATA_3"},
-  {LIB3DS_VIEWPORT_SIZE, "LIB3DS_VIEWPORT_SIZE"},
-  {LIB3DS_NETWORK_VIEW, "LIB3DS_NETWORK_VIEW"},
-  {0,0}
-};
-
-#ifdef __cplusplus
-}
-#endif
-#endif
-
Index: /enSceneGraph/trunk/src/osgPlugins/3ds/tracks.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/tracks.cpp (revision 10076)
+++  (revision )
@@ -1,1385 +1,0 @@
-/*
- * The 3D Studio File Format Library
- * Copyright (C) 1996-2001 by J.E. Hoffmann <je-h@gmx.net>
- * All rights reserved.
- *
- * This program is  free  software;  you can redistribute it and/or modify it
- * under the terms of the  GNU Lesser General Public License  as published by 
- * the  Free Software Foundation;  either version 2.1 of the License,  or (at 
- * your option) any later version.
- *
- * This  program  is  distributed in  the  hope that it will  be useful,  but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or  FITNESS FOR A  PARTICULAR PURPOSE.  See the  GNU Lesser General Public  
- * License for more details.
- *
- * You should  have received  a copy of the GNU Lesser General Public License
- * along with  this program;  if not, write to the  Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id$
- */
-#define LIB3DS_EXPORT
-#include "tracks.h"
-#include "readwrite.h"
-#include "chunk.h"
-#include "lib3ds_float.h"
-#include "vector.h"
-#include "quat.h"
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-#include "config.h"
-#ifdef WITH_DMALLOC
-#include <dmalloc.h>
-#endif
-
-
-/*!
- * \defgroup tracks Keyframing Tracks
- *
- * \author J.E. Hoffmann <je-h@gmx.net>
- */
-
-
-/*!
- * \ingroup tracks 
- */
-Lib3dsBoolKey*
-lib3ds_bool_key_new()
-{
-  Lib3dsBoolKey* k;
-  k=(Lib3dsBoolKey*)calloc(sizeof(Lib3dsBoolKey), 1);
-  return(k);
-}
-
-
-/*!
- * \ingroup tracks 
- */
-void
-lib3ds_bool_key_free(Lib3dsBoolKey *key)
-{
-  ASSERT(key);
-  free(key);
-}
-
-
-/*!
- * \ingroup tracks 
- */
-void
-lib3ds_bool_track_free_keys(Lib3dsBoolTrack *track)
-{
-  Lib3dsBoolKey *p,*q;
-
-  ASSERT(track);
-  for (p=track->keyL; p; p=q) {
-    q=p->next;
-    lib3ds_bool_key_free(p);
-  }
-}
-
-
-/*!
- * \ingroup tracks 
- */
-void
-lib3ds_bool_track_insert(Lib3dsBoolTrack *track, Lib3dsBoolKey *key)
-{
-  ASSERT(track);
-  ASSERT(key);
-  ASSERT(!key->next);
-
-  if (!track->keyL) {
-    track->keyL=key;
-    key->next=0;
-  }
-  else {
-    Lib3dsBoolKey *k,*p;
-
-    for (p=0,k=track->keyL; k!=0; p=k, k=k->next) {
-      if (k->tcb.frame>key->tcb.frame) {
-        break;
-      }
-    }
-    if (!p) {
-      key->next=track->keyL;
-      track->keyL=key;
-    }
-    else {
-      key->next=k;
-      p->next=key;
-    }
- 
-    if (k && (key->tcb.frame==k->tcb.frame)) {
-      key->next=k->next;
-      lib3ds_bool_key_free(k);
-    }
-  }
-}
-
-
-/*!
- * \ingroup tracks 
- */
-void
-lib3ds_bool_track_remove(Lib3dsBoolTrack *track, Lib3dsIntd frame)
-{
-  Lib3dsBoolKey *k,*p;
-  
-  ASSERT(track);
-  if (!track->keyL) {
-    return;
-  }
-  for (p=0,k=track->keyL; k!=0; p=k, k=k->next) {
-    if (k->tcb.frame==frame) {
-      if (!p) {
-        track->keyL=track->keyL->next;
-      }
-      else {
-        p->next=k->next;
-      }
-      lib3ds_bool_key_free(k);
-      break;
-    }
-  }
-}
-
-
-/*!
- * \ingroup tracks 
- */
-void
-lib3ds_bool_track_eval(Lib3dsBoolTrack *track, Lib3dsBool *p, Lib3dsFloat t)
-{
-  Lib3dsBoolKey *k;
-  Lib3dsBool result;
-
-  ASSERT(p);
-  if (!track->keyL) {
-    *p=LIB3DS_FALSE;
-    return;
-  }
-  if (!track->keyL->next) {
-    *p = LIB3DS_TRUE;
-    return;
-  }
-
-  result=LIB3DS_FALSE;
-  k=track->keyL;
-  while ((t<(Lib3dsFloat)k->tcb.frame) && (t>=(Lib3dsFloat)k->next->tcb.frame)) {
-    if (result) {
-      result=LIB3DS_FALSE;
-    }
-    else {
-      result=LIB3DS_TRUE;
-    }
-    if (!k->next) {
-      if (track->flags&LIB3DS_REPEAT) {
-        t-=(Lib3dsFloat)k->tcb.frame;
-        k=track->keyL;
-      }
-      else {
-        break;
-      }
-    }
-    else {
-      k=k->next;
-    }
-  }
-  *p=result;
-}
-
-
-/*!
- * \ingroup tracks 
- */
-Lib3dsBool
-lib3ds_bool_track_read(Lib3dsBoolTrack *track, iostream *strm)
-{
-  int keys;
-  int i;
-  Lib3dsBoolKey *k;
-
-  track->flags=lib3ds_word_read(strm);
-  lib3ds_dword_read(strm);
-  lib3ds_dword_read(strm);
-  keys=lib3ds_intd_read(strm);
-
-  for (i=0; i<keys; ++i) {
-    k=lib3ds_bool_key_new();
-    if (!lib3ds_tcb_read(&k->tcb, strm)) {
-      return(LIB3DS_FALSE);
-    }
-    lib3ds_bool_track_insert(track, k);
-  }
-  
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
- * \ingroup tracks 
- */
-Lib3dsBool
-lib3ds_bool_track_write(Lib3dsBoolTrack *track, iostream *strm)
-{
-  Lib3dsBoolKey *k;
-  Lib3dsDword num=0;
-  for (k=track->keyL; k; k=k->next) {
-    ++num;
-  }
-  lib3ds_word_write((Lib3dsWord)track->flags,strm);
-  lib3ds_dword_write(0,strm);
-  lib3ds_dword_write(0,strm);
-  lib3ds_dword_write(num,strm);
-
-  for (k=track->keyL; k; k=k->next) {
-    if (!lib3ds_tcb_write(&k->tcb,strm)) {
-      return(LIB3DS_FALSE);
-    }
-  }
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
- * \ingroup tracks 
- */
-Lib3dsLin1Key*
-lib3ds_lin1_key_new()
-{
-  Lib3dsLin1Key* k;
-  k=(Lib3dsLin1Key*)calloc(sizeof(Lib3dsLin1Key), 1);
-  return(k);
-}
-
-
-/*!
- * \ingroup tracks 
- */
-void
-lib3ds_lin1_key_free(Lib3dsLin1Key *key)
-{
-  ASSERT(key);
-  free(key);
-}
-
-
-/*!
- * \ingroup tracks 
- */
-void
-lib3ds_lin1_track_free_keys(Lib3dsLin1Track *track)
-{
-  Lib3dsLin1Key *p,*q;
-
-  ASSERT(track);
-  for (p=track->keyL; p; p=q) {
-    q=p->next;
-    lib3ds_lin1_key_free(p);
-  }
-}
-
-
-/*!
- * \ingroup tracks 
- */
-void
-lib3ds_lin1_key_setup(Lib3dsLin1Key *p, Lib3dsLin1Key *cp, Lib3dsLin1Key *c,
-  Lib3dsLin1Key *cn, Lib3dsLin1Key *n)
-{
-  Lib3dsFloat np,nn;
-  Lib3dsFloat ksm,ksp,kdm,kdp;
-  
-  ASSERT(c);
-  if (!cp) {
-    cp=c;
-  }
-  if (!cn) {
-    cn=c;
-  }
-  if (!p && !n) {
-    c->ds=0;
-    c->dd=0;
-    return;
-  }
-
-  if (n && p) {
-    lib3ds_tcb(&p->tcb, &cp->tcb, &c->tcb, &cn->tcb, &n->tcb, &ksm, &ksp, &kdm, &kdp);
-    np = c->value - p->value; 
-    nn = n->value - c->value; 
-
-    c->ds=ksm*np + ksp*nn;
-    c->dd=kdm*np + kdp*nn;
-  }
-  else {
-    if (p) {
-      np = c->value - p->value;
-      c->ds = np;
-      c->dd = np;
-    }
-    if (n) {
-      nn = n->value - c->value; 
-      c->ds = nn;
-      c->dd = nn;
-    }
-  }
-}
-
-
-/*!
- * \ingroup tracks 
- */
-void
-lib3ds_lin1_track_setup(Lib3dsLin1Track *track)
-{
-  Lib3dsLin1Key *pp,*pc,*pn,*pl;
-
-  ASSERT(track);
-  pc=track->keyL;
-  if (!pc) {
-    return;
-  }
-  if (!pc->next) {
-    pc->ds=0;
-    pc->dd=0;
-    return;
-  }
-
-  if (track->flags&LIB3DS_SMOOTH) {
-    for (pl=track->keyL; pl->next->next; pl=pl->next);
-    lib3ds_lin1_key_setup(pl, pl->next, pc, 0, pc->next);
- }
- else {
-   lib3ds_lin1_key_setup(0, 0, pc, 0, pc->next);
- }
-  for (;;) {
-    pp=pc;
-    pc=pc->next;
-    pn=pc->next;
-    if (!pn) {
-      break;
-    }
-    lib3ds_lin1_key_setup(pp, 0, pc, 0, pn);
-  }
-
-  if (track->flags&LIB3DS_SMOOTH) {
-    lib3ds_lin1_key_setup(pp, 0, pc, track->keyL, track->keyL->next);
-  }
-  else {
-    lib3ds_lin1_key_setup(pp, 0, pc, 0, 0);
-  }
-}
-
-
-/*!
- * \ingroup tracks 
- */
-void
-lib3ds_lin1_track_insert(Lib3dsLin1Track *track, Lib3dsLin1Key *key)
-{
-  ASSERT(track);
-  ASSERT(key);
-  ASSERT(!key->next);
-
-  if (!track->keyL) {
-    track->keyL=key;
-    key->next=0;
-  }
-  else {
-    Lib3dsLin1Key *k,*p;
-
-    for (p=0,k=track->keyL; k!=0; p=k, k=k->next) {
-      if (k->tcb.frame>key->tcb.frame) {
-        break;
-      }
-    }
-    if (!p) {
-      key->next=track->keyL;
-      track->keyL=key;
-    }
-    else {
-      key->next=k;
-      p->next=key;
-    }
- 
-    if (k && (key->tcb.frame==k->tcb.frame)) {
-      key->next=k->next;
-      lib3ds_lin1_key_free(k);
-    }
-  }
-}
-
-
-/*!
- * \ingroup tracks 
- */
-void
-lib3ds_lin1_track_remove(Lib3dsLin1Track *track, Lib3dsIntd frame)
-{
-  Lib3dsLin1Key *k,*p;
-  
-  ASSERT(track);
-  if (!track->keyL) {
-    return;
-  }
-  for (p=0,k=track->keyL; k!=0; p=k, k=k->next) {
-    if (k->tcb.frame==frame) {
-      if (!p) {
-        track->keyL=track->keyL->next;
-      }
-      else {
-        p->next=k->next;
-      }
-      lib3ds_lin1_key_free(k);
-      break;
-    }
-  }
-}
-
-
-/*!
- * \ingroup tracks 
- */
-void
-lib3ds_lin1_track_eval(Lib3dsLin1Track *track, Lib3dsFloat *p, Lib3dsFloat t)
-{
-  Lib3dsLin1Key *k;
-  Lib3dsFloat nt;
-  Lib3dsFloat u;
-
-  ASSERT(p);
-  if (!track->keyL) {
-    *p=0;
-    return;
-  }
-  if (!track->keyL->next) {
-    *p = track->keyL->value;
-    return;
-  }
-
-  for (k=track->keyL; k->next!=0; k=k->next) {
-    if ((t>=(Lib3dsFloat)k->tcb.frame) && (t<(Lib3dsFloat)k->next->tcb.frame)) {
-      break;
-    }
-  }
-  if (!k->next) {
-    if (track->flags&LIB3DS_REPEAT) {
-      nt=(Lib3dsFloat)fmod(t, (float)k->tcb.frame);
-      for (k=track->keyL; k->next!=0; k=k->next) {
-        if ((nt>=(Lib3dsFloat)k->tcb.frame) && (nt<(Lib3dsFloat)k->next->tcb.frame)) {
-          break;
-        }
-      }
-      ASSERT(k->next);
-    }
-    else {
-      *p = k->value;
-      return;
-    }
-  }
-  else {
-    nt=t;
-  }
-  u=nt - (Lib3dsFloat)k->tcb.frame;
-  u/=(Lib3dsFloat)(k->next->tcb.frame - k->tcb.frame);
-
-  *p = lib3ds_float_cubic(
-    k->value,
-    k->dd,
-    k->next->ds,
-    k->next->value,
-    u
-  );
-}
-
-
-/*!
- * \ingroup tracks 
- */
-Lib3dsBool
-lib3ds_lin1_track_read(Lib3dsLin1Track *track, iostream *strm)
-{
-  int keys;
-  int i;
-  Lib3dsLin1Key *k;
-
-  track->flags=lib3ds_word_read(strm);
-  lib3ds_dword_read(strm);
-  lib3ds_dword_read(strm);
-  keys=lib3ds_intd_read(strm);
-
-  for (i=0; i<keys; ++i) {
-    k=lib3ds_lin1_key_new();
-    if (!lib3ds_tcb_read(&k->tcb, strm)) {
-      return(LIB3DS_FALSE);
-    }
-    k->value=lib3ds_float_read(strm);
-    lib3ds_lin1_track_insert(track, k);
-  }
-  lib3ds_lin1_track_setup(track);
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
- * \ingroup tracks 
- */
-Lib3dsBool
-lib3ds_lin1_track_write(Lib3dsLin1Track *track, iostream *strm)
-{
-  Lib3dsLin1Key *k;
-  Lib3dsDword num=0;
-  for (k=track->keyL; k; k=k->next) {
-    ++num;
-  }
-  lib3ds_word_write((Lib3dsWord)track->flags,strm);
-  lib3ds_dword_write(0,strm);
-  lib3ds_dword_write(0,strm);
-  lib3ds_dword_write(num,strm);
-
-  for (k=track->keyL; k; k=k->next) {
-    if (!lib3ds_tcb_write(&k->tcb,strm)) {
-      return(LIB3DS_FALSE);
-    }
-    lib3ds_float_write(k->value,strm);
-  }
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
- * \ingroup tracks 
- */
-Lib3dsLin3Key*
-lib3ds_lin3_key_new()
-{
-  Lib3dsLin3Key* k;
-  k=(Lib3dsLin3Key*)calloc(sizeof(Lib3dsLin3Key), 1);
-  return(k);
-}
-
-
-/*!
- * \ingroup tracks 
- */
-void
-lib3ds_lin3_key_free(Lib3dsLin3Key *key)
-{
-  ASSERT(key);
-  free(key);
-}
-
-
-/*!
- * \ingroup tracks 
- */
-void
-lib3ds_lin3_track_free_keys(Lib3dsLin3Track *track)
-{
-  Lib3dsLin3Key *p,*q;
-
-  ASSERT(track);
-  for (p=track->keyL; p; p=q) {
-    q=p->next;
-    lib3ds_lin3_key_free(p);
-  }
-}
-
-
-/*!
- * \ingroup tracks 
- */
-void
-lib3ds_lin3_key_setup(Lib3dsLin3Key *p, Lib3dsLin3Key *cp, Lib3dsLin3Key *c,
-  Lib3dsLin3Key *cn, Lib3dsLin3Key *n)
-{
-  Lib3dsVector np,nn;
-  Lib3dsFloat ksm,ksp,kdm,kdp;
-  int i;
-  
-  ASSERT(c);
-  if (!cp) {
-    cp=c;
-  }
-  if (!cn) {
-    cn=c;
-  }
-  if (!p && !n) {
-    lib3ds_vector_zero(c->ds);
-    lib3ds_vector_zero(c->dd);
-    return;
-  }
-
-  if (n && p) {
-    lib3ds_tcb(&p->tcb, &cp->tcb, &c->tcb, &cn->tcb, &n->tcb, &ksm, &ksp, &kdm, &kdp);
-    lib3ds_vector_sub(np, c->value, p->value); 
-    lib3ds_vector_sub(nn, n->value, c->value); 
-
-    for(i=0; i<3; ++i) {
-      c->ds[i]=ksm*np[i] + ksp*nn[i];
-      c->dd[i]=kdm*np[i] + kdp*nn[i];
-    }
-  }
-  else {
-    if (p) {
-      lib3ds_vector_sub(np, c->value, p->value);
-      lib3ds_vector_copy(c->ds, np);
-      lib3ds_vector_copy(c->dd, np);
-    }
-    if (n) {
-      lib3ds_vector_sub(nn, n->value, c->value); 
-      lib3ds_vector_copy(c->ds, nn);
-      lib3ds_vector_copy(c->dd, nn);
-    }
-  }
-}
-
-
-/*!
- * \ingroup tracks 
- */
-void
-lib3ds_lin3_track_setup(Lib3dsLin3Track *track)
-{
-  Lib3dsLin3Key *pp,*pc,*pn,*pl;
-
-  ASSERT(track);
-  pc=track->keyL;
-  if (!pc) {
-    return;
-  }
-  if (!pc->next) {
-    lib3ds_vector_zero(pc->ds);
-    lib3ds_vector_zero(pc->dd);
-    return;
-  }
-
-  if (track->flags&LIB3DS_SMOOTH) {
-    for (pl=track->keyL; pl->next->next; pl=pl->next);
-    lib3ds_lin3_key_setup(pl, pl->next, pc, 0, pc->next);
- }
- else {
-   lib3ds_lin3_key_setup(0, 0, pc, 0, pc->next);
- }
-  for (;;) {
-    pp=pc;
-    pc=pc->next;
-    pn=pc->next;
-    if (!pn) {
-      break;
-    }
-    lib3ds_lin3_key_setup(pp, 0, pc, 0, pn);
-  }
-
-  if (track->flags&LIB3DS_SMOOTH) {
-    lib3ds_lin3_key_setup(pp, 0, pc, track->keyL, track->keyL->next);
-  }
-  else {
-    lib3ds_lin3_key_setup(pp, 0, pc, 0, 0);
-  }
-}
-
-
-/*!
- * \ingroup tracks 
- */
-void
-lib3ds_lin3_track_insert(Lib3dsLin3Track *track, Lib3dsLin3Key *key)
-{
-  ASSERT(track);
-  ASSERT(key);
-  ASSERT(!key->next);
-
-  if (!track->keyL) {
-    track->keyL=key;
-    key->next=0;
-  }
-  else {
-    Lib3dsLin3Key *k,*p;
-
-    for (p=0,k=track->keyL; k!=0; p=k, k=k->next) {
-      if (k->tcb.frame>key->tcb.frame) {
-        break;
-      }
-    }
-    if (!p) {
-      key->next=track->keyL;
-      track->keyL=key;
-    }
-    else {
-      key->next=k;
-      p->next=key;
-    }
- 
-    if (k && (key->tcb.frame==k->tcb.frame)) {
-      key->next=k->next;
-      lib3ds_lin3_key_free(k);
-    }
-  }
-}
-
-
-/*!
- * \ingroup tracks 
- */
-void
-lib3ds_lin3_track_remove(Lib3dsLin3Track *track, Lib3dsIntd frame)
-{
-  Lib3dsLin3Key *k,*p;
-  
-  ASSERT(track);
-  if (!track->keyL) {
-    return;
-  }
-  for (p=0,k=track->keyL; k!=0; p=k, k=k->next) {
-    if (k->tcb.frame==frame) {
-      if (!p) {
-        track->keyL=track->keyL->next;
-      }
-      else {
-        p->next=k->next;
-      }
-      lib3ds_lin3_key_free(k);
-      break;
-    }
-  }
-}
-
-
-/*!
- * \ingroup tracks 
- */
-void
-lib3ds_lin3_track_eval(Lib3dsLin3Track *track, Lib3dsVector p, Lib3dsFloat t)
-{
-  Lib3dsLin3Key *k;
-  Lib3dsFloat nt;
-  Lib3dsFloat u;
-
-  if (!track->keyL) {
-    lib3ds_vector_zero(p);
-    return;
-  }
-  if (!track->keyL->next) {
-      lib3ds_vector_copy(p, track->keyL->value);
-    return;
-  }
-
-  for (k=track->keyL; k->next!=0; k=k->next) {
-    if ((t>=(Lib3dsFloat)k->tcb.frame) && (t<(Lib3dsFloat)k->next->tcb.frame)) {
-      break;
-    }
-  }
-  if (!k->next) {
-    if (track->flags&LIB3DS_REPEAT) {
-      nt=(Lib3dsFloat)fmod(t, (float)k->tcb.frame);
-      for (k=track->keyL; k->next!=0; k=k->next) {
-        if ((nt>=(Lib3dsFloat)k->tcb.frame) && (nt<(Lib3dsFloat)k->next->tcb.frame)) {
-          break;
-        }
-      }
-      ASSERT(k->next);
-    }
-    else {
-      lib3ds_vector_copy(p, k->value);
-      return;
-    }
-  }
-  else {
-    nt=t;
-  }
-  u=nt - (Lib3dsFloat)k->tcb.frame;
-  u/=(Lib3dsFloat)(k->next->tcb.frame - k->tcb.frame);
-  
-  lib3ds_vector_cubic(
-    p,
-    k->value,
-    k->dd,
-    k->next->ds,
-    k->next->value,
-    u
-  );
-}
-
-
-/*!
- * \ingroup tracks 
- */
-Lib3dsBool
-lib3ds_lin3_track_read(Lib3dsLin3Track *track, iostream *strm)
-{
-  int keys;
-  int i,j;
-  Lib3dsLin3Key *k;
-
-  track->flags=lib3ds_word_read(strm);
-  lib3ds_dword_read(strm);
-  lib3ds_dword_read(strm);
-  keys=lib3ds_intd_read(strm);
-
-  for (i=0; i<keys; ++i) {
-    k=lib3ds_lin3_key_new();
-    if (!lib3ds_tcb_read(&k->tcb, strm)) {
-      return(LIB3DS_FALSE);
-    }
-    for (j=0; j<3; ++j) {
-      k->value[j]=lib3ds_float_read(strm);
-    }
-    lib3ds_lin3_track_insert(track, k);
-  }
-  lib3ds_lin3_track_setup(track);
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
- * \ingroup tracks 
- */
-Lib3dsBool
-lib3ds_lin3_track_write(Lib3dsLin3Track *track, iostream *strm)
-{
-  Lib3dsLin3Key *k;
-  Lib3dsDword num=0;
-  for (k=track->keyL; k; k=k->next) {
-    ++num;
-  }
-  lib3ds_word_write((Lib3dsWord)track->flags,strm);
-  lib3ds_dword_write(0,strm);
-  lib3ds_dword_write(0,strm);
-  lib3ds_dword_write(num,strm);
-
-  for (k=track->keyL; k; k=k->next) {
-    if (!lib3ds_tcb_write(&k->tcb,strm)) {
-      return(LIB3DS_FALSE);
-    }
-    lib3ds_vector_write(k->value,strm);
-  }
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
- * \ingroup tracks 
- */
-Lib3dsQuatKey*
-lib3ds_quat_key_new()
-{
-  Lib3dsQuatKey* k;
-  k=(Lib3dsQuatKey*)calloc(sizeof(Lib3dsQuatKey), 1);
-  return(k);
-}
-
-
-/*!
- * \ingroup tracks 
- */
-void
-lib3ds_quat_key_free(Lib3dsQuatKey *key)
-{
-  ASSERT(key);
-  free(key);
-}
-
-
-/*!
- * \ingroup tracks 
- */
-void
-lib3ds_quat_track_free_keys(Lib3dsQuatTrack *track)
-{
-  Lib3dsQuatKey *p,*q;
-
-  ASSERT(track);
-  for (p=track->keyL; p; p=q) {
-    q=p->next;
-    lib3ds_quat_key_free(p);
-  }
-}
-
-
-/*!
- * \ingroup tracks 
- */
-void
-lib3ds_quat_key_setup(Lib3dsQuatKey *p, Lib3dsQuatKey *cp, Lib3dsQuatKey *c,
-  Lib3dsQuatKey *cn, Lib3dsQuatKey *n)
-{
-  Lib3dsFloat ksm,ksp,kdm,kdp;
-  Lib3dsQuat q,qp,qn,qa,qb;
-  int i;
-  
-  ASSERT(c);
-  if (!cp) {
-    cp=c;
-  }
-  if (!cn) {
-    cn=c;
-  }
-  if (!p || !n) {
-    lib3ds_quat_copy(c->ds, c->q);
-    lib3ds_quat_copy(c->dd, c->q);
-    return;
-  }
-
-  if (p) {
-    if (p->angle>LIB3DS_TWOPI-LIB3DS_EPSILON) {
-      lib3ds_quat_axis_angle(qp, p->axis, 0.0f);
-      lib3ds_quat_ln(qp);
-    }
-    else {
-      lib3ds_quat_copy(q, p->q);
-      if (lib3ds_quat_dot(q,c->q)<0) lib3ds_quat_neg(q);
-      lib3ds_quat_ln_dif(qp, c->q, q);
-    }
-  }
-  if (n) {
-    if (n->angle>LIB3DS_TWOPI-LIB3DS_EPSILON) {
-      lib3ds_quat_axis_angle(qn, n->axis, 0.0f);
-      lib3ds_quat_ln(qn);
-    }
-    else {
-      lib3ds_quat_copy(q, n->q);
-      if (lib3ds_quat_dot(q,c->q)<0) lib3ds_quat_neg(q);
-      lib3ds_quat_ln_dif(qn, c->q, q);
-    }
-  }
-
-  if (n && p) {
-    lib3ds_tcb(&p->tcb, &cp->tcb, &c->tcb, &cn->tcb, &n->tcb, &ksm, &ksp, &kdm, &kdp);
-    for(i=0; i<4; i++) {
-      qa[i]=-0.5f*(kdm*qn[i]+kdp*qp[i]);
-      qb[i]=-0.5f*(ksm*qn[i]+ksp*qp[i]);
-    }
-    lib3ds_quat_exp(qa);
-    lib3ds_quat_exp(qb);
-    
-    lib3ds_quat_mul(c->ds, c->q, qa);
-    lib3ds_quat_mul(c->dd, c->q, qb);
-  }
-  else {
-    if (p) {
-      lib3ds_quat_exp(qp);
-      lib3ds_quat_mul(c->ds, c->q, qp);
-      lib3ds_quat_mul(c->dd, c->q, qp);
-    }
-    if (n) {
-      lib3ds_quat_exp(qn);
-      lib3ds_quat_mul(c->ds, c->q, qn);
-      lib3ds_quat_mul(c->dd, c->q, qn);
-    }
-  }
-}
-
-
-/*!
- * \ingroup tracks 
- */
-void
-lib3ds_quat_track_setup(Lib3dsQuatTrack *track)
-{
-  Lib3dsQuatKey *pp,*pc,*pn,*pl;
-  Lib3dsQuat q;
-
-  ASSERT(track);
-  for (pp=0,pc=track->keyL; pc; pp=pc,pc=pc->next) {
-    lib3ds_quat_axis_angle(q, pc->axis, pc->angle);
-    if (pp) {
-      lib3ds_quat_mul(pc->q, q, pp->q);
-    }
-    else {
-      lib3ds_quat_copy(pc->q, q);
-    }
-  }
-
-  pc=track->keyL;
-  if (!pc) {
-    return;
-  }
-  if (!pc->next) {
-    lib3ds_quat_copy(pc->ds, pc->q);
-    lib3ds_quat_copy(pc->dd, pc->q);
-    return;
-  }
-
-  if (track->flags&LIB3DS_SMOOTH) {
-    for (pl=track->keyL; pl->next->next; pl=pl->next);
-    lib3ds_quat_key_setup(pl, pl->next, pc, 0, pc->next);
- }
-  else {
-    lib3ds_quat_key_setup(0, 0, pc, 0, pc->next);
-  }
-  for (;;) {
-    pp=pc;
-    pc=pc->next;
-    pn=pc->next;
-    if (!pn) {
-      break;
-    }
-    lib3ds_quat_key_setup(pp, 0, pc, 0, pn);
-  }
-
-  if (track->flags&LIB3DS_SMOOTH) {
-    lib3ds_quat_key_setup(pp, 0, pc, track->keyL, track->keyL->next);
-  }
-  else {
-    lib3ds_quat_key_setup(pp, 0, pc, 0, 0);
-  }
-}
-
-
-/*!
- * \ingroup tracks 
- */
-void
-lib3ds_quat_track_insert(Lib3dsQuatTrack *track, Lib3dsQuatKey *key)
-{
-  ASSERT(track);
-  ASSERT(key);
-  ASSERT(!key->next);
-
-  if (!track->keyL) {
-    track->keyL=key;
-    key->next=0;
-  }
-  else {
-    Lib3dsQuatKey *k,*p;
-
-    for (p=0,k=track->keyL; k!=0; p=k, k=k->next) {
-      if (k->tcb.frame>key->tcb.frame) {
-        break;
-      }
-    }
-    if (!p) {
-      key->next=track->keyL;
-      track->keyL=key;
-    }
-    else {
-      key->next=k;
-      p->next=key;
-    }
- 
-    if (k && (key->tcb.frame==k->tcb.frame)) {
-      key->next=k->next;
-      lib3ds_quat_key_free(k);
-    }
-  }
-}
-
-
-/*!
- * \ingroup tracks 
- */
-void
-lib3ds_quat_track_remove(Lib3dsQuatTrack *track, Lib3dsIntd frame)
-{
-  Lib3dsQuatKey *k,*p;
-  
-  ASSERT(track);
-  if (!track->keyL) {
-    return;
-  }
-  for (p=0,k=track->keyL; k!=0; p=k, k=k->next) {
-    if (k->tcb.frame==frame) {
-      if (!p) {
-        track->keyL=track->keyL->next;
-      }
-      else {
-        p->next=k->next;
-      }
-      lib3ds_quat_key_free(k);
-      break;
-    }
-  }
-}
-
-
-/*!
- * \ingroup tracks 
- */
-void
-lib3ds_quat_track_eval(Lib3dsQuatTrack *track, Lib3dsQuat q, Lib3dsFloat t)
-{
-  Lib3dsQuatKey *k;
-  Lib3dsFloat nt;
-  Lib3dsFloat u;
-
-  if (!track->keyL) {
-    lib3ds_quat_identity(q);
-    return;
-  }
-  if (!track->keyL->next) {
-    lib3ds_quat_copy(q, track->keyL->q);
-    return;
-  }
-
-  for (k=track->keyL; k->next!=0; k=k->next) {
-    if ((t>=k->tcb.frame) && (t<k->next->tcb.frame)) {
-      break;
-    }
-  }
-  if (!k->next) {
-    if (track->flags&LIB3DS_REPEAT) {
-      nt=(Lib3dsFloat)fmod(t, (float)k->tcb.frame);
-      for (k=track->keyL; k->next!=0; k=k->next) {
-        if ((nt>=k->tcb.frame) && (nt<k->next->tcb.frame)) {
-          break;
-        }
-      }
-      ASSERT(k->next);
-    }
-    else {
-      lib3ds_quat_copy(q, k->q);
-      return;
-    }
-  }
-  else {
-    nt=t;
-  }
-  u=nt - k->tcb.frame;
-  u/=(k->next->tcb.frame - k->tcb.frame);
-
-  lib3ds_quat_squad(
-    q,
-    k->q,
-    k->dd,
-    k->next->ds,
-    k->next->q,
-    u
-  );
-}
-
-
-/*!
- * \ingroup tracks 
- */
-Lib3dsBool
-lib3ds_quat_track_read(Lib3dsQuatTrack *track, iostream *strm)
-{
-  int keys;
-  int i,j;
-  Lib3dsQuatKey *k;
-
-  track->flags=lib3ds_word_read(strm);
-  lib3ds_dword_read(strm);
-  lib3ds_dword_read(strm);
-  keys=lib3ds_intd_read(strm);
-
-  for (i=0; i<keys; ++i) {
-    k=lib3ds_quat_key_new();
-    if (!lib3ds_tcb_read(&k->tcb, strm)) {
-      return(LIB3DS_FALSE);
-    }
-    k->angle=lib3ds_float_read(strm);
-    for (j=0; j<3; ++j) {
-      k->axis[j]=lib3ds_float_read(strm);
-    }
-    lib3ds_quat_track_insert(track, k);
-  }
-  lib3ds_quat_track_setup(track);
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
- * \ingroup tracks 
- */
-Lib3dsBool
-lib3ds_quat_track_write(Lib3dsQuatTrack *track, iostream *strm)
-{
-  Lib3dsQuatKey *k;
-  Lib3dsDword num=0;
-  for (k=track->keyL; k; k=k->next) {
-    ++num;
-  }
-  lib3ds_word_write((Lib3dsWord)track->flags,strm);
-  lib3ds_dword_write(0,strm);
-  lib3ds_dword_write(0,strm);
-  lib3ds_dword_write(num,strm);
-
-  for (k=track->keyL; k; k=k->next) {
-    if (!lib3ds_tcb_write(&k->tcb,strm)) {
-      return(LIB3DS_FALSE);
-    }
-    lib3ds_float_write(k->angle,strm);
-    lib3ds_vector_write(k->axis,strm);
-  }
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
- * \ingroup tracks 
- */
-Lib3dsMorphKey*
-lib3ds_morph_key_new()
-{
-  Lib3dsMorphKey* k;
-  k=(Lib3dsMorphKey*)calloc(sizeof(Lib3dsMorphKey), 1);
-  return(k);
-}
-
-
-/*!
- * \ingroup tracks 
- */
-void
-lib3ds_morph_key_free(Lib3dsMorphKey *key)
-{
-  ASSERT(key);
-  free(key);
-}
-
-
-/*!
- * \ingroup tracks 
- */
-void
-lib3ds_morph_track_free_keys(Lib3dsMorphTrack *track)
-{
-  Lib3dsMorphKey *p,*q;
-
-  ASSERT(track);
-  for (p=track->keyL; p; p=q) {
-    q=p->next;
-    lib3ds_morph_key_free(p);
-  }
-}
-
-
-/*!
- * \ingroup tracks 
- */
-void
-lib3ds_morph_track_insert(Lib3dsMorphTrack *track, Lib3dsMorphKey *key)
-{
-  ASSERT(track);
-  ASSERT(key);
-  ASSERT(!key->next);
-
-  if (!track->keyL) {
-    track->keyL=key;
-    key->next=0;
-  }
-  else {
-    Lib3dsMorphKey *k,*p;
-
-    for (p=0,k=track->keyL; k!=0; p=k, k=k->next) {
-      if (k->tcb.frame>key->tcb.frame) {
-        break;
-      }
-    }
-    if (!p) {
-      key->next=track->keyL;
-      track->keyL=key;
-    }
-    else {
-      key->next=k;
-      p->next=key;
-    }
- 
-    if (k && (key->tcb.frame==k->tcb.frame)) {
-      key->next=k->next;
-      lib3ds_morph_key_free(k);
-    }
-  }
-}
-
-
-/*!
- * \ingroup tracks 
- */
-void
-lib3ds_morph_track_remove(Lib3dsMorphTrack *track, Lib3dsIntd frame)
-{
-  Lib3dsMorphKey *k,*p;
-  
-  ASSERT(track);
-  if (!track->keyL) {
-    return;
-  }
-  for (p=0,k=track->keyL; k!=0; p=k, k=k->next) {
-    if (k->tcb.frame==frame) {
-      if (!p) {
-        track->keyL=track->keyL->next;
-      }
-      else {
-        p->next=k->next;
-      }
-      lib3ds_morph_key_free(k);
-      break;
-    }
-  }
-}
-
-
-/*!
- * \ingroup tracks 
- */
-void
-lib3ds_morph_track_eval(Lib3dsMorphTrack *track, char *p, Lib3dsFloat t)
-{
-  Lib3dsMorphKey *k;
-  char* result;
-
-  ASSERT(p);
-  if (!track->keyL) {
-    strcpy(p,"");
-    return;
-  }
-  if (!track->keyL->next) {
-    strcpy(p,track->keyL->name);
-    return;
-  }
-
-  result=0;
-  k=track->keyL;
-  while ((t<k->tcb.frame) && (t>=k->next->tcb.frame)) {
-    result=k->name;
-    if (!k->next) {
-      if (track->flags&LIB3DS_REPEAT) {
-        t-=k->tcb.frame;
-        k=track->keyL;
-      }
-      else {
-        break;
-      }
-    }
-    else {
-      k=k->next;
-    }
-  }
-  if (result) {
-    strcpy(p,result);
-  }
-  else {
-    strcpy(p,"");
-  }
-}
-
-
-/*!
- * \ingroup tracks
- */
-Lib3dsBool
-lib3ds_morph_track_read(Lib3dsMorphTrack *, iostream *strm)
-{
-  /* FIXME: */
-  return(LIB3DS_TRUE);
-}
-
-
-/*!
- * \ingroup tracks 
- */
-Lib3dsBool
-lib3ds_morph_track_write(Lib3dsMorphTrack *, iostream *strm)
-{
-  /* FIXME: */
-  ASSERT(0);
-  return(LIB3DS_FALSE);
-}
-
-
Index: /enSceneGraph/trunk/src/osgPlugins/3ds/node.h
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/node.h (revision 10076)
+++  (revision )
@@ -1,173 +1,0 @@
-/* -*- c -*- */
-#ifndef INCLUDED_LIB3DS_NODE_H
-#define INCLUDED_LIB3DS_NODE_H
-/*
- * The 3D Studio File Format Library
- * Copyright (C) 1996-2001 by J.E. Hoffmann <je-h@gmx.net>
- * All rights reserved.
- *
- * This program is  free  software;  you can redistribute it and/or modify it
- * under the terms of the  GNU Lesser General Public License  as published by 
- * the  Free Software Foundation;  either version 2.1 of the License,  or (at 
- * your option) any later version.
- *
- * This  program  is  distributed in  the  hope that it will  be useful,  but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or  FITNESS FOR A  PARTICULAR PURPOSE.  See the  GNU Lesser General Public  
- * License for more details.
- *
- * You should  have received  a copy of the GNU Lesser General Public License
- * along with  this program;  if not, write to the  Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id$
- */
-
-#ifndef INCLUDED_LIB3DS_TRACKS_H
-#include "tracks.h"
-#endif
-
-#include <iostream>
-using namespace std;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/*!
- * Scene graph ambient color node data
- * \ingroup node
- */
-typedef struct _Lib3dsAmbientData {
-    Lib3dsRgb col;
-    Lib3dsLin3Track col_track;
-} Lib3dsAmbientData;
-
-/*!
- * Scene graph object instance node data
- * \ingroup node
- */
-typedef struct _Lib3dsObjectData {
-    Lib3dsVector pivot;
-    char instance[64];
-    Lib3dsVector bbox_min;
-    Lib3dsVector bbox_max;
-    Lib3dsVector pos;
-    Lib3dsLin3Track pos_track;
-    Lib3dsQuat rot;
-    Lib3dsQuatTrack rot_track;
-    Lib3dsVector scl;
-    Lib3dsLin3Track scl_track;
-    Lib3dsFloat morph_smooth;
-    char morph[64];
-    Lib3dsMorphTrack morph_track;
-    Lib3dsBool hide;
-    Lib3dsBoolTrack hide_track;
-} Lib3dsObjectData;
-
-/*!
- * Scene graph camera node data
- * \ingroup node
- */
-typedef struct _Lib3dsCameraData {
-    Lib3dsVector pos;
-    Lib3dsLin3Track pos_track;
-    Lib3dsFloat fov;
-    Lib3dsLin1Track fov_track;
-    Lib3dsFloat roll;
-    Lib3dsLin1Track roll_track;
-} Lib3dsCameraData;
-
-/*!
- * Scene graph camera target node data
- * \ingroup node
- */
-typedef struct _Lib3dsTargetData {
-    Lib3dsVector pos;
-    Lib3dsLin3Track pos_track;
-} Lib3dsTargetData;
-
-/*!
- * Scene graph light node data
- * \ingroup node
- */
-typedef struct _Lib3dsLightData {
-    Lib3dsVector pos;
-    Lib3dsLin3Track pos_track;
-    Lib3dsRgb col;
-    Lib3dsLin3Track col_track;
-    Lib3dsFloat hotspot;
-    Lib3dsLin1Track hotspot_track;
-    Lib3dsFloat falloff;
-    Lib3dsLin1Track falloff_track;
-    Lib3dsFloat roll;
-    Lib3dsLin1Track roll_track;
-} Lib3dsLightData;
-
-/*!
- * Scene graph spotlight target node data
- * \ingroup node
- */
-typedef struct _Lib3dsSpotData {
-    Lib3dsVector pos;
-    Lib3dsLin3Track pos_track;
-} Lib3dsSpotData;
-
-/*!
- * Scene graph node data union
- * \ingroup node
- */
-typedef union _Lib3dsNodeData {
-    Lib3dsAmbientData ambient;
-    Lib3dsObjectData object;
-    Lib3dsCameraData camera;
-    Lib3dsTargetData target;
-    Lib3dsLightData light;
-    Lib3dsSpotData spot;
-} Lib3dsNodeData;
-
-/*!
- * \ingroup node
- */
-#define LIB3DS_NO_PARENT 65535
-
-/*!
- * Scene graph node
- * \ingroup node
- */
-struct _Lib3dsNode {
-    Lib3dsUserData user;
-    Lib3dsNode *next;\
-    Lib3dsNode *childs;\
-    Lib3dsNode *parent;\
-    Lib3dsNodeTypes type;\
-    Lib3dsWord node_id;\
-    char name[64];\
-    Lib3dsWord flags1;\
-    Lib3dsWord flags2;\
-    Lib3dsWord parent_id;
-    Lib3dsMatrix matrix;
-    Lib3dsNodeData data;
-};
-
-extern LIB3DSAPI Lib3dsNode* lib3ds_node_new_ambient();
-extern LIB3DSAPI Lib3dsNode* lib3ds_node_new_object();
-extern LIB3DSAPI Lib3dsNode* lib3ds_node_new_camera();
-extern LIB3DSAPI Lib3dsNode* lib3ds_node_new_target();
-extern LIB3DSAPI Lib3dsNode* lib3ds_node_new_light();
-extern LIB3DSAPI Lib3dsNode* lib3ds_node_new_spot();
-extern LIB3DSAPI void lib3ds_node_free(Lib3dsNode *node);
-extern LIB3DSAPI void lib3ds_node_eval(Lib3dsNode *node, Lib3dsFloat t);
-extern LIB3DSAPI Lib3dsNode* lib3ds_node_by_name(Lib3dsNode *node, const char* name,
-  Lib3dsNodeTypes type);
-extern LIB3DSAPI Lib3dsNode* lib3ds_node_by_id(Lib3dsNode *node, Lib3dsWord node_id);
-extern LIB3DSAPI void lib3ds_node_dump(Lib3dsNode *node, Lib3dsIntd level);
-extern LIB3DSAPI Lib3dsBool lib3ds_node_read(Lib3dsNode *node, Lib3dsFile *file, iostream *strm);
-extern LIB3DSAPI Lib3dsBool lib3ds_node_write(Lib3dsNode *node, Lib3dsFile *file, iostream *strm);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
-
Index: /enSceneGraph/trunk/src/osgPlugins/3ds/shadow.h
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/shadow.h (revision 10076)
+++  (revision )
@@ -1,62 +1,0 @@
-/* -*- c -*- */
-#ifndef INCLUDED_LIB3DS_SHADOW_H
-#define INCLUDED_LIB3DS_SHADOW_H
-/*
- * The 3D Studio File Format Library
- * Copyright (C) 1996-2001 by J.E. Hoffmann <je-h@gmx.net>
- * All rights reserved.
- *
- * This program is  free  software;  you can redistribute it and/or modify it
- * under the terms of the  GNU Lesser General Public License  as published by 
- * the  Free Software Foundation;  either version 2.1 of the License,  or (at 
- * your option) any later version.
- *
- * This  program  is  distributed in  the  hope that it will  be useful,  but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or  FITNESS FOR A  PARTICULAR PURPOSE.  See the  GNU Lesser General Public  
- * License for more details.
- *
- * You should  have received  a copy of the GNU Lesser General Public License
- * along with  this program;  if not, write to the  Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id$
- */
-
-#ifndef INCLUDED_LIB3DS_TYPES_H
-#include "types.h"
-#endif
-
-#include <iostream>
-using namespace std;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*!
- * Shadow map settings
- * \ingroup shadow
- */
-struct _Lib3dsShadow {
-    Lib3dsIntw map_size;
-    Lib3dsFloat lo_bias;
-    Lib3dsFloat hi_bias;
-    Lib3dsIntw samples;
-    Lib3dsIntd range;
-    Lib3dsFloat filter;
-    Lib3dsFloat ray_bias;
-};
-
-extern LIB3DSAPI Lib3dsBool lib3ds_shadow_read(Lib3dsShadow *shadow, iostream *strm);
-extern LIB3DSAPI Lib3dsBool lib3ds_shadow_write(Lib3dsShadow *shadow, iostream *strm);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
-
-
-
-
-
Index: /enSceneGraph/trunk/src/osgPlugins/3ds/readwrite.h
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/readwrite.h (revision 10076)
+++  (revision )
@@ -1,63 +1,0 @@
-/* -*- c -*- */
-#ifndef INCLUDED_LIB3DS_READWRITE_H
-#define INCLUDED_LIB3DS_READWRITE_H
-/*
- * The 3D Studio File Format Library
- * Copyright (C) 1996-2001 by J.E. Hoffmann <je-h@gmx.net>
- * All rights reserved.
- *
- * This program is  free  software;  you can redistribute it and/or modify it
- * under the terms of the  GNU Lesser General Public License  as published by 
- * the  Free Software Foundation;  either version 2.1 of the License,  or (at 
- * your option) any later version.
- *
- * This  program  is  distributed in  the  hope that it will  be useful,  but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or  FITNESS FOR A  PARTICULAR PURPOSE.  See the  GNU Lesser General Public  
- * License for more details.
- *
- * You should  have received  a copy of the GNU Lesser General Public License
- * along with  this program;  if not, write to the  Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id$
- */
-
-#ifndef INCLUDED_LIB3DS_TYPES_H
-#include "types.h"
-#endif
-
-#include <iostream>
-using namespace std;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern LIB3DSAPI void setByteOrder();
-extern LIB3DSAPI Lib3dsByte lib3ds_byte_read(iostream *strm);
-extern LIB3DSAPI Lib3dsWord lib3ds_word_read(iostream *strm);
-extern LIB3DSAPI Lib3dsDword lib3ds_dword_read(iostream *strm);
-extern LIB3DSAPI Lib3dsIntb lib3ds_intb_read(iostream *strm);
-extern LIB3DSAPI Lib3dsIntw lib3ds_intw_read(iostream *strm);
-extern LIB3DSAPI Lib3dsIntd lib3ds_intd_read(iostream *strm);
-extern LIB3DSAPI Lib3dsFloat lib3ds_float_read(iostream *strm);
-extern LIB3DSAPI Lib3dsBool lib3ds_vector_read(Lib3dsVector v, iostream *strm);
-extern LIB3DSAPI Lib3dsBool lib3ds_rgb_read(Lib3dsRgb rgb, iostream *strm);
-extern LIB3DSAPI Lib3dsBool lib3ds_string_read(char *s, int buflen, iostream *strm);
-extern LIB3DSAPI Lib3dsBool lib3ds_byte_write(Lib3dsByte b, iostream *strm);
-extern LIB3DSAPI Lib3dsBool lib3ds_word_write(Lib3dsWord w, iostream *strm);
-extern LIB3DSAPI Lib3dsBool lib3ds_dword_write(Lib3dsDword d, iostream *strm);
-extern LIB3DSAPI Lib3dsBool lib3ds_intb_write(Lib3dsIntb b, iostream *strm);
-extern LIB3DSAPI Lib3dsBool lib3ds_intw_write(Lib3dsIntw w, iostream *strm);
-extern LIB3DSAPI Lib3dsBool lib3ds_intd_write(Lib3dsIntd d, iostream *strm);
-extern LIB3DSAPI Lib3dsBool lib3ds_float_write(Lib3dsFloat l, iostream *strm);
-extern LIB3DSAPI Lib3dsBool lib3ds_vector_write(Lib3dsVector v, iostream *strm);
-extern LIB3DSAPI Lib3dsBool lib3ds_rgb_write(Lib3dsRgb rgb, iostream *strm);
-extern LIB3DSAPI Lib3dsBool lib3ds_string_write(const char *s, iostream *strm);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
-
Index: /enSceneGraph/trunk/src/osgPlugins/3ds/camera.h
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/3ds/camera.h (revision 10076)
+++  (revision )
@@ -1,63 +1,0 @@
-/* -*- c -*- */
-#ifndef INCLUDED_LIB3DS_CAMERA_H
-#define INCLUDED_LIB3DS_CAMERA_H
-/*
- * The 3D Studio File Format Library
- * Copyright (C) 1996-2001 by J.E. Hoffmann <je-h@gmx.net>
- * All rights reserved.
- *
- * This program is  free  software;  you can redistribute it and/or modify it
- * under the terms of the  GNU Lesser General Public License  as published by 
- * the  Free Software Foundation;  either version 2.1 of the License,  or (at 
- * your option) any later version.
- *
- * This  program  is  distributed in  the  hope that it will  be useful,  but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or  FITNESS FOR A  PARTICULAR PURPOSE.  See the  GNU Lesser General Public  
- * License for more details.
- *
- * You should  have received  a copy of the GNU Lesser General Public License
- * along with  this program;  if not, write to the  Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id$
- */
-
-#ifndef INCLUDED_LIB3DS_TYPES_H
-#include "types.h"
-#endif
-
-#include <iostream>
-using namespace std;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*!
- * Camera object
- * \ingroup camera
- */
-struct _Lib3dsCamera {
-    Lib3dsCamera *next;
-    char name[64];
-    Lib3dsVector position;
-    Lib3dsVector target;
-    Lib3dsFloat roll;
-    Lib3dsFloat fov;
-    Lib3dsBool see_cone;
-    Lib3dsFloat near_range;
-    Lib3dsFloat far_range;
-}; 
-
-extern LIB3DSAPI Lib3dsCamera* lib3ds_camera_new(const char *name);
-extern LIB3DSAPI void lib3ds_camera_free(Lib3dsCamera *mesh);
-extern LIB3DSAPI void lib3ds_camera_dump(Lib3dsCamera *camera);
-extern LIB3DSAPI Lib3dsBool lib3ds_camera_read(Lib3dsCamera *camera, iostream *strm);
-extern LIB3DSAPI Lib3dsBool lib3ds_camera_write(Lib3dsCamera *camera, iostream *strm);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
-
