Home | API | File List | Examples | Download

lib3ds_light.c

00001 /*
00002     Copyright (C) 1996-2008 by Jan Eric Kyprianidis <www.kyprianidis.com>
00003     All rights reserved.
00004     
00005     This program is free  software: you can redistribute it and/or modify 
00006     it under the terms of the GNU Lesser General Public License as published 
00007     by the Free Software Foundation, either version 2.1 of the License, or 
00008     (at your option) any later version.
00009 
00010     Thisprogram  is  distributed in the hope that it will be useful, 
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of 
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
00013     GNU Lesser General Public License for more details.
00014     
00015     You should  have received a copy of the GNU Lesser General Public License
00016     along with  this program; If not, see <http://www.gnu.org/licenses/>. 
00017 */
00018 #include "lib3ds_impl.h"
00019 
00020 
00021 Lib3dsLight*
00022 lib3ds_light_new(const char *name) {
00023     Lib3dsLight *light;
00024 
00025     assert(name);
00026     assert(strlen(name) < 64);
00027 
00028     light = (Lib3dsLight*)calloc(sizeof(Lib3dsLight), 1);
00029     if (!light) {
00030         return(0);
00031     }
00032     strcpy(light->name, name);
00033     return(light);
00034 }
00035 
00036 
00037 void
00038 lib3ds_light_free(Lib3dsLight *light) {
00039     memset(light, 0, sizeof(Lib3dsLight));
00040     free(light);
00041 }
00042 
00043 
00044 static void
00045 spotlight_read(Lib3dsLight *light, Lib3dsIo *io) {
00046     Lib3dsChunk c;
00047     uint16_t chunk;
00048     int i;
00049 
00050     lib3ds_chunk_read_start(&c, CHK_DL_SPOTLIGHT, io);
00051 
00052     light->spot_light = TRUE;
00053     for (i = 0; i < 3; ++i) {
00054         light->target[i] = lib3ds_io_read_float(io);
00055     }
00056     light->hotspot = lib3ds_io_read_float(io);
00057     light->falloff = lib3ds_io_read_float(io);
00058     lib3ds_chunk_read_tell(&c, io);
00059 
00060     while ((chunk = lib3ds_chunk_read_next(&c, io)) != 0) {
00061         switch (chunk) {
00062             case CHK_DL_SPOT_ROLL: 
00063                 light->roll = lib3ds_io_read_float(io);
00064                 break;
00065 
00066             case CHK_DL_SHADOWED: {
00067                 light->shadowed = TRUE;
00068                 break;
00069             }
00070 
00071             case CHK_DL_LOCAL_SHADOW2: {
00072                 light->shadow_bias = lib3ds_io_read_float(io);
00073                 light->shadow_filter = lib3ds_io_read_float(io);
00074                 light->shadow_size = lib3ds_io_read_intw(io);
00075                 break;
00076             }
00077 
00078             case CHK_DL_SEE_CONE: {
00079                 light->see_cone = TRUE;
00080                 break;
00081             }
00082 
00083             case CHK_DL_SPOT_RECTANGULAR: {
00084                 light->rectangular_spot = TRUE;
00085                 break;
00086             }
00087 
00088             case CHK_DL_SPOT_ASPECT: {
00089                 light->spot_aspect = lib3ds_io_read_float(io);
00090                 break;
00091             }
00092 
00093             case CHK_DL_SPOT_PROJECTOR: {
00094                 light->use_projector = TRUE;
00095                 lib3ds_io_read_string(io, light->projector, 64);
00096                 break;
00097             }
00098 
00099             case CHK_DL_SPOT_OVERSHOOT: {
00100                 light->spot_overshoot = TRUE;
00101                 break;
00102             }
00103 
00104             case CHK_DL_RAY_BIAS: {
00105                 light->ray_bias = lib3ds_io_read_float(io);
00106                 break;
00107             }
00108 
00109             case CHK_DL_RAYSHAD: {
00110                 light->ray_shadows = TRUE;
00111                 break;
00112             }
00113 
00114             default:
00115                 lib3ds_chunk_unknown(chunk, io);
00116         }
00117     }
00118 
00119     lib3ds_chunk_read_end(&c, io);
00120 }
00121 
00122 
00123 void
00124 lib3ds_light_read(Lib3dsLight *light, Lib3dsIo *io) {
00125     Lib3dsChunk c;
00126     uint16_t chunk;
00127 
00128     lib3ds_chunk_read_start(&c, CHK_N_DIRECT_LIGHT, io);
00129 
00130     {
00131         int i;
00132         for (i = 0; i < 3; ++i) {
00133             light->position[i] = lib3ds_io_read_float(io);
00134         }
00135     }
00136     lib3ds_chunk_read_tell(&c, io);
00137 
00138     while ((chunk = lib3ds_chunk_read_next(&c, io)) != 0) {
00139         switch (chunk) {
00140             case CHK_COLOR_F: {
00141                 int i;
00142                 for (i = 0; i < 3; ++i) {
00143                     light->color[i] = lib3ds_io_read_float(io);
00144                 }
00145                 break;
00146             }
00147 
00148             case CHK_DL_OFF: 
00149                 light->off = TRUE;
00150                 break;
00151 
00152             case CHK_DL_OUTER_RANGE: 
00153                 light->outer_range = lib3ds_io_read_float(io);
00154                 break;
00155 
00156             case CHK_DL_INNER_RANGE: 
00157                 light->inner_range = lib3ds_io_read_float(io);
00158                 break;
00159 
00160             case CHK_DL_MULTIPLIER: 
00161                 light->multiplier = lib3ds_io_read_float(io);
00162                 break;
00163 
00164             case CHK_DL_EXCLUDE: {
00165                 /* FIXME: */
00166                 lib3ds_chunk_unknown(chunk, io);
00167                 break;
00168             }
00169 
00170             case CHK_DL_ATTENUATE: 
00171                 light->attenuation = lib3ds_io_read_float(io);
00172                 break;
00173 
00174             case CHK_DL_SPOTLIGHT: {
00175                 lib3ds_chunk_read_reset(&c, io);
00176                 spotlight_read(light, io);
00177                 break;
00178             }
00179 
00180             default:
00181                 lib3ds_chunk_unknown(chunk, io);
00182         }
00183     }
00184 
00185     lib3ds_chunk_read_end(&c, io);
00186 }
00187 
00188 
00189 void
00190 lib3ds_light_write(Lib3dsLight *light, Lib3dsIo *io) {
00191     Lib3dsChunk c;
00192 
00193     c.chunk = CHK_N_DIRECT_LIGHT;
00194     lib3ds_chunk_write_start(&c, io);
00195 
00196     lib3ds_io_write_vector(io, light->position);
00197     { /*---- LIB3DS_COLOR_F ----*/
00198         Lib3dsChunk c;
00199         c.chunk = CHK_COLOR_F;
00200         c.size = 18;
00201         lib3ds_chunk_write(&c, io);
00202         lib3ds_io_write_rgb(io, light->color);
00203     }
00204     if (light->off) { /*---- LIB3DS_DL_OFF ----*/
00205         Lib3dsChunk c;
00206         c.chunk = CHK_DL_OFF;
00207         c.size = 6;
00208         lib3ds_chunk_write(&c, io);
00209     }
00210     { /*---- LIB3DS_DL_OUTER_RANGE ----*/
00211         Lib3dsChunk c;
00212         c.chunk = CHK_DL_OUTER_RANGE;
00213         c.size = 10;
00214         lib3ds_chunk_write(&c, io);
00215         lib3ds_io_write_float(io, light->outer_range);
00216     }
00217     { /*---- LIB3DS_DL_INNER_RANGE ----*/
00218         Lib3dsChunk c;
00219         c.chunk = CHK_DL_INNER_RANGE;
00220         c.size = 10;
00221         lib3ds_chunk_write(&c, io);
00222         lib3ds_io_write_float(io, light->inner_range);
00223     }
00224     { /*---- LIB3DS_DL_MULTIPLIER ----*/
00225         Lib3dsChunk c;
00226         c.chunk = CHK_DL_MULTIPLIER;
00227         c.size = 10;
00228         lib3ds_chunk_write(&c, io);
00229         lib3ds_io_write_float(io, light->multiplier);
00230     }
00231     if (light->attenuation) { /*---- LIB3DS_DL_ATTENUATE ----*/
00232         Lib3dsChunk c;
00233         c.chunk = CHK_DL_ATTENUATE;
00234         c.size = 6;
00235         lib3ds_chunk_write(&c, io);
00236     }
00237 
00238     if (light->spot_light) {
00239         Lib3dsChunk c;
00240 
00241         c.chunk = CHK_DL_SPOTLIGHT;
00242         lib3ds_chunk_write_start(&c, io);
00243 
00244         lib3ds_io_write_vector(io, light->target);
00245         lib3ds_io_write_float(io, light->hotspot);
00246         lib3ds_io_write_float(io, light->falloff);
00247 
00248         { /*---- LIB3DS_DL_SPOT_ROLL ----*/
00249             Lib3dsChunk c;
00250             c.chunk = CHK_DL_SPOT_ROLL;
00251             c.size = 10;
00252             lib3ds_chunk_write(&c, io);
00253             lib3ds_io_write_float(io, light->roll);
00254         }
00255         if (light->shadowed) { /*---- LIB3DS_DL_SHADOWED ----*/
00256             Lib3dsChunk c;
00257             c.chunk = CHK_DL_SHADOWED;
00258             c.size = 6;
00259             lib3ds_chunk_write(&c, io);
00260         }
00261         if ((fabs(light->shadow_bias) > LIB3DS_EPSILON) ||
00262             (fabs(light->shadow_filter) > LIB3DS_EPSILON) ||
00263             (light->shadow_size != 0)) { /*---- LIB3DS_DL_LOCAL_SHADOW2 ----*/
00264             Lib3dsChunk c;
00265             c.chunk = CHK_DL_LOCAL_SHADOW2;
00266             c.size = 16;
00267             lib3ds_chunk_write(&c, io);
00268             lib3ds_io_write_float(io, light->shadow_bias);
00269             lib3ds_io_write_float(io, light->shadow_filter);
00270             lib3ds_io_write_intw(io, light->shadow_size);
00271         }
00272         if (light->see_cone) { /*---- LIB3DS_DL_SEE_CONE ----*/
00273             Lib3dsChunk c;
00274             c.chunk = CHK_DL_SEE_CONE;
00275             c.size = 6;
00276             lib3ds_chunk_write(&c, io);
00277         }
00278         if (light->rectangular_spot) { /*---- LIB3DS_DL_SPOT_RECTANGULAR ----*/
00279             Lib3dsChunk c;
00280             c.chunk = CHK_DL_SPOT_RECTANGULAR;
00281             c.size = 6;
00282             lib3ds_chunk_write(&c, io);
00283         }
00284         if (fabs(light->spot_aspect) > LIB3DS_EPSILON) { /*---- LIB3DS_DL_SPOT_ASPECT ----*/
00285             Lib3dsChunk c;
00286             c.chunk = CHK_DL_SPOT_ASPECT;
00287             c.size = 10;
00288             lib3ds_chunk_write(&c, io);
00289             lib3ds_io_write_float(io, light->spot_aspect);
00290         }
00291         if (light->use_projector) { /*---- LIB3DS_DL_SPOT_PROJECTOR ----*/
00292             Lib3dsChunk c;
00293             c.chunk = CHK_DL_SPOT_PROJECTOR;
00294             c.size = 10;
00295             lib3ds_chunk_write(&c, io);
00296             lib3ds_io_write_string(io, light->projector);
00297         }
00298         if (light->spot_overshoot) { /*---- LIB3DS_DL_SPOT_OVERSHOOT ----*/
00299             Lib3dsChunk c;
00300             c.chunk = CHK_DL_SPOT_OVERSHOOT;
00301             c.size = 6;
00302             lib3ds_chunk_write(&c, io);
00303         }
00304         if (fabs(light->ray_bias) > LIB3DS_EPSILON) { /*---- LIB3DS_DL_RAY_BIAS ----*/
00305             Lib3dsChunk c;
00306             c.chunk = CHK_DL_RAY_BIAS;
00307             c.size = 10;
00308             lib3ds_chunk_write(&c, io);
00309             lib3ds_io_write_float(io, light->ray_bias);
00310         }
00311         if (light->ray_shadows) { /*---- LIB3DS_DL_RAYSHAD ----*/
00312             Lib3dsChunk c;
00313             c.chunk = CHK_DL_RAYSHAD;
00314             c.size = 6;
00315             lib3ds_chunk_write(&c, io);
00316         }
00317         lib3ds_chunk_write_end(&c, io);
00318     }
00319 
00320     lib3ds_chunk_write_end(&c, io);
00321 }
00322 
00323