00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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
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 {
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) {
00205 Lib3dsChunk c;
00206 c.chunk = CHK_DL_OFF;
00207 c.size = 6;
00208 lib3ds_chunk_write(&c, io);
00209 }
00210 {
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 {
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 {
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) {
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 {
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) {
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)) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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