├── .gitignore ├── .travis.yml ├── AUTHORS ├── CMakeLists.txt ├── LICENSE ├── README.md ├── examples ├── 3ds2obj │ ├── .svn │ │ ├── all-wcprops │ │ ├── entries │ │ ├── prop-base │ │ │ └── 3ds2obj.c.svn-base │ │ └── text-base │ │ │ ├── 3ds2obj.c.svn-base │ │ │ ├── CMakeLists.txt.svn-base │ │ │ └── Makefile.am.svn-base │ ├── 3ds2obj.c │ └── CMakeLists.txt ├── 3dsdump │ ├── .svn │ │ ├── all-wcprops │ │ ├── entries │ │ ├── prop-base │ │ │ └── 3dsdump.c.svn-base │ │ └── text-base │ │ │ ├── 3dsdump.c.svn-base │ │ │ ├── CMakeLists.txt.svn-base │ │ │ └── Makefile.am.svn-base │ ├── 3dsdump.c │ └── CMakeLists.txt ├── 3dsplay │ ├── .svn │ │ ├── all-wcprops │ │ ├── entries │ │ ├── prop-base │ │ │ └── 3dsplay.cpp.svn-base │ │ └── text-base │ │ │ ├── 3dsplay.cpp.svn-base │ │ │ ├── CMakeLists.txt.svn-base │ │ │ ├── tga.c.svn-base │ │ │ └── tga.h.svn-base │ ├── 3dsplay.cpp │ ├── CMakeLists.txt │ ├── tga.c │ └── tga.h ├── CMakeLists.txt └── cube │ ├── .svn │ ├── all-wcprops │ ├── entries │ ├── prop-base │ │ ├── cube.c.svn-base │ │ └── cube.tga.svn-base │ └── text-base │ │ ├── CMakeLists.txt.svn-base │ │ ├── Makefile.am.svn-base │ │ ├── cube.c.svn-base │ │ └── cube.tga.svn-base │ ├── CMakeLists.txt │ ├── cube.c │ └── cube.tga └── src ├── CMakeLists.txt ├── lib3ds.h ├── lib3ds.rc ├── lib3ds_atmosphere.c ├── lib3ds_background.c ├── lib3ds_camera.c ├── lib3ds_chunk.c ├── lib3ds_chunktable.c ├── lib3ds_file.c ├── lib3ds_impl.h ├── lib3ds_io.c ├── lib3ds_light.c ├── lib3ds_material.c ├── lib3ds_math.c ├── lib3ds_matrix.c ├── lib3ds_mesh.c ├── lib3ds_node.c ├── lib3ds_quat.c ├── lib3ds_shadow.c ├── lib3ds_track.c ├── lib3ds_util.c ├── lib3ds_vector.c └── lib3ds_viewport.c /.gitignore: -------------------------------------------------------------------------------- 1 | /build*/ 2 | 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: cpp 2 | compiler: 3 | - gcc 4 | script: mkdir build && cd build && cmake .. && make 5 | notifications: 6 | email: 7 | recipients: 8 | - vkocherizhkin@gmail.com 9 | on_success: change 10 | on_failure: always -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Author of lib3ds is Jan Eric Kyprianidis 2 | 3 | The following people have contributed additional changes to lib3ds: 4 | 5 | Reed Hedges 6 | David Rogers 7 | Edward Falk 8 | Gernot Zeigler 9 | Haik Lorenz 10 | Jean-Charles Quillet 11 | Mike Frysinger 12 | Miles Bader 13 | Tomas Rapkauskas 14 | Torsten Blank 15 | Ralf Corsepius 16 | Stephane Denis 17 | 18 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | CMAKE_MINIMUM_REQUIRED(VERSION 2.6.2) 2 | PROJECT(lib3ds) 3 | 4 | SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin) 5 | SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin) 6 | SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib) 7 | 8 | if(UNIX) 9 | link_libraries(m) 10 | endif(UNIX) 11 | 12 | ADD_SUBDIRECTORY(src) 13 | ADD_SUBDIRECTORY(examples) 14 | 15 | # Install Rules 16 | install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/src/lib3ds.h" DESTINATION "include") -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://travis-ci.org/hoopoe/lib3ds.svg?branch=master)](https://travis-ci.org/hoopoe/lib3ds) 2 | 3 | Lib3ds is a free toolkit for handling the "3DS" format for 3D model files. 4 | Its main goal is to simplify the creation of 3DS import and export filters. 5 | 6 | This program is distributed in the hope that it will be useful, but 7 | WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 8 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 9 | License for more details. 10 | 11 | The official Lib3ds Homepage can be found at: www.lib3ds.org 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/3ds2obj/.svn/all-wcprops: -------------------------------------------------------------------------------- 1 | K 25 2 | svn:wc:ra_dav:version-url 3 | V 39 4 | /svn/!svn/ver/91/trunk/examples/3ds2obj 5 | END 6 | 3ds2obj.c 7 | K 25 8 | svn:wc:ra_dav:version-url 9 | V 49 10 | /svn/!svn/ver/85/trunk/examples/3ds2obj/3ds2obj.c 11 | END 12 | Makefile.am 13 | K 25 14 | svn:wc:ra_dav:version-url 15 | V 51 16 | /svn/!svn/ver/84/trunk/examples/3ds2obj/Makefile.am 17 | END 18 | CMakeLists.txt 19 | K 25 20 | svn:wc:ra_dav:version-url 21 | V 54 22 | /svn/!svn/ver/91/trunk/examples/3ds2obj/CMakeLists.txt 23 | END 24 | -------------------------------------------------------------------------------- /examples/3ds2obj/.svn/entries: -------------------------------------------------------------------------------- 1 | 10 2 | 3 | dir 4 | 107 5 | http://lib3ds.googlecode.com/svn/trunk/examples/3ds2obj 6 | http://lib3ds.googlecode.com/svn 7 | 8 | 9 | 10 | 2008-11-11T12:00:06.790149Z 11 | 91 12 | jeh 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 984c2e8c-059d-11df-a9fb-49f3208c864b 28 | 29 | 3ds2obj.c 30 | file 31 | 32 | 33 | 34 | 35 | 2014-11-03T08:36:57.516509Z 36 | 1c93ba1ed64dd33db4e792396047f9a4 37 | 2008-09-09T22:02:10.798270Z 38 | 85 39 | jeh 40 | has-props 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 9705 62 | 63 | Makefile.am 64 | file 65 | 66 | 67 | 68 | 69 | 2014-11-03T08:36:57.517509Z 70 | 5749ecd8e5de93666850c934788b2442 71 | 2008-09-09T13:41:25.501711Z 72 | 84 73 | jeh 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 153 96 | 97 | CMakeLists.txt 98 | file 99 | 100 | 101 | 102 | 103 | 2014-11-03T08:36:57.517509Z 104 | 527be941683de2efcdecf69cbe16e16f 105 | 2008-11-11T12:00:06.790149Z 106 | 91 107 | jeh 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 121 130 | 131 | -------------------------------------------------------------------------------- /examples/3ds2obj/.svn/prop-base/3ds2obj.c.svn-base: -------------------------------------------------------------------------------- 1 | K 13 2 | svn:mergeinfo 3 | V 0 4 | 5 | END 6 | -------------------------------------------------------------------------------- /examples/3ds2obj/.svn/text-base/3ds2obj.c.svn-base: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2008 by Jan Eric Kyprianidis 3 | All rights reserved. 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published 7 | by the Free Software Foundation, either version 2.1 of the License, or 8 | (at your option) any later version. 9 | 10 | Thisprogram is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program; If not, see . 17 | */ 18 | 19 | /** @file 3ds2obj.c 20 | Implementation of 3ds2obj converter. */ 21 | /** @example 3ds2obj.c 22 | This example shows how to convert a 3DS file to a Wavefront OBJ file. */ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #ifdef _MSC_VER 34 | #pragma warning ( disable : 4996 ) 35 | #endif 36 | 37 | 38 | static void 39 | help() { 40 | fprintf(stderr, 41 | "Syntax: 3ds2obj 3ds-file [obj-file] [mtl-file]\n" 42 | ); 43 | exit(1); 44 | } 45 | 46 | 47 | static const char* input = 0; 48 | static char* obj_file = 0; 49 | static char* mtl_file = 0; 50 | static int max_vertices = 0; 51 | static int max_texcos = 0; 52 | static int max_normals = 0; 53 | 54 | 55 | void parse_args(int argc, char **argv) { 56 | int i; 57 | 58 | for (i = 1; i < argc; ++i) { 59 | if (argv[i][0] == '-') { 60 | if ((strcmp(argv[i], "-h") == 0) || (strcmp(argv[i], "--help") == 0)) { 61 | help(); 62 | } else { 63 | help(); 64 | } 65 | } else { 66 | if (!input) { 67 | input = argv[i]; 68 | } else if (!obj_file) { 69 | obj_file = argv[i]; 70 | } else if (!mtl_file) { 71 | mtl_file = argv[i]; 72 | } else { 73 | help(); 74 | } 75 | } 76 | } 77 | 78 | if (input) { 79 | size_t input_len = strlen(input); 80 | if ((input_len > 4) && (strcmp(input + input_len - 4, ".3ds") == 0)) { 81 | if (!obj_file) { 82 | obj_file = (char*)malloc(sizeof(char*) * (input_len + 1)); 83 | strcpy(obj_file, input); 84 | strcpy(obj_file + input_len - 4, ".obj"); 85 | } 86 | if (!mtl_file) { 87 | mtl_file = (char*)malloc(sizeof(char*) * (input_len + 1)); 88 | strcpy(mtl_file, input); 89 | strcpy(mtl_file + input_len - 4, ".mtl"); 90 | } 91 | } 92 | } 93 | 94 | if (!input || !obj_file) { 95 | help(); 96 | } 97 | } 98 | 99 | 100 | void write_mtl(FILE *mtl, Lib3dsFile *f) { 101 | int i, j; 102 | 103 | fprintf(mtl, "# Wavefront material file\n"); 104 | fprintf(mtl, "# Converted by 3ds2obj\n"); 105 | fprintf(mtl, "# http://www.lib3ds.org\n\n"); 106 | 107 | { 108 | int unique = 1; 109 | for (i = 0; i < f->nmaterials; ++i) { 110 | char *p; 111 | for (p = f->materials[i]->name; *p; ++p) { 112 | if (!isalnum(*p) && (*p != '_')) *p = '_'; 113 | } 114 | 115 | for (j = 0; j < i; ++j) { 116 | if (strcmp(f->materials[i]->name, f->materials[j]->name) == 0) { 117 | unique = 0; 118 | break; 119 | } 120 | } 121 | if (!unique) 122 | break; 123 | } 124 | if (!unique) { 125 | for (i = 0; i < f->nmaterials; ++i) { 126 | sprintf(f->materials[i]->name, "mat_%d", i); 127 | } 128 | } 129 | } 130 | 131 | for (i = 0; i < f->nmaterials; ++i) { 132 | Lib3dsMaterial *m = f->materials[i]; 133 | fprintf(mtl, "newmtl %s\n", m->name); 134 | fprintf(mtl, "Ka %f %f %f\n", m->ambient[0], m->ambient[1], m->ambient[2]); 135 | fprintf(mtl, "Kd %f %f %f\n", m->diffuse[0], m->diffuse[1], m->diffuse[2]); 136 | fprintf(mtl, "Ks %f %f %f\n", m->specular[0], m->specular[1], m->specular[2]); 137 | fprintf(mtl, "illum 2\n"); 138 | fprintf(mtl, "Ns %f\n", pow(2, 10 * m->shininess + 1)); 139 | fprintf(mtl, "d %f\n", 1.0 - m->transparency); 140 | fprintf(mtl, "map_Kd %s\n", m->texture1_map.name); 141 | fprintf(mtl, "map_bump %s\n", m->bump_map.name); 142 | fprintf(mtl, "map_d %s\n", m->opacity_map.name); 143 | fprintf(mtl, "refl %s\n", m->reflection_map.name); 144 | fprintf(mtl, "map_KS %s\n", m->specular_map.name); 145 | fprintf(mtl, "\n"); 146 | } 147 | } 148 | 149 | 150 | void write_mesh(FILE *o, Lib3dsFile *f, Lib3dsMeshInstanceNode *node) { 151 | float (*orig_vertices)[3]; 152 | int export_texcos; 153 | int export_normals; 154 | int i, j; 155 | Lib3dsMesh *mesh; 156 | 157 | mesh = lib3ds_file_mesh_for_node(f, (Lib3dsNode*)node); 158 | if (!mesh || !mesh->vertices) return; 159 | 160 | fprintf(o, "# object %s\n", node->base.name); 161 | fprintf(o, "g %s\n", node->instance_name[0]? node->instance_name : node->base.name); 162 | 163 | orig_vertices = (float(*)[3])malloc(sizeof(float) * 3 * mesh->nvertices); 164 | memcpy(orig_vertices, mesh->vertices, sizeof(float) * 3 * mesh->nvertices); 165 | { 166 | float inv_matrix[4][4], M[4][4]; 167 | float tmp[3]; 168 | int i; 169 | 170 | lib3ds_matrix_copy(M, node->base.matrix); 171 | lib3ds_matrix_translate(M, -node->pivot[0], -node->pivot[1], -node->pivot[2]); 172 | lib3ds_matrix_copy(inv_matrix, mesh->matrix); 173 | lib3ds_matrix_inv(inv_matrix); 174 | lib3ds_matrix_mult(M, M, inv_matrix); 175 | 176 | for (i = 0; i < mesh->nvertices; ++i) { 177 | lib3ds_vector_transform(tmp, M, mesh->vertices[i]); 178 | lib3ds_vector_copy(mesh->vertices[i], tmp); 179 | } 180 | } 181 | 182 | export_texcos = (mesh->texcos != 0); 183 | export_normals = (mesh->faces != 0); 184 | 185 | for (i = 0; i < mesh->nvertices; ++i) { 186 | fprintf(o, "v %f %f %f\n", mesh->vertices[i][0], 187 | mesh->vertices[i][1], 188 | mesh->vertices[i][2]); 189 | } 190 | fprintf(o, "# %d vertices\n", mesh->nvertices); 191 | 192 | if (export_texcos) { 193 | for (i = 0; i < mesh->nvertices; ++i) { 194 | fprintf(o, "vt %f %f\n", mesh->texcos[i][0], 195 | mesh->texcos[i][1]); 196 | } 197 | fprintf(o, "# %d texture vertices\n", mesh->nvertices); 198 | } 199 | 200 | if (export_normals) { 201 | float (*normals)[3] = (float(*)[3])malloc(sizeof(float) * 9 * mesh->nfaces); 202 | lib3ds_mesh_calculate_vertex_normals(mesh, normals); 203 | for (i = 0; i < 3 * mesh->nfaces; ++i) { 204 | fprintf(o, "vn %f %f %f\n", normals[i][0], 205 | normals[i][1], 206 | normals[i][2]); 207 | } 208 | free(normals); 209 | fprintf(o, "# %d normals\n", 3 * mesh->nfaces); 210 | } 211 | 212 | { 213 | int mat_index = -1; 214 | for (i = 0; i < mesh->nfaces; ++i) { 215 | if (mat_index != mesh->faces[i].material) { 216 | mat_index = mesh->faces[i].material; 217 | if (mat_index != -1) { 218 | fprintf(o, "usemtl %s\n", f->materials[mat_index]->name); 219 | } 220 | } 221 | 222 | fprintf(o, "f "); 223 | for (j = 0; j < 3; ++j) { 224 | fprintf(o, "%d", mesh->faces[i].index[j] + max_vertices + 1); 225 | if (export_texcos) { 226 | fprintf(o, "/%d", mesh->faces[i].index[j] + max_texcos + 1); 227 | } else if (export_normals) { 228 | fprintf(o, "/"); 229 | } 230 | if (export_normals) { 231 | fprintf(o, "/%d", 3 * i + j + max_normals + 1); 232 | } 233 | if (j < 3) { 234 | fprintf(o, " "); 235 | } 236 | } 237 | fprintf(o, "\n"); 238 | } 239 | } 240 | 241 | max_vertices += mesh->nvertices; 242 | if (export_texcos) 243 | max_texcos += mesh->nvertices; 244 | if (export_normals) 245 | max_normals += 3 * mesh->nfaces; 246 | 247 | memcpy(mesh->vertices, orig_vertices, sizeof(float) * 3 * mesh->nvertices); 248 | free(orig_vertices); 249 | } 250 | 251 | 252 | void write_nodes(FILE *o, Lib3dsFile *f, Lib3dsNode *first_node) { 253 | Lib3dsNode *p; 254 | for (p = first_node; p; p = p->next) { 255 | if (p->type == LIB3DS_NODE_MESH_INSTANCE) { 256 | write_mesh(o, f, (Lib3dsMeshInstanceNode*)p); 257 | write_nodes(o, f, p->childs); 258 | } 259 | } 260 | } 261 | 262 | 263 | int main(int argc, char **argv) { 264 | Lib3dsFile *f; 265 | parse_args(argc, argv); 266 | 267 | f = lib3ds_file_open(input); 268 | if (!f) { 269 | fprintf(stderr, "***ERROR***\nLoading file failed: %s\n", input); 270 | exit(1); 271 | } 272 | 273 | if (mtl_file) { 274 | FILE *mtl = fopen(mtl_file, "wt"); 275 | if (!mtl) { 276 | fprintf(stderr, "***ERROR***\nCreating output file failed: %s\n", mtl_file); 277 | exit(1); 278 | } 279 | write_mtl(mtl, f); 280 | fclose(mtl); 281 | } 282 | 283 | { 284 | FILE *obj = fopen(obj_file, "wt"); 285 | if (!obj) { 286 | fprintf(stderr, "***ERROR***\nCreating output file failed: %s\n", obj_file); 287 | exit(1); 288 | } 289 | 290 | if (!f->nodes) 291 | lib3ds_file_create_nodes_for_meshes(f); 292 | lib3ds_file_eval(f, 0); 293 | 294 | fprintf(obj, "# Wavefront OBJ file\n"); 295 | fprintf(obj, "# Converted by 3ds2obj\n"); 296 | fprintf(obj, "# http://www.lib3ds.org\n\n"); 297 | if (mtl_file) { 298 | fprintf(obj, "mtllib %s\n", mtl_file); 299 | } 300 | 301 | write_nodes(obj, f, f->nodes); 302 | fclose(obj); 303 | } 304 | 305 | lib3ds_file_free(f); 306 | return 0; 307 | } 308 | -------------------------------------------------------------------------------- /examples/3ds2obj/.svn/text-base/CMakeLists.txt.svn-base: -------------------------------------------------------------------------------- 1 | INCLUDE_DIRECTORIES( ${lib3ds_SOURCE_DIR}/src ) 2 | ADD_EXECUTABLE(3ds2obj 3ds2obj.c) 3 | TARGET_LINK_LIBRARIES(3ds2obj lib3ds) 4 | -------------------------------------------------------------------------------- /examples/3ds2obj/.svn/text-base/Makefile.am.svn-base: -------------------------------------------------------------------------------- 1 | INCLUDES = -I$(top_srcdir)/src 2 | 3 | bin_PROGRAMS = 3ds2obj 4 | 3ds2obj_SOURCES = 3ds2obj.c 5 | 6 | LDADD = $(top_builddir)/src/lib3ds.la 7 | 8 | EXTRA_DIST = 3ds2obj.vcproj 9 | -------------------------------------------------------------------------------- /examples/3ds2obj/3ds2obj.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2008 by Jan Eric Kyprianidis 3 | All rights reserved. 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published 7 | by the Free Software Foundation, either version 2.1 of the License, or 8 | (at your option) any later version. 9 | 10 | Thisprogram is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program; If not, see . 17 | */ 18 | 19 | /** @file 3ds2obj.c 20 | Implementation of 3ds2obj converter. */ 21 | /** @example 3ds2obj.c 22 | This example shows how to convert a 3DS file to a Wavefront OBJ file. */ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #ifdef _MSC_VER 34 | #pragma warning ( disable : 4996 ) 35 | #endif 36 | 37 | 38 | static void 39 | help() { 40 | fprintf(stderr, 41 | "Syntax: 3ds2obj 3ds-file [obj-file] [mtl-file]\n" 42 | ); 43 | exit(1); 44 | } 45 | 46 | 47 | static const char* input = 0; 48 | static char* obj_file = 0; 49 | static char* mtl_file = 0; 50 | static int max_vertices = 0; 51 | static int max_texcos = 0; 52 | static int max_normals = 0; 53 | 54 | 55 | void parse_args(int argc, char **argv) { 56 | int i; 57 | 58 | for (i = 1; i < argc; ++i) { 59 | if (argv[i][0] == '-') { 60 | if ((strcmp(argv[i], "-h") == 0) || (strcmp(argv[i], "--help") == 0)) { 61 | help(); 62 | } else { 63 | help(); 64 | } 65 | } else { 66 | if (!input) { 67 | input = argv[i]; 68 | } else if (!obj_file) { 69 | obj_file = argv[i]; 70 | } else if (!mtl_file) { 71 | mtl_file = argv[i]; 72 | } else { 73 | help(); 74 | } 75 | } 76 | } 77 | 78 | if (input) { 79 | size_t input_len = strlen(input); 80 | if ((input_len > 4) && (strcmp(input + input_len - 4, ".3ds") == 0)) { 81 | if (!obj_file) { 82 | obj_file = (char*)malloc(sizeof(char*) * (input_len + 1)); 83 | strcpy(obj_file, input); 84 | strcpy(obj_file + input_len - 4, ".obj"); 85 | } 86 | if (!mtl_file) { 87 | mtl_file = (char*)malloc(sizeof(char*) * (input_len + 1)); 88 | strcpy(mtl_file, input); 89 | strcpy(mtl_file + input_len - 4, ".mtl"); 90 | } 91 | } 92 | } 93 | 94 | if (!input || !obj_file) { 95 | help(); 96 | } 97 | } 98 | 99 | 100 | void write_mtl(FILE *mtl, Lib3dsFile *f) { 101 | int i, j; 102 | 103 | fprintf(mtl, "# Wavefront material file\n"); 104 | fprintf(mtl, "# Converted by 3ds2obj\n"); 105 | fprintf(mtl, "# http://www.lib3ds.org\n\n"); 106 | 107 | { 108 | int unique = 1; 109 | for (i = 0; i < f->nmaterials; ++i) { 110 | char *p; 111 | for (p = f->materials[i]->name; *p; ++p) { 112 | if (!isalnum(*p) && (*p != '_')) *p = '_'; 113 | } 114 | 115 | for (j = 0; j < i; ++j) { 116 | if (strcmp(f->materials[i]->name, f->materials[j]->name) == 0) { 117 | unique = 0; 118 | break; 119 | } 120 | } 121 | if (!unique) 122 | break; 123 | } 124 | if (!unique) { 125 | for (i = 0; i < f->nmaterials; ++i) { 126 | sprintf(f->materials[i]->name, "mat_%d", i); 127 | } 128 | } 129 | } 130 | 131 | for (i = 0; i < f->nmaterials; ++i) { 132 | Lib3dsMaterial *m = f->materials[i]; 133 | fprintf(mtl, "newmtl %s\n", m->name); 134 | fprintf(mtl, "Ka %f %f %f\n", m->ambient[0], m->ambient[1], m->ambient[2]); 135 | fprintf(mtl, "Kd %f %f %f\n", m->diffuse[0], m->diffuse[1], m->diffuse[2]); 136 | fprintf(mtl, "Ks %f %f %f\n", m->specular[0], m->specular[1], m->specular[2]); 137 | fprintf(mtl, "illum 2\n"); 138 | fprintf(mtl, "Ns %f\n", pow(2, 10 * m->shininess + 1)); 139 | fprintf(mtl, "d %f\n", 1.0 - m->transparency); 140 | fprintf(mtl, "map_Kd %s\n", m->texture1_map.name); 141 | fprintf(mtl, "map_bump %s\n", m->bump_map.name); 142 | fprintf(mtl, "map_d %s\n", m->opacity_map.name); 143 | fprintf(mtl, "refl %s\n", m->reflection_map.name); 144 | fprintf(mtl, "map_KS %s\n", m->specular_map.name); 145 | fprintf(mtl, "\n"); 146 | } 147 | } 148 | 149 | 150 | void write_mesh(FILE *o, Lib3dsFile *f, Lib3dsMeshInstanceNode *node) { 151 | float (*orig_vertices)[3]; 152 | int export_texcos; 153 | int export_normals; 154 | int i, j; 155 | Lib3dsMesh *mesh; 156 | 157 | mesh = lib3ds_file_mesh_for_node(f, (Lib3dsNode*)node); 158 | if (!mesh || !mesh->vertices) return; 159 | 160 | fprintf(o, "# object %s\n", node->base.name); 161 | fprintf(o, "g %s\n", node->instance_name[0]? node->instance_name : node->base.name); 162 | 163 | orig_vertices = (float(*)[3])malloc(sizeof(float) * 3 * mesh->nvertices); 164 | memcpy(orig_vertices, mesh->vertices, sizeof(float) * 3 * mesh->nvertices); 165 | { 166 | float inv_matrix[4][4], M[4][4]; 167 | float tmp[3]; 168 | int i; 169 | 170 | lib3ds_matrix_copy(M, node->base.matrix); 171 | lib3ds_matrix_translate(M, -node->pivot[0], -node->pivot[1], -node->pivot[2]); 172 | lib3ds_matrix_copy(inv_matrix, mesh->matrix); 173 | lib3ds_matrix_inv(inv_matrix); 174 | lib3ds_matrix_mult(M, M, inv_matrix); 175 | 176 | for (i = 0; i < mesh->nvertices; ++i) { 177 | lib3ds_vector_transform(tmp, M, mesh->vertices[i]); 178 | lib3ds_vector_copy(mesh->vertices[i], tmp); 179 | } 180 | } 181 | 182 | export_texcos = (mesh->texcos != 0); 183 | export_normals = (mesh->faces != 0); 184 | 185 | for (i = 0; i < mesh->nvertices; ++i) { 186 | fprintf(o, "v %f %f %f\n", mesh->vertices[i][0], 187 | mesh->vertices[i][1], 188 | mesh->vertices[i][2]); 189 | } 190 | fprintf(o, "# %d vertices\n", mesh->nvertices); 191 | 192 | if (export_texcos) { 193 | for (i = 0; i < mesh->nvertices; ++i) { 194 | fprintf(o, "vt %f %f\n", mesh->texcos[i][0], 195 | mesh->texcos[i][1]); 196 | } 197 | fprintf(o, "# %d texture vertices\n", mesh->nvertices); 198 | } 199 | 200 | if (export_normals) { 201 | float (*normals)[3] = (float(*)[3])malloc(sizeof(float) * 9 * mesh->nfaces); 202 | lib3ds_mesh_calculate_vertex_normals(mesh, normals); 203 | for (i = 0; i < 3 * mesh->nfaces; ++i) { 204 | fprintf(o, "vn %f %f %f\n", normals[i][0], 205 | normals[i][1], 206 | normals[i][2]); 207 | } 208 | free(normals); 209 | fprintf(o, "# %d normals\n", 3 * mesh->nfaces); 210 | } 211 | 212 | { 213 | int mat_index = -1; 214 | for (i = 0; i < mesh->nfaces; ++i) { 215 | if (mat_index != mesh->faces[i].material) { 216 | mat_index = mesh->faces[i].material; 217 | if (mat_index != -1) { 218 | fprintf(o, "usemtl %s\n", f->materials[mat_index]->name); 219 | } 220 | } 221 | 222 | fprintf(o, "f "); 223 | for (j = 0; j < 3; ++j) { 224 | fprintf(o, "%d", mesh->faces[i].index[j] + max_vertices + 1); 225 | if (export_texcos) { 226 | fprintf(o, "/%d", mesh->faces[i].index[j] + max_texcos + 1); 227 | } else if (export_normals) { 228 | fprintf(o, "/"); 229 | } 230 | if (export_normals) { 231 | fprintf(o, "/%d", 3 * i + j + max_normals + 1); 232 | } 233 | if (j < 3) { 234 | fprintf(o, " "); 235 | } 236 | } 237 | fprintf(o, "\n"); 238 | } 239 | } 240 | 241 | max_vertices += mesh->nvertices; 242 | if (export_texcos) 243 | max_texcos += mesh->nvertices; 244 | if (export_normals) 245 | max_normals += 3 * mesh->nfaces; 246 | 247 | memcpy(mesh->vertices, orig_vertices, sizeof(float) * 3 * mesh->nvertices); 248 | free(orig_vertices); 249 | } 250 | 251 | 252 | void write_nodes(FILE *o, Lib3dsFile *f, Lib3dsNode *first_node) { 253 | Lib3dsNode *p; 254 | for (p = first_node; p; p = p->next) { 255 | if (p->type == LIB3DS_NODE_MESH_INSTANCE) { 256 | write_mesh(o, f, (Lib3dsMeshInstanceNode*)p); 257 | write_nodes(o, f, p->childs); 258 | } 259 | } 260 | } 261 | 262 | 263 | int main(int argc, char **argv) { 264 | Lib3dsFile *f; 265 | parse_args(argc, argv); 266 | 267 | f = lib3ds_file_open(input); 268 | if (!f) { 269 | fprintf(stderr, "***ERROR***\nLoading file failed: %s\n", input); 270 | exit(1); 271 | } 272 | 273 | if (mtl_file) { 274 | FILE *mtl = fopen(mtl_file, "wt"); 275 | if (!mtl) { 276 | fprintf(stderr, "***ERROR***\nCreating output file failed: %s\n", mtl_file); 277 | exit(1); 278 | } 279 | write_mtl(mtl, f); 280 | fclose(mtl); 281 | } 282 | 283 | { 284 | FILE *obj = fopen(obj_file, "wt"); 285 | if (!obj) { 286 | fprintf(stderr, "***ERROR***\nCreating output file failed: %s\n", obj_file); 287 | exit(1); 288 | } 289 | 290 | if (!f->nodes) 291 | lib3ds_file_create_nodes_for_meshes(f); 292 | lib3ds_file_eval(f, 0); 293 | 294 | fprintf(obj, "# Wavefront OBJ file\n"); 295 | fprintf(obj, "# Converted by 3ds2obj\n"); 296 | fprintf(obj, "# http://www.lib3ds.org\n\n"); 297 | if (mtl_file) { 298 | fprintf(obj, "mtllib %s\n", mtl_file); 299 | } 300 | 301 | write_nodes(obj, f, f->nodes); 302 | fclose(obj); 303 | } 304 | 305 | lib3ds_file_free(f); 306 | return 0; 307 | } 308 | -------------------------------------------------------------------------------- /examples/3ds2obj/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | INCLUDE_DIRECTORIES( ${lib3ds_SOURCE_DIR}/src ) 2 | ADD_EXECUTABLE(3ds2obj 3ds2obj.c) 3 | TARGET_LINK_LIBRARIES(3ds2obj lib3ds) 4 | -------------------------------------------------------------------------------- /examples/3dsdump/.svn/all-wcprops: -------------------------------------------------------------------------------- 1 | K 25 2 | svn:wc:ra_dav:version-url 3 | V 40 4 | /svn/!svn/ver/103/trunk/examples/3dsdump 5 | END 6 | 3dsdump.c 7 | K 25 8 | svn:wc:ra_dav:version-url 9 | V 50 10 | /svn/!svn/ver/103/trunk/examples/3dsdump/3dsdump.c 11 | END 12 | Makefile.am 13 | K 25 14 | svn:wc:ra_dav:version-url 15 | V 51 16 | /svn/!svn/ver/84/trunk/examples/3dsdump/Makefile.am 17 | END 18 | CMakeLists.txt 19 | K 25 20 | svn:wc:ra_dav:version-url 21 | V 54 22 | /svn/!svn/ver/91/trunk/examples/3dsdump/CMakeLists.txt 23 | END 24 | -------------------------------------------------------------------------------- /examples/3dsdump/.svn/entries: -------------------------------------------------------------------------------- 1 | 10 2 | 3 | dir 4 | 107 5 | http://lib3ds.googlecode.com/svn/trunk/examples/3dsdump 6 | http://lib3ds.googlecode.com/svn 7 | 8 | 9 | 10 | 2010-01-21T08:44:56.307384Z 11 | 103 12 | jkyprian 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 984c2e8c-059d-11df-a9fb-49f3208c864b 28 | 29 | 3dsdump.c 30 | file 31 | 32 | 33 | 34 | 35 | 2014-11-03T08:36:57.505509Z 36 | ab4bf935193940253ff8ca7977362241 37 | 2010-01-21T08:44:56.307384Z 38 | 103 39 | jkyprian 40 | has-props 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 18443 62 | 63 | Makefile.am 64 | file 65 | 66 | 67 | 68 | 69 | 2014-11-03T08:36:57.506509Z 70 | 51c84f56072e26c9778f2e03c5dac246 71 | 2008-09-09T13:41:25.501711Z 72 | 84 73 | jeh 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 153 96 | 97 | CMakeLists.txt 98 | file 99 | 100 | 101 | 102 | 103 | 2014-11-03T08:36:57.506509Z 104 | 59f7cb85e6f69de3ad478d3f923ed585 105 | 2008-11-11T12:00:06.790149Z 106 | 91 107 | jeh 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 121 130 | 131 | -------------------------------------------------------------------------------- /examples/3dsdump/.svn/prop-base/3dsdump.c.svn-base: -------------------------------------------------------------------------------- 1 | K 12 2 | svn:keywords 3 | V 0 4 | 5 | K 13 6 | svn:mergeinfo 7 | V 0 8 | 9 | END 10 | -------------------------------------------------------------------------------- /examples/3dsdump/.svn/text-base/CMakeLists.txt.svn-base: -------------------------------------------------------------------------------- 1 | INCLUDE_DIRECTORIES( ${lib3ds_SOURCE_DIR}/src ) 2 | ADD_EXECUTABLE(3dsdump 3dsdump.c) 3 | TARGET_LINK_LIBRARIES(3dsdump lib3ds) 4 | -------------------------------------------------------------------------------- /examples/3dsdump/.svn/text-base/Makefile.am.svn-base: -------------------------------------------------------------------------------- 1 | INCLUDES = -I$(top_srcdir)/src 2 | 3 | bin_PROGRAMS = 3dsdump 4 | 3dsdump_SOURCES = 3dsdump.c 5 | 6 | LDADD = $(top_builddir)/src/lib3ds.la 7 | 8 | EXTRA_DIST = 3dsdump.vcproj 9 | -------------------------------------------------------------------------------- /examples/3dsdump/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | INCLUDE_DIRECTORIES( ${lib3ds_SOURCE_DIR}/src ) 2 | ADD_EXECUTABLE(3dsdump 3dsdump.c) 3 | TARGET_LINK_LIBRARIES(3dsdump lib3ds) 4 | -------------------------------------------------------------------------------- /examples/3dsplay/.svn/all-wcprops: -------------------------------------------------------------------------------- 1 | K 25 2 | svn:wc:ra_dav:version-url 3 | V 40 4 | /svn/!svn/ver/107/trunk/examples/3dsplay 5 | END 6 | 3dsplay.cpp 7 | K 25 8 | svn:wc:ra_dav:version-url 9 | V 52 10 | /svn/!svn/ver/107/trunk/examples/3dsplay/3dsplay.cpp 11 | END 12 | tga.h 13 | K 25 14 | svn:wc:ra_dav:version-url 15 | V 46 16 | /svn/!svn/ver/106/trunk/examples/3dsplay/tga.h 17 | END 18 | tga.c 19 | K 25 20 | svn:wc:ra_dav:version-url 21 | V 46 22 | /svn/!svn/ver/106/trunk/examples/3dsplay/tga.c 23 | END 24 | CMakeLists.txt 25 | K 25 26 | svn:wc:ra_dav:version-url 27 | V 55 28 | /svn/!svn/ver/106/trunk/examples/3dsplay/CMakeLists.txt 29 | END 30 | -------------------------------------------------------------------------------- /examples/3dsplay/.svn/entries: -------------------------------------------------------------------------------- 1 | 10 2 | 3 | dir 4 | 107 5 | http://lib3ds.googlecode.com/svn/trunk/examples/3dsplay 6 | http://lib3ds.googlecode.com/svn 7 | 8 | 9 | 10 | 2011-11-15T14:06:58.239866Z 11 | 107 12 | jkyprian 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 984c2e8c-059d-11df-a9fb-49f3208c864b 28 | 29 | 3dsplay.cpp 30 | file 31 | 32 | 33 | 34 | 35 | 2014-11-03T08:36:57.513509Z 36 | 47272036b29dcb9d007a731100fb3ab1 37 | 2011-11-15T14:06:58.239866Z 38 | 107 39 | jkyprian 40 | has-props 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 34080 62 | 63 | tga.h 64 | file 65 | 66 | 67 | 68 | 69 | 2014-11-03T08:36:57.514509Z 70 | d413e06b166629ec104da0373bf78f7f 71 | 2011-11-15T13:31:48.645953Z 72 | 106 73 | jkyprian 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 1251 96 | 97 | tga.c 98 | file 99 | 100 | 101 | 102 | 103 | 2014-11-03T08:36:57.514509Z 104 | cae10ed972f6d8c5fa04966bdb4c88a9 105 | 2011-11-15T13:31:48.645953Z 106 | 106 107 | jkyprian 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 8716 130 | 131 | CMakeLists.txt 132 | file 133 | 134 | 135 | 136 | 137 | 2014-11-03T08:36:57.514509Z 138 | 4e54748f0099004cde93ea175912a392 139 | 2011-11-15T13:31:48.645953Z 140 | 106 141 | jkyprian 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 365 164 | 165 | -------------------------------------------------------------------------------- /examples/3dsplay/.svn/prop-base/3dsplay.cpp.svn-base: -------------------------------------------------------------------------------- 1 | K 12 2 | svn:keywords 3 | V 0 4 | 5 | K 13 6 | svn:mergeinfo 7 | V 0 8 | 9 | END 10 | -------------------------------------------------------------------------------- /examples/3dsplay/.svn/text-base/CMakeLists.txt.svn-base: -------------------------------------------------------------------------------- 1 | FIND_PACKAGE(OpenGL) 2 | FIND_PACKAGE(GLUT) 3 | IF(GLUT_FOUND) 4 | IF(MSVC) 5 | ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS) 6 | ENDIF(MSVC) 7 | INCLUDE_DIRECTORIES( ${lib3ds_SOURCE_DIR}/src ${OPENGL_INCLUDE_DIR} ${GLUT_INCLUDE_DIR}) 8 | ADD_EXECUTABLE(3dsplay 3dsplay.cpp tga.c tga.h) 9 | TARGET_LINK_LIBRARIES(3dsplay lib3ds ${OPENGL_LIBRARIES} ${GLUT_LIBRARIES}) 10 | ENDIF(GLUT_FOUND) -------------------------------------------------------------------------------- /examples/3dsplay/.svn/text-base/tga.c.svn-base: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 1995-2011 Jan Eric Kyprianidis 3 | All rights reserved. 4 | 5 | Permission to use, copy, modify, and/or distribute this software for any 6 | purpose with or without fee is hereby granted, provided that the above 7 | copyright notice and this permission notice appear in all copies. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 | */ 17 | #include 18 | #include 19 | #include 20 | #include "tga.h" 21 | 22 | 23 | /*--Descriptor flags---------------*/ 24 | #define ds_BottomLeft 0x00 25 | #define ds_BottomRight 0x01 26 | #define ds_TopLeft 0x02 27 | #define ds_TopRight 0x03 28 | 29 | /*--Color map types----------------*/ 30 | #define cm_NoColorMap 0 31 | #define cm_ColorMap 1 32 | 33 | /*--Image data types---------------*/ 34 | #define im_NoImageData 0 35 | #define im_ColMapImage 1 36 | #define im_RgbImage 2 37 | #define im_MonoImage 3 38 | #define im_ColMapImageRLE 9 39 | #define im_RgbImageRLE 10 40 | #define im_MonoImageRLE 11 41 | 42 | 43 | static unsigned short fgetword(FILE *f) { 44 | unsigned char b[2]; 45 | fread(b, 2, 1, f); 46 | return ((unsigned short)b[1] << 8) | (unsigned short)b[0]; 47 | } 48 | 49 | 50 | static void fputword(unsigned short s, FILE *f) { 51 | unsigned char b[2]; 52 | b[0] = (unsigned char)(s & 0xff); 53 | b[1] = (unsigned char)((s >> 8) & 0xff); 54 | fwrite(b, 2, 1, f); 55 | } 56 | 57 | 58 | int tga_load(const char *name, unsigned char **buffer, int *width, int *height) { 59 | FILE *f; 60 | int idLen; 61 | int colorMapType; 62 | int imageType; 63 | int firstColor; 64 | int colorMapLen; 65 | int colorMapBits; 66 | int xOrgin; 67 | int yOrgin; 68 | int iw; 69 | int ih; 70 | int bitsPerPix; 71 | int descriptor; 72 | int i, j, k; 73 | unsigned char *p; 74 | unsigned char *q; 75 | unsigned char *pp; 76 | int bb; 77 | int cp[4]; 78 | int rle; 79 | int n; 80 | int c; 81 | int ix, iy; 82 | unsigned char colorMap[256][3]; 83 | unsigned char *data; 84 | 85 | data = NULL; 86 | if ((f = fopen(name, "rb")) == NULL) 87 | return 0; 88 | 89 | idLen = fgetc(f); 90 | colorMapType = fgetc(f); 91 | imageType = fgetc(f); 92 | firstColor = fgetword(f); 93 | colorMapLen = fgetword(f); 94 | colorMapBits = fgetc(f); 95 | xOrgin = fgetword(f); 96 | yOrgin = fgetword(f); 97 | iw = fgetword(f); 98 | ih = fgetword(f); 99 | bitsPerPix = fgetc(f); 100 | descriptor = fgetc(f); 101 | 102 | switch(imageType) { 103 | case im_MonoImage: 104 | case im_ColMapImage: 105 | case im_RgbImage: 106 | case im_MonoImageRLE: 107 | case im_ColMapImageRLE: 108 | case im_RgbImageRLE: 109 | break; 110 | default: 111 | goto error; 112 | } 113 | switch (bitsPerPix) { 114 | case 8: 115 | case 24: 116 | case 32: 117 | bb = bitsPerPix / 8; 118 | break; 119 | default: 120 | goto error; 121 | } 122 | 123 | if (idLen) 124 | fseek(f, idLen, SEEK_CUR); 125 | *width = iw; 126 | *height = ih; 127 | 128 | if (colorMapType == cm_ColorMap) { 129 | memset(colorMap, 0, sizeof(colorMap)); 130 | if ((colorMapBits != 24) || (colorMapLen + firstColor > 256)) { 131 | goto error; 132 | } 133 | for (i = 0, pp = colorMap[firstColor]; i < colorMapLen; i++) { 134 | *pp++ = fgetc(f); 135 | *pp++ = fgetc(f); 136 | *pp++ = fgetc(f); 137 | } 138 | } else { 139 | for (i = 0; i < 256; ++i) 140 | colorMap[i][0] = colorMap[i][1] = colorMap[i][2] = i; 141 | } 142 | 143 | if ((data = malloc(iw * bb * ih)) == NULL) { 144 | goto error; 145 | } 146 | 147 | if ((imageType == im_MonoImage) || (imageType == im_ColMapImage) || (imageType == im_RgbImage)) { 148 | fread(data, ih, iw*bb, f); 149 | } else { 150 | p = data; 151 | n = 0; 152 | for (j = 0; j < ih; ++j) { 153 | for (i = 0; i < iw; ++i, p += bb) { 154 | if (n == 0) { 155 | c = fgetc(f); 156 | n = (c & 0x7F) + 1; 157 | if (c&0x80) { 158 | for (k = 0; k < bb; k++) cp[k] = fgetc(f); 159 | rle = 1; 160 | } else { 161 | rle = 0; 162 | } 163 | } 164 | if (rle) 165 | for (k = 0; k < bb; k++) p[k] = cp[k]; 166 | else 167 | for (k = 0; k < bb; k++) p[k] = fgetc(f); 168 | n--; 169 | } 170 | } 171 | } 172 | if (ferror(f)) { 173 | goto error; 174 | } 175 | fclose(f); 176 | 177 | *buffer = (unsigned char*)malloc(iw * ih * 4); 178 | if (!*buffer) 179 | goto error; 180 | 181 | p = *buffer; 182 | switch ((descriptor >> 4) & 0x3) { 183 | case ds_BottomLeft: 184 | ix = bb; 185 | iy = -2 * iw * bb; 186 | q = data + iw * bb * (ih - 1); 187 | break; 188 | case ds_BottomRight: 189 | ix = -bb; 190 | iy = 0; 191 | q = data + (iw - 1) * bb * (ih); 192 | break; 193 | case ds_TopLeft: 194 | ix = bb; 195 | iy = 0; 196 | q = data; 197 | break; 198 | case ds_TopRight: 199 | ix = -bb; 200 | iy = 2 * iw * bb; 201 | q = data + (iw - 1) * bb; 202 | break; 203 | } 204 | 205 | switch (bitsPerPix) { 206 | case 8: { 207 | for (j = 0; j < ih; ++j) { 208 | for (i = 0; i < iw; ++i) { 209 | for (k = 0; k < 3; ++k) { 210 | p[k] = colorMap[*q][k]; 211 | } 212 | p[3] = 0xff; 213 | p += 4; 214 | q += ix; 215 | } 216 | q += iy; 217 | } 218 | break; 219 | } 220 | 221 | case 24: { 222 | for (j = 0; j < ih; ++j) { 223 | for (i = 0; i < iw; ++i) { 224 | p[0] = q[0]; 225 | p[1] = q[1]; 226 | p[2] = q[2]; 227 | p[3] = 0xff; 228 | p += 4; 229 | q += ix; 230 | } 231 | q += iy; 232 | } 233 | break; 234 | } 235 | 236 | case 32: { 237 | for (j = 0; j < ih; ++j) { 238 | for (i = 0; i < iw; ++i) { 239 | p[0] = q[0]; 240 | p[1] = q[1]; 241 | p[2] = q[2]; 242 | p[3] = q[3]; 243 | p += 4; 244 | q += ix; 245 | } 246 | q += iy; 247 | } 248 | break; 249 | } 250 | } 251 | 252 | free(data); 253 | return 1; 254 | 255 | error: 256 | if (data) free(data); 257 | if (f) fclose(f); 258 | *buffer = NULL; 259 | *width = 0; 260 | *height = 0; 261 | return 0; 262 | } 263 | 264 | 265 | int tga_save(const char *name, unsigned char *buffer, unsigned char *colorMap, int width, int height, int bits) { 266 | FILE *f; 267 | int colorMapType = 0; 268 | int imageType; 269 | int colorMapLen = 0; 270 | int colorMapBits = 0; 271 | int bitsPerPix; 272 | int i; 273 | int bb; 274 | unsigned char *pp; 275 | 276 | if ((f = fopen(name, "wb+")) == NULL) 277 | return 0; 278 | 279 | switch (bits) { 280 | case 8: 281 | imageType = im_ColMapImage; 282 | if (colorMap != NULL) { 283 | colorMapType = cm_ColorMap; 284 | colorMapLen = 256; 285 | colorMapBits = 24; 286 | } 287 | bitsPerPix = 8; 288 | bb = 1; 289 | break; 290 | case 16: 291 | imageType = im_RgbImage; 292 | bitsPerPix = 16; 293 | bb = 2; 294 | break; 295 | case 24: 296 | imageType = im_RgbImage; 297 | bitsPerPix = 24; 298 | bb = 3; 299 | break; 300 | case 32: 301 | imageType = im_RgbImage; 302 | bitsPerPix = 32; 303 | bb = 4; 304 | break; 305 | default: 306 | fclose(f); 307 | return 0; 308 | } 309 | 310 | fputc(0, f); 311 | fputc(colorMapType, f); 312 | fputc(imageType, f); 313 | fputword(0, f); 314 | fputword(colorMapLen, f); 315 | fputc(colorMapBits, f); 316 | fputword(0, f); 317 | fputword(0, f); 318 | fputword(width, f); 319 | fputword(height, f); 320 | fputc(bitsPerPix, f); 321 | fputc(ds_TopLeft << 4, f); 322 | 323 | if (colorMapType == cm_ColorMap) { 324 | for (i = 0, pp = colorMap; i < 256; i++, pp += 3) { 325 | fputc(pp[0], f); 326 | fputc(pp[1], f); 327 | fputc(pp[2], f); 328 | } 329 | } 330 | 331 | fwrite(buffer, width*bb, height, f); 332 | if (ferror(f)) { 333 | fclose(f); 334 | return 0; 335 | } 336 | 337 | fclose(f); 338 | return 1; 339 | } 340 | -------------------------------------------------------------------------------- /examples/3dsplay/.svn/text-base/tga.h.svn-base: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 1995-2011 Jan Eric Kyprianidis 3 | All rights reserved. 4 | 5 | Permission to use, copy, modify, and/or distribute this software for any 6 | purpose with or without fee is hereby granted, provided that the above 7 | copyright notice and this permission notice appear in all copies. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 | */ 17 | #ifndef INCLUDED_TGA_H 18 | #define INCLUDED_TGA_H 19 | #ifdef __cplusplus 20 | extern "C" { 21 | #endif 22 | 23 | extern int tga_load( const char *path, unsigned char **buffer, 24 | int *width, int *height ); 25 | 26 | extern int tga_save( const char *path, unsigned char *buffer, unsigned char *colorMap, 27 | int width, int height, int bits ); 28 | 29 | #ifdef __cplusplus 30 | } 31 | #endif 32 | #endif 33 | -------------------------------------------------------------------------------- /examples/3dsplay/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | FIND_PACKAGE(OpenGL) 2 | FIND_PACKAGE(GLUT) 3 | IF(GLUT_FOUND) 4 | IF(MSVC) 5 | ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS) 6 | ENDIF(MSVC) 7 | INCLUDE_DIRECTORIES( ${lib3ds_SOURCE_DIR}/src ${OPENGL_INCLUDE_DIR} ${GLUT_INCLUDE_DIR}) 8 | ADD_EXECUTABLE(3dsplay 3dsplay.cpp tga.c tga.h) 9 | TARGET_LINK_LIBRARIES(3dsplay lib3ds ${OPENGL_LIBRARIES} ${GLUT_LIBRARIES}) 10 | ENDIF(GLUT_FOUND) -------------------------------------------------------------------------------- /examples/3dsplay/tga.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 1995-2011 Jan Eric Kyprianidis 3 | All rights reserved. 4 | 5 | Permission to use, copy, modify, and/or distribute this software for any 6 | purpose with or without fee is hereby granted, provided that the above 7 | copyright notice and this permission notice appear in all copies. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 | */ 17 | #include 18 | #include 19 | #include 20 | #include "tga.h" 21 | 22 | 23 | /*--Descriptor flags---------------*/ 24 | #define ds_BottomLeft 0x00 25 | #define ds_BottomRight 0x01 26 | #define ds_TopLeft 0x02 27 | #define ds_TopRight 0x03 28 | 29 | /*--Color map types----------------*/ 30 | #define cm_NoColorMap 0 31 | #define cm_ColorMap 1 32 | 33 | /*--Image data types---------------*/ 34 | #define im_NoImageData 0 35 | #define im_ColMapImage 1 36 | #define im_RgbImage 2 37 | #define im_MonoImage 3 38 | #define im_ColMapImageRLE 9 39 | #define im_RgbImageRLE 10 40 | #define im_MonoImageRLE 11 41 | 42 | 43 | static unsigned short fgetword(FILE *f) { 44 | unsigned char b[2]; 45 | fread(b, 2, 1, f); 46 | return ((unsigned short)b[1] << 8) | (unsigned short)b[0]; 47 | } 48 | 49 | 50 | static void fputword(unsigned short s, FILE *f) { 51 | unsigned char b[2]; 52 | b[0] = (unsigned char)(s & 0xff); 53 | b[1] = (unsigned char)((s >> 8) & 0xff); 54 | fwrite(b, 2, 1, f); 55 | } 56 | 57 | 58 | int tga_load(const char *name, unsigned char **buffer, int *width, int *height) { 59 | FILE *f; 60 | int idLen; 61 | int colorMapType; 62 | int imageType; 63 | int firstColor; 64 | int colorMapLen; 65 | int colorMapBits; 66 | int xOrgin; 67 | int yOrgin; 68 | int iw; 69 | int ih; 70 | int bitsPerPix; 71 | int descriptor; 72 | int i, j, k; 73 | unsigned char *p; 74 | unsigned char *q; 75 | unsigned char *pp; 76 | int bb; 77 | int cp[4]; 78 | int rle; 79 | int n; 80 | int c; 81 | int ix, iy; 82 | unsigned char colorMap[256][3]; 83 | unsigned char *data; 84 | 85 | data = NULL; 86 | if ((f = fopen(name, "rb")) == NULL) 87 | return 0; 88 | 89 | idLen = fgetc(f); 90 | colorMapType = fgetc(f); 91 | imageType = fgetc(f); 92 | firstColor = fgetword(f); 93 | colorMapLen = fgetword(f); 94 | colorMapBits = fgetc(f); 95 | xOrgin = fgetword(f); 96 | yOrgin = fgetword(f); 97 | iw = fgetword(f); 98 | ih = fgetword(f); 99 | bitsPerPix = fgetc(f); 100 | descriptor = fgetc(f); 101 | 102 | switch(imageType) { 103 | case im_MonoImage: 104 | case im_ColMapImage: 105 | case im_RgbImage: 106 | case im_MonoImageRLE: 107 | case im_ColMapImageRLE: 108 | case im_RgbImageRLE: 109 | break; 110 | default: 111 | goto error; 112 | } 113 | switch (bitsPerPix) { 114 | case 8: 115 | case 24: 116 | case 32: 117 | bb = bitsPerPix / 8; 118 | break; 119 | default: 120 | goto error; 121 | } 122 | 123 | if (idLen) 124 | fseek(f, idLen, SEEK_CUR); 125 | *width = iw; 126 | *height = ih; 127 | 128 | if (colorMapType == cm_ColorMap) { 129 | memset(colorMap, 0, sizeof(colorMap)); 130 | if ((colorMapBits != 24) || (colorMapLen + firstColor > 256)) { 131 | goto error; 132 | } 133 | for (i = 0, pp = colorMap[firstColor]; i < colorMapLen; i++) { 134 | *pp++ = fgetc(f); 135 | *pp++ = fgetc(f); 136 | *pp++ = fgetc(f); 137 | } 138 | } else { 139 | for (i = 0; i < 256; ++i) 140 | colorMap[i][0] = colorMap[i][1] = colorMap[i][2] = i; 141 | } 142 | 143 | if ((data = malloc(iw * bb * ih)) == NULL) { 144 | goto error; 145 | } 146 | 147 | if ((imageType == im_MonoImage) || (imageType == im_ColMapImage) || (imageType == im_RgbImage)) { 148 | fread(data, ih, iw*bb, f); 149 | } else { 150 | p = data; 151 | n = 0; 152 | for (j = 0; j < ih; ++j) { 153 | for (i = 0; i < iw; ++i, p += bb) { 154 | if (n == 0) { 155 | c = fgetc(f); 156 | n = (c & 0x7F) + 1; 157 | if (c&0x80) { 158 | for (k = 0; k < bb; k++) cp[k] = fgetc(f); 159 | rle = 1; 160 | } else { 161 | rle = 0; 162 | } 163 | } 164 | if (rle) 165 | for (k = 0; k < bb; k++) p[k] = cp[k]; 166 | else 167 | for (k = 0; k < bb; k++) p[k] = fgetc(f); 168 | n--; 169 | } 170 | } 171 | } 172 | if (ferror(f)) { 173 | goto error; 174 | } 175 | fclose(f); 176 | 177 | *buffer = (unsigned char*)malloc(iw * ih * 4); 178 | if (!*buffer) 179 | goto error; 180 | 181 | p = *buffer; 182 | switch ((descriptor >> 4) & 0x3) { 183 | case ds_BottomLeft: 184 | ix = bb; 185 | iy = -2 * iw * bb; 186 | q = data + iw * bb * (ih - 1); 187 | break; 188 | case ds_BottomRight: 189 | ix = -bb; 190 | iy = 0; 191 | q = data + (iw - 1) * bb * (ih); 192 | break; 193 | case ds_TopLeft: 194 | ix = bb; 195 | iy = 0; 196 | q = data; 197 | break; 198 | case ds_TopRight: 199 | ix = -bb; 200 | iy = 2 * iw * bb; 201 | q = data + (iw - 1) * bb; 202 | break; 203 | } 204 | 205 | switch (bitsPerPix) { 206 | case 8: { 207 | for (j = 0; j < ih; ++j) { 208 | for (i = 0; i < iw; ++i) { 209 | for (k = 0; k < 3; ++k) { 210 | p[k] = colorMap[*q][k]; 211 | } 212 | p[3] = 0xff; 213 | p += 4; 214 | q += ix; 215 | } 216 | q += iy; 217 | } 218 | break; 219 | } 220 | 221 | case 24: { 222 | for (j = 0; j < ih; ++j) { 223 | for (i = 0; i < iw; ++i) { 224 | p[0] = q[0]; 225 | p[1] = q[1]; 226 | p[2] = q[2]; 227 | p[3] = 0xff; 228 | p += 4; 229 | q += ix; 230 | } 231 | q += iy; 232 | } 233 | break; 234 | } 235 | 236 | case 32: { 237 | for (j = 0; j < ih; ++j) { 238 | for (i = 0; i < iw; ++i) { 239 | p[0] = q[0]; 240 | p[1] = q[1]; 241 | p[2] = q[2]; 242 | p[3] = q[3]; 243 | p += 4; 244 | q += ix; 245 | } 246 | q += iy; 247 | } 248 | break; 249 | } 250 | } 251 | 252 | free(data); 253 | return 1; 254 | 255 | error: 256 | if (data) free(data); 257 | if (f) fclose(f); 258 | *buffer = NULL; 259 | *width = 0; 260 | *height = 0; 261 | return 0; 262 | } 263 | 264 | 265 | int tga_save(const char *name, unsigned char *buffer, unsigned char *colorMap, int width, int height, int bits) { 266 | FILE *f; 267 | int colorMapType = 0; 268 | int imageType; 269 | int colorMapLen = 0; 270 | int colorMapBits = 0; 271 | int bitsPerPix; 272 | int i; 273 | int bb; 274 | unsigned char *pp; 275 | 276 | if ((f = fopen(name, "wb+")) == NULL) 277 | return 0; 278 | 279 | switch (bits) { 280 | case 8: 281 | imageType = im_ColMapImage; 282 | if (colorMap != NULL) { 283 | colorMapType = cm_ColorMap; 284 | colorMapLen = 256; 285 | colorMapBits = 24; 286 | } 287 | bitsPerPix = 8; 288 | bb = 1; 289 | break; 290 | case 16: 291 | imageType = im_RgbImage; 292 | bitsPerPix = 16; 293 | bb = 2; 294 | break; 295 | case 24: 296 | imageType = im_RgbImage; 297 | bitsPerPix = 24; 298 | bb = 3; 299 | break; 300 | case 32: 301 | imageType = im_RgbImage; 302 | bitsPerPix = 32; 303 | bb = 4; 304 | break; 305 | default: 306 | fclose(f); 307 | return 0; 308 | } 309 | 310 | fputc(0, f); 311 | fputc(colorMapType, f); 312 | fputc(imageType, f); 313 | fputword(0, f); 314 | fputword(colorMapLen, f); 315 | fputc(colorMapBits, f); 316 | fputword(0, f); 317 | fputword(0, f); 318 | fputword(width, f); 319 | fputword(height, f); 320 | fputc(bitsPerPix, f); 321 | fputc(ds_TopLeft << 4, f); 322 | 323 | if (colorMapType == cm_ColorMap) { 324 | for (i = 0, pp = colorMap; i < 256; i++, pp += 3) { 325 | fputc(pp[0], f); 326 | fputc(pp[1], f); 327 | fputc(pp[2], f); 328 | } 329 | } 330 | 331 | fwrite(buffer, width*bb, height, f); 332 | if (ferror(f)) { 333 | fclose(f); 334 | return 0; 335 | } 336 | 337 | fclose(f); 338 | return 1; 339 | } 340 | -------------------------------------------------------------------------------- /examples/3dsplay/tga.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 1995-2011 Jan Eric Kyprianidis 3 | All rights reserved. 4 | 5 | Permission to use, copy, modify, and/or distribute this software for any 6 | purpose with or without fee is hereby granted, provided that the above 7 | copyright notice and this permission notice appear in all copies. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 | */ 17 | #ifndef INCLUDED_TGA_H 18 | #define INCLUDED_TGA_H 19 | #ifdef __cplusplus 20 | extern "C" { 21 | #endif 22 | 23 | extern int tga_load( const char *path, unsigned char **buffer, 24 | int *width, int *height ); 25 | 26 | extern int tga_save( const char *path, unsigned char *buffer, unsigned char *colorMap, 27 | int width, int height, int bits ); 28 | 29 | #ifdef __cplusplus 30 | } 31 | #endif 32 | #endif 33 | -------------------------------------------------------------------------------- /examples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ADD_SUBDIRECTORY(3ds2obj) 2 | ADD_SUBDIRECTORY(3dsdump) 3 | ADD_SUBDIRECTORY(cube) 4 | ADD_SUBDIRECTORY(3dsplay) 5 | -------------------------------------------------------------------------------- /examples/cube/.svn/all-wcprops: -------------------------------------------------------------------------------- 1 | K 25 2 | svn:wc:ra_dav:version-url 3 | V 36 4 | /svn/!svn/ver/91/trunk/examples/cube 5 | END 6 | cube.c 7 | K 25 8 | svn:wc:ra_dav:version-url 9 | V 43 10 | /svn/!svn/ver/91/trunk/examples/cube/cube.c 11 | END 12 | cube.tga 13 | K 25 14 | svn:wc:ra_dav:version-url 15 | V 45 16 | /svn/!svn/ver/62/trunk/examples/cube/cube.tga 17 | END 18 | Makefile.am 19 | K 25 20 | svn:wc:ra_dav:version-url 21 | V 48 22 | /svn/!svn/ver/84/trunk/examples/cube/Makefile.am 23 | END 24 | CMakeLists.txt 25 | K 25 26 | svn:wc:ra_dav:version-url 27 | V 51 28 | /svn/!svn/ver/91/trunk/examples/cube/CMakeLists.txt 29 | END 30 | -------------------------------------------------------------------------------- /examples/cube/.svn/entries: -------------------------------------------------------------------------------- 1 | 10 2 | 3 | dir 4 | 107 5 | http://lib3ds.googlecode.com/svn/trunk/examples/cube 6 | http://lib3ds.googlecode.com/svn 7 | 8 | 9 | 10 | 2008-11-11T12:00:06.790149Z 11 | 91 12 | jeh 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 984c2e8c-059d-11df-a9fb-49f3208c864b 28 | 29 | cube.c 30 | file 31 | 32 | 33 | 34 | 35 | 2014-11-03T08:36:57.520509Z 36 | f7aeca6eef48f165e75bafb841d86d76 37 | 2008-11-11T12:00:06.790149Z 38 | 91 39 | jeh 40 | has-props 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 4907 62 | 63 | cube.tga 64 | file 65 | 66 | 67 | 68 | 69 | 2014-11-03T08:36:57.521509Z 70 | 6c96ba5441902e41d332a604d2ea76cf 71 | 2008-09-06T20:45:48.590503Z 72 | 62 73 | jeh 74 | has-props 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 12332 96 | 97 | Makefile.am 98 | file 99 | 100 | 101 | 102 | 103 | 2014-11-03T08:36:57.521509Z 104 | 83362b686f359dac5139483389568481 105 | 2008-09-09T13:41:25.501711Z 106 | 84 107 | jeh 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 153 130 | 131 | CMakeLists.txt 132 | file 133 | 134 | 135 | 136 | 137 | 2014-11-03T08:36:57.521509Z 138 | 4a1b4732d657c33ade92e71d685beac2 139 | 2008-11-11T12:00:06.790149Z 140 | 91 141 | jeh 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 112 164 | 165 | -------------------------------------------------------------------------------- /examples/cube/.svn/prop-base/cube.c.svn-base: -------------------------------------------------------------------------------- 1 | K 13 2 | svn:mergeinfo 3 | V 0 4 | 5 | END 6 | -------------------------------------------------------------------------------- /examples/cube/.svn/prop-base/cube.tga.svn-base: -------------------------------------------------------------------------------- 1 | K 13 2 | svn:mergeinfo 3 | V 0 4 | 5 | K 13 6 | svn:mime-type 7 | V 24 8 | application/octet-stream 9 | END 10 | -------------------------------------------------------------------------------- /examples/cube/.svn/text-base/CMakeLists.txt.svn-base: -------------------------------------------------------------------------------- 1 | INCLUDE_DIRECTORIES( ${lib3ds_SOURCE_DIR}/src ) 2 | ADD_EXECUTABLE(cube cube.c) 3 | TARGET_LINK_LIBRARIES(cube lib3ds) 4 | -------------------------------------------------------------------------------- /examples/cube/.svn/text-base/Makefile.am.svn-base: -------------------------------------------------------------------------------- 1 | INCLUDES = -I$(top_srcdir)/src 2 | 3 | bin_PROGRAMS = cube 4 | cube_SOURCES = cube.c 5 | 6 | LDADD = $(top_builddir)/src/lib3ds.la 7 | 8 | EXTRA_DIST = cube.vcproj cube.tga 9 | 10 | -------------------------------------------------------------------------------- /examples/cube/.svn/text-base/cube.c.svn-base: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 1996-2008 by Jan Eric Kyprianidis 3 | All rights reserved. 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published 7 | by the Free Software Foundation, either version 2.1 of the License, or 8 | (at your option) any later version. 9 | 10 | Thisprogram is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program; If not, see . 17 | */ 18 | 19 | /** @file cube.c 20 | Implementation of cube example. */ 21 | /** @example cube.c 22 | This examples demonstrates how to export a textured cube using lib3ds. */ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #pragma warning ( disable : 4996 ) 31 | 32 | #ifndef MPI 33 | #define M_PI 3.14159265358979323846 34 | #endif 35 | 36 | 37 | static float g_vertices[8][3] = { 38 | { -10.0, -10.0, 15.0 }, 39 | { 10.0, -10.0, 15.0 }, 40 | { 10.0, 10.0, 15.0 }, 41 | { -10.0, 10.0, 15.0 }, 42 | { -10.0, -10.0, -15.0 }, 43 | { 10.0, -10.0, -15.0 }, 44 | { 10.0, 10.0, -15.0 }, 45 | { -10.0, 10.0, -15.0 } 46 | }; 47 | 48 | 49 | // Texture coodinate origin (0,0) is in bottom-left corner! 50 | static float g_texcoords[8][3] = { 51 | { 0.00, 1.0 }, 52 | { 0.25, 1.0 }, 53 | { 0.50, 1.0 }, 54 | { 0.75, 1.0 }, 55 | { 0.00, 0.0 }, 56 | { 0.25, 0.0 }, 57 | { 0.50, 0.0 }, 58 | { 0.75, 0.0 } 59 | }; 60 | 61 | 62 | // CCW 63 | static unsigned short g_indices[12][3] = { 64 | { 0, 5, 1 }, 65 | { 0, 4, 5 }, 66 | { 1, 6, 2 }, 67 | { 1, 5, 6 }, 68 | { 2, 6, 7 }, 69 | { 2, 7, 3 }, 70 | { 0, 3, 7 }, 71 | { 0, 7, 4 }, 72 | { 0, 1, 2 }, 73 | { 0, 2, 3 }, 74 | { 4, 7, 6 }, 75 | { 4, 6, 5 } 76 | }; 77 | 78 | 79 | int main(int argc, char **argv) { 80 | Lib3dsFile *file = lib3ds_file_new(); 81 | file->frames = 360; 82 | 83 | { 84 | Lib3dsMaterial *mat = lib3ds_material_new("c_tex"); 85 | lib3ds_file_insert_material(file, mat, -1); 86 | strcpy(mat->texture1_map.name, "cube.tga"); 87 | mat->texture1_map.percent = 1.0; 88 | 89 | mat = lib3ds_material_new("c_red"); 90 | lib3ds_file_insert_material(file, mat, -1); 91 | mat->diffuse[0] = 1.0; 92 | mat->diffuse[1] = 0.0; 93 | mat->diffuse[2] = 0.0; 94 | 95 | mat = lib3ds_material_new("c_blue"); 96 | lib3ds_file_insert_material(file, mat, -1); 97 | mat->diffuse[0] = 0.0; 98 | mat->diffuse[1] = 0.0; 99 | mat->diffuse[2] = 1.0; 100 | } 101 | 102 | { 103 | int i, j; 104 | Lib3dsMesh *mesh = lib3ds_mesh_new("cube"); 105 | Lib3dsMeshInstanceNode *inst; 106 | lib3ds_file_insert_mesh(file, mesh, -1); 107 | 108 | lib3ds_mesh_resize_vertices(mesh, 8, 1, 0); 109 | for (i = 0; i < 8; ++i) { 110 | lib3ds_vector_copy(mesh->vertices[i], g_vertices[i]); 111 | mesh->texcos[i][0] = g_texcoords[i][0]; 112 | mesh->texcos[i][1] = g_texcoords[i][1]; 113 | } 114 | 115 | lib3ds_mesh_resize_faces(mesh, 12); 116 | for (i = 0; i < 12; ++i) { 117 | for (j = 0; j < 3; ++j) { 118 | mesh->faces[i].index[j] = g_indices[i][j]; 119 | } 120 | } 121 | 122 | for (i = 0; i < 8; ++i) { 123 | mesh->faces[i].material = 0; 124 | } 125 | for (i = 0; i < 2; ++i) { 126 | mesh->faces[8+i].material = 1; 127 | } 128 | for (i = 0; i < 2; ++i) { 129 | mesh->faces[10+i].material = 2; 130 | } 131 | 132 | inst = lib3ds_node_new_mesh_instance(mesh, "01", NULL, NULL, NULL); 133 | lib3ds_file_append_node(file, (Lib3dsNode*)inst, NULL); 134 | } 135 | 136 | { 137 | Lib3dsCamera *camera; 138 | Lib3dsCameraNode *n; 139 | Lib3dsTargetNode *t; 140 | int i; 141 | 142 | camera = lib3ds_camera_new("camera01"); 143 | lib3ds_file_insert_camera(file, camera, -1); 144 | lib3ds_vector_make(camera->position, 0.0, -100, 0.0); 145 | lib3ds_vector_make(camera->target, 0.0, 0.0, 0.0); 146 | 147 | n = lib3ds_node_new_camera(camera); 148 | t = lib3ds_node_new_camera_target(camera); 149 | lib3ds_file_append_node(file, (Lib3dsNode*)n, NULL); 150 | lib3ds_file_append_node(file, (Lib3dsNode*)t, NULL); 151 | 152 | lib3ds_track_resize(&n->pos_track, 37); 153 | for (i = 0; i <= 36; i++) { 154 | n->pos_track.keys[i].frame = 10 * i; 155 | lib3ds_vector_make(n->pos_track.keys[i].value, 156 | (float)(100.0 * cos(2 * M_PI * i / 36.0)), 157 | (float)(100.0 * sin(2 * M_PI * i / 36.0)), 158 | 50.0 159 | ); 160 | } 161 | } 162 | 163 | if (!lib3ds_file_save(file, "cube.3ds")) { 164 | fprintf(stderr, "ERROR: Saving 3ds file failed!\n"); 165 | } 166 | lib3ds_file_free(file); 167 | } 168 | -------------------------------------------------------------------------------- /examples/cube/.svn/text-base/cube.tga.svn-base: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vkocheryzhkin/lib3ds/f8cfd93e7a4f81feeb8473f0b73b0397e9ebf996/examples/cube/.svn/text-base/cube.tga.svn-base -------------------------------------------------------------------------------- /examples/cube/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | INCLUDE_DIRECTORIES( ${lib3ds_SOURCE_DIR}/src ) 2 | ADD_EXECUTABLE(cube cube.c) 3 | TARGET_LINK_LIBRARIES(cube lib3ds) 4 | -------------------------------------------------------------------------------- /examples/cube/cube.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 1996-2008 by Jan Eric Kyprianidis 3 | All rights reserved. 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published 7 | by the Free Software Foundation, either version 2.1 of the License, or 8 | (at your option) any later version. 9 | 10 | Thisprogram is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program; If not, see . 17 | */ 18 | 19 | /** @file cube.c 20 | Implementation of cube example. */ 21 | /** @example cube.c 22 | This examples demonstrates how to export a textured cube using lib3ds. */ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #pragma warning ( disable : 4996 ) 31 | 32 | #ifndef MPI 33 | #define M_PI 3.14159265358979323846 34 | #endif 35 | 36 | 37 | static float g_vertices[8][3] = { 38 | { -10.0, -10.0, 15.0 }, 39 | { 10.0, -10.0, 15.0 }, 40 | { 10.0, 10.0, 15.0 }, 41 | { -10.0, 10.0, 15.0 }, 42 | { -10.0, -10.0, -15.0 }, 43 | { 10.0, -10.0, -15.0 }, 44 | { 10.0, 10.0, -15.0 }, 45 | { -10.0, 10.0, -15.0 } 46 | }; 47 | 48 | 49 | // Texture coodinate origin (0,0) is in bottom-left corner! 50 | static float g_texcoords[8][3] = { 51 | { 0.00, 1.0 }, 52 | { 0.25, 1.0 }, 53 | { 0.50, 1.0 }, 54 | { 0.75, 1.0 }, 55 | { 0.00, 0.0 }, 56 | { 0.25, 0.0 }, 57 | { 0.50, 0.0 }, 58 | { 0.75, 0.0 } 59 | }; 60 | 61 | 62 | // CCW 63 | static unsigned short g_indices[12][3] = { 64 | { 0, 5, 1 }, 65 | { 0, 4, 5 }, 66 | { 1, 6, 2 }, 67 | { 1, 5, 6 }, 68 | { 2, 6, 7 }, 69 | { 2, 7, 3 }, 70 | { 0, 3, 7 }, 71 | { 0, 7, 4 }, 72 | { 0, 1, 2 }, 73 | { 0, 2, 3 }, 74 | { 4, 7, 6 }, 75 | { 4, 6, 5 } 76 | }; 77 | 78 | 79 | int main(int argc, char **argv) { 80 | Lib3dsFile *file = lib3ds_file_new(); 81 | file->frames = 360; 82 | 83 | { 84 | Lib3dsMaterial *mat = lib3ds_material_new("c_tex"); 85 | lib3ds_file_insert_material(file, mat, -1); 86 | strcpy(mat->texture1_map.name, "cube.tga"); 87 | mat->texture1_map.percent = 1.0; 88 | 89 | mat = lib3ds_material_new("c_red"); 90 | lib3ds_file_insert_material(file, mat, -1); 91 | mat->diffuse[0] = 1.0; 92 | mat->diffuse[1] = 0.0; 93 | mat->diffuse[2] = 0.0; 94 | 95 | mat = lib3ds_material_new("c_blue"); 96 | lib3ds_file_insert_material(file, mat, -1); 97 | mat->diffuse[0] = 0.0; 98 | mat->diffuse[1] = 0.0; 99 | mat->diffuse[2] = 1.0; 100 | } 101 | 102 | { 103 | int i, j; 104 | Lib3dsMesh *mesh = lib3ds_mesh_new("cube"); 105 | Lib3dsMeshInstanceNode *inst; 106 | lib3ds_file_insert_mesh(file, mesh, -1); 107 | 108 | lib3ds_mesh_resize_vertices(mesh, 8, 1, 0); 109 | for (i = 0; i < 8; ++i) { 110 | lib3ds_vector_copy(mesh->vertices[i], g_vertices[i]); 111 | mesh->texcos[i][0] = g_texcoords[i][0]; 112 | mesh->texcos[i][1] = g_texcoords[i][1]; 113 | } 114 | 115 | lib3ds_mesh_resize_faces(mesh, 12); 116 | for (i = 0; i < 12; ++i) { 117 | for (j = 0; j < 3; ++j) { 118 | mesh->faces[i].index[j] = g_indices[i][j]; 119 | } 120 | } 121 | 122 | for (i = 0; i < 8; ++i) { 123 | mesh->faces[i].material = 0; 124 | } 125 | for (i = 0; i < 2; ++i) { 126 | mesh->faces[8+i].material = 1; 127 | } 128 | for (i = 0; i < 2; ++i) { 129 | mesh->faces[10+i].material = 2; 130 | } 131 | 132 | inst = lib3ds_node_new_mesh_instance(mesh, "01", NULL, NULL, NULL); 133 | lib3ds_file_append_node(file, (Lib3dsNode*)inst, NULL); 134 | } 135 | 136 | { 137 | Lib3dsCamera *camera; 138 | Lib3dsCameraNode *n; 139 | Lib3dsTargetNode *t; 140 | int i; 141 | 142 | camera = lib3ds_camera_new("camera01"); 143 | lib3ds_file_insert_camera(file, camera, -1); 144 | lib3ds_vector_make(camera->position, 0.0, -100, 0.0); 145 | lib3ds_vector_make(camera->target, 0.0, 0.0, 0.0); 146 | 147 | n = lib3ds_node_new_camera(camera); 148 | t = lib3ds_node_new_camera_target(camera); 149 | lib3ds_file_append_node(file, (Lib3dsNode*)n, NULL); 150 | lib3ds_file_append_node(file, (Lib3dsNode*)t, NULL); 151 | 152 | lib3ds_track_resize(&n->pos_track, 37); 153 | for (i = 0; i <= 36; i++) { 154 | n->pos_track.keys[i].frame = 10 * i; 155 | lib3ds_vector_make(n->pos_track.keys[i].value, 156 | (float)(100.0 * cos(2 * M_PI * i / 36.0)), 157 | (float)(100.0 * sin(2 * M_PI * i / 36.0)), 158 | 50.0 159 | ); 160 | } 161 | } 162 | 163 | if (!lib3ds_file_save(file, "cube.3ds")) { 164 | fprintf(stderr, "ERROR: Saving 3ds file failed!\n"); 165 | } 166 | lib3ds_file_free(file); 167 | } 168 | -------------------------------------------------------------------------------- /examples/cube/cube.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vkocheryzhkin/lib3ds/f8cfd93e7a4f81feeb8473f0b73b0397e9ebf996/examples/cube/cube.tga -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | IF(MSVC) 2 | ADD_DEFINITIONS(-DLIB3DS_EXPORTS) 3 | ENDIF(MSVC) 4 | 5 | ADD_LIBRARY(lib3ds SHARED 6 | lib3ds.h 7 | lib3ds_impl.h 8 | lib3ds_atmosphere.c 9 | lib3ds_background.c 10 | lib3ds_camera.c 11 | lib3ds_chunk.c 12 | lib3ds_chunktable.c 13 | lib3ds_file.c 14 | lib3ds_io.c 15 | lib3ds_light.c 16 | lib3ds_material.c 17 | lib3ds_math.c 18 | lib3ds_matrix.c 19 | lib3ds_mesh.c 20 | lib3ds_node.c 21 | lib3ds_quat.c 22 | lib3ds_shadow.c 23 | lib3ds_track.c 24 | lib3ds_util.c 25 | lib3ds_vector.c 26 | lib3ds_viewport.c 27 | lib3ds.rc) 28 | 29 | IF(WIN32) 30 | SET_TARGET_PROPERTIES(lib3ds PROPERTIES 31 | OUTPUT_NAME "lib3ds-2_0" 32 | DEBUG_POSTFIX "d") 33 | ENDIF(WIN32) 34 | 35 | SET_TARGET_PROPERTIES(lib3ds 36 | PROPERTIES VERSION 2.0) 37 | 38 | # Install Rules 39 | install (TARGETS lib3ds DESTINATION "lib") 40 | -------------------------------------------------------------------------------- /src/lib3ds.rc: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 1996-2008 by Jan Eric Kyprianidis 3 | All rights reserved. 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published 7 | by the Free Software Foundation, either version 2.1 of the License, or 8 | (at your option) any later version. 9 | 10 | Thisprogram is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program; If not, see . 17 | */ 18 | #include "winres.h" 19 | 20 | #ifdef _WIN32 21 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US 22 | #pragma code_page(1252) 23 | #endif //_WIN32 24 | 25 | VS_VERSION_INFO VERSIONINFO 26 | FILEVERSION 1,3,0,0 27 | PRODUCTVERSION 1,3,0,0 28 | FILEFLAGSMASK 0x17L 29 | #ifdef _DEBUG 30 | FILEFLAGS 0x1L 31 | #else 32 | FILEFLAGS 0x0L 33 | #endif 34 | FILEOS 0x4L 35 | FILETYPE 0x2L 36 | FILESUBTYPE 0x0L 37 | BEGIN 38 | BLOCK "StringFileInfo" 39 | BEGIN 40 | BLOCK "040904b0" 41 | BEGIN 42 | VALUE "FileDescription", "lib3ds Dynamic Link Library" 43 | VALUE "FileVersion", "1.3.0" 44 | VALUE "InternalName", "lib3ds" 45 | VALUE "LegalCopyright", "Copyright (C) 1996-2007 by Jan Eric Kyprianidis" 46 | VALUE "OriginalFilename", "lib3ds.dll" 47 | VALUE "ProductName", "lib3ds Dynamic Link Library" 48 | VALUE "ProductVersion", "1.3.0" 49 | END 50 | END 51 | BLOCK "VarFileInfo" 52 | BEGIN 53 | VALUE "Translation", 0x409, 1200 54 | END 55 | END 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /src/lib3ds_atmosphere.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 1996-2008 by Jan Eric Kyprianidis 3 | All rights reserved. 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published 7 | by the Free Software Foundation, either version 2.1 of the License, or 8 | (at your option) any later version. 9 | 10 | Thisprogram is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program; If not, see . 17 | */ 18 | #include "lib3ds_impl.h" 19 | 20 | 21 | static void 22 | fog_read(Lib3dsAtmosphere *at, Lib3dsIo *io) { 23 | Lib3dsChunk c; 24 | uint16_t chunk; 25 | 26 | lib3ds_chunk_read_start(&c, CHK_FOG, io); 27 | 28 | at->fog_near_plane = lib3ds_io_read_float(io); 29 | at->fog_near_density = lib3ds_io_read_float(io); 30 | at->fog_far_plane = lib3ds_io_read_float(io); 31 | at->fog_far_density = lib3ds_io_read_float(io); 32 | lib3ds_chunk_read_tell(&c, io); 33 | 34 | while ((chunk = lib3ds_chunk_read_next(&c, io)) != 0) { 35 | switch (chunk) { 36 | case CHK_LIN_COLOR_F: { 37 | int i; 38 | for (i = 0; i < 3; ++i) { 39 | at->fog_color[i] = lib3ds_io_read_float(io); 40 | } 41 | } 42 | break; 43 | 44 | case CHK_COLOR_F: 45 | break; 46 | 47 | case CHK_FOG_BGND: { 48 | at->fog_background = TRUE; 49 | } 50 | break; 51 | 52 | default: 53 | lib3ds_chunk_unknown(chunk, io); 54 | } 55 | } 56 | 57 | lib3ds_chunk_read_end(&c, io); 58 | } 59 | 60 | 61 | static void 62 | layer_fog_read(Lib3dsAtmosphere *at, Lib3dsIo *io) { 63 | Lib3dsChunk c; 64 | uint16_t chunk; 65 | int have_lin = FALSE; 66 | 67 | lib3ds_chunk_read_start(&c, CHK_LAYER_FOG, io); 68 | 69 | at->layer_fog_near_y = lib3ds_io_read_float(io); 70 | at->layer_fog_far_y = lib3ds_io_read_float(io); 71 | at->layer_fog_density = lib3ds_io_read_float(io); 72 | at->layer_fog_flags = lib3ds_io_read_dword(io); 73 | lib3ds_chunk_read_tell(&c, io); 74 | 75 | while ((chunk = lib3ds_chunk_read_next(&c, io)) != 0) { 76 | switch (chunk) { 77 | case CHK_LIN_COLOR_F: 78 | lib3ds_io_read_rgb(io, at->layer_fog_color); 79 | have_lin = TRUE; 80 | break; 81 | 82 | case CHK_COLOR_F: 83 | lib3ds_io_read_rgb(io, at->layer_fog_color); 84 | break; 85 | 86 | default: 87 | lib3ds_chunk_unknown(chunk, io); 88 | } 89 | } 90 | 91 | lib3ds_chunk_read_end(&c, io); 92 | } 93 | 94 | 95 | static void 96 | distance_cue_read(Lib3dsAtmosphere *at, Lib3dsIo *io) { 97 | Lib3dsChunk c; 98 | uint16_t chunk; 99 | 100 | lib3ds_chunk_read_start(&c, CHK_DISTANCE_CUE, io); 101 | 102 | at->dist_cue_near_plane = lib3ds_io_read_float(io); 103 | at->dist_cue_near_dimming = lib3ds_io_read_float(io); 104 | at->dist_cue_far_plane = lib3ds_io_read_float(io); 105 | at->dist_cue_far_dimming = lib3ds_io_read_float(io); 106 | lib3ds_chunk_read_tell(&c, io); 107 | 108 | while ((chunk = lib3ds_chunk_read_next(&c, io)) != 0) { 109 | switch (chunk) { 110 | case CHK_DCUE_BGND: { 111 | at->dist_cue_background = TRUE; 112 | } 113 | break; 114 | 115 | default: 116 | lib3ds_chunk_unknown(chunk, io); 117 | } 118 | } 119 | 120 | lib3ds_chunk_read_end(&c, io); 121 | } 122 | 123 | 124 | void 125 | lib3ds_atmosphere_read(Lib3dsAtmosphere *atmosphere, Lib3dsIo *io) { 126 | Lib3dsChunk c; 127 | 128 | lib3ds_chunk_read(&c, io); 129 | switch (c.chunk) { 130 | case CHK_FOG: { 131 | lib3ds_chunk_read_reset(&c, io); 132 | fog_read(atmosphere, io); 133 | break; 134 | } 135 | 136 | case CHK_LAYER_FOG: { 137 | lib3ds_chunk_read_reset(&c, io); 138 | layer_fog_read(atmosphere, io); 139 | break; 140 | } 141 | 142 | case CHK_DISTANCE_CUE: { 143 | lib3ds_chunk_read_reset(&c, io); 144 | distance_cue_read(atmosphere, io); 145 | break; 146 | } 147 | 148 | case CHK_USE_FOG: { 149 | atmosphere->use_fog = TRUE; 150 | break; 151 | } 152 | 153 | case CHK_USE_LAYER_FOG: { 154 | atmosphere->use_layer_fog = TRUE; 155 | break; 156 | } 157 | 158 | case CHK_USE_DISTANCE_CUE: { 159 | atmosphere->use_dist_cue = TRUE; 160 | break; 161 | } 162 | } 163 | } 164 | 165 | 166 | void 167 | lib3ds_atmosphere_write(Lib3dsAtmosphere *atmosphere, Lib3dsIo *io) { 168 | if (atmosphere->use_fog) { /*---- LIB3DS_FOG ----*/ 169 | Lib3dsChunk c; 170 | c.chunk = CHK_FOG; 171 | lib3ds_chunk_write_start(&c, io); 172 | 173 | lib3ds_io_write_float(io, atmosphere->fog_near_plane); 174 | lib3ds_io_write_float(io, atmosphere->fog_near_density); 175 | lib3ds_io_write_float(io, atmosphere->fog_far_plane); 176 | lib3ds_io_write_float(io, atmosphere->fog_far_density); 177 | { 178 | Lib3dsChunk c; 179 | c.chunk = CHK_COLOR_F; 180 | c.size = 18; 181 | lib3ds_chunk_write(&c, io); 182 | lib3ds_io_write_rgb(io, atmosphere->fog_color); 183 | } 184 | if (atmosphere->fog_background) { 185 | Lib3dsChunk c; 186 | c.chunk = CHK_FOG_BGND; 187 | c.size = 6; 188 | lib3ds_chunk_write(&c, io); 189 | } 190 | 191 | lib3ds_chunk_write_end(&c, io); 192 | } 193 | 194 | if (atmosphere->use_layer_fog) { /*---- LIB3DS_LAYER_FOG ----*/ 195 | Lib3dsChunk c; 196 | c.chunk = CHK_LAYER_FOG; 197 | c.size = 40; 198 | lib3ds_chunk_write(&c, io); 199 | lib3ds_io_write_float(io, atmosphere->layer_fog_near_y); 200 | lib3ds_io_write_float(io, atmosphere->layer_fog_far_y); 201 | lib3ds_io_write_float(io, atmosphere->layer_fog_near_y); 202 | lib3ds_io_write_dword(io, atmosphere->layer_fog_flags); 203 | { 204 | Lib3dsChunk c; 205 | c.chunk = CHK_COLOR_F; 206 | c.size = 18; 207 | lib3ds_chunk_write(&c, io); 208 | lib3ds_io_write_rgb(io, atmosphere->fog_color); 209 | } 210 | } 211 | 212 | if (atmosphere->use_dist_cue) { /*---- LIB3DS_DISTANCE_CUE ----*/ 213 | Lib3dsChunk c; 214 | c.chunk = CHK_DISTANCE_CUE; 215 | lib3ds_chunk_write_start(&c, io); 216 | 217 | lib3ds_io_write_float(io, atmosphere->dist_cue_near_plane); 218 | lib3ds_io_write_float(io, atmosphere->dist_cue_near_dimming); 219 | lib3ds_io_write_float(io, atmosphere->dist_cue_far_plane); 220 | lib3ds_io_write_float(io, atmosphere->dist_cue_far_dimming); 221 | if (atmosphere->dist_cue_background) { 222 | Lib3dsChunk c; 223 | c.chunk = CHK_DCUE_BGND; 224 | c.size = 6; 225 | lib3ds_chunk_write(&c, io); 226 | } 227 | 228 | lib3ds_chunk_write_end(&c, io); 229 | } 230 | 231 | if (atmosphere->use_fog) { /*---- LIB3DS_USE_FOG ----*/ 232 | Lib3dsChunk c; 233 | c.chunk = CHK_USE_FOG; 234 | c.size = 6; 235 | lib3ds_chunk_write(&c, io); 236 | } 237 | 238 | if (atmosphere->use_layer_fog) { /*---- LIB3DS_USE_LAYER_FOG ----*/ 239 | Lib3dsChunk c; 240 | c.chunk = CHK_USE_LAYER_FOG; 241 | c.size = 6; 242 | lib3ds_chunk_write(&c, io); 243 | } 244 | 245 | if (atmosphere->use_dist_cue) { /*---- LIB3DS_USE_DISTANCE_CUE ----*/ 246 | Lib3dsChunk c; 247 | c.chunk = CHK_USE_V_GRADIENT; 248 | c.size = 6; 249 | lib3ds_chunk_write(&c, io); 250 | } 251 | } 252 | 253 | 254 | -------------------------------------------------------------------------------- /src/lib3ds_background.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 1996-2008 by Jan Eric Kyprianidis 3 | All rights reserved. 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published 7 | by the Free Software Foundation, either version 2.1 of the License, or 8 | (at your option) any later version. 9 | 10 | Thisprogram is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program; If not, see . 17 | */ 18 | #include "lib3ds_impl.h" 19 | 20 | 21 | static void 22 | solid_bgnd_read(Lib3dsBackground *background, Lib3dsIo *io) { 23 | Lib3dsChunk c; 24 | uint16_t chunk; 25 | int have_lin = FALSE; 26 | 27 | lib3ds_chunk_read_start(&c, CHK_SOLID_BGND, io); 28 | 29 | while ((chunk = lib3ds_chunk_read_next(&c, io)) != 0) { 30 | switch (chunk) { 31 | case CHK_LIN_COLOR_F: 32 | lib3ds_io_read_rgb(io, background->solid_color); 33 | have_lin = TRUE; 34 | break; 35 | 36 | case CHK_COLOR_F: 37 | lib3ds_io_read_rgb(io, background->solid_color); 38 | break; 39 | 40 | default: 41 | lib3ds_chunk_unknown(chunk, io); 42 | } 43 | } 44 | 45 | lib3ds_chunk_read_end(&c, io); 46 | } 47 | 48 | 49 | static void 50 | v_gradient_read(Lib3dsBackground *background, Lib3dsIo *io) { 51 | Lib3dsChunk c; 52 | uint16_t chunk; 53 | int index[2]; 54 | float col[2][3][3]; 55 | int have_lin = 0; 56 | 57 | lib3ds_chunk_read_start(&c, CHK_V_GRADIENT, io); 58 | 59 | background->gradient_percent = lib3ds_io_read_float(io); 60 | lib3ds_chunk_read_tell(&c, io); 61 | 62 | index[0] = index[1] = 0; 63 | while ((chunk = lib3ds_chunk_read_next(&c, io)) != 0) { 64 | switch (chunk) { 65 | case CHK_COLOR_F: 66 | lib3ds_io_read_rgb(io, col[0][index[0]]); 67 | index[0]++; 68 | break; 69 | 70 | case CHK_LIN_COLOR_F: 71 | lib3ds_io_read_rgb(io, col[1][index[1]]); 72 | index[1]++; 73 | have_lin = 1; 74 | break; 75 | 76 | default: 77 | lib3ds_chunk_unknown(chunk, io); 78 | } 79 | } 80 | { 81 | int i; 82 | for (i = 0; i < 3; ++i) { 83 | background->gradient_top[i] = col[have_lin][0][i]; 84 | background->gradient_middle[i] = col[have_lin][1][i]; 85 | background->gradient_bottom[i] = col[have_lin][2][i]; 86 | } 87 | } 88 | lib3ds_chunk_read_end(&c, io); 89 | } 90 | 91 | 92 | void 93 | lib3ds_background_read(Lib3dsBackground *background, Lib3dsIo *io) { 94 | Lib3dsChunk c; 95 | 96 | lib3ds_chunk_read(&c, io); 97 | switch (c.chunk) { 98 | case CHK_BIT_MAP: { 99 | lib3ds_io_read_string(io, background->bitmap_name, 64); 100 | break; 101 | } 102 | 103 | case CHK_SOLID_BGND: { 104 | lib3ds_chunk_read_reset(&c, io); 105 | solid_bgnd_read(background, io); 106 | break; 107 | } 108 | 109 | case CHK_V_GRADIENT: { 110 | lib3ds_chunk_read_reset(&c, io); 111 | v_gradient_read(background, io); 112 | break; 113 | } 114 | 115 | case CHK_USE_BIT_MAP: { 116 | background->use_bitmap = TRUE; 117 | break; 118 | } 119 | 120 | case CHK_USE_SOLID_BGND: { 121 | background->use_solid = TRUE; 122 | break; 123 | } 124 | 125 | case CHK_USE_V_GRADIENT: { 126 | background->use_gradient = TRUE; 127 | break; 128 | } 129 | } 130 | } 131 | 132 | 133 | static void 134 | colorf_write(float rgb[3], Lib3dsIo *io) { 135 | Lib3dsChunk c; 136 | 137 | c.chunk = CHK_COLOR_F; 138 | c.size = 18; 139 | lib3ds_chunk_write(&c, io); 140 | lib3ds_io_write_rgb(io, rgb); 141 | 142 | c.chunk = CHK_LIN_COLOR_F; 143 | c.size = 18; 144 | lib3ds_chunk_write(&c, io); 145 | lib3ds_io_write_rgb(io, rgb); 146 | } 147 | 148 | 149 | static int 150 | colorf_defined(float rgb[3]) { 151 | int i; 152 | for (i = 0; i < 3; ++i) { 153 | if (fabs(rgb[i]) > LIB3DS_EPSILON) { 154 | break; 155 | } 156 | } 157 | return(i < 3); 158 | } 159 | 160 | 161 | void 162 | lib3ds_background_write(Lib3dsBackground *background, Lib3dsIo *io) { 163 | if (strlen(background->bitmap_name)) { /*---- LIB3DS_BIT_MAP ----*/ 164 | Lib3dsChunk c; 165 | c.chunk = CHK_BIT_MAP; 166 | c.size = 6 + 1 + (uint32_t)strlen(background->bitmap_name); 167 | lib3ds_chunk_write(&c, io); 168 | lib3ds_io_write_string(io, background->bitmap_name); 169 | } 170 | 171 | if (colorf_defined(background->solid_color)) { /*---- LIB3DS_SOLID_BGND ----*/ 172 | Lib3dsChunk c; 173 | c.chunk = CHK_SOLID_BGND; 174 | c.size = 42; 175 | lib3ds_chunk_write(&c, io); 176 | colorf_write(background->solid_color, io); 177 | } 178 | 179 | if (colorf_defined(background->gradient_top) || 180 | colorf_defined(background->gradient_middle) || 181 | colorf_defined(background->gradient_bottom)) { /*---- LIB3DS_V_GRADIENT ----*/ 182 | Lib3dsChunk c; 183 | c.chunk = CHK_V_GRADIENT; 184 | c.size = 118; 185 | lib3ds_chunk_write(&c, io); 186 | lib3ds_io_write_float(io, background->gradient_percent); 187 | colorf_write(background->gradient_top, io); 188 | colorf_write(background->gradient_middle, io); 189 | colorf_write(background->gradient_bottom, io); 190 | } 191 | 192 | if (background->use_bitmap) { /*---- LIB3DS_USE_BIT_MAP ----*/ 193 | Lib3dsChunk c; 194 | c.chunk = CHK_USE_BIT_MAP; 195 | c.size = 6; 196 | lib3ds_chunk_write(&c, io); 197 | } 198 | 199 | if (background->use_solid) { /*---- LIB3DS_USE_SOLID_BGND ----*/ 200 | Lib3dsChunk c; 201 | c.chunk = CHK_USE_SOLID_BGND; 202 | c.size = 6; 203 | lib3ds_chunk_write(&c, io); 204 | } 205 | 206 | if (background->use_gradient) { /*---- LIB3DS_USE_V_GRADIENT ----*/ 207 | Lib3dsChunk c; 208 | c.chunk = CHK_USE_V_GRADIENT; 209 | c.size = 6; 210 | lib3ds_chunk_write(&c, io); 211 | } 212 | } 213 | 214 | -------------------------------------------------------------------------------- /src/lib3ds_camera.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 1996-2008 by Jan Eric Kyprianidis 3 | All rights reserved. 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published 7 | by the Free Software Foundation, either version 2.1 of the License, or 8 | (at your option) any later version. 9 | 10 | Thisprogram is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program; If not, see . 17 | */ 18 | #include "lib3ds_impl.h" 19 | 20 | 21 | /*! 22 | * Return a new Lib3dsCamera object. 23 | * 24 | * Object is initialized with the given name and fov=45. All other 25 | * values are 0. 26 | * 27 | * \param name Name of this camera. Must not be NULL. Must be < 64 characters. 28 | * 29 | * \return Lib3dsCamera object or NULL on failure. 30 | */ 31 | Lib3dsCamera* 32 | lib3ds_camera_new(const char *name) { 33 | Lib3dsCamera *camera; 34 | 35 | assert(name); 36 | assert(strlen(name) < 64); 37 | 38 | camera = (Lib3dsCamera*)calloc(sizeof(Lib3dsCamera), 1); 39 | if (!camera) { 40 | return(0); 41 | } 42 | strcpy(camera->name, name); 43 | camera->fov = 45.0f; 44 | return(camera); 45 | } 46 | 47 | 48 | /*! 49 | * Free a Lib3dsCamera object and all of its resources. 50 | * 51 | * \param camera Lib3dsCamera object to be freed. 52 | */ 53 | void 54 | lib3ds_camera_free(Lib3dsCamera *camera) { 55 | memset(camera, 0, sizeof(Lib3dsCamera)); 56 | free(camera); 57 | } 58 | 59 | 60 | /*! 61 | * Read a camera definition from a file. 62 | * 63 | * This function is called by lib3ds_file_read(), and you probably 64 | * don't want to call it directly. 65 | * 66 | * \param camera A Lib3dsCamera to be filled in. 67 | * \param io A Lib3dsIo object previously set up by the caller. 68 | * 69 | * \see lib3ds_file_read 70 | */ 71 | void 72 | lib3ds_camera_read(Lib3dsCamera *camera, Lib3dsIo *io) { 73 | Lib3dsChunk c; 74 | uint16_t chunk; 75 | 76 | lib3ds_chunk_read_start(&c, CHK_N_CAMERA, io); 77 | 78 | { 79 | int i; 80 | for (i = 0; i < 3; ++i) { 81 | camera->position[i] = lib3ds_io_read_float(io); 82 | } 83 | for (i = 0; i < 3; ++i) { 84 | camera->target[i] = lib3ds_io_read_float(io); 85 | } 86 | } 87 | camera->roll = lib3ds_io_read_float(io); 88 | { 89 | float s; 90 | s = lib3ds_io_read_float(io); 91 | if (fabs(s) < LIB3DS_EPSILON) { 92 | camera->fov = 45.0; 93 | } else { 94 | camera->fov = 2400.0f / s; 95 | } 96 | } 97 | lib3ds_chunk_read_tell(&c, io); 98 | 99 | while ((chunk = lib3ds_chunk_read_next(&c, io)) != 0) { 100 | switch (chunk) { 101 | case CHK_CAM_SEE_CONE: { 102 | camera->see_cone = TRUE; 103 | } 104 | break; 105 | 106 | case CHK_CAM_RANGES: { 107 | camera->near_range = lib3ds_io_read_float(io); 108 | camera->far_range = lib3ds_io_read_float(io); 109 | } 110 | break; 111 | 112 | default: 113 | lib3ds_chunk_unknown(chunk, io); 114 | } 115 | } 116 | 117 | lib3ds_chunk_read_end(&c, io); 118 | } 119 | 120 | 121 | /*! 122 | * Write a camera definition to a file. 123 | * 124 | * This function is called by lib3ds_file_write(), and you probably 125 | * don't want to call it directly. 126 | * 127 | * \param camera A Lib3dsCamera to be written. 128 | * \param io A Lib3dsIo object previously set up by the caller. 129 | * 130 | * \see lib3ds_file_write 131 | */ 132 | void 133 | lib3ds_camera_write(Lib3dsCamera *camera, Lib3dsIo *io) { 134 | Lib3dsChunk c; 135 | 136 | c.chunk = CHK_N_CAMERA; 137 | lib3ds_chunk_write_start(&c, io); 138 | 139 | lib3ds_io_write_vector(io, camera->position); 140 | lib3ds_io_write_vector(io, camera->target); 141 | lib3ds_io_write_float(io, camera->roll); 142 | if (fabs(camera->fov) < LIB3DS_EPSILON) { 143 | lib3ds_io_write_float(io, 2400.0f / 45.0f); 144 | } else { 145 | lib3ds_io_write_float(io, 2400.0f / camera->fov); 146 | } 147 | 148 | if (camera->see_cone) { 149 | Lib3dsChunk c; 150 | c.chunk = CHK_CAM_SEE_CONE; 151 | c.size = 6; 152 | lib3ds_chunk_write(&c, io); 153 | } 154 | { 155 | Lib3dsChunk c; 156 | c.chunk = CHK_CAM_RANGES; 157 | c.size = 14; 158 | lib3ds_chunk_write(&c, io); 159 | lib3ds_io_write_float(io, camera->near_range); 160 | lib3ds_io_write_float(io, camera->far_range); 161 | } 162 | 163 | lib3ds_chunk_write_end(&c, io); 164 | } 165 | 166 | -------------------------------------------------------------------------------- /src/lib3ds_chunk.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 1996-2008 by Jan Eric Kyprianidis 3 | All rights reserved. 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published 7 | by the Free Software Foundation, either version 2.1 of the License, or 8 | (at your option) any later version. 9 | 10 | Thisprogram is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program; If not, see . 17 | */ 18 | #include "lib3ds_impl.h" 19 | 20 | 21 | /*#define LIB3DS_CHUNK_DEBUG*/ 22 | /*#define LIB3DS_CHUNK_WARNING*/ 23 | 24 | 25 | /*! 26 | * Reads a 3d-Studio chunk header from a little endian file stream. 27 | * 28 | * \param c The chunk to store the data. 29 | * \param io The file stream. 30 | * 31 | * \return True on success, False otherwise. 32 | */ 33 | void 34 | lib3ds_chunk_read(Lib3dsChunk *c, Lib3dsIo *io) { 35 | assert(c); 36 | assert(io); 37 | c->cur = lib3ds_io_tell(io); 38 | c->chunk = lib3ds_io_read_word(io); 39 | c->size = lib3ds_io_read_dword(io); 40 | c->end = c->cur + c->size; 41 | c->cur += 6; 42 | if (c->size < 6) { 43 | lib3ds_io_log(io, LIB3DS_LOG_ERROR, "Invalid chunk header."); 44 | } 45 | 46 | } 47 | 48 | 49 | void 50 | lib3ds_chunk_read_start(Lib3dsChunk *c, uint16_t chunk, Lib3dsIo *io) { 51 | assert(c); 52 | assert(io); 53 | lib3ds_chunk_read(c, io); 54 | if ((chunk != 0) && (c->chunk != chunk)) { 55 | lib3ds_io_log(io, LIB3DS_LOG_ERROR, "Unexpected chunk found."); 56 | } 57 | ((Lib3dsIoImpl*)io->impl)->log_indent++; 58 | } 59 | 60 | 61 | void 62 | lib3ds_chunk_read_tell(Lib3dsChunk *c, Lib3dsIo *io) { 63 | c->cur = lib3ds_io_tell(io); 64 | } 65 | 66 | 67 | uint16_t 68 | lib3ds_chunk_read_next(Lib3dsChunk *c, Lib3dsIo *io) { 69 | Lib3dsChunk d; 70 | 71 | if (c->cur >= c->end) { 72 | assert(c->cur == c->end); 73 | return 0; 74 | } 75 | 76 | lib3ds_io_seek(io, (long)c->cur, LIB3DS_SEEK_SET); 77 | d.chunk = lib3ds_io_read_word(io); 78 | d.size = lib3ds_io_read_dword(io); 79 | c->cur += d.size; 80 | 81 | if (io->log_func) { 82 | lib3ds_io_log(io, LIB3DS_LOG_INFO, "%s (0x%X) size=%lu", lib3ds_chunk_name(d.chunk), d.chunk, d.size); 83 | } 84 | 85 | return d.chunk; 86 | } 87 | 88 | 89 | void 90 | lib3ds_chunk_read_reset(Lib3dsChunk *c, Lib3dsIo *io) { 91 | lib3ds_io_seek(io, -6, LIB3DS_SEEK_CUR); 92 | } 93 | 94 | 95 | void 96 | lib3ds_chunk_read_end(Lib3dsChunk *c, Lib3dsIo *io) { 97 | ((Lib3dsIoImpl*)io->impl)->log_indent--; 98 | lib3ds_io_seek(io, c->end, LIB3DS_SEEK_SET); 99 | } 100 | 101 | 102 | /*! 103 | * Writes a 3d-Studio chunk header into a little endian file stream. 104 | * 105 | * \param c The chunk to be written. 106 | * \param io The file stream. 107 | * 108 | * \return True on success, False otherwise. 109 | */ 110 | void 111 | lib3ds_chunk_write(Lib3dsChunk *c, Lib3dsIo *io) { 112 | assert(c); 113 | lib3ds_io_write_word(io, c->chunk); 114 | lib3ds_io_write_dword(io, c->size); 115 | } 116 | 117 | 118 | void 119 | lib3ds_chunk_write_start(Lib3dsChunk *c, Lib3dsIo *io) { 120 | assert(c); 121 | c->size = 0; 122 | c->cur = lib3ds_io_tell(io); 123 | lib3ds_io_write_word(io, c->chunk); 124 | lib3ds_io_write_dword(io, c->size); 125 | } 126 | 127 | 128 | void 129 | lib3ds_chunk_write_end(Lib3dsChunk *c, Lib3dsIo *io) { 130 | assert(c); 131 | c->size = lib3ds_io_tell(io) - c->cur; 132 | lib3ds_io_seek(io, c->cur + 2, LIB3DS_SEEK_SET); 133 | lib3ds_io_write_dword(io, c->size); 134 | c->cur += c->size; 135 | lib3ds_io_seek(io, c->cur, LIB3DS_SEEK_SET); 136 | } 137 | 138 | 139 | void 140 | lib3ds_chunk_unknown(uint16_t chunk, Lib3dsIo *io) { 141 | if (io->log_func) { 142 | lib3ds_io_log(io, LIB3DS_LOG_WARN, "Unknown Chunk: %s (0x%X)", lib3ds_chunk_name(chunk), chunk); 143 | } 144 | } 145 | 146 | 147 | -------------------------------------------------------------------------------- /src/lib3ds_chunktable.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 1996-2008 by Jan Eric Kyprianidis 3 | All rights reserved. 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published 7 | by the Free Software Foundation, either version 2.1 of the License, or 8 | (at your option) any later version. 9 | 10 | Thisprogram is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program; If not, see . 17 | */ 18 | #include "lib3ds_impl.h" 19 | 20 | 21 | typedef struct Lib3dsChunkTable { 22 | uint32_t chunk; 23 | const char* name; 24 | } Lib3dsChunkTable; 25 | 26 | 27 | static Lib3dsChunkTable lib3ds_chunk_table[] = { 28 | {CHK_NULL_CHUNK, "NULL_CHUNK"}, 29 | {CHK_M3DMAGIC, "M3DMAGIC"}, 30 | {CHK_SMAGIC, "SMAGIC"}, 31 | {CHK_LMAGIC, "LMAGIC"}, 32 | {CHK_MLIBMAGIC, "MLIBMAGIC"}, 33 | {CHK_MATMAGIC, "MATMAGIC"}, 34 | {CHK_CMAGIC, "CMAGIC"}, 35 | {CHK_M3D_VERSION, "M3D_VERSION"}, 36 | {CHK_M3D_KFVERSION, "M3D_KFVERSION"}, 37 | {CHK_COLOR_F, "COLOR_F"}, 38 | {CHK_COLOR_24, "COLOR_24"}, 39 | {CHK_LIN_COLOR_24, "LIN_COLOR_24"}, 40 | {CHK_LIN_COLOR_F, "LIN_COLOR_F"}, 41 | {CHK_INT_PERCENTAGE, "INT_PERCENTAGE"}, 42 | {CHK_FLOAT_PERCENTAGE, "FLOAT_PERCENTAGE"}, 43 | {CHK_MDATA, "MDATA"}, 44 | {CHK_MESH_VERSION, "MESH_VERSION"}, 45 | {CHK_MASTER_SCALE, "MASTER_SCALE"}, 46 | {CHK_LO_SHADOW_BIAS, "LO_SHADOW_BIAS"}, 47 | {CHK_HI_SHADOW_BIAS, "HI_SHADOW_BIAS"}, 48 | {CHK_SHADOW_MAP_SIZE, "SHADOW_MAP_SIZE"}, 49 | {CHK_SHADOW_SAMPLES, "SHADOW_SAMPLES"}, 50 | {CHK_SHADOW_RANGE, "SHADOW_RANGE"}, 51 | {CHK_SHADOW_FILTER, "SHADOW_FILTER"}, 52 | {CHK_RAY_BIAS, "RAY_BIAS"}, 53 | {CHK_O_CONSTS, "O_CONSTS"}, 54 | {CHK_AMBIENT_LIGHT, "AMBIENT_LIGHT"}, 55 | {CHK_BIT_MAP, "BIT_MAP"}, 56 | {CHK_SOLID_BGND, "SOLID_BGND"}, 57 | {CHK_V_GRADIENT, "V_GRADIENT"}, 58 | {CHK_USE_BIT_MAP, "USE_BIT_MAP"}, 59 | {CHK_USE_SOLID_BGND, "USE_SOLID_BGND"}, 60 | {CHK_USE_V_GRADIENT, "USE_V_GRADIENT"}, 61 | {CHK_FOG, "FOG"}, 62 | {CHK_FOG_BGND, "FOG_BGND"}, 63 | {CHK_LAYER_FOG, "LAYER_FOG"}, 64 | {CHK_DISTANCE_CUE, "DISTANCE_CUE"}, 65 | {CHK_DCUE_BGND, "DCUE_BGND"}, 66 | {CHK_USE_FOG, "USE_FOG"}, 67 | {CHK_USE_LAYER_FOG, "USE_LAYER_FOG"}, 68 | {CHK_USE_DISTANCE_CUE, "USE_DISTANCE_CUE"}, 69 | {CHK_MAT_ENTRY, "MAT_ENTRY"}, 70 | {CHK_MAT_NAME, "MAT_NAME"}, 71 | {CHK_MAT_AMBIENT, "MAT_AMBIENT"}, 72 | {CHK_MAT_DIFFUSE, "MAT_DIFFUSE"}, 73 | {CHK_MAT_SPECULAR, "MAT_SPECULAR"}, 74 | {CHK_MAT_SHININESS, "MAT_SHININESS"}, 75 | {CHK_MAT_SHIN2PCT, "MAT_SHIN2PCT"}, 76 | {CHK_MAT_TRANSPARENCY, "MAT_TRANSPARENCY"}, 77 | {CHK_MAT_XPFALL, "MAT_XPFALL"}, 78 | {CHK_MAT_USE_XPFALL, "MAT_USE_XPFALL"}, 79 | {CHK_MAT_REFBLUR, "MAT_REFBLUR"}, 80 | {CHK_MAT_SHADING, "MAT_SHADING"}, 81 | {CHK_MAT_USE_REFBLUR, "MAT_USE_REFBLUR"}, 82 | {CHK_MAT_SELF_ILLUM, "MAT_SELF_ILLUM"}, 83 | {CHK_MAT_TWO_SIDE, "MAT_TWO_SIDE"}, 84 | {CHK_MAT_DECAL, "MAT_DECAL"}, 85 | {CHK_MAT_ADDITIVE, "MAT_ADDITIVE"}, 86 | {CHK_MAT_SELF_ILPCT, "MAT_SELF_ILPCT"}, 87 | {CHK_MAT_WIRE, "MAT_WIRE"}, 88 | {CHK_MAT_FACEMAP, "MAT_FACEMAP"}, 89 | {CHK_MAT_PHONGSOFT, "MAT_PHONGSOFT"}, 90 | {CHK_MAT_WIREABS, "MAT_WIREABS"}, 91 | {CHK_MAT_WIRE_SIZE, "MAT_WIRE_SIZE"}, 92 | {CHK_MAT_TEXMAP, "MAT_TEXMAP"}, 93 | {CHK_MAT_SXP_TEXT_DATA, "MAT_SXP_TEXT_DATA"}, 94 | {CHK_MAT_TEXMASK, "MAT_TEXMASK"}, 95 | {CHK_MAT_SXP_TEXTMASK_DATA, "MAT_SXP_TEXTMASK_DATA"}, 96 | {CHK_MAT_TEX2MAP, "MAT_TEX2MAP"}, 97 | {CHK_MAT_SXP_TEXT2_DATA, "MAT_SXP_TEXT2_DATA"}, 98 | {CHK_MAT_TEX2MASK, "MAT_TEX2MASK"}, 99 | {CHK_MAT_SXP_TEXT2MASK_DATA, "MAT_SXP_TEXT2MASK_DATA"}, 100 | {CHK_MAT_OPACMAP, "MAT_OPACMAP"}, 101 | {CHK_MAT_SXP_OPAC_DATA, "MAT_SXP_OPAC_DATA"}, 102 | {CHK_MAT_OPACMASK, "MAT_OPACMASK"}, 103 | {CHK_MAT_SXP_OPACMASK_DATA, "MAT_SXP_OPACMASK_DATA"}, 104 | {CHK_MAT_BUMPMAP, "MAT_BUMPMAP"}, 105 | {CHK_MAT_SXP_BUMP_DATA, "MAT_SXP_BUMP_DATA"}, 106 | {CHK_MAT_BUMPMASK, "MAT_BUMPMASK"}, 107 | {CHK_MAT_SXP_BUMPMASK_DATA, "MAT_SXP_BUMPMASK_DATA"}, 108 | {CHK_MAT_SPECMAP, "MAT_SPECMAP"}, 109 | {CHK_MAT_SXP_SPEC_DATA, "MAT_SXP_SPEC_DATA"}, 110 | {CHK_MAT_SPECMASK, "MAT_SPECMASK"}, 111 | {CHK_MAT_SXP_SPECMASK_DATA, "MAT_SXP_SPECMASK_DATA"}, 112 | {CHK_MAT_SHINMAP, "MAT_SHINMAP"}, 113 | {CHK_MAT_SXP_SHIN_DATA, "MAT_SXP_SHIN_DATA"}, 114 | {CHK_MAT_SHINMASK, "MAT_SHINMASK"}, 115 | {CHK_MAT_SXP_SHINMASK_DATA, "MAT_SXP_SHINMASK_DATA"}, 116 | {CHK_MAT_SELFIMAP, "MAT_SELFIMAP"}, 117 | {CHK_MAT_SXP_SELFI_DATA, "MAT_SXP_SELFI_DATA"}, 118 | {CHK_MAT_SELFIMASK, "MAT_SELFIMASK"}, 119 | {CHK_MAT_SXP_SELFIMASK_DATA, "MAT_SXP_SELFIMASK_DATA"}, 120 | {CHK_MAT_REFLMAP, "MAT_REFLMAP"}, 121 | {CHK_MAT_REFLMASK, "MAT_REFLMASK"}, 122 | {CHK_MAT_SXP_REFLMASK_DATA, "MAT_SXP_REFLMASK_DATA"}, 123 | {CHK_MAT_ACUBIC, "MAT_ACUBIC"}, 124 | {CHK_MAT_MAPNAME, "MAT_MAPNAME"}, 125 | {CHK_MAT_MAP_TILING, "MAT_MAP_TILING"}, 126 | {CHK_MAT_MAP_TEXBLUR, "MAT_MAP_TEXBLUR"}, 127 | {CHK_MAT_MAP_USCALE, "MAT_MAP_USCALE"}, 128 | {CHK_MAT_MAP_VSCALE, "MAT_MAP_VSCALE"}, 129 | {CHK_MAT_MAP_UOFFSET, "MAT_MAP_UOFFSET"}, 130 | {CHK_MAT_MAP_VOFFSET, "MAT_MAP_VOFFSET"}, 131 | {CHK_MAT_MAP_ANG, "MAT_MAP_ANG"}, 132 | {CHK_MAT_MAP_COL1, "MAT_MAP_COL1"}, 133 | {CHK_MAT_MAP_COL2, "MAT_MAP_COL2"}, 134 | {CHK_MAT_MAP_RCOL, "MAT_MAP_RCOL"}, 135 | {CHK_MAT_MAP_GCOL, "MAT_MAP_GCOL"}, 136 | {CHK_MAT_MAP_BCOL, "MAT_MAP_BCOL"}, 137 | {CHK_NAMED_OBJECT, "NAMED_OBJECT"}, 138 | {CHK_N_DIRECT_LIGHT, "N_DIRECT_LIGHT"}, 139 | {CHK_DL_OFF, "DL_OFF"}, 140 | {CHK_DL_OUTER_RANGE, "DL_OUTER_RANGE"}, 141 | {CHK_DL_INNER_RANGE, "DL_INNER_RANGE"}, 142 | {CHK_DL_MULTIPLIER, "DL_MULTIPLIER"}, 143 | {CHK_DL_EXCLUDE, "DL_EXCLUDE"}, 144 | {CHK_DL_ATTENUATE, "DL_ATTENUATE"}, 145 | {CHK_DL_SPOTLIGHT, "DL_SPOTLIGHT"}, 146 | {CHK_DL_SPOT_ROLL, "DL_SPOT_ROLL"}, 147 | {CHK_DL_SHADOWED, "DL_SHADOWED"}, 148 | {CHK_DL_LOCAL_SHADOW2, "DL_LOCAL_SHADOW2"}, 149 | {CHK_DL_SEE_CONE, "DL_SEE_CONE"}, 150 | {CHK_DL_SPOT_RECTANGULAR, "DL_SPOT_RECTANGULAR"}, 151 | {CHK_DL_SPOT_ASPECT, "DL_SPOT_ASPECT"}, 152 | {CHK_DL_SPOT_PROJECTOR, "DL_SPOT_PROJECTOR"}, 153 | {CHK_DL_SPOT_OVERSHOOT, "DL_SPOT_OVERSHOOT"}, 154 | {CHK_DL_RAY_BIAS, "DL_RAY_BIAS"}, 155 | {CHK_DL_RAYSHAD, "DL_RAYSHAD"}, 156 | {CHK_N_CAMERA, "N_CAMERA"}, 157 | {CHK_CAM_SEE_CONE, "CAM_SEE_CONE"}, 158 | {CHK_CAM_RANGES, "CAM_RANGES"}, 159 | {CHK_OBJ_HIDDEN, "OBJ_HIDDEN"}, 160 | {CHK_OBJ_VIS_LOFTER, "OBJ_VIS_LOFTER"}, 161 | {CHK_OBJ_DOESNT_CAST, "OBJ_DOESNT_CAST"}, 162 | {CHK_OBJ_DONT_RCVSHADOW, "OBJ_DONT_RCVSHADOW"}, 163 | {CHK_OBJ_MATTE, "OBJ_MATTE"}, 164 | {CHK_OBJ_FAST, "OBJ_FAST"}, 165 | {CHK_OBJ_PROCEDURAL, "OBJ_PROCEDURAL"}, 166 | {CHK_OBJ_FROZEN, "OBJ_FROZEN"}, 167 | {CHK_N_TRI_OBJECT, "N_TRI_OBJECT"}, 168 | {CHK_POINT_ARRAY, "POINT_ARRAY"}, 169 | {CHK_POINT_FLAG_ARRAY, "POINT_FLAG_ARRAY"}, 170 | {CHK_FACE_ARRAY, "FACE_ARRAY"}, 171 | {CHK_MSH_MAT_GROUP, "MSH_MAT_GROUP"}, 172 | {CHK_SMOOTH_GROUP, "SMOOTH_GROUP"}, 173 | {CHK_MSH_BOXMAP, "MSH_BOXMAP"}, 174 | {CHK_TEX_VERTS, "TEX_VERTS"}, 175 | {CHK_MESH_MATRIX, "MESH_MATRIX"}, 176 | {CHK_MESH_COLOR, "MESH_COLOR"}, 177 | {CHK_MESH_TEXTURE_INFO, "MESH_TEXTURE_INFO"}, 178 | {CHK_KFDATA, "KFDATA"}, 179 | {CHK_KFHDR, "KFHDR"}, 180 | {CHK_KFSEG, "KFSEG"}, 181 | {CHK_KFCURTIME, "KFCURTIME"}, 182 | {CHK_AMBIENT_NODE_TAG, "AMBIENT_NODE_TAG"}, 183 | {CHK_OBJECT_NODE_TAG, "OBJECT_NODE_TAG"}, 184 | {CHK_CAMERA_NODE_TAG, "CAMERA_NODE_TAG"}, 185 | {CHK_TARGET_NODE_TAG, "TARGET_NODE_TAG"}, 186 | {CHK_LIGHT_NODE_TAG, "LIGHT_NODE_TAG"}, 187 | {CHK_L_TARGET_NODE_TAG, "L_TARGET_NODE_TAG"}, 188 | {CHK_SPOTLIGHT_NODE_TAG, "SPOTLIGHT_NODE_TAG"}, 189 | {CHK_NODE_ID, "NODE_ID"}, 190 | {CHK_NODE_HDR, "NODE_HDR"}, 191 | {CHK_PIVOT, "PIVOT"}, 192 | {CHK_INSTANCE_NAME, "INSTANCE_NAME"}, 193 | {CHK_MORPH_SMOOTH, "MORPH_SMOOTH"}, 194 | {CHK_BOUNDBOX, "BOUNDBOX"}, 195 | {CHK_POS_TRACK_TAG, "POS_TRACK_TAG"}, 196 | {CHK_COL_TRACK_TAG, "COL_TRACK_TAG"}, 197 | {CHK_ROT_TRACK_TAG, "ROT_TRACK_TAG"}, 198 | {CHK_SCL_TRACK_TAG, "SCL_TRACK_TAG"}, 199 | {CHK_MORPH_TRACK_TAG, "MORPH_TRACK_TAG"}, 200 | {CHK_FOV_TRACK_TAG, "FOV_TRACK_TAG"}, 201 | {CHK_ROLL_TRACK_TAG, "ROLL_TRACK_TAG"}, 202 | {CHK_HOT_TRACK_TAG, "HOT_TRACK_TAG"}, 203 | {CHK_FALL_TRACK_TAG, "FALL_TRACK_TAG"}, 204 | {CHK_HIDE_TRACK_TAG, "HIDE_TRACK_TAG"}, 205 | {CHK_POLY_2D, "POLY_2D"}, 206 | {CHK_SHAPE_OK, "SHAPE_OK"}, 207 | {CHK_SHAPE_NOT_OK, "SHAPE_NOT_OK"}, 208 | {CHK_SHAPE_HOOK, "SHAPE_HOOK"}, 209 | {CHK_PATH_3D, "PATH_3D"}, 210 | {CHK_PATH_MATRIX, "PATH_MATRIX"}, 211 | {CHK_SHAPE_2D, "SHAPE_2D"}, 212 | {CHK_M_SCALE, "M_SCALE"}, 213 | {CHK_M_TWIST, "M_TWIST"}, 214 | {CHK_M_TEETER, "M_TEETER"}, 215 | {CHK_M_FIT, "M_FIT"}, 216 | {CHK_M_BEVEL, "M_BEVEL"}, 217 | {CHK_XZ_CURVE, "XZ_CURVE"}, 218 | {CHK_YZ_CURVE, "YZ_CURVE"}, 219 | {CHK_INTERPCT, "INTERPCT"}, 220 | {CHK_DEFORM_LIMIT, "DEFORM_LIMIT"}, 221 | {CHK_USE_CONTOUR, "USE_CONTOUR"}, 222 | {CHK_USE_TWEEN, "USE_TWEEN"}, 223 | {CHK_USE_SCALE, "USE_SCALE"}, 224 | {CHK_USE_TWIST, "USE_TWIST"}, 225 | {CHK_USE_TEETER, "USE_TEETER"}, 226 | {CHK_USE_FIT, "USE_FIT"}, 227 | {CHK_USE_BEVEL, "USE_BEVEL"}, 228 | {CHK_DEFAULT_VIEW, "DEFAULT_VIEW"}, 229 | {CHK_VIEW_TOP, "VIEW_TOP"}, 230 | {CHK_VIEW_BOTTOM, "VIEW_BOTTOM"}, 231 | {CHK_VIEW_LEFT, "VIEW_LEFT"}, 232 | {CHK_VIEW_RIGHT, "VIEW_RIGHT"}, 233 | {CHK_VIEW_FRONT, "VIEW_FRONT"}, 234 | {CHK_VIEW_BACK, "VIEW_BACK"}, 235 | {CHK_VIEW_USER, "VIEW_USER"}, 236 | {CHK_VIEW_CAMERA, "VIEW_CAMERA"}, 237 | {CHK_VIEW_WINDOW, "VIEW_WINDOW"}, 238 | {CHK_VIEWPORT_LAYOUT_OLD, "VIEWPORT_LAYOUT_OLD"}, 239 | {CHK_VIEWPORT_DATA_OLD, "VIEWPORT_DATA_OLD"}, 240 | {CHK_VIEWPORT_LAYOUT, "VIEWPORT_LAYOUT"}, 241 | {CHK_VIEWPORT_DATA, "VIEWPORT_DATA"}, 242 | {CHK_VIEWPORT_DATA_3, "VIEWPORT_DATA_3"}, 243 | {CHK_VIEWPORT_SIZE, "VIEWPORT_SIZE"}, 244 | {CHK_NETWORK_VIEW, "NETWORK_VIEW"}, 245 | {0, 0} 246 | }; 247 | 248 | 249 | const char* 250 | lib3ds_chunk_name(uint16_t chunk) { 251 | Lib3dsChunkTable *p; 252 | 253 | for (p = lib3ds_chunk_table; p->name != 0; ++p) { 254 | if (p->chunk == chunk) { 255 | return(p->name); 256 | } 257 | } 258 | return("***UNKNOWN***"); 259 | } 260 | -------------------------------------------------------------------------------- /src/lib3ds_impl.h: -------------------------------------------------------------------------------- 1 | /* -*- c -*- */ 2 | #ifndef INCLUDED_LIB3DS_IMPL_H 3 | #define INCLUDED_LIB3DS_IMPL_H 4 | /* 5 | Copyright (C) 1996-2008 by Jan Eric Kyprianidis 6 | All rights reserved. 7 | 8 | This program is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU Lesser General Public License as published 10 | by the Free Software Foundation, either version 2.1 of the License, or 11 | (at your option) any later version. 12 | 13 | Thisprogram is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public License 19 | along with this program; If not, see . 20 | */ 21 | 22 | /** @file lib3ds_impl.h 23 | Private header file used internally by lib3ds */ 24 | 25 | #include "lib3ds.h" 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | #ifdef _MSC_VER 37 | #pragma warning ( disable : 4996 ) 38 | #pragma warning ( disable : 4100 ) 39 | #endif 40 | 41 | #ifndef _MSC_VER 42 | #include 43 | #else 44 | typedef unsigned __int8 uint8_t; 45 | typedef unsigned __int16 uint16_t; 46 | typedef unsigned __int32 uint32_t; 47 | typedef signed __int8 int8_t; 48 | typedef signed __int16 int16_t; 49 | typedef signed __int32 int32_t; 50 | #endif 51 | 52 | #ifndef TRUE 53 | #define TRUE 1 54 | #endif 55 | #ifndef FALSE 56 | #define FALSE 0 57 | #endif 58 | 59 | #define LIB3DS_EPSILON (1e-5) 60 | #define LIB3DS_PI 3.14159265358979323846 61 | #define LIB3DS_TWOPI (2.0*LIB3DS_PI) 62 | #define LIB3DS_HALFPI (LIB3DS_PI/2.0) 63 | #define LIB3DS_RAD_TO_DEG(x) ((180.0/LIB3DS_PI)*(x)) 64 | #define LIB3DS_DEG_TO_RAD(x) ((LIB3DS_PI/180.0)*(x)) 65 | 66 | #ifdef __cplusplus 67 | extern "C" { 68 | #endif 69 | 70 | typedef enum Lib3dsChunks { 71 | CHK_NULL_CHUNK =0x0000, 72 | CHK_M3DMAGIC =0x4D4D, /*3DS file*/ 73 | CHK_SMAGIC =0x2D2D, 74 | CHK_LMAGIC =0x2D3D, 75 | CHK_MLIBMAGIC =0x3DAA, /*MLI file*/ 76 | CHK_MATMAGIC =0x3DFF, 77 | CHK_CMAGIC =0xC23D, /*PRJ file*/ 78 | CHK_M3D_VERSION =0x0002, 79 | CHK_M3D_KFVERSION =0x0005, 80 | 81 | CHK_COLOR_F =0x0010, 82 | CHK_COLOR_24 =0x0011, 83 | CHK_LIN_COLOR_24 =0x0012, 84 | CHK_LIN_COLOR_F =0x0013, 85 | CHK_INT_PERCENTAGE =0x0030, 86 | CHK_FLOAT_PERCENTAGE =0x0031, 87 | 88 | CHK_MDATA =0x3D3D, 89 | CHK_MESH_VERSION =0x3D3E, 90 | CHK_MASTER_SCALE =0x0100, 91 | CHK_LO_SHADOW_BIAS =0x1400, 92 | CHK_HI_SHADOW_BIAS =0x1410, 93 | CHK_SHADOW_MAP_SIZE =0x1420, 94 | CHK_SHADOW_SAMPLES =0x1430, 95 | CHK_SHADOW_RANGE =0x1440, 96 | CHK_SHADOW_FILTER =0x1450, 97 | CHK_RAY_BIAS =0x1460, 98 | CHK_O_CONSTS =0x1500, 99 | CHK_AMBIENT_LIGHT =0x2100, 100 | CHK_BIT_MAP =0x1100, 101 | CHK_SOLID_BGND =0x1200, 102 | CHK_V_GRADIENT =0x1300, 103 | CHK_USE_BIT_MAP =0x1101, 104 | CHK_USE_SOLID_BGND =0x1201, 105 | CHK_USE_V_GRADIENT =0x1301, 106 | CHK_FOG =0x2200, 107 | CHK_FOG_BGND =0x2210, 108 | CHK_LAYER_FOG =0x2302, 109 | CHK_DISTANCE_CUE =0x2300, 110 | CHK_DCUE_BGND =0x2310, 111 | CHK_USE_FOG =0x2201, 112 | CHK_USE_LAYER_FOG =0x2303, 113 | CHK_USE_DISTANCE_CUE =0x2301, 114 | 115 | CHK_MAT_ENTRY =0xAFFF, 116 | CHK_MAT_NAME =0xA000, 117 | CHK_MAT_AMBIENT =0xA010, 118 | CHK_MAT_DIFFUSE =0xA020, 119 | CHK_MAT_SPECULAR =0xA030, 120 | CHK_MAT_SHININESS =0xA040, 121 | CHK_MAT_SHIN2PCT =0xA041, 122 | CHK_MAT_TRANSPARENCY =0xA050, 123 | CHK_MAT_XPFALL =0xA052, 124 | CHK_MAT_USE_XPFALL =0xA240, 125 | CHK_MAT_REFBLUR =0xA053, 126 | CHK_MAT_SHADING =0xA100, 127 | CHK_MAT_USE_REFBLUR =0xA250, 128 | CHK_MAT_SELF_ILLUM =0xA080, 129 | CHK_MAT_TWO_SIDE =0xA081, 130 | CHK_MAT_DECAL =0xA082, 131 | CHK_MAT_ADDITIVE =0xA083, 132 | CHK_MAT_SELF_ILPCT =0xA084, 133 | CHK_MAT_WIRE =0xA085, 134 | CHK_MAT_FACEMAP =0xA088, 135 | CHK_MAT_PHONGSOFT =0xA08C, 136 | CHK_MAT_WIREABS =0xA08E, 137 | CHK_MAT_WIRE_SIZE =0xA087, 138 | CHK_MAT_TEXMAP =0xA200, 139 | CHK_MAT_SXP_TEXT_DATA =0xA320, 140 | CHK_MAT_TEXMASK =0xA33E, 141 | CHK_MAT_SXP_TEXTMASK_DATA =0xA32A, 142 | CHK_MAT_TEX2MAP =0xA33A, 143 | CHK_MAT_SXP_TEXT2_DATA =0xA321, 144 | CHK_MAT_TEX2MASK =0xA340, 145 | CHK_MAT_SXP_TEXT2MASK_DATA =0xA32C, 146 | CHK_MAT_OPACMAP =0xA210, 147 | CHK_MAT_SXP_OPAC_DATA =0xA322, 148 | CHK_MAT_OPACMASK =0xA342, 149 | CHK_MAT_SXP_OPACMASK_DATA =0xA32E, 150 | CHK_MAT_BUMPMAP =0xA230, 151 | CHK_MAT_SXP_BUMP_DATA =0xA324, 152 | CHK_MAT_BUMPMASK =0xA344, 153 | CHK_MAT_SXP_BUMPMASK_DATA =0xA330, 154 | CHK_MAT_SPECMAP =0xA204, 155 | CHK_MAT_SXP_SPEC_DATA =0xA325, 156 | CHK_MAT_SPECMASK =0xA348, 157 | CHK_MAT_SXP_SPECMASK_DATA =0xA332, 158 | CHK_MAT_SHINMAP =0xA33C, 159 | CHK_MAT_SXP_SHIN_DATA =0xA326, 160 | CHK_MAT_SHINMASK =0xA346, 161 | CHK_MAT_SXP_SHINMASK_DATA =0xA334, 162 | CHK_MAT_SELFIMAP =0xA33D, 163 | CHK_MAT_SXP_SELFI_DATA =0xA328, 164 | CHK_MAT_SELFIMASK =0xA34A, 165 | CHK_MAT_SXP_SELFIMASK_DATA =0xA336, 166 | CHK_MAT_REFLMAP =0xA220, 167 | CHK_MAT_REFLMASK =0xA34C, 168 | CHK_MAT_SXP_REFLMASK_DATA =0xA338, 169 | CHK_MAT_ACUBIC =0xA310, 170 | CHK_MAT_MAPNAME =0xA300, 171 | CHK_MAT_MAP_TILING =0xA351, 172 | CHK_MAT_MAP_TEXBLUR =0xA353, 173 | CHK_MAT_MAP_USCALE =0xA354, 174 | CHK_MAT_MAP_VSCALE =0xA356, 175 | CHK_MAT_MAP_UOFFSET =0xA358, 176 | CHK_MAT_MAP_VOFFSET =0xA35A, 177 | CHK_MAT_MAP_ANG =0xA35C, 178 | CHK_MAT_MAP_COL1 =0xA360, 179 | CHK_MAT_MAP_COL2 =0xA362, 180 | CHK_MAT_MAP_RCOL =0xA364, 181 | CHK_MAT_MAP_GCOL =0xA366, 182 | CHK_MAT_MAP_BCOL =0xA368, 183 | 184 | CHK_NAMED_OBJECT =0x4000, 185 | CHK_N_DIRECT_LIGHT =0x4600, 186 | CHK_DL_OFF =0x4620, 187 | CHK_DL_OUTER_RANGE =0x465A, 188 | CHK_DL_INNER_RANGE =0x4659, 189 | CHK_DL_MULTIPLIER =0x465B, 190 | CHK_DL_EXCLUDE =0x4654, 191 | CHK_DL_ATTENUATE =0x4625, 192 | CHK_DL_SPOTLIGHT =0x4610, 193 | CHK_DL_SPOT_ROLL =0x4656, 194 | CHK_DL_SHADOWED =0x4630, 195 | CHK_DL_LOCAL_SHADOW2 =0x4641, 196 | CHK_DL_SEE_CONE =0x4650, 197 | CHK_DL_SPOT_RECTANGULAR =0x4651, 198 | CHK_DL_SPOT_ASPECT =0x4657, 199 | CHK_DL_SPOT_PROJECTOR =0x4653, 200 | CHK_DL_SPOT_OVERSHOOT =0x4652, 201 | CHK_DL_RAY_BIAS =0x4658, 202 | CHK_DL_RAYSHAD =0x4627, 203 | CHK_N_CAMERA =0x4700, 204 | CHK_CAM_SEE_CONE =0x4710, 205 | CHK_CAM_RANGES =0x4720, 206 | CHK_OBJ_HIDDEN =0x4010, 207 | CHK_OBJ_VIS_LOFTER =0x4011, 208 | CHK_OBJ_DOESNT_CAST =0x4012, 209 | CHK_OBJ_DONT_RCVSHADOW =0x4017, 210 | CHK_OBJ_MATTE =0x4013, 211 | CHK_OBJ_FAST =0x4014, 212 | CHK_OBJ_PROCEDURAL =0x4015, 213 | CHK_OBJ_FROZEN =0x4016, 214 | CHK_N_TRI_OBJECT =0x4100, 215 | CHK_POINT_ARRAY =0x4110, 216 | CHK_POINT_FLAG_ARRAY =0x4111, 217 | CHK_FACE_ARRAY =0x4120, 218 | CHK_MSH_MAT_GROUP =0x4130, 219 | CHK_SMOOTH_GROUP =0x4150, 220 | CHK_MSH_BOXMAP =0x4190, 221 | CHK_TEX_VERTS =0x4140, 222 | CHK_MESH_MATRIX =0x4160, 223 | CHK_MESH_COLOR =0x4165, 224 | CHK_MESH_TEXTURE_INFO =0x4170, 225 | 226 | CHK_KFDATA =0xB000, 227 | CHK_KFHDR =0xB00A, 228 | CHK_KFSEG =0xB008, 229 | CHK_KFCURTIME =0xB009, 230 | CHK_AMBIENT_NODE_TAG =0xB001, 231 | CHK_OBJECT_NODE_TAG =0xB002, 232 | CHK_CAMERA_NODE_TAG =0xB003, 233 | CHK_TARGET_NODE_TAG =0xB004, 234 | CHK_LIGHT_NODE_TAG =0xB005, 235 | CHK_L_TARGET_NODE_TAG =0xB006, 236 | CHK_SPOTLIGHT_NODE_TAG =0xB007, 237 | CHK_NODE_ID =0xB030, 238 | CHK_NODE_HDR =0xB010, 239 | CHK_PIVOT =0xB013, 240 | CHK_INSTANCE_NAME =0xB011, 241 | CHK_MORPH_SMOOTH =0xB015, 242 | CHK_BOUNDBOX =0xB014, 243 | CHK_POS_TRACK_TAG =0xB020, 244 | CHK_COL_TRACK_TAG =0xB025, 245 | CHK_ROT_TRACK_TAG =0xB021, 246 | CHK_SCL_TRACK_TAG =0xB022, 247 | CHK_MORPH_TRACK_TAG =0xB026, 248 | CHK_FOV_TRACK_TAG =0xB023, 249 | CHK_ROLL_TRACK_TAG =0xB024, 250 | CHK_HOT_TRACK_TAG =0xB027, 251 | CHK_FALL_TRACK_TAG =0xB028, 252 | CHK_HIDE_TRACK_TAG =0xB029, 253 | 254 | CHK_POLY_2D = 0x5000, 255 | CHK_SHAPE_OK = 0x5010, 256 | CHK_SHAPE_NOT_OK = 0x5011, 257 | CHK_SHAPE_HOOK = 0x5020, 258 | CHK_PATH_3D = 0x6000, 259 | CHK_PATH_MATRIX = 0x6005, 260 | CHK_SHAPE_2D = 0x6010, 261 | CHK_M_SCALE = 0x6020, 262 | CHK_M_TWIST = 0x6030, 263 | CHK_M_TEETER = 0x6040, 264 | CHK_M_FIT = 0x6050, 265 | CHK_M_BEVEL = 0x6060, 266 | CHK_XZ_CURVE = 0x6070, 267 | CHK_YZ_CURVE = 0x6080, 268 | CHK_INTERPCT = 0x6090, 269 | CHK_DEFORM_LIMIT = 0x60A0, 270 | 271 | CHK_USE_CONTOUR = 0x6100, 272 | CHK_USE_TWEEN = 0x6110, 273 | CHK_USE_SCALE = 0x6120, 274 | CHK_USE_TWIST = 0x6130, 275 | CHK_USE_TEETER = 0x6140, 276 | CHK_USE_FIT = 0x6150, 277 | CHK_USE_BEVEL = 0x6160, 278 | 279 | CHK_DEFAULT_VIEW = 0x3000, 280 | CHK_VIEW_TOP = 0x3010, 281 | CHK_VIEW_BOTTOM = 0x3020, 282 | CHK_VIEW_LEFT = 0x3030, 283 | CHK_VIEW_RIGHT = 0x3040, 284 | CHK_VIEW_FRONT = 0x3050, 285 | CHK_VIEW_BACK = 0x3060, 286 | CHK_VIEW_USER = 0x3070, 287 | CHK_VIEW_CAMERA = 0x3080, 288 | CHK_VIEW_WINDOW = 0x3090, 289 | 290 | CHK_VIEWPORT_LAYOUT_OLD = 0x7000, 291 | CHK_VIEWPORT_DATA_OLD = 0x7010, 292 | CHK_VIEWPORT_LAYOUT = 0x7001, 293 | CHK_VIEWPORT_DATA = 0x7011, 294 | CHK_VIEWPORT_DATA_3 = 0x7012, 295 | CHK_VIEWPORT_SIZE = 0x7020, 296 | CHK_NETWORK_VIEW = 0x7030 297 | } Lib3dsChunks; 298 | 299 | typedef struct Lib3dsChunk { 300 | uint16_t chunk; 301 | uint32_t size; 302 | uint32_t end; 303 | uint32_t cur; 304 | } Lib3dsChunk; 305 | 306 | extern void lib3ds_chunk_read(Lib3dsChunk *c, Lib3dsIo *io); 307 | extern void lib3ds_chunk_read_start(Lib3dsChunk *c, uint16_t chunk, Lib3dsIo *io); 308 | extern void lib3ds_chunk_read_tell(Lib3dsChunk *c, Lib3dsIo *io); 309 | extern uint16_t lib3ds_chunk_read_next(Lib3dsChunk *c, Lib3dsIo *io); 310 | extern void lib3ds_chunk_read_reset(Lib3dsChunk *c, Lib3dsIo *io); 311 | extern void lib3ds_chunk_read_end(Lib3dsChunk *c, Lib3dsIo *io); 312 | extern void lib3ds_chunk_write(Lib3dsChunk *c, Lib3dsIo *io); 313 | extern void lib3ds_chunk_write_start(Lib3dsChunk *c, Lib3dsIo *io); 314 | extern void lib3ds_chunk_write_end(Lib3dsChunk *c, Lib3dsIo *io); 315 | extern const char* lib3ds_chunk_name(uint16_t chunk); 316 | extern void lib3ds_chunk_unknown(uint16_t chunk, Lib3dsIo *io); 317 | 318 | typedef struct Lib3dsIoImpl { 319 | jmp_buf jmpbuf; 320 | int log_indent; 321 | void *tmp_mem; 322 | Lib3dsNode *tmp_node; 323 | } Lib3dsIoImpl; 324 | 325 | extern void lib3ds_io_setup(Lib3dsIo *io); 326 | extern void lib3ds_io_cleanup(Lib3dsIo *io); 327 | 328 | extern long lib3ds_io_seek(Lib3dsIo *io, long offset, Lib3dsIoSeek origin); 329 | extern long lib3ds_io_tell(Lib3dsIo *io); 330 | extern size_t lib3ds_io_read(Lib3dsIo *io, void *buffer, size_t size); 331 | extern size_t lib3ds_io_write(Lib3dsIo *io, const void *buffer, size_t size); 332 | extern void lib3ds_io_log(Lib3dsIo *io, Lib3dsLogLevel level, const char *format, ...); 333 | extern void lib3ds_io_log_indent(Lib3dsIo *io, int indent); 334 | extern void lib3ds_io_read_error(Lib3dsIo *io); 335 | extern void lib3ds_io_write_error(Lib3dsIo *io); 336 | 337 | extern uint8_t lib3ds_io_read_byte(Lib3dsIo *io); 338 | extern uint16_t lib3ds_io_read_word(Lib3dsIo *io); 339 | extern uint32_t lib3ds_io_read_dword(Lib3dsIo *io); 340 | extern int8_t lib3ds_io_read_intb(Lib3dsIo *io); 341 | extern int16_t lib3ds_io_read_intw(Lib3dsIo *io); 342 | extern int32_t lib3ds_io_read_intd(Lib3dsIo *io); 343 | extern float lib3ds_io_read_float(Lib3dsIo *io); 344 | extern void lib3ds_io_read_vector(Lib3dsIo *io, float v[3]); 345 | extern void lib3ds_io_read_rgb(Lib3dsIo *io, float rgb[3]); 346 | extern void lib3ds_io_read_string(Lib3dsIo *io, char *s, int buflen); 347 | 348 | extern void lib3ds_io_write_byte(Lib3dsIo *io, uint8_t b); 349 | extern void lib3ds_io_write_word(Lib3dsIo *io, uint16_t w); 350 | extern void lib3ds_io_write_dword(Lib3dsIo *io, uint32_t d); 351 | extern void lib3ds_io_write_intb(Lib3dsIo *io, int8_t b); 352 | extern void lib3ds_io_write_intw(Lib3dsIo *io, int16_t w); 353 | extern void lib3ds_io_write_intd(Lib3dsIo *io, int32_t d); 354 | extern void lib3ds_io_write_float(Lib3dsIo *io, float l); 355 | extern void lib3ds_io_write_vector(Lib3dsIo *io, float v[3]); 356 | extern void lib3ds_io_write_rgb(Lib3dsIo *io, float rgb[3]); 357 | extern void lib3ds_io_write_string(Lib3dsIo *io, const char *s); 358 | 359 | extern void lib3ds_atmosphere_read(Lib3dsAtmosphere *atmosphere, Lib3dsIo *io); 360 | extern void lib3ds_atmosphere_write(Lib3dsAtmosphere *atmosphere, Lib3dsIo *io); 361 | extern void lib3ds_background_read(Lib3dsBackground *background, Lib3dsIo *io); 362 | extern void lib3ds_background_write(Lib3dsBackground *background, Lib3dsIo *io); 363 | extern void lib3ds_shadow_read(Lib3dsShadow *shadow, Lib3dsIo *io); 364 | extern void lib3ds_shadow_write(Lib3dsShadow *shadow, Lib3dsIo *io); 365 | extern void lib3ds_viewport_read(Lib3dsViewport *viewport, Lib3dsIo *io); 366 | extern void lib3ds_viewport_write(Lib3dsViewport *viewport, Lib3dsIo *io); 367 | extern void lib3ds_material_read(Lib3dsMaterial *material, Lib3dsIo *io); 368 | extern void lib3ds_material_write(Lib3dsMaterial *material, Lib3dsIo *io); 369 | extern void lib3ds_camera_read(Lib3dsCamera *camera, Lib3dsIo *io); 370 | extern void lib3ds_camera_write(Lib3dsCamera *camera, Lib3dsIo *io); 371 | extern void lib3ds_light_read(Lib3dsLight *light, Lib3dsIo *io); 372 | extern void lib3ds_light_write(Lib3dsLight *light, Lib3dsIo *io); 373 | extern void lib3ds_mesh_read(Lib3dsFile *file, Lib3dsMesh *mesh, Lib3dsIo *io); 374 | extern void lib3ds_mesh_write(Lib3dsFile *file, Lib3dsMesh *mesh, Lib3dsIo *io); 375 | extern void lib3ds_track_read(Lib3dsTrack *track, Lib3dsIo *io); 376 | extern void lib3ds_track_write(Lib3dsTrack *track, Lib3dsIo *io); 377 | extern void lib3ds_node_read(Lib3dsNode *node, Lib3dsIo *io); 378 | extern void lib3ds_node_write(Lib3dsNode *node, uint16_t node_id, uint16_t parent_id, Lib3dsIo *io); 379 | 380 | typedef void (*Lib3dsFreeFunc)(void *ptr); 381 | 382 | extern void* lib3ds_util_realloc_array(void *ptr, int old_size, int new_size, int element_size); 383 | extern void lib3ds_util_reserve_array(void ***ptr, int *n, int *size, int new_size, int force, Lib3dsFreeFunc free_func); 384 | extern void lib3ds_util_insert_array(void ***ptr, int *n, int *size, void *element, int index); 385 | extern void lib3ds_util_remove_array(void ***ptr, int *n, int index, Lib3dsFreeFunc free_func); 386 | 387 | #ifdef __cplusplus 388 | } 389 | #endif 390 | #endif 391 | 392 | 393 | -------------------------------------------------------------------------------- /src/lib3ds_io.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 1996-2008 by Jan Eric Kyprianidis 3 | All rights reserved. 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published 7 | by the Free Software Foundation, either version 2.1 of the License, or 8 | (at your option) any later version. 9 | 10 | Thisprogram is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program; If not, see . 17 | */ 18 | #include "lib3ds_impl.h" 19 | 20 | 21 | typedef union { 22 | uint32_t dword_value; 23 | float float_value; 24 | } Lib3dsDwordFloat; 25 | 26 | 27 | void 28 | lib3ds_io_setup(Lib3dsIo *io) { 29 | assert(io); 30 | io->impl = calloc(sizeof(Lib3dsIoImpl), 1); 31 | } 32 | 33 | 34 | void 35 | lib3ds_io_cleanup(Lib3dsIo *io) { 36 | Lib3dsIoImpl *impl; 37 | assert(io); 38 | impl = (Lib3dsIoImpl*)io->impl; 39 | if (impl->tmp_mem) { 40 | free(impl->tmp_mem); 41 | impl->tmp_mem = NULL; 42 | } 43 | if (impl->tmp_node) { 44 | lib3ds_node_free(impl->tmp_node); 45 | impl->tmp_node = NULL; 46 | } 47 | free(impl); 48 | } 49 | 50 | 51 | long 52 | lib3ds_io_seek(Lib3dsIo *io, long offset, Lib3dsIoSeek origin) { 53 | assert(io); 54 | if (!io || !io->seek_func) { 55 | return 0; 56 | } 57 | return (*io->seek_func)(io->self, offset, origin); 58 | } 59 | 60 | 61 | long 62 | lib3ds_io_tell(Lib3dsIo *io) { 63 | assert(io); 64 | if (!io || !io->tell_func) { 65 | return 0; 66 | } 67 | return (*io->tell_func)(io->self); 68 | } 69 | 70 | 71 | size_t 72 | lib3ds_io_read(Lib3dsIo *io, void *buffer, size_t size) { 73 | assert(io); 74 | if (!io || !io->read_func) { 75 | return 0; 76 | } 77 | return (*io->read_func)(io->self, buffer, size); 78 | } 79 | 80 | 81 | size_t 82 | lib3ds_io_write(Lib3dsIo *io, const void *buffer, size_t size) { 83 | assert(io); 84 | if (!io || !io->write_func) { 85 | return 0; 86 | } 87 | return (*io->write_func)(io->self, buffer, size); 88 | } 89 | 90 | 91 | static void 92 | lib3ds_io_log_str(Lib3dsIo *io, Lib3dsLogLevel level, const char *str) { 93 | if (!io || !io->log_func) 94 | return; 95 | (*io->log_func)(io->self, level, ((Lib3dsIoImpl*)io->impl)->log_indent, str); 96 | } 97 | 98 | 99 | void 100 | lib3ds_io_log(Lib3dsIo *io, Lib3dsLogLevel level, const char *format, ...) { 101 | va_list args; 102 | /* FIXME */ char str[1024]; 103 | 104 | assert(io); 105 | if (!io || !io->log_func) 106 | return; 107 | 108 | va_start(args, format); 109 | /* FIXME: */ vsprintf(str, format, args); 110 | lib3ds_io_log_str(io, level, str); 111 | 112 | if (level == LIB3DS_LOG_ERROR) { 113 | longjmp(((Lib3dsIoImpl*)io->impl)->jmpbuf, 1); 114 | } 115 | } 116 | 117 | 118 | void 119 | lib3ds_io_log_indent(Lib3dsIo *io, int indent) { 120 | assert(io); 121 | if (!io) 122 | return; 123 | ((Lib3dsIoImpl*)io->impl)->log_indent += indent; 124 | } 125 | 126 | 127 | void 128 | lib3ds_io_read_error(Lib3dsIo *io) { 129 | lib3ds_io_log(io, LIB3DS_LOG_ERROR, "Reading from input stream failed."); 130 | } 131 | 132 | 133 | void 134 | lib3ds_io_write_error(Lib3dsIo *io) { 135 | lib3ds_io_log(io, LIB3DS_LOG_ERROR, "Writing to output stream failed."); 136 | } 137 | 138 | 139 | /*! 140 | * Read a byte from a file stream. 141 | */ 142 | uint8_t 143 | lib3ds_io_read_byte(Lib3dsIo *io) { 144 | uint8_t b; 145 | 146 | assert(io); 147 | lib3ds_io_read(io, &b, 1); 148 | return(b); 149 | } 150 | 151 | 152 | /** 153 | * Read a word from a file stream in little endian format. 154 | */ 155 | uint16_t 156 | lib3ds_io_read_word(Lib3dsIo *io) { 157 | uint8_t b[2]; 158 | uint16_t w; 159 | 160 | assert(io); 161 | lib3ds_io_read(io, b, 2); 162 | w = ((uint16_t)b[1] << 8) | 163 | ((uint16_t)b[0]); 164 | return(w); 165 | } 166 | 167 | 168 | /*! 169 | * Read a dword from file a stream in little endian format. 170 | */ 171 | uint32_t 172 | lib3ds_io_read_dword(Lib3dsIo *io) { 173 | uint8_t b[4]; 174 | uint32_t d; 175 | 176 | assert(io); 177 | lib3ds_io_read(io, b, 4); 178 | d = ((uint32_t)b[3] << 24) | 179 | ((uint32_t)b[2] << 16) | 180 | ((uint32_t)b[1] << 8) | 181 | ((uint32_t)b[0]); 182 | return(d); 183 | } 184 | 185 | 186 | /*! 187 | * Read a signed byte from a file stream. 188 | */ 189 | int8_t 190 | lib3ds_io_read_intb(Lib3dsIo *io) { 191 | int8_t b; 192 | 193 | assert(io); 194 | lib3ds_io_read(io, &b, 1); 195 | return(b); 196 | } 197 | 198 | 199 | /*! 200 | * Read a signed word from a file stream in little endian format. 201 | */ 202 | int16_t 203 | lib3ds_io_read_intw(Lib3dsIo *io) { 204 | uint8_t b[2]; 205 | uint16_t w; 206 | 207 | assert(io); 208 | lib3ds_io_read(io, b, 2); 209 | w = ((uint16_t)b[1] << 8) | 210 | ((uint16_t)b[0]); 211 | return((int16_t)w); 212 | } 213 | 214 | 215 | /*! 216 | * Read a signed dword a from file stream in little endian format. 217 | */ 218 | int32_t 219 | lib3ds_io_read_intd(Lib3dsIo *io) { 220 | uint8_t b[4]; 221 | uint32_t d; 222 | 223 | assert(io); 224 | lib3ds_io_read(io, b, 4); 225 | d = ((uint32_t)b[3] << 24) | 226 | ((uint32_t)b[2] << 16) | 227 | ((uint32_t)b[1] << 8) | 228 | ((uint32_t)b[0]); 229 | return((int32_t)d); 230 | } 231 | 232 | 233 | /*! 234 | * Read a float from a file stream in little endian format. 235 | */ 236 | float 237 | lib3ds_io_read_float(Lib3dsIo *io) { 238 | uint8_t b[4]; 239 | Lib3dsDwordFloat d; 240 | 241 | assert(io); 242 | lib3ds_io_read(io, b, 4); 243 | d.dword_value = ((uint32_t)b[3] << 24) | 244 | ((uint32_t)b[2] << 16) | 245 | ((uint32_t)b[1] << 8) | 246 | ((uint32_t)b[0]); 247 | return d.float_value; 248 | } 249 | 250 | 251 | /*! 252 | * Read a vector from a file stream in little endian format. 253 | * 254 | * \param io IO input handle. 255 | * \param v The vector to store the data. 256 | */ 257 | void 258 | lib3ds_io_read_vector(Lib3dsIo *io, float v[3]) { 259 | assert(io); 260 | v[0] = lib3ds_io_read_float(io); 261 | v[1] = lib3ds_io_read_float(io); 262 | v[2] = lib3ds_io_read_float(io); 263 | } 264 | 265 | 266 | void 267 | lib3ds_io_read_rgb(Lib3dsIo *io, float rgb[3]) { 268 | assert(io); 269 | rgb[0] = lib3ds_io_read_float(io); 270 | rgb[1] = lib3ds_io_read_float(io); 271 | rgb[2] = lib3ds_io_read_float(io); 272 | } 273 | 274 | 275 | /*! 276 | * Read a zero-terminated string from a file stream. 277 | * 278 | * \param io IO input handle. 279 | * \param s The buffer to store the read string. 280 | * \param buflen Buffer length. 281 | * 282 | * \return True on success, False otherwise. 283 | */ 284 | void 285 | lib3ds_io_read_string(Lib3dsIo *io, char *s, int buflen) { 286 | char c; 287 | int k = 0; 288 | 289 | assert(io); 290 | for (;;) { 291 | if (lib3ds_io_read(io, &c, 1) != 1) { 292 | lib3ds_io_read_error(io); 293 | } 294 | *s++ = c; 295 | if (!c) { 296 | break; 297 | } 298 | ++k; 299 | if (k >= buflen) { 300 | lib3ds_io_log(io, LIB3DS_LOG_ERROR, "Invalid string in input stream."); 301 | } 302 | } 303 | } 304 | 305 | 306 | /*! 307 | * Writes a byte into a file stream. 308 | */ 309 | void 310 | lib3ds_io_write_byte(Lib3dsIo *io, uint8_t b) { 311 | assert(io); 312 | if (lib3ds_io_write(io, &b, 1) != 1) { 313 | lib3ds_io_write_error(io); 314 | } 315 | } 316 | 317 | 318 | /*! 319 | * Writes a word into a little endian file stream. 320 | */ 321 | void 322 | lib3ds_io_write_word(Lib3dsIo *io, uint16_t w) { 323 | uint8_t b[2]; 324 | 325 | assert(io); 326 | b[1] = ((uint16_t)w & 0xFF00) >> 8; 327 | b[0] = ((uint16_t)w & 0x00FF); 328 | if (lib3ds_io_write(io, b, 2) != 2) { 329 | lib3ds_io_write_error(io); 330 | } 331 | } 332 | 333 | 334 | /*! 335 | * Writes a dword into a little endian file stream. 336 | */ 337 | void 338 | lib3ds_io_write_dword(Lib3dsIo *io, uint32_t d) { 339 | uint8_t b[4]; 340 | 341 | assert(io); 342 | b[3] = (uint8_t)(((uint32_t)d & 0xFF000000) >> 24); 343 | b[2] = (uint8_t)(((uint32_t)d & 0x00FF0000) >> 16); 344 | b[1] = (uint8_t)(((uint32_t)d & 0x0000FF00) >> 8); 345 | b[0] = (uint8_t)(((uint32_t)d & 0x000000FF)); 346 | if (lib3ds_io_write(io, b, 4) != 4) { 347 | lib3ds_io_write_error(io); 348 | } 349 | } 350 | 351 | 352 | /*! 353 | * Writes a signed byte in a file stream. 354 | */ 355 | void 356 | lib3ds_io_write_intb(Lib3dsIo *io, int8_t b) { 357 | assert(io); 358 | if (lib3ds_io_write(io, &b, 1) != 1) { 359 | lib3ds_io_write_error(io); 360 | } 361 | } 362 | 363 | 364 | /*! 365 | * Writes a signed word into a little endian file stream. 366 | */ 367 | void 368 | lib3ds_io_write_intw(Lib3dsIo *io, int16_t w) { 369 | uint8_t b[2]; 370 | 371 | assert(io); 372 | b[1] = ((uint16_t)w & 0xFF00) >> 8; 373 | b[0] = ((uint16_t)w & 0x00FF); 374 | if (lib3ds_io_write(io, b, 2) != 2) { 375 | lib3ds_io_write_error(io); 376 | } 377 | } 378 | 379 | 380 | /*! 381 | * Writes a signed dword into a little endian file stream. 382 | */ 383 | void 384 | lib3ds_io_write_intd(Lib3dsIo *io, int32_t d) { 385 | uint8_t b[4]; 386 | 387 | assert(io); 388 | b[3] = (uint8_t)(((uint32_t)d & 0xFF000000) >> 24); 389 | b[2] = (uint8_t)(((uint32_t)d & 0x00FF0000) >> 16); 390 | b[1] = (uint8_t)(((uint32_t)d & 0x0000FF00) >> 8); 391 | b[0] = (uint8_t)(((uint32_t)d & 0x000000FF)); 392 | if (lib3ds_io_write(io, b, 4) != 4) { 393 | lib3ds_io_write_error(io); 394 | } 395 | } 396 | 397 | 398 | /*! 399 | * Writes a float into a little endian file stream. 400 | */ 401 | void 402 | lib3ds_io_write_float(Lib3dsIo *io, float l) { 403 | uint8_t b[4]; 404 | Lib3dsDwordFloat d; 405 | 406 | assert(io); 407 | d.float_value = l; 408 | b[3] = (uint8_t)(((uint32_t)d.dword_value & 0xFF000000) >> 24); 409 | b[2] = (uint8_t)(((uint32_t)d.dword_value & 0x00FF0000) >> 16); 410 | b[1] = (uint8_t)(((uint32_t)d.dword_value & 0x0000FF00) >> 8); 411 | b[0] = (uint8_t)(((uint32_t)d.dword_value & 0x000000FF)); 412 | if (lib3ds_io_write(io, b, 4) != 4) { 413 | lib3ds_io_write_error(io); 414 | } 415 | } 416 | 417 | 418 | /*! 419 | * Writes a vector into a file stream in little endian format. 420 | */ 421 | void 422 | lib3ds_io_write_vector(Lib3dsIo *io, float v[3]) { 423 | int i; 424 | for (i = 0; i < 3; ++i) { 425 | lib3ds_io_write_float(io, v[i]); 426 | } 427 | } 428 | 429 | 430 | void 431 | lib3ds_io_write_rgb(Lib3dsIo *io, float rgb[3]) { 432 | int i; 433 | for (i = 0; i < 3; ++i) { 434 | lib3ds_io_write_float(io, rgb[i]); 435 | } 436 | } 437 | 438 | 439 | /*! 440 | * Writes a zero-terminated string into a file stream. 441 | */ 442 | void 443 | lib3ds_io_write_string(Lib3dsIo *io, const char *s) { 444 | size_t len; 445 | assert(io && s); 446 | len = strlen(s); 447 | if (lib3ds_io_write(io, s, len + 1) != len +1) { 448 | lib3ds_io_write_error(io); 449 | } 450 | } 451 | -------------------------------------------------------------------------------- /src/lib3ds_light.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 1996-2008 by Jan Eric Kyprianidis 3 | All rights reserved. 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published 7 | by the Free Software Foundation, either version 2.1 of the License, or 8 | (at your option) any later version. 9 | 10 | Thisprogram is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program; If not, see . 17 | */ 18 | #include "lib3ds_impl.h" 19 | 20 | 21 | Lib3dsLight* 22 | lib3ds_light_new(const char *name) { 23 | Lib3dsLight *light; 24 | 25 | assert(name); 26 | assert(strlen(name) < 64); 27 | 28 | light = (Lib3dsLight*)calloc(sizeof(Lib3dsLight), 1); 29 | if (!light) { 30 | return(0); 31 | } 32 | strcpy(light->name, name); 33 | return(light); 34 | } 35 | 36 | 37 | void 38 | lib3ds_light_free(Lib3dsLight *light) { 39 | memset(light, 0, sizeof(Lib3dsLight)); 40 | free(light); 41 | } 42 | 43 | 44 | static void 45 | spotlight_read(Lib3dsLight *light, Lib3dsIo *io) { 46 | Lib3dsChunk c; 47 | uint16_t chunk; 48 | int i; 49 | 50 | lib3ds_chunk_read_start(&c, CHK_DL_SPOTLIGHT, io); 51 | 52 | light->spot_light = TRUE; 53 | for (i = 0; i < 3; ++i) { 54 | light->target[i] = lib3ds_io_read_float(io); 55 | } 56 | light->hotspot = lib3ds_io_read_float(io); 57 | light->falloff = lib3ds_io_read_float(io); 58 | lib3ds_chunk_read_tell(&c, io); 59 | 60 | while ((chunk = lib3ds_chunk_read_next(&c, io)) != 0) { 61 | switch (chunk) { 62 | case CHK_DL_SPOT_ROLL: 63 | light->roll = lib3ds_io_read_float(io); 64 | break; 65 | 66 | case CHK_DL_SHADOWED: { 67 | light->shadowed = TRUE; 68 | break; 69 | } 70 | 71 | case CHK_DL_LOCAL_SHADOW2: { 72 | light->shadow_bias = lib3ds_io_read_float(io); 73 | light->shadow_filter = lib3ds_io_read_float(io); 74 | light->shadow_size = lib3ds_io_read_intw(io); 75 | break; 76 | } 77 | 78 | case CHK_DL_SEE_CONE: { 79 | light->see_cone = TRUE; 80 | break; 81 | } 82 | 83 | case CHK_DL_SPOT_RECTANGULAR: { 84 | light->rectangular_spot = TRUE; 85 | break; 86 | } 87 | 88 | case CHK_DL_SPOT_ASPECT: { 89 | light->spot_aspect = lib3ds_io_read_float(io); 90 | break; 91 | } 92 | 93 | case CHK_DL_SPOT_PROJECTOR: { 94 | light->use_projector = TRUE; 95 | lib3ds_io_read_string(io, light->projector, 64); 96 | break; 97 | } 98 | 99 | case CHK_DL_SPOT_OVERSHOOT: { 100 | light->spot_overshoot = TRUE; 101 | break; 102 | } 103 | 104 | case CHK_DL_RAY_BIAS: { 105 | light->ray_bias = lib3ds_io_read_float(io); 106 | break; 107 | } 108 | 109 | case CHK_DL_RAYSHAD: { 110 | light->ray_shadows = TRUE; 111 | break; 112 | } 113 | 114 | default: 115 | lib3ds_chunk_unknown(chunk, io); 116 | } 117 | } 118 | 119 | lib3ds_chunk_read_end(&c, io); 120 | } 121 | 122 | 123 | void 124 | lib3ds_light_read(Lib3dsLight *light, Lib3dsIo *io) { 125 | Lib3dsChunk c; 126 | uint16_t chunk; 127 | 128 | lib3ds_chunk_read_start(&c, CHK_N_DIRECT_LIGHT, io); 129 | 130 | { 131 | int i; 132 | for (i = 0; i < 3; ++i) { 133 | light->position[i] = lib3ds_io_read_float(io); 134 | } 135 | } 136 | lib3ds_chunk_read_tell(&c, io); 137 | 138 | while ((chunk = lib3ds_chunk_read_next(&c, io)) != 0) { 139 | switch (chunk) { 140 | case CHK_COLOR_F: { 141 | int i; 142 | for (i = 0; i < 3; ++i) { 143 | light->color[i] = lib3ds_io_read_float(io); 144 | } 145 | break; 146 | } 147 | 148 | case CHK_DL_OFF: 149 | light->off = TRUE; 150 | break; 151 | 152 | case CHK_DL_OUTER_RANGE: 153 | light->outer_range = lib3ds_io_read_float(io); 154 | break; 155 | 156 | case CHK_DL_INNER_RANGE: 157 | light->inner_range = lib3ds_io_read_float(io); 158 | break; 159 | 160 | case CHK_DL_MULTIPLIER: 161 | light->multiplier = lib3ds_io_read_float(io); 162 | break; 163 | 164 | case CHK_DL_EXCLUDE: { 165 | /* FIXME: */ 166 | lib3ds_chunk_unknown(chunk, io); 167 | break; 168 | } 169 | 170 | case CHK_DL_ATTENUATE: 171 | light->attenuation = lib3ds_io_read_float(io); 172 | break; 173 | 174 | case CHK_DL_SPOTLIGHT: { 175 | lib3ds_chunk_read_reset(&c, io); 176 | spotlight_read(light, io); 177 | break; 178 | } 179 | 180 | default: 181 | lib3ds_chunk_unknown(chunk, io); 182 | } 183 | } 184 | 185 | lib3ds_chunk_read_end(&c, io); 186 | } 187 | 188 | 189 | void 190 | lib3ds_light_write(Lib3dsLight *light, Lib3dsIo *io) { 191 | Lib3dsChunk c; 192 | 193 | c.chunk = CHK_N_DIRECT_LIGHT; 194 | lib3ds_chunk_write_start(&c, io); 195 | 196 | lib3ds_io_write_vector(io, light->position); 197 | { /*---- LIB3DS_COLOR_F ----*/ 198 | Lib3dsChunk c; 199 | c.chunk = CHK_COLOR_F; 200 | c.size = 18; 201 | lib3ds_chunk_write(&c, io); 202 | lib3ds_io_write_rgb(io, light->color); 203 | } 204 | if (light->off) { /*---- LIB3DS_DL_OFF ----*/ 205 | Lib3dsChunk c; 206 | c.chunk = CHK_DL_OFF; 207 | c.size = 6; 208 | lib3ds_chunk_write(&c, io); 209 | } 210 | { /*---- LIB3DS_DL_OUTER_RANGE ----*/ 211 | Lib3dsChunk c; 212 | c.chunk = CHK_DL_OUTER_RANGE; 213 | c.size = 10; 214 | lib3ds_chunk_write(&c, io); 215 | lib3ds_io_write_float(io, light->outer_range); 216 | } 217 | { /*---- LIB3DS_DL_INNER_RANGE ----*/ 218 | Lib3dsChunk c; 219 | c.chunk = CHK_DL_INNER_RANGE; 220 | c.size = 10; 221 | lib3ds_chunk_write(&c, io); 222 | lib3ds_io_write_float(io, light->inner_range); 223 | } 224 | { /*---- LIB3DS_DL_MULTIPLIER ----*/ 225 | Lib3dsChunk c; 226 | c.chunk = CHK_DL_MULTIPLIER; 227 | c.size = 10; 228 | lib3ds_chunk_write(&c, io); 229 | lib3ds_io_write_float(io, light->multiplier); 230 | } 231 | if (light->attenuation) { /*---- LIB3DS_DL_ATTENUATE ----*/ 232 | Lib3dsChunk c; 233 | c.chunk = CHK_DL_ATTENUATE; 234 | c.size = 6; 235 | lib3ds_chunk_write(&c, io); 236 | } 237 | 238 | if (light->spot_light) { 239 | Lib3dsChunk c; 240 | 241 | c.chunk = CHK_DL_SPOTLIGHT; 242 | lib3ds_chunk_write_start(&c, io); 243 | 244 | lib3ds_io_write_vector(io, light->target); 245 | lib3ds_io_write_float(io, light->hotspot); 246 | lib3ds_io_write_float(io, light->falloff); 247 | 248 | { /*---- LIB3DS_DL_SPOT_ROLL ----*/ 249 | Lib3dsChunk c; 250 | c.chunk = CHK_DL_SPOT_ROLL; 251 | c.size = 10; 252 | lib3ds_chunk_write(&c, io); 253 | lib3ds_io_write_float(io, light->roll); 254 | } 255 | if (light->shadowed) { /*---- LIB3DS_DL_SHADOWED ----*/ 256 | Lib3dsChunk c; 257 | c.chunk = CHK_DL_SHADOWED; 258 | c.size = 6; 259 | lib3ds_chunk_write(&c, io); 260 | } 261 | if ((fabs(light->shadow_bias) > LIB3DS_EPSILON) || 262 | (fabs(light->shadow_filter) > LIB3DS_EPSILON) || 263 | (light->shadow_size != 0)) { /*---- LIB3DS_DL_LOCAL_SHADOW2 ----*/ 264 | Lib3dsChunk c; 265 | c.chunk = CHK_DL_LOCAL_SHADOW2; 266 | c.size = 16; 267 | lib3ds_chunk_write(&c, io); 268 | lib3ds_io_write_float(io, light->shadow_bias); 269 | lib3ds_io_write_float(io, light->shadow_filter); 270 | lib3ds_io_write_intw(io, (int16_t)light->shadow_size); 271 | } 272 | if (light->see_cone) { /*---- LIB3DS_DL_SEE_CONE ----*/ 273 | Lib3dsChunk c; 274 | c.chunk = CHK_DL_SEE_CONE; 275 | c.size = 6; 276 | lib3ds_chunk_write(&c, io); 277 | } 278 | if (light->rectangular_spot) { /*---- LIB3DS_DL_SPOT_RECTANGULAR ----*/ 279 | Lib3dsChunk c; 280 | c.chunk = CHK_DL_SPOT_RECTANGULAR; 281 | c.size = 6; 282 | lib3ds_chunk_write(&c, io); 283 | } 284 | if (fabs(light->spot_aspect) > LIB3DS_EPSILON) { /*---- LIB3DS_DL_SPOT_ASPECT ----*/ 285 | Lib3dsChunk c; 286 | c.chunk = CHK_DL_SPOT_ASPECT; 287 | c.size = 10; 288 | lib3ds_chunk_write(&c, io); 289 | lib3ds_io_write_float(io, light->spot_aspect); 290 | } 291 | if (light->use_projector) { /*---- LIB3DS_DL_SPOT_PROJECTOR ----*/ 292 | Lib3dsChunk c; 293 | c.chunk = CHK_DL_SPOT_PROJECTOR; 294 | c.size = 10; 295 | lib3ds_chunk_write(&c, io); 296 | lib3ds_io_write_string(io, light->projector); 297 | } 298 | if (light->spot_overshoot) { /*---- LIB3DS_DL_SPOT_OVERSHOOT ----*/ 299 | Lib3dsChunk c; 300 | c.chunk = CHK_DL_SPOT_OVERSHOOT; 301 | c.size = 6; 302 | lib3ds_chunk_write(&c, io); 303 | } 304 | if (fabs(light->ray_bias) > LIB3DS_EPSILON) { /*---- LIB3DS_DL_RAY_BIAS ----*/ 305 | Lib3dsChunk c; 306 | c.chunk = CHK_DL_RAY_BIAS; 307 | c.size = 10; 308 | lib3ds_chunk_write(&c, io); 309 | lib3ds_io_write_float(io, light->ray_bias); 310 | } 311 | if (light->ray_shadows) { /*---- LIB3DS_DL_RAYSHAD ----*/ 312 | Lib3dsChunk c; 313 | c.chunk = CHK_DL_RAYSHAD; 314 | c.size = 6; 315 | lib3ds_chunk_write(&c, io); 316 | } 317 | lib3ds_chunk_write_end(&c, io); 318 | } 319 | 320 | lib3ds_chunk_write_end(&c, io); 321 | } 322 | 323 | 324 | -------------------------------------------------------------------------------- /src/lib3ds_math.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 1996-2008 by Jan Eric Kyprianidis 3 | All rights reserved. 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published 7 | by the Free Software Foundation, either version 2.1 of the License, or 8 | (at your option) any later version. 9 | 10 | Thisprogram is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program; If not, see . 17 | */ 18 | #include "lib3ds_impl.h" 19 | 20 | 21 | float 22 | lib3ds_math_ease(float fp, float fc, float fn, float ease_from, float ease_to) { 23 | double s, step; 24 | double tofrom; 25 | double a; 26 | 27 | s = step = (float)(fc - fp) / (fn - fp); 28 | tofrom = ease_to + ease_from; 29 | if (tofrom != 0.0) { 30 | if (tofrom > 1.0) { 31 | ease_to = (float)(ease_to / tofrom); 32 | ease_from = (float)(ease_from / tofrom); 33 | } 34 | a = 1.0 / (2.0 - (ease_to + ease_from)); 35 | 36 | if (step < ease_from) s = a / ease_from * step * step; 37 | else { 38 | if ((1.0 - ease_to) <= step) { 39 | step = 1.0 - step; 40 | s = 1.0 - a / ease_to * step * step; 41 | } else { 42 | s = ((2.0 * step) - ease_from) * a; 43 | } 44 | } 45 | } 46 | return((float)s); 47 | } 48 | 49 | 50 | void 51 | lib3ds_math_cubic_interp(float *v, float *a, float *p, float *q, float *b, int n, float t) { 52 | float x, y, z, w; 53 | int i; 54 | 55 | x = 2 * t * t * t - 3 * t * t + 1; 56 | y = -2 * t * t * t + 3 * t * t; 57 | z = t * t * t - 2 * t * t + t; 58 | w = t * t * t - t * t; 59 | for (i = 0; i < n; ++i) { 60 | v[i] = x * a[i] + y * b[i] + z * p[i] + w * q[i]; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/lib3ds_matrix.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 1996-2008 by Jan Eric Kyprianidis 3 | All rights reserved. 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published 7 | by the Free Software Foundation, either version 2.1 of the License, or 8 | (at your option) any later version. 9 | 10 | Thisprogram is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program; If not, see . 17 | */ 18 | 19 | /** @file lib3ds_matrix.c 20 | Matrix mathematics implementation */ 21 | 22 | #include "lib3ds_impl.h" 23 | 24 | 25 | /*! 26 | * Clear a matrix to all zeros. 27 | * 28 | * \param m Matrix to be cleared. 29 | */ 30 | void 31 | lib3ds_matrix_zero(float m[4][4]) { 32 | int i, j; 33 | 34 | for (i = 0; i < 4; i++) { 35 | for (j = 0; j < 4; j++) m[i][j] = 0.0f; 36 | } 37 | } 38 | 39 | 40 | /*! 41 | * Set a matrix to identity. 42 | * 43 | * \param m Matrix to be set. 44 | */ 45 | void 46 | lib3ds_matrix_identity(float m[4][4]) { 47 | int i, j; 48 | 49 | for (i = 0; i < 4; i++) { 50 | for (j = 0; j < 4; j++) m[i][j] = 0.0; 51 | } 52 | for (i = 0; i < 4; i++) m[i][i] = 1.0; 53 | } 54 | 55 | 56 | /*! 57 | * Copy a matrix. 58 | */ 59 | void 60 | lib3ds_matrix_copy(float dest[4][4], float src[4][4]) { 61 | memcpy(dest, src, 16 * sizeof(float)); 62 | } 63 | 64 | 65 | /*! 66 | * Negate a matrix -- all elements negated. 67 | */ 68 | void 69 | lib3ds_matrix_neg(float m[4][4]) { 70 | int i, j; 71 | 72 | for (j = 0; j < 4; j++) { 73 | for (i = 0; i < 4; i++) { 74 | m[j][i] = -m[j][i]; 75 | } 76 | } 77 | } 78 | 79 | 80 | /*! 81 | * Transpose a matrix in place. 82 | */ 83 | void 84 | lib3ds_matrix_transpose(float m[4][4]) { 85 | int i, j; 86 | float swp; 87 | 88 | for (j = 0; j < 4; j++) { 89 | for (i = j + 1; i < 4; i++) { 90 | swp = m[j][i]; 91 | m[j][i] = m[i][j]; 92 | m[i][j] = swp; 93 | } 94 | } 95 | } 96 | 97 | 98 | /*! 99 | * Add two matrices. 100 | */ 101 | void 102 | lib3ds_matrix_add(float m[4][4], float a[4][4], float b[4][4]) { 103 | int i, j; 104 | 105 | for (j = 0; j < 4; j++) { 106 | for (i = 0; i < 4; i++) { 107 | m[j][i] = a[j][i] + b[j][i]; 108 | } 109 | } 110 | } 111 | 112 | 113 | /*! 114 | * Subtract two matrices. 115 | * 116 | * \param m Result. 117 | * \param a Addend. 118 | * \param b Minuend. 119 | */ 120 | void 121 | lib3ds_matrix_sub(float m[4][4], float a[4][4], float b[4][4]) { 122 | int i, j; 123 | 124 | for (j = 0; j < 4; j++) { 125 | for (i = 0; i < 4; i++) { 126 | m[j][i] = a[j][i] - b[j][i]; 127 | } 128 | } 129 | } 130 | 131 | 132 | /*! 133 | * Multiplies a matrix by a second one (m = m * n). 134 | */ 135 | void 136 | lib3ds_matrix_mult(float m[4][4], float a[4][4], float b[4][4]) { 137 | float tmp[4][4]; 138 | int i, j, k; 139 | float ab; 140 | 141 | memcpy(tmp, a, 16 * sizeof(float)); 142 | for (j = 0; j < 4; j++) { 143 | for (i = 0; i < 4; i++) { 144 | ab = 0.0f; 145 | for (k = 0; k < 4; k++) ab += tmp[k][i] * b[j][k]; 146 | m[j][i] = ab; 147 | } 148 | } 149 | } 150 | 151 | 152 | /*! 153 | * Multiply a matrix by a scalar. 154 | * 155 | * \param m Matrix to be set. 156 | * \param k Scalar. 157 | */ 158 | void 159 | lib3ds_matrix_scalar(float m[4][4], float k) { 160 | int i, j; 161 | 162 | for (j = 0; j < 4; j++) { 163 | for (i = 0; i < 4; i++) { 164 | m[j][i] *= k; 165 | } 166 | } 167 | } 168 | 169 | 170 | static float 171 | det2x2( 172 | float a, float b, 173 | float c, float d) { 174 | return((a)*(d) - (b)*(c)); 175 | } 176 | 177 | 178 | static float 179 | det3x3( 180 | float a1, float a2, float a3, 181 | float b1, float b2, float b3, 182 | float c1, float c2, float c3) { 183 | return( 184 | a1*det2x2(b2, b3, c2, c3) - 185 | b1*det2x2(a2, a3, c2, c3) + 186 | c1*det2x2(a2, a3, b2, b3) 187 | ); 188 | } 189 | 190 | 191 | /*! 192 | * Find determinant of a matrix. 193 | */ 194 | float 195 | lib3ds_matrix_det(float m[4][4]) { 196 | float a1, a2, a3, a4, b1, b2, b3, b4, c1, c2, c3, c4, d1, d2, d3, d4; 197 | 198 | a1 = m[0][0]; 199 | b1 = m[1][0]; 200 | c1 = m[2][0]; 201 | d1 = m[3][0]; 202 | a2 = m[0][1]; 203 | b2 = m[1][1]; 204 | c2 = m[2][1]; 205 | d2 = m[3][1]; 206 | a3 = m[0][2]; 207 | b3 = m[1][2]; 208 | c3 = m[2][2]; 209 | d3 = m[3][2]; 210 | a4 = m[0][3]; 211 | b4 = m[1][3]; 212 | c4 = m[2][3]; 213 | d4 = m[3][3]; 214 | return( 215 | a1 * det3x3(b2, b3, b4, c2, c3, c4, d2, d3, d4) - 216 | b1 * det3x3(a2, a3, a4, c2, c3, c4, d2, d3, d4) + 217 | c1 * det3x3(a2, a3, a4, b2, b3, b4, d2, d3, d4) - 218 | d1 * det3x3(a2, a3, a4, b2, b3, b4, c2, c3, c4) 219 | ); 220 | } 221 | 222 | 223 | /*! 224 | * Invert a matrix in place. 225 | * 226 | * \param m Matrix to invert. 227 | * 228 | * \return LIB3DS_TRUE on success, LIB3DS_FALSE on failure. 229 | * 230 | * GGemsII, K.Wu, Fast Matrix Inversion 231 | */ 232 | int 233 | lib3ds_matrix_inv(float m[4][4]) { 234 | int i, j, k; 235 | int pvt_i[4], pvt_j[4]; /* Locations of pivot elements */ 236 | float pvt_val; /* Value of current pivot element */ 237 | float hold; /* Temporary storage */ 238 | float determinat; 239 | 240 | determinat = 1.0f; 241 | for (k = 0; k < 4; k++) { 242 | /* Locate k'th pivot element */ 243 | pvt_val = m[k][k]; /* Initialize for search */ 244 | pvt_i[k] = k; 245 | pvt_j[k] = k; 246 | for (i = k; i < 4; i++) { 247 | for (j = k; j < 4; j++) { 248 | if (fabs(m[i][j]) > fabs(pvt_val)) { 249 | pvt_i[k] = i; 250 | pvt_j[k] = j; 251 | pvt_val = m[i][j]; 252 | } 253 | } 254 | } 255 | 256 | /* Product of pivots, gives determinant when finished */ 257 | determinat *= pvt_val; 258 | if (fabs(determinat) < LIB3DS_EPSILON) { 259 | return(FALSE); /* Matrix is singular (zero determinant) */ 260 | } 261 | 262 | /* "Interchange" rows (with sign change stuff) */ 263 | i = pvt_i[k]; 264 | if (i != k) { /* If rows are different */ 265 | for (j = 0; j < 4; j++) { 266 | hold = -m[k][j]; 267 | m[k][j] = m[i][j]; 268 | m[i][j] = hold; 269 | } 270 | } 271 | 272 | /* "Interchange" columns */ 273 | j = pvt_j[k]; 274 | if (j != k) { /* If columns are different */ 275 | for (i = 0; i < 4; i++) { 276 | hold = -m[i][k]; 277 | m[i][k] = m[i][j]; 278 | m[i][j] = hold; 279 | } 280 | } 281 | 282 | /* Divide column by minus pivot value */ 283 | for (i = 0; i < 4; i++) { 284 | if (i != k) m[i][k] /= (-pvt_val) ; 285 | } 286 | 287 | /* Reduce the matrix */ 288 | for (i = 0; i < 4; i++) { 289 | hold = m[i][k]; 290 | for (j = 0; j < 4; j++) { 291 | if (i != k && j != k) m[i][j] += hold * m[k][j]; 292 | } 293 | } 294 | 295 | /* Divide row by pivot */ 296 | for (j = 0; j < 4; j++) { 297 | if (j != k) m[k][j] /= pvt_val; 298 | } 299 | 300 | /* Replace pivot by reciprocal (at last we can touch it). */ 301 | m[k][k] = 1.0f / pvt_val; 302 | } 303 | 304 | /* That was most of the work, one final pass of row/column interchange */ 305 | /* to finish */ 306 | for (k = 4 - 2; k >= 0; k--) { /* Don't need to work with 1 by 1 corner*/ 307 | i = pvt_j[k]; /* Rows to swap correspond to pivot COLUMN */ 308 | if (i != k) { /* If rows are different */ 309 | for (j = 0; j < 4; j++) { 310 | hold = m[k][j]; 311 | m[k][j] = -m[i][j]; 312 | m[i][j] = hold; 313 | } 314 | } 315 | 316 | j = pvt_i[k]; /* Columns to swap correspond to pivot ROW */ 317 | if (j != k) /* If columns are different */ 318 | for (i = 0; i < 4; i++) { 319 | hold = m[i][k]; 320 | m[i][k] = -m[i][j]; 321 | m[i][j] = hold; 322 | } 323 | } 324 | return(TRUE); 325 | } 326 | 327 | 328 | /*! 329 | * Apply a translation to a matrix. 330 | */ 331 | void 332 | lib3ds_matrix_translate(float m[4][4], float x, float y, float z) { 333 | int i; 334 | 335 | for (i = 0; i < 3; i++) { 336 | m[3][i] += m[0][i] * x + m[1][i] * y + m[2][i] * z; 337 | } 338 | } 339 | 340 | 341 | /*! 342 | * Apply scale factors to a matrix. 343 | */ 344 | void 345 | lib3ds_matrix_scale(float m[4][4], float x, float y, float z) { 346 | int i; 347 | 348 | for (i = 0; i < 4; i++) { 349 | m[0][i] *= x; 350 | m[1][i] *= y; 351 | m[2][i] *= z; 352 | } 353 | } 354 | 355 | 356 | /*! 357 | * Apply a rotation about an arbitrary axis to a matrix. 358 | */ 359 | void 360 | lib3ds_matrix_rotate_quat(float m[4][4], float q[4]) { 361 | float s, xs, ys, zs, wx, wy, wz, xx, xy, xz, yy, yz, zz, l; 362 | float R[4][4]; 363 | 364 | l = q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]; 365 | if (fabs(l) < LIB3DS_EPSILON) { 366 | s = 1.0f; 367 | } else { 368 | s = 2.0f / l; 369 | } 370 | 371 | xs = q[0] * s; 372 | ys = q[1] * s; 373 | zs = q[2] * s; 374 | wx = q[3] * xs; 375 | wy = q[3] * ys; 376 | wz = q[3] * zs; 377 | xx = q[0] * xs; 378 | xy = q[0] * ys; 379 | xz = q[0] * zs; 380 | yy = q[1] * ys; 381 | yz = q[1] * zs; 382 | zz = q[2] * zs; 383 | 384 | R[0][0] = 1.0f - (yy + zz); 385 | R[1][0] = xy - wz; 386 | R[2][0] = xz + wy; 387 | R[0][1] = xy + wz; 388 | R[1][1] = 1.0f - (xx + zz); 389 | R[2][1] = yz - wx; 390 | R[0][2] = xz - wy; 391 | R[1][2] = yz + wx; 392 | R[2][2] = 1.0f - (xx + yy); 393 | R[3][0] = R[3][1] = R[3][2] = R[0][3] = R[1][3] = R[2][3] = 0.0f; 394 | R[3][3] = 1.0f; 395 | 396 | lib3ds_matrix_mult(m, m, R); 397 | } 398 | 399 | 400 | /*! 401 | * Apply a rotation about an arbitrary axis to a matrix. 402 | */ 403 | void 404 | lib3ds_matrix_rotate(float m[4][4], float angle, float ax, float ay, float az) { 405 | float q[4]; 406 | float axis[3]; 407 | 408 | lib3ds_vector_make(axis, ax, ay, az); 409 | lib3ds_quat_axis_angle(q, axis, angle); 410 | lib3ds_matrix_rotate_quat(m, q); 411 | } 412 | 413 | 414 | /*! 415 | * Compute a camera matrix based on position, target and roll. 416 | * 417 | * Generates a translate/rotate matrix that maps world coordinates 418 | * to camera coordinates. Resulting matrix does not include perspective 419 | * transform. 420 | * 421 | * \param matrix Destination matrix. 422 | * \param pos Camera position 423 | * \param tgt Camera target 424 | * \param roll Roll angle 425 | */ 426 | void 427 | lib3ds_matrix_camera(float matrix[4][4], float pos[3], float tgt[3], float roll) { 428 | float M[4][4]; 429 | float x[3], y[3], z[3]; 430 | 431 | lib3ds_vector_sub(y, tgt, pos); 432 | lib3ds_vector_normalize(y); 433 | 434 | if (y[0] != 0. || y[1] != 0) { 435 | z[0] = 0; 436 | z[1] = 0; 437 | z[2] = 1.0; 438 | } else { /* Special case: looking straight up or down z axis */ 439 | z[0] = -1.0; 440 | z[1] = 0; 441 | z[2] = 0; 442 | } 443 | 444 | lib3ds_vector_cross(x, y, z); 445 | lib3ds_vector_cross(z, x, y); 446 | lib3ds_vector_normalize(x); 447 | lib3ds_vector_normalize(z); 448 | 449 | lib3ds_matrix_identity(M); 450 | M[0][0] = x[0]; 451 | M[1][0] = x[1]; 452 | M[2][0] = x[2]; 453 | M[0][1] = y[0]; 454 | M[1][1] = y[1]; 455 | M[2][1] = y[2]; 456 | M[0][2] = z[0]; 457 | M[1][2] = z[1]; 458 | M[2][2] = z[2]; 459 | 460 | lib3ds_matrix_identity(matrix); 461 | lib3ds_matrix_rotate(matrix, roll, 0, 1, 0); 462 | lib3ds_matrix_mult(matrix, matrix, M); 463 | lib3ds_matrix_translate(matrix, -pos[0], -pos[1], -pos[2]); 464 | } 465 | 466 | 467 | 468 | 469 | 470 | 471 | -------------------------------------------------------------------------------- /src/lib3ds_quat.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 1996-2008 by Jan Eric Kyprianidis 3 | All rights reserved. 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published 7 | by the Free Software Foundation, either version 2.1 of the License, or 8 | (at your option) any later version. 9 | 10 | Thisprogram is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program; If not, see . 17 | */ 18 | 19 | /** @file lib3ds_quat.c 20 | Quaternion mathematics implementation */ 21 | 22 | #include "lib3ds_impl.h" 23 | 24 | 25 | /*! 26 | * Set a quaternion to Identity 27 | */ 28 | void 29 | lib3ds_quat_identity(float c[4]) { 30 | c[0] = c[1] = c[2] = 0.0f; 31 | c[3] = 1.0f; 32 | } 33 | 34 | 35 | /*! 36 | * Copy a quaternion. 37 | */ 38 | void 39 | lib3ds_quat_copy(float dest[4], float src[4]) { 40 | int i; 41 | for (i = 0; i < 4; ++i) { 42 | dest[i] = src[i]; 43 | } 44 | } 45 | 46 | 47 | /*! 48 | * Compute a quaternion from axis and angle. 49 | * 50 | * \param c Computed quaternion 51 | * \param axis Rotation axis 52 | * \param angle Angle of rotation, radians. 53 | */ 54 | void 55 | lib3ds_quat_axis_angle(float c[4], float axis[3], float angle) { 56 | double omega, s; 57 | double l; 58 | 59 | l = sqrt(axis[0] * axis[0] + axis[1] * axis[1] + axis[2] * axis[2]); 60 | if (l < LIB3DS_EPSILON) { 61 | c[0] = c[1] = c[2] = 0.0f; 62 | c[3] = 1.0f; 63 | } else { 64 | omega = -0.5 * angle; 65 | s = sin(omega) / l; 66 | c[0] = (float)s * axis[0]; 67 | c[1] = (float)s * axis[1]; 68 | c[2] = (float)s * axis[2]; 69 | c[3] = (float)cos(omega); 70 | } 71 | } 72 | 73 | 74 | /*! 75 | * Negate a quaternion 76 | */ 77 | void 78 | lib3ds_quat_neg(float c[4]) { 79 | int i; 80 | for (i = 0; i < 4; ++i) { 81 | c[i] = -c[i]; 82 | } 83 | } 84 | 85 | 86 | /*! 87 | * Compute the conjugate of a quaternion 88 | */ 89 | void 90 | lib3ds_quat_cnj(float c[4]) { 91 | int i; 92 | for (i = 0; i < 3; ++i) { 93 | c[i] = -c[i]; 94 | } 95 | } 96 | 97 | 98 | /*! 99 | * Multiply two quaternions. 100 | * 101 | * \param c Result 102 | * \param a,b Inputs 103 | */ 104 | void 105 | lib3ds_quat_mul(float c[4], float a[4], float b[4]) { 106 | float qa[4], qb[4]; 107 | lib3ds_quat_copy(qa, a); 108 | lib3ds_quat_copy(qb, b); 109 | c[0] = qa[3] * qb[0] + qa[0] * qb[3] + qa[1] * qb[2] - qa[2] * qb[1]; 110 | c[1] = qa[3] * qb[1] + qa[1] * qb[3] + qa[2] * qb[0] - qa[0] * qb[2]; 111 | c[2] = qa[3] * qb[2] + qa[2] * qb[3] + qa[0] * qb[1] - qa[1] * qb[0]; 112 | c[3] = qa[3] * qb[3] - qa[0] * qb[0] - qa[1] * qb[1] - qa[2] * qb[2]; 113 | } 114 | 115 | 116 | /*! 117 | * Multiply a quaternion by a scalar. 118 | */ 119 | void 120 | lib3ds_quat_scalar(float c[4], float k) { 121 | int i; 122 | for (i = 0; i < 4; ++i) { 123 | c[i] *= k; 124 | } 125 | } 126 | 127 | 128 | /*! 129 | * Normalize a quaternion. 130 | */ 131 | void 132 | lib3ds_quat_normalize(float c[4]) { 133 | double l, m; 134 | 135 | l = sqrt(c[0] * c[0] + c[1] * c[1] + c[2] * c[2] + c[3] * c[3]); 136 | if (fabs(l) < LIB3DS_EPSILON) { 137 | c[0] = c[1] = c[2] = 0.0f; 138 | c[3] = 1.0f; 139 | } else { 140 | int i; 141 | m = 1.0f / l; 142 | for (i = 0; i < 4; ++i) { 143 | c[i] = (float)(c[i] * m); 144 | } 145 | } 146 | } 147 | 148 | 149 | /*! 150 | * Compute the inverse of a quaternion. 151 | */ 152 | void 153 | lib3ds_quat_inv(float c[4]) { 154 | double l, m; 155 | 156 | l = sqrt(c[0] * c[0] + c[1] * c[1] + c[2] * c[2] + c[3] * c[3]); 157 | if (fabs(l) < LIB3DS_EPSILON) { 158 | c[0] = c[1] = c[2] = 0.0f; 159 | c[3] = 1.0f; 160 | } else { 161 | m = 1.0f / l; 162 | c[0] = (float)(-c[0] * m); 163 | c[1] = (float)(-c[1] * m); 164 | c[2] = (float)(-c[2] * m); 165 | c[3] = (float)(c[3] * m); 166 | } 167 | } 168 | 169 | 170 | /*! 171 | * Compute the dot-product of a quaternion. 172 | */ 173 | float 174 | lib3ds_quat_dot(float a[4], float b[4]) { 175 | return(a[0]*b[0] + a[1]*b[1] + a[2]*b[2] + a[3]*b[3]); 176 | } 177 | 178 | 179 | float 180 | lib3ds_quat_norm(float c[4]) { 181 | return(c[0]*c[0] + c[1]*c[1] + c[2]*c[2] + c[3]*c[3]); 182 | } 183 | 184 | 185 | void 186 | lib3ds_quat_ln(float c[4]) { 187 | double om, s, t; 188 | 189 | s = sqrt(c[0] * c[0] + c[1] * c[1] + c[2] * c[2]); 190 | om = atan2(s, (double)c[3]); 191 | if (fabs(s) < LIB3DS_EPSILON) { 192 | t = 0.0f; 193 | } else { 194 | t = om / s; 195 | } 196 | { 197 | int i; 198 | for (i = 0; i < 3; ++i) { 199 | c[i] = (float)(c[i] * t); 200 | } 201 | c[3] = 0.0f; 202 | } 203 | } 204 | 205 | 206 | void 207 | lib3ds_quat_ln_dif(float c[4], float a[4], float b[4]) { 208 | float invp[4]; 209 | 210 | lib3ds_quat_copy(invp, a); 211 | lib3ds_quat_inv(invp); 212 | lib3ds_quat_mul(c, invp, b); 213 | lib3ds_quat_ln(c); 214 | } 215 | 216 | 217 | void 218 | lib3ds_quat_exp(float c[4]) { 219 | double om, sinom; 220 | 221 | om = sqrt(c[0] * c[0] + c[1] * c[1] + c[2] * c[2]); 222 | if (fabs(om) < LIB3DS_EPSILON) { 223 | sinom = 1.0f; 224 | } else { 225 | sinom = sin(om) / om; 226 | } 227 | { 228 | int i; 229 | for (i = 0; i < 3; ++i) { 230 | c[i] = (float)(c[i] * sinom); 231 | } 232 | c[3] = (float)cos(om); 233 | } 234 | } 235 | 236 | 237 | void 238 | lib3ds_quat_slerp(float c[4], float a[4], float b[4], float t) { 239 | double l; 240 | double om, sinom; 241 | double sp, sq; 242 | float flip = 1.0f; 243 | int i; 244 | 245 | l = a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3]; 246 | if (l < 0) { 247 | flip = -1.0f; 248 | l = -l; 249 | } 250 | 251 | om = acos(l); 252 | sinom = sin(om); 253 | if (fabs(sinom) > LIB3DS_EPSILON) { 254 | sp = sin((1.0f - t) * om) / sinom; 255 | sq = sin(t * om) / sinom; 256 | } else { 257 | sp = 1.0f - t; 258 | sq = t; 259 | } 260 | sq *= flip; 261 | for (i = 0; i < 4; ++i) { 262 | c[i] = (float)(sp * a[i] + sq * b[i]); 263 | } 264 | } 265 | 266 | 267 | void 268 | lib3ds_quat_squad(float c[4], float a[4], float p[4], float q[4], float b[4], float t) { 269 | float ab[4]; 270 | float pq[4]; 271 | 272 | lib3ds_quat_slerp(ab, a, b, t); 273 | lib3ds_quat_slerp(pq, p, q, t); 274 | lib3ds_quat_slerp(c, ab, pq, 2*t*(1 - t)); 275 | } 276 | 277 | 278 | void 279 | lib3ds_quat_tangent(float c[4], float p[4], float q[4], float n[4]) { 280 | float dn[4], dp[4], x[4]; 281 | int i; 282 | 283 | lib3ds_quat_ln_dif(dn, q, n); 284 | lib3ds_quat_ln_dif(dp, q, p); 285 | 286 | for (i = 0; i < 4; i++) { 287 | x[i] = -1.0f / 4.0f * (dn[i] + dp[i]); 288 | } 289 | lib3ds_quat_exp(x); 290 | lib3ds_quat_mul(c, q, x); 291 | } 292 | 293 | 294 | void 295 | lib3ds_quat_dump(float q[4]) { 296 | printf("%f %f %f %f\n", q[0], q[1], q[2], q[3]); 297 | } 298 | 299 | -------------------------------------------------------------------------------- /src/lib3ds_shadow.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 1996-2008 by Jan Eric Kyprianidis 3 | All rights reserved. 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published 7 | by the Free Software Foundation, either version 2.1 of the License, or 8 | (at your option) any later version. 9 | 10 | Thisprogram is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program; If not, see . 17 | */ 18 | #include "lib3ds_impl.h" 19 | 20 | 21 | void 22 | lib3ds_shadow_read(Lib3dsShadow *shadow, Lib3dsIo *io) { 23 | Lib3dsChunk c; 24 | 25 | lib3ds_chunk_read(&c, io); 26 | switch (c.chunk) { 27 | case CHK_SHADOW_MAP_SIZE: { 28 | shadow->map_size = lib3ds_io_read_intw(io); 29 | break; 30 | } 31 | 32 | case CHK_LO_SHADOW_BIAS: { 33 | shadow->low_bias = lib3ds_io_read_float(io); 34 | break; 35 | } 36 | 37 | case CHK_HI_SHADOW_BIAS: { 38 | shadow->hi_bias = lib3ds_io_read_float(io); 39 | break; 40 | } 41 | 42 | case CHK_SHADOW_FILTER: { 43 | shadow->filter = lib3ds_io_read_float(io); 44 | break; 45 | } 46 | 47 | case CHK_RAY_BIAS: { 48 | shadow->ray_bias = lib3ds_io_read_float(io); 49 | break; 50 | } 51 | } 52 | } 53 | 54 | 55 | void 56 | lib3ds_shadow_write(Lib3dsShadow *shadow, Lib3dsIo *io) { 57 | if (fabs(shadow->low_bias) > LIB3DS_EPSILON) { /*---- CHK_LO_SHADOW_BIAS ----*/ 58 | Lib3dsChunk c; 59 | c.chunk = CHK_LO_SHADOW_BIAS; 60 | c.size = 10; 61 | lib3ds_chunk_write(&c, io); 62 | lib3ds_io_write_float(io, shadow->low_bias); 63 | } 64 | 65 | if (fabs(shadow->hi_bias) > LIB3DS_EPSILON) { /*---- CHK_HI_SHADOW_BIAS ----*/ 66 | Lib3dsChunk c; 67 | c.chunk = CHK_HI_SHADOW_BIAS; 68 | c.size = 10; 69 | lib3ds_chunk_write(&c, io); 70 | lib3ds_io_write_float(io, shadow->hi_bias); 71 | } 72 | 73 | if (shadow->map_size) { /*---- CHK_SHADOW_MAP_SIZE ----*/ 74 | Lib3dsChunk c; 75 | c.chunk = CHK_SHADOW_MAP_SIZE; 76 | c.size = 8; 77 | lib3ds_chunk_write(&c, io); 78 | lib3ds_io_write_intw(io, shadow->map_size); 79 | } 80 | 81 | if (fabs(shadow->filter) > LIB3DS_EPSILON) { /*---- CHK_SHADOW_FILTER ----*/ 82 | Lib3dsChunk c; 83 | c.chunk = CHK_SHADOW_FILTER; 84 | c.size = 10; 85 | lib3ds_chunk_write(&c, io); 86 | lib3ds_io_write_float(io, shadow->filter); 87 | } 88 | if (fabs(shadow->ray_bias) > LIB3DS_EPSILON) { /*---- CHK_RAY_BIAS ----*/ 89 | Lib3dsChunk c; 90 | c.chunk = CHK_RAY_BIAS; 91 | c.size = 10; 92 | lib3ds_chunk_write(&c, io); 93 | lib3ds_io_write_float(io, shadow->ray_bias); 94 | } 95 | } 96 | 97 | -------------------------------------------------------------------------------- /src/lib3ds_track.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 1996-2008 by Jan Eric Kyprianidis 3 | All rights reserved. 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published 7 | by the Free Software Foundation, either version 2.1 of the License, or 8 | (at your option) any later version. 9 | 10 | Thisprogram is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program; If not, see . 17 | */ 18 | #include "lib3ds_impl.h" 19 | 20 | 21 | Lib3dsTrack* 22 | lib3ds_track_new(Lib3dsTrackType type, int nkeys) { 23 | Lib3dsTrack *track = (Lib3dsTrack*)calloc(sizeof(Lib3dsTrack), 1); 24 | track->type = type; 25 | lib3ds_track_resize(track, nkeys); 26 | return track; 27 | } 28 | 29 | 30 | void 31 | lib3ds_track_free(Lib3dsTrack *track) { 32 | assert(track); 33 | lib3ds_track_resize(track, 0); 34 | memset(track, 0, sizeof(Lib3dsTrack)); 35 | free(track); 36 | } 37 | 38 | 39 | void 40 | lib3ds_track_resize(Lib3dsTrack *track, int nkeys) { 41 | char *p; 42 | 43 | assert(track); 44 | if (track->nkeys == nkeys) 45 | return; 46 | 47 | p = (char*)realloc(track->keys, sizeof(Lib3dsKey) * nkeys); 48 | if (nkeys > track->nkeys) { 49 | memset(p + (sizeof(Lib3dsKey)*track->nkeys), 0, sizeof(Lib3dsKey)*(nkeys - track->nkeys)); 50 | } 51 | track->keys = (Lib3dsKey*)p; 52 | track->nkeys = nkeys; 53 | } 54 | 55 | 56 | static void 57 | pos_key_setup(int n, Lib3dsKey *pp, Lib3dsKey *pc, Lib3dsKey *pn, float *dd, float *ds) { 58 | float tm, cm, cp, bm, bp, tmcm, tmcp, ksm, ksp, kdm, kdp, c; 59 | float dt, fp, fn; 60 | float delm[3], delp[3]; 61 | int i; 62 | 63 | assert(pc); 64 | fp = fn = 1.0f; 65 | if (pp && pn) { 66 | dt = 0.5f * (pn->frame - pp->frame); 67 | fp = (float)(pc->frame - pp->frame) / dt; 68 | fn = (float)(pn->frame - pc->frame) / dt; 69 | c = (float)fabs(pc->cont); 70 | fp = fp + c - c * fp; 71 | fn = fn + c - c * fn; 72 | } 73 | 74 | cm = 1.0f - pc->cont; 75 | tm = 0.5f * (1.0f - pc->tens); 76 | cp = 2.0f - cm; 77 | bm = 1.0f - pc->bias; 78 | bp = 2.0f - bm; 79 | tmcm = tm * cm; 80 | tmcp = tm * cp; 81 | ksm = tmcm * bp * fp; 82 | ksp = tmcp * bm * fp; 83 | kdm = tmcp * bp * fn; 84 | kdp = tmcm * bm * fn; 85 | 86 | for (i = 0; i < n; ++i) delm[i] = delp[i] = 0; 87 | if (pp) { 88 | for (i = 0; i < n; ++i) delm[i] = pc->value[i] - pp->value[i]; 89 | } 90 | if (pn) { 91 | for (i = 0; i < n; ++i) delp[i] = pn->value[i] - pc->value[i]; 92 | } 93 | if (!pp) { 94 | for (i = 0; i < n; ++i) delm[i] = delp[i]; 95 | } 96 | if (!pn) { 97 | for (i = 0; i < n; ++i) delp[i] = delm[i]; 98 | } 99 | 100 | for (i = 0; i < n; ++i) { 101 | ds[i] = ksm * delm[i] + ksp * delp[i]; 102 | dd[i] = kdm * delm[i] + kdp * delp[i]; 103 | } 104 | } 105 | 106 | 107 | static void 108 | rot_key_setup(Lib3dsKey *prev, Lib3dsKey *cur, Lib3dsKey *next, float a[4], float b[4]) { 109 | float tm, cm, cp, bm, bp, tmcm, tmcp, ksm, ksp, kdm, kdp, c; 110 | float dt, fp, fn; 111 | float q[4], qm[4], qp[4], qa[4], qb[4]; 112 | int i; 113 | 114 | assert(cur); 115 | if (prev) { 116 | if (cur->value[3] > LIB3DS_TWOPI - LIB3DS_EPSILON) { 117 | lib3ds_quat_axis_angle(qm, cur->value, 0.0f); 118 | lib3ds_quat_ln(qm); 119 | } else { 120 | lib3ds_quat_copy(q, prev->value); 121 | if (lib3ds_quat_dot(q, cur->value) < 0) lib3ds_quat_neg(q); 122 | lib3ds_quat_ln_dif(qm, q, cur->value); 123 | } 124 | } 125 | if (next) { 126 | if (next->value[3] > LIB3DS_TWOPI - LIB3DS_EPSILON) { 127 | lib3ds_quat_axis_angle(qp, next->value, 0.0f); 128 | lib3ds_quat_ln(qp); 129 | } else { 130 | lib3ds_quat_copy(q, next->value); 131 | if (lib3ds_quat_dot(q, cur->value) < 0) lib3ds_quat_neg(q); 132 | lib3ds_quat_ln_dif(qp, cur->value, q); 133 | } 134 | } 135 | if (!prev) lib3ds_quat_copy(qm, qp); 136 | if (!next) lib3ds_quat_copy(qp, qm); 137 | 138 | fp = fn = 1.0f; 139 | cm = 1.0f - cur->cont; 140 | if (prev && next) { 141 | dt = 0.5f * (next->frame - prev->frame); 142 | fp = (float)(cur->frame - prev->frame) / dt; 143 | fn = (float)(next->frame - cur->frame) / dt; 144 | c = (float)fabs(cur->cont); 145 | fp = fp + c - c * fp; 146 | fn = fn + c - c * fn; 147 | } 148 | 149 | tm = 0.5f * (1.0f - cur->tens); 150 | cp = 2.0f - cm; 151 | bm = 1.0f - cur->bias; 152 | bp = 2.0f - bm; 153 | tmcm = tm * cm; 154 | tmcp = tm * cp; 155 | ksm = 1.0f - tmcm * bp * fp; 156 | ksp = -tmcp * bm * fp; 157 | kdm = tmcp * bp * fn; 158 | kdp = tmcm * bm * fn - 1.0f; 159 | 160 | for (i = 0; i < 4; i++) { 161 | qa[i] = 0.5f * (kdm * qm[i] + kdp * qp[i]); 162 | qb[i] = 0.5f * (ksm * qm[i] + ksp * qp[i]); 163 | } 164 | lib3ds_quat_exp(qa); 165 | lib3ds_quat_exp(qb); 166 | 167 | lib3ds_quat_mul(a, cur->value, qa); 168 | lib3ds_quat_mul(b, cur->value, qb); 169 | } 170 | 171 | 172 | static void 173 | quat_for_index(Lib3dsTrack *track, int index, float q[4]) { 174 | float p[4]; 175 | int i; 176 | lib3ds_quat_identity(q); 177 | for (i = 0; i <= index; ++i) { 178 | lib3ds_quat_axis_angle(p, track->keys[i].value, track->keys[i].value[3]); 179 | lib3ds_quat_mul(q, p, q); 180 | } 181 | } 182 | 183 | 184 | static int 185 | find_index(Lib3dsTrack *track, float t, float *u) { 186 | int i; 187 | float nt; 188 | int t0, t1; 189 | 190 | assert(track); 191 | assert(track->nkeys > 0); 192 | 193 | if (track->nkeys <= 1) 194 | return -1; 195 | 196 | t0 = track->keys[0].frame; 197 | t1 = track->keys[track->nkeys-1].frame; 198 | if (track->flags & LIB3DS_TRACK_REPEAT) { 199 | nt = (float)fmod((float)(t - t0), (float)(t1 - t0)) + t0; 200 | } else { 201 | nt = t; 202 | } 203 | 204 | if (nt <= t0) { 205 | return -1; 206 | } 207 | if (nt >= t1) { 208 | return track->nkeys; 209 | } 210 | 211 | for (i = 1; i < track->nkeys; ++i) { 212 | if (nt < track->keys[i].frame) 213 | break; 214 | } 215 | 216 | *u = nt - (float)track->keys[i-1].frame; 217 | *u /= (float)(track->keys[i].frame - track->keys[i-1].frame); 218 | 219 | assert((*u >= 0.0f) && (*u <= 1.0f)); 220 | return i; 221 | } 222 | 223 | 224 | static void 225 | setup_segment(Lib3dsTrack *track, int index, Lib3dsKey *pp, Lib3dsKey *p0, Lib3dsKey *p1, Lib3dsKey *pn) { 226 | int ip = 0; 227 | int in = 0; 228 | 229 | pp->frame = pn->frame = -1; 230 | if (index >= 2) { 231 | ip = index - 2; 232 | *pp = track->keys[index - 2]; 233 | } else { 234 | if (track->flags & LIB3DS_TRACK_SMOOTH) { 235 | ip = track->nkeys - 2; 236 | *pp = track->keys[track->nkeys - 2]; 237 | pp->frame = track->keys[track->nkeys - 2].frame - (track->keys[track->nkeys - 1].frame - track->keys[0].frame); 238 | } 239 | } 240 | 241 | *p0 = track->keys[index - 1]; 242 | *p1 = track->keys[index]; 243 | 244 | if (index < (int)track->nkeys - 1) { 245 | in = index + 1; 246 | *pn = track->keys[index + 1]; 247 | } else { 248 | if (track->flags & LIB3DS_TRACK_SMOOTH) { 249 | in = 1; 250 | *pn = track->keys[1]; 251 | pn->frame = track->keys[1].frame + (track->keys[track->nkeys-1].frame - track->keys[0].frame); 252 | } 253 | } 254 | 255 | if (track->type == LIB3DS_TRACK_QUAT) { 256 | float q[4]; 257 | if (pp->frame >= 0) { 258 | quat_for_index(track, ip, pp->value); 259 | } else { 260 | lib3ds_quat_identity(pp->value); 261 | } 262 | 263 | quat_for_index(track, index - 1, p0->value); 264 | lib3ds_quat_axis_angle(q, track->keys[index].value, track->keys[index].value[3]); 265 | lib3ds_quat_mul(p1->value, q, p0->value); 266 | 267 | if (pn->frame >= 0) { 268 | lib3ds_quat_axis_angle(q, track->keys[in].value, track->keys[in].value[3]); 269 | lib3ds_quat_mul(pn->value, q, p1->value); 270 | } else { 271 | lib3ds_quat_identity(pn->value); 272 | } 273 | } 274 | } 275 | 276 | 277 | void 278 | lib3ds_track_eval_bool(Lib3dsTrack *track, int *b, float t) { 279 | *b = FALSE; 280 | if (track) { 281 | int index; 282 | float u; 283 | 284 | assert(track->type == LIB3DS_TRACK_BOOL); 285 | if (!track->nkeys) { 286 | return; 287 | } 288 | 289 | index = find_index(track, t, &u); 290 | if (index < 0) { 291 | *b = FALSE; 292 | return; 293 | } 294 | if (index >= track->nkeys) { 295 | *b = !(track->nkeys & 1); 296 | return; 297 | } 298 | *b = !(index & 1); 299 | } 300 | } 301 | 302 | 303 | static void 304 | track_eval_linear(Lib3dsTrack *track, float *value, float t) { 305 | Lib3dsKey pp, p0, p1, pn; 306 | float u; 307 | int index; 308 | float dsp[3], ddp[3], dsn[3], ddn[3]; 309 | 310 | assert(track); 311 | if (!track->nkeys) { 312 | int i; 313 | for (i = 0; i < track->type; ++i) value[i] = 0.0f; 314 | return; 315 | } 316 | 317 | index = find_index(track, t, &u); 318 | 319 | if (index < 0) { 320 | int i; 321 | for (i = 0; i < track->type; ++i) value[i] = track->keys[0].value[i]; 322 | return; 323 | } 324 | if (index >= track->nkeys) { 325 | int i; 326 | for (i = 0; i < track->type; ++i) value[i] = track->keys[track->nkeys-1].value[i]; 327 | return; 328 | } 329 | 330 | setup_segment(track, index, &pp, &p0, &p1, &pn); 331 | 332 | pos_key_setup(track->type, pp.frame>=0? &pp : NULL, &p0, &p1, ddp, dsp); 333 | pos_key_setup(track->type, &p0, &p1, pn.frame>=0? &pn : NULL, ddn, dsn); 334 | 335 | lib3ds_math_cubic_interp( 336 | value, 337 | p0.value, 338 | ddp, 339 | dsn, 340 | p1.value, 341 | track->type, 342 | u 343 | ); 344 | } 345 | 346 | 347 | void 348 | lib3ds_track_eval_float(Lib3dsTrack *track, float *f, float t) { 349 | *f = 0; 350 | if (track) { 351 | assert(track->type == LIB3DS_TRACK_FLOAT); 352 | track_eval_linear(track, f, t); 353 | } 354 | } 355 | 356 | 357 | void 358 | lib3ds_track_eval_vector(Lib3dsTrack *track, float v[3], float t) { 359 | lib3ds_vector_zero(v); 360 | if (track) { 361 | assert(track->type == LIB3DS_TRACK_VECTOR); 362 | track_eval_linear(track, v, t); 363 | } 364 | } 365 | 366 | 367 | void 368 | lib3ds_track_eval_quat(Lib3dsTrack *track, float q[4], float t) { 369 | lib3ds_quat_identity(q); 370 | if (track) { 371 | Lib3dsKey pp, p0, p1, pn; 372 | float u; 373 | int index; 374 | float ap[4], bp[4], an[4], bn[4]; 375 | 376 | assert(track->type == LIB3DS_TRACK_QUAT); 377 | if (!track->nkeys) { 378 | return; 379 | } 380 | 381 | index = find_index(track, t, &u); 382 | if (index < 0) { 383 | lib3ds_quat_axis_angle(q, track->keys[0].value, track->keys[0].value[3]); 384 | return; 385 | } 386 | if (index >= track->nkeys) { 387 | quat_for_index(track, track->nkeys - 1, q); 388 | return; 389 | } 390 | 391 | setup_segment(track, index, &pp, &p0, &p1, &pn); 392 | 393 | rot_key_setup(pp.frame>=0? &pp : NULL, &p0, &p1, ap, bp); 394 | rot_key_setup(&p0, &p1, pn.frame>=0? &pn : NULL, an, bn); 395 | 396 | lib3ds_quat_squad(q, p0.value, ap, bn, p1.value, u); 397 | } 398 | } 399 | 400 | 401 | static void 402 | tcb_read(Lib3dsKey *key, Lib3dsIo *io) { 403 | key->flags = lib3ds_io_read_word(io); 404 | if (key->flags & LIB3DS_KEY_USE_TENS) { 405 | key->tens = lib3ds_io_read_float(io); 406 | } 407 | if (key->flags & LIB3DS_KEY_USE_CONT) { 408 | key->cont = lib3ds_io_read_float(io); 409 | } 410 | if (key->flags & LIB3DS_KEY_USE_BIAS) { 411 | key->bias = lib3ds_io_read_float(io); 412 | } 413 | if (key->flags & LIB3DS_KEY_USE_EASE_TO) { 414 | key->ease_to = lib3ds_io_read_float(io); 415 | } 416 | if (key->flags & LIB3DS_KEY_USE_EASE_FROM) { 417 | key->ease_from = lib3ds_io_read_float(io); 418 | } 419 | } 420 | 421 | 422 | void 423 | lib3ds_track_read(Lib3dsTrack *track, Lib3dsIo *io) { 424 | unsigned nkeys; 425 | unsigned i; 426 | 427 | track->flags = lib3ds_io_read_word(io); 428 | lib3ds_io_read_dword(io); 429 | lib3ds_io_read_dword(io); 430 | nkeys = lib3ds_io_read_intd(io); 431 | lib3ds_track_resize(track, nkeys); 432 | 433 | switch (track->type) { 434 | case LIB3DS_TRACK_BOOL: 435 | for (i = 0; i < nkeys; ++i) { 436 | track->keys[i].frame = lib3ds_io_read_intd(io); 437 | tcb_read(&track->keys[i], io); 438 | } 439 | break; 440 | 441 | case LIB3DS_TRACK_FLOAT: 442 | for (i = 0; i < nkeys; ++i) { 443 | track->keys[i].frame = lib3ds_io_read_intd(io); 444 | tcb_read(&track->keys[i], io); 445 | track->keys[i].value[0] = lib3ds_io_read_float(io); 446 | } 447 | break; 448 | 449 | case LIB3DS_TRACK_VECTOR: 450 | for (i = 0; i < nkeys; ++i) { 451 | track->keys[i].frame = lib3ds_io_read_intd(io); 452 | tcb_read(&track->keys[i], io); 453 | lib3ds_io_read_vector(io, track->keys[i].value); 454 | } 455 | break; 456 | 457 | case LIB3DS_TRACK_QUAT: 458 | for (i = 0; i < nkeys; ++i) { 459 | track->keys[i].frame = lib3ds_io_read_intd(io); 460 | tcb_read(&track->keys[i], io); 461 | track->keys[i].value[3] = lib3ds_io_read_float(io); 462 | lib3ds_io_read_vector(io, track->keys[i].value); 463 | } 464 | break; 465 | 466 | /*case LIB3DS_TRACK_MORPH: 467 | for (i = 0; i < nkeys; ++i) { 468 | track->keys[i].frame = lib3ds_io_read_intd(io); 469 | tcb_read(&track->keys[i].tcb, io); 470 | lib3ds_io_read_string(io, track->keys[i].data.m.name, 64); 471 | } 472 | break;*/ 473 | 474 | default: 475 | break; 476 | } 477 | } 478 | 479 | 480 | void 481 | tcb_write(Lib3dsKey *key, Lib3dsIo *io) { 482 | lib3ds_io_write_word(io, (uint16_t)key->flags); 483 | if (key->flags & LIB3DS_KEY_USE_TENS) { 484 | lib3ds_io_write_float(io, key->tens); 485 | } 486 | if (key->flags & LIB3DS_KEY_USE_CONT) { 487 | lib3ds_io_write_float(io, key->cont); 488 | } 489 | if (key->flags & LIB3DS_KEY_USE_BIAS) { 490 | lib3ds_io_write_float(io, key->bias); 491 | } 492 | if (key->flags & LIB3DS_KEY_USE_EASE_TO) { 493 | lib3ds_io_write_float(io, key->ease_to); 494 | } 495 | if (key->flags & LIB3DS_KEY_USE_EASE_FROM) { 496 | lib3ds_io_write_float(io, key->ease_from); 497 | } 498 | } 499 | 500 | 501 | void 502 | lib3ds_track_write(Lib3dsTrack *track, Lib3dsIo *io) { 503 | int i; 504 | 505 | lib3ds_io_write_word(io, (uint16_t)track->flags); 506 | lib3ds_io_write_dword(io, 0); 507 | lib3ds_io_write_dword(io, 0); 508 | lib3ds_io_write_dword(io, track->nkeys); 509 | 510 | switch (track->type) { 511 | case LIB3DS_TRACK_BOOL: 512 | for (i = 0; i < track->nkeys; ++i) { 513 | lib3ds_io_write_intd(io, track->keys[i].frame); 514 | tcb_write(&track->keys[i], io); 515 | } 516 | break; 517 | 518 | case LIB3DS_TRACK_FLOAT: 519 | for (i = 0; i < track->nkeys; ++i) { 520 | lib3ds_io_write_intd(io, track->keys[i].frame); 521 | tcb_write(&track->keys[i], io); 522 | lib3ds_io_write_float(io, track->keys[i].value[0]); 523 | } 524 | break; 525 | 526 | case LIB3DS_TRACK_VECTOR: 527 | for (i = 0; i < track->nkeys; ++i) { 528 | lib3ds_io_write_intd(io, track->keys[i].frame); 529 | tcb_write(&track->keys[i], io); 530 | lib3ds_io_write_vector(io, track->keys[i].value); 531 | } 532 | break; 533 | 534 | case LIB3DS_TRACK_QUAT: 535 | for (i = 0; i < track->nkeys; ++i) { 536 | lib3ds_io_write_intd(io, track->keys[i].frame); 537 | tcb_write(&track->keys[i], io); 538 | lib3ds_io_write_float(io, track->keys[i].value[3]); 539 | lib3ds_io_write_vector(io, track->keys[i].value); 540 | } 541 | break; 542 | 543 | /*case LIB3DS_TRACK_MORPH: 544 | for (i = 0; i < track->nkeys; ++i) { 545 | lib3ds_io_write_intd(io, track->keys[i].frame); 546 | tcb_write(&track->keys[i].tcb, io); 547 | lib3ds_io_write_string(io, track->keys[i].data.m.name); 548 | } 549 | break;*/ 550 | } 551 | } 552 | -------------------------------------------------------------------------------- /src/lib3ds_util.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 1996-2008 by Jan Eric Kyprianidis 3 | All rights reserved. 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published 7 | by the Free Software Foundation, either version 2.1 of the License, or 8 | (at your option) any later version. 9 | 10 | Thisprogram is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program; If not, see . 17 | */ 18 | #include "lib3ds_impl.h" 19 | 20 | 21 | void* lib3ds_util_realloc_array(void *ptr, int old_size, int new_size, int element_size) { 22 | if (!ptr) 23 | old_size = 0; 24 | if (old_size != new_size) { 25 | ptr = realloc(ptr, element_size * new_size); 26 | if (old_size < new_size) { 27 | memset((char*)ptr + element_size * old_size, 0, element_size * (new_size - old_size)); 28 | } 29 | } 30 | return ptr; 31 | } 32 | 33 | 34 | void lib3ds_util_reserve_array(void ***ptr, int *n, int *size, int new_size, int force, Lib3dsFreeFunc free_func) { 35 | assert(ptr && n && size); 36 | if ((*size < new_size) || force) { 37 | if (force && free_func) { 38 | int i; 39 | for (i = new_size; i < *n; ++i) { 40 | free_func((*ptr)[i]); 41 | (*ptr)[i] = 0; 42 | } 43 | } 44 | *ptr = (void**)realloc(*ptr, sizeof(void*) * new_size); 45 | *size = new_size; 46 | if (*n > new_size) { 47 | *n = new_size; 48 | } 49 | } 50 | } 51 | 52 | 53 | void lib3ds_util_insert_array(void ***ptr, int *n, int *size, void *element, int index) { 54 | int i; 55 | assert(ptr && n && size && element); 56 | i = ((index >= 0) && (index < *n)) ? index : *n; 57 | if (i >= *size) { 58 | int new_size = 2 * (*size); 59 | #ifdef _DEBUG 60 | if (new_size < 1) { 61 | new_size = 1; 62 | } 63 | #else 64 | if (new_size < 32) { 65 | new_size = 32; 66 | } 67 | #endif 68 | lib3ds_util_reserve_array(ptr, n, size, new_size, FALSE, NULL); 69 | } 70 | assert(*ptr); 71 | if (i < *n) { 72 | memmove(&(*ptr)[i+1], &(*ptr)[i], sizeof(void*) * (*n - i)); 73 | } 74 | (*ptr)[i] = element; 75 | *n = *n + 1; 76 | } 77 | 78 | 79 | void lib3ds_util_remove_array(void ***ptr, int *n, int index, Lib3dsFreeFunc free_func) { 80 | assert(ptr && n); 81 | if ((index >= 0) && (index < *n)) { 82 | assert(*ptr); 83 | free_func((*ptr)[index]); 84 | if (index < *n - 1) { 85 | memmove(&(*ptr)[index], &(*ptr)[index+1], sizeof(void*) * (*n - index - 1)); 86 | } 87 | *n = *n - 1; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/lib3ds_vector.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 1996-2008 by Jan Eric Kyprianidis 3 | All rights reserved. 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published 7 | by the Free Software Foundation, either version 2.1 of the License, or 8 | (at your option) any later version. 9 | 10 | Thisprogram is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program; If not, see . 17 | */ 18 | 19 | /** @file lib3ds_vector.c 20 | Vector mathematics implementation */ 21 | 22 | #include "lib3ds_impl.h" 23 | 24 | 25 | void 26 | lib3ds_vector_make(float c[3], float x, float y, float z) { 27 | c[0] = x; 28 | c[1] = y; 29 | c[2] = z; 30 | } 31 | 32 | 33 | void 34 | lib3ds_vector_zero(float c[3]) { 35 | int i; 36 | for (i = 0; i < 3; ++i) { 37 | c[i] = 0.0f; 38 | } 39 | } 40 | 41 | 42 | void 43 | lib3ds_vector_copy(float dst[3], float src[3]) { 44 | int i; 45 | for (i = 0; i < 3; ++i) { 46 | dst[i] = src[i]; 47 | } 48 | } 49 | 50 | 51 | /*! 52 | * Add two vectors. 53 | * 54 | * \param c Result. 55 | * \param a First addend. 56 | * \param b Second addend. 57 | */ 58 | void 59 | lib3ds_vector_add(float c[3], float a[3], float b[3]) { 60 | int i; 61 | for (i = 0; i < 3; ++i) { 62 | c[i] = a[i] + b[i]; 63 | } 64 | } 65 | 66 | 67 | /*! 68 | * Subtract two vectors. 69 | * 70 | * \param c Result. 71 | * \param a Addend. 72 | * \param b Minuend. 73 | */ 74 | void 75 | lib3ds_vector_sub(float c[3], float a[3], float b[3]) { 76 | int i; 77 | for (i = 0; i < 3; ++i) { 78 | c[i] = a[i] - b[i]; 79 | } 80 | } 81 | 82 | 83 | /*! 84 | * Multiply a vector by a scalar. 85 | * 86 | * \param c Result. 87 | * \param a Vector to be multiplied. 88 | * \param k Scalar. 89 | */ 90 | void 91 | lib3ds_vector_scalar_mul(float c[3], float a[3], float k) { 92 | int i; 93 | for (i = 0; i < 3; ++i) { 94 | c[i] = a[i] * k; 95 | } 96 | } 97 | 98 | 99 | /*! 100 | * Compute cross product. 101 | * 102 | * \param c Result. 103 | * \param a First vector. 104 | * \param b Second vector. 105 | */ 106 | void 107 | lib3ds_vector_cross(float c[3], float a[3], float b[3]) { 108 | c[0] = a[1] * b[2] - a[2] * b[1]; 109 | c[1] = a[2] * b[0] - a[0] * b[2]; 110 | c[2] = a[0] * b[1] - a[1] * b[0]; 111 | } 112 | 113 | 114 | /*! 115 | * Compute dot product. 116 | * 117 | * \param a First vector. 118 | * \param b Second vector. 119 | * 120 | * \return Dot product. 121 | */ 122 | float 123 | lib3ds_vector_dot(float a[3], float b[3]) { 124 | return(a[0]*b[0] + a[1]*b[1] + a[2]*b[2]); 125 | } 126 | 127 | 128 | /*! 129 | * Compute length of vector. 130 | * 131 | * Computes |c| = sqrt(x*x + y*y + z*z) 132 | * 133 | * \param c Vector to compute. 134 | * 135 | * \return Length of vector. 136 | */ 137 | float 138 | lib3ds_vector_length(float c[3]) { 139 | return((float)sqrt(c[0]*c[0] + c[1]*c[1] + c[2]*c[2])); 140 | } 141 | 142 | 143 | /*! 144 | * Normalize a vector. 145 | * 146 | * Scales a vector so that its length is 1.0. 147 | * 148 | * \param c Vector to normalize. 149 | */ 150 | void 151 | lib3ds_vector_normalize(float c[3]) { 152 | float l, m; 153 | 154 | l = (float)sqrt(c[0] * c[0] + c[1] * c[1] + c[2] * c[2]); 155 | if (fabs(l) < LIB3DS_EPSILON) { 156 | if ((c[0] >= c[1]) && (c[0] >= c[2])) { 157 | c[0] = 1.0f; 158 | c[1] = c[2] = 0.0f; 159 | } else 160 | if (c[1] >= c[2]) { 161 | c[1] = 1.0f; 162 | c[0] = c[2] = 0.0f; 163 | } else { 164 | c[2] = 1.0f; 165 | c[0] = c[1] = 0.0f; 166 | } 167 | } else { 168 | m = 1.0f / l; 169 | c[0] *= m; 170 | c[1] *= m; 171 | c[2] *= m; 172 | } 173 | } 174 | 175 | 176 | /*! 177 | * Compute a vector normal to two line segments. 178 | * 179 | * Computes the normal vector to the lines b-a and b-c. 180 | * 181 | * \param n Returned normal vector. 182 | * \param a Endpoint of first line. 183 | * \param b Base point of both lines. 184 | * \param c Endpoint of second line. 185 | */ 186 | void 187 | lib3ds_vector_normal(float n[3], float a[3], float b[3], float c[3]) { 188 | float p[3], q[3]; 189 | 190 | lib3ds_vector_sub(p, c, b); 191 | lib3ds_vector_sub(q, a, b); 192 | lib3ds_vector_cross(n, p, q); 193 | lib3ds_vector_normalize(n); 194 | } 195 | 196 | 197 | /*! 198 | * Multiply a point by a transformation matrix. 199 | * 200 | * Applies the given transformation matrix to the given point. With some 201 | * transformation matrices, a vector may also be transformed. 202 | * 203 | * \param c Result. 204 | * \param m Transformation matrix. 205 | * \param a Input point. 206 | */ 207 | void 208 | lib3ds_vector_transform(float c[3], float m[4][4], float a[3]) { 209 | c[0] = m[0][0] * a[0] + m[1][0] * a[1] + m[2][0] * a[2] + m[3][0]; 210 | c[1] = m[0][1] * a[0] + m[1][1] * a[1] + m[2][1] * a[2] + m[3][1]; 211 | c[2] = m[0][2] * a[0] + m[1][2] * a[1] + m[2][2] * a[2] + m[3][2]; 212 | } 213 | 214 | 215 | /*! 216 | * c[i] = min(c[i], a[i]); 217 | * 218 | * Computes minimum values of x,y,z independently. 219 | */ 220 | void 221 | lib3ds_vector_min(float c[3], float a[3]) { 222 | int i; 223 | for (i = 0; i < 3; ++i) { 224 | if (a[i] < c[i]) { 225 | c[i] = a[i]; 226 | } 227 | } 228 | } 229 | 230 | 231 | /*! 232 | * c[i] = max(c[i], a[i]); 233 | * 234 | * Computes maximum values of x,y,z independently. 235 | */ 236 | void 237 | lib3ds_vector_max(float c[3], float a[3]) { 238 | int i; 239 | for (i = 0; i < 3; ++i) { 240 | if (a[i] > c[i]) { 241 | c[i] = a[i]; 242 | } 243 | } 244 | } 245 | 246 | 247 | void 248 | lib3ds_vector_dump(float c[3]) { 249 | fprintf(stderr, "%f %f %f\n", c[0], c[1], c[2]); 250 | } 251 | 252 | -------------------------------------------------------------------------------- /src/lib3ds_viewport.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 1996-2008 by Jan Eric Kyprianidis 3 | All rights reserved. 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU Lesser General Public License as published 7 | by the Free Software Foundation, either version 2.1 of the License, or 8 | (at your option) any later version. 9 | 10 | Thisprogram is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public License 16 | along with this program; If not, see . 17 | */ 18 | #include "lib3ds_impl.h" 19 | 20 | 21 | void 22 | lib3ds_viewport_read(Lib3dsViewport *viewport, Lib3dsIo *io) { 23 | Lib3dsChunk c; 24 | uint16_t chunk; 25 | 26 | memset(viewport, 0, sizeof(*viewport)); 27 | lib3ds_chunk_read_start(&c, 0, io); 28 | switch (c.chunk) { 29 | case CHK_VIEWPORT_LAYOUT: { 30 | int cur = 0; 31 | viewport->layout_style = lib3ds_io_read_word(io); 32 | viewport->layout_active = lib3ds_io_read_intw(io); 33 | lib3ds_io_read_intw(io); 34 | viewport->layout_swap = lib3ds_io_read_intw(io); 35 | lib3ds_io_read_intw(io); 36 | viewport->layout_swap_prior = lib3ds_io_read_intw(io); 37 | viewport->layout_swap_view = lib3ds_io_read_intw(io); 38 | lib3ds_chunk_read_tell(&c, io); 39 | while ((chunk = lib3ds_chunk_read_next(&c, io)) != 0) { 40 | switch (chunk) { 41 | case CHK_VIEWPORT_SIZE: { 42 | viewport->layout_position[0] = lib3ds_io_read_word(io); 43 | viewport->layout_position[1] = lib3ds_io_read_word(io); 44 | viewport->layout_size[0] = lib3ds_io_read_word(io); 45 | viewport->layout_size[1] = lib3ds_io_read_word(io); 46 | break; 47 | } 48 | 49 | case CHK_VIEWPORT_DATA_3: { 50 | if (cur < LIB3DS_LAYOUT_MAX_VIEWS) { 51 | lib3ds_io_read_intw(io); 52 | viewport->layout_views[cur].axis_lock = lib3ds_io_read_word(io); 53 | viewport->layout_views[cur].position[0] = lib3ds_io_read_intw(io); 54 | viewport->layout_views[cur].position[1] = lib3ds_io_read_intw(io); 55 | viewport->layout_views[cur].size[0] = lib3ds_io_read_intw(io); 56 | viewport->layout_views[cur].size[1] = lib3ds_io_read_intw(io); 57 | viewport->layout_views[cur].type = lib3ds_io_read_word(io); 58 | viewport->layout_views[cur].zoom = lib3ds_io_read_float(io); 59 | lib3ds_io_read_vector(io, viewport->layout_views[cur].center); 60 | viewport->layout_views[cur].horiz_angle = lib3ds_io_read_float(io); 61 | viewport->layout_views[cur].vert_angle = lib3ds_io_read_float(io); 62 | lib3ds_io_read(io, viewport->layout_views[cur].camera, 11); 63 | ++cur; 64 | } 65 | break; 66 | } 67 | 68 | case CHK_VIEWPORT_DATA: 69 | /* 3DS R2 & R3 chunk unsupported */ 70 | break; 71 | 72 | default: 73 | lib3ds_chunk_unknown(chunk, io); 74 | } 75 | } 76 | break; 77 | } 78 | 79 | case CHK_DEFAULT_VIEW: { 80 | while ((chunk = lib3ds_chunk_read_next(&c, io)) != 0) { 81 | switch (chunk) { 82 | case CHK_VIEW_TOP: { 83 | viewport->default_type = LIB3DS_VIEW_TOP; 84 | lib3ds_io_read_vector(io, viewport->default_position); 85 | viewport->default_width = lib3ds_io_read_float(io); 86 | break; 87 | } 88 | 89 | case CHK_VIEW_BOTTOM: { 90 | viewport->default_type = LIB3DS_VIEW_BOTTOM; 91 | lib3ds_io_read_vector(io, viewport->default_position); 92 | viewport->default_width = lib3ds_io_read_float(io); 93 | break; 94 | } 95 | 96 | case CHK_VIEW_LEFT: { 97 | viewport->default_type = LIB3DS_VIEW_LEFT; 98 | lib3ds_io_read_vector(io, viewport->default_position); 99 | viewport->default_width = lib3ds_io_read_float(io); 100 | break; 101 | } 102 | 103 | case CHK_VIEW_RIGHT: { 104 | viewport->default_type = LIB3DS_VIEW_RIGHT; 105 | lib3ds_io_read_vector(io, viewport->default_position); 106 | viewport->default_width = lib3ds_io_read_float(io); 107 | break; 108 | } 109 | 110 | case CHK_VIEW_FRONT: { 111 | viewport->default_type = LIB3DS_VIEW_FRONT; 112 | lib3ds_io_read_vector(io, viewport->default_position); 113 | viewport->default_width = lib3ds_io_read_float(io); 114 | break; 115 | } 116 | 117 | case CHK_VIEW_BACK: { 118 | viewport->default_type = LIB3DS_VIEW_BACK; 119 | lib3ds_io_read_vector(io, viewport->default_position); 120 | viewport->default_width = lib3ds_io_read_float(io); 121 | break; 122 | } 123 | 124 | case CHK_VIEW_USER: { 125 | viewport->default_type = LIB3DS_VIEW_USER; 126 | lib3ds_io_read_vector(io, viewport->default_position); 127 | viewport->default_width = lib3ds_io_read_float(io); 128 | viewport->default_horiz_angle = lib3ds_io_read_float(io); 129 | viewport->default_vert_angle = lib3ds_io_read_float(io); 130 | viewport->default_roll_angle = lib3ds_io_read_float(io); 131 | break; 132 | } 133 | 134 | case CHK_VIEW_CAMERA: { 135 | viewport->default_type = LIB3DS_VIEW_CAMERA; 136 | lib3ds_io_read(io, viewport->default_camera, 11); 137 | break; 138 | } 139 | 140 | default: 141 | lib3ds_chunk_unknown(chunk, io); 142 | } 143 | } 144 | break; 145 | } 146 | } 147 | 148 | lib3ds_chunk_read_end(&c, io); 149 | } 150 | 151 | 152 | void 153 | lib3ds_viewport_write(Lib3dsViewport *viewport, Lib3dsIo *io) { 154 | if (viewport->layout_nviews) { 155 | Lib3dsChunk c; 156 | int i; 157 | 158 | c.chunk = CHK_VIEWPORT_LAYOUT; 159 | lib3ds_chunk_write_start(&c, io); 160 | 161 | lib3ds_io_write_word(io, (uint16_t)viewport->layout_style); 162 | lib3ds_io_write_intw(io, (int16_t)viewport->layout_active); 163 | lib3ds_io_write_intw(io, 0); 164 | lib3ds_io_write_intw(io, (int16_t)viewport->layout_swap); 165 | lib3ds_io_write_intw(io, 0); 166 | lib3ds_io_write_intw(io, (int16_t)viewport->layout_swap_prior); 167 | lib3ds_io_write_intw(io, (int16_t)viewport->layout_swap_view); 168 | 169 | { 170 | Lib3dsChunk c; 171 | c.chunk = CHK_VIEWPORT_SIZE; 172 | c.size = 14; 173 | lib3ds_chunk_write(&c, io); 174 | lib3ds_io_write_intw(io, viewport->layout_position[0]); 175 | lib3ds_io_write_intw(io, viewport->layout_position[1]); 176 | lib3ds_io_write_intw(io, viewport->layout_size[0]); 177 | lib3ds_io_write_intw(io, viewport->layout_size[1]); 178 | } 179 | 180 | for (i = 0; i < viewport->layout_nviews; ++i) { 181 | Lib3dsChunk c; 182 | c.chunk = CHK_VIEWPORT_DATA_3; 183 | c.size = 55; 184 | lib3ds_chunk_write(&c, io); 185 | 186 | lib3ds_io_write_intw(io, 0); 187 | lib3ds_io_write_word(io, (uint16_t)viewport->layout_views[i].axis_lock); 188 | lib3ds_io_write_intw(io, (int16_t)viewport->layout_views[i].position[0]); 189 | lib3ds_io_write_intw(io, viewport->layout_views[i].position[1]); 190 | lib3ds_io_write_intw(io, viewport->layout_views[i].size[0]); 191 | lib3ds_io_write_intw(io, viewport->layout_views[i].size[1]); 192 | lib3ds_io_write_word(io, (uint16_t)viewport->layout_views[i].type); 193 | lib3ds_io_write_float(io, viewport->layout_views[i].zoom); 194 | lib3ds_io_write_vector(io, viewport->layout_views[i].center); 195 | lib3ds_io_write_float(io, viewport->layout_views[i].horiz_angle); 196 | lib3ds_io_write_float(io, viewport->layout_views[i].vert_angle); 197 | lib3ds_io_write(io, viewport->layout_views[i].camera, 11); 198 | } 199 | 200 | lib3ds_chunk_write_end(&c, io); 201 | } 202 | 203 | if (viewport->default_type) { 204 | Lib3dsChunk c; 205 | 206 | c.chunk = CHK_DEFAULT_VIEW; 207 | lib3ds_chunk_write_start(&c, io); 208 | 209 | switch (viewport->default_type) { 210 | case LIB3DS_VIEW_TOP: { 211 | Lib3dsChunk c; 212 | c.chunk = CHK_VIEW_TOP; 213 | c.size = 22; 214 | lib3ds_chunk_write(&c, io); 215 | lib3ds_io_write_vector(io, viewport->default_position); 216 | lib3ds_io_write_float(io, viewport->default_width); 217 | break; 218 | } 219 | 220 | case LIB3DS_VIEW_BOTTOM: { 221 | Lib3dsChunk c; 222 | c.chunk = CHK_VIEW_BOTTOM; 223 | c.size = 22; 224 | lib3ds_chunk_write(&c, io); 225 | lib3ds_io_write_vector(io, viewport->default_position); 226 | lib3ds_io_write_float(io, viewport->default_width); 227 | break; 228 | } 229 | 230 | case LIB3DS_VIEW_LEFT: { 231 | Lib3dsChunk c; 232 | c.chunk = CHK_VIEW_LEFT; 233 | c.size = 22; 234 | lib3ds_chunk_write(&c, io); 235 | lib3ds_io_write_vector(io, viewport->default_position); 236 | lib3ds_io_write_float(io, viewport->default_width); 237 | break; 238 | } 239 | 240 | case LIB3DS_VIEW_RIGHT: { 241 | Lib3dsChunk c; 242 | c.chunk = CHK_VIEW_RIGHT; 243 | c.size = 22; 244 | lib3ds_chunk_write(&c, io); 245 | lib3ds_io_write_vector(io, viewport->default_position); 246 | lib3ds_io_write_float(io, viewport->default_width); 247 | break; 248 | } 249 | 250 | case LIB3DS_VIEW_FRONT: { 251 | Lib3dsChunk c; 252 | c.chunk = CHK_VIEW_FRONT; 253 | c.size = 22; 254 | lib3ds_chunk_write(&c, io); 255 | lib3ds_io_write_vector(io, viewport->default_position); 256 | lib3ds_io_write_float(io, viewport->default_width); 257 | break; 258 | } 259 | 260 | case LIB3DS_VIEW_BACK: { 261 | Lib3dsChunk c; 262 | c.chunk = CHK_VIEW_BACK; 263 | c.size = 22; 264 | lib3ds_chunk_write(&c, io); 265 | lib3ds_io_write_vector(io, viewport->default_position); 266 | lib3ds_io_write_float(io, viewport->default_width); 267 | break; 268 | } 269 | 270 | case LIB3DS_VIEW_USER: { 271 | Lib3dsChunk c; 272 | c.chunk = CHK_VIEW_USER; 273 | c.size = 34; 274 | lib3ds_chunk_write(&c, io); 275 | lib3ds_io_write_vector(io, viewport->default_position); 276 | lib3ds_io_write_float(io, viewport->default_width); 277 | lib3ds_io_write_float(io, viewport->default_horiz_angle); 278 | lib3ds_io_write_float(io, viewport->default_vert_angle); 279 | lib3ds_io_write_float(io, viewport->default_roll_angle); 280 | break; 281 | } 282 | 283 | case LIB3DS_VIEW_CAMERA: { 284 | Lib3dsChunk c; 285 | c.chunk = CHK_VIEW_CAMERA; 286 | c.size = 17; 287 | lib3ds_chunk_write(&c, io); 288 | lib3ds_io_write(io, viewport->default_camera, 11); 289 | break; 290 | } 291 | } 292 | 293 | lib3ds_chunk_write_end(&c, io); 294 | } 295 | } 296 | 297 | --------------------------------------------------------------------------------