C:/jkyprian/devel/lib3ds/lib3ds/material.c

00001 /*
00002  * The 3D Studio File Format Library
00003  * Copyright (C) 1996-2007 by Jan Eric Kyprianidis <www.kyprianidis.com>
00004  * All rights reserved.
00005  *
00006  * This program is  free  software;  you can redistribute it and/or modify it
00007  * under the terms of the  GNU Lesser General Public License  as published by 
00008  * the  Free Software Foundation;  either version 2.1 of the License,  or (at 
00009  * your option) any later version.
00010  *
00011  * This  program  is  distributed in  the  hope that it will  be useful,  but
00012  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
00013  * or  FITNESS FOR A  PARTICULAR PURPOSE.  See the  GNU Lesser General Public  
00014  * License for more details.
00015  *
00016  * You should  have received  a copy of the GNU Lesser General Public License
00017  * along with  this program;  if not, write to the  Free Software Foundation,
00018  * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019  *
00020  * $Id: material.c,v 1.24 2007/06/20 17:04:08 jeh Exp $
00021  */
00022 #include <lib3ds/material.h>
00023 #include <lib3ds/chunk.h>
00024 #include <lib3ds/io.h>
00025 #include <stdlib.h>
00026 #include <math.h>
00027 #include <string.h>
00028 
00029 
00035 static void
00036 initialize_texture_map(Lib3dsTextureMap *map)
00037 {
00038   map->flags = 0x10;
00039   map->percent = 1.0f;
00040   map->scale[0] = 1.0f;
00041   map->scale[1] = 1.0f;
00042 }
00043 
00044 
00055 Lib3dsMaterial*
00056 lib3ds_material_new()
00057 {
00058   Lib3dsMaterial *mat;
00059 
00060   mat = (Lib3dsMaterial*)calloc(sizeof(Lib3dsMaterial), 1);
00061   if (!mat) {
00062     return(0);
00063   }
00064 
00065   mat->ambient[0] = mat->ambient[1] = mat->ambient[2] = 0.588235f;
00066   mat->diffuse[0] = mat->diffuse[1] = mat->diffuse[2] = 0.588235f;
00067   mat->specular[0] = mat->specular[1] = mat->specular[2] = 0.898039f;
00068   mat->shininess = 0.1f;
00069   mat->wire_size = 1.0f;
00070   mat->shading = 3;
00071 
00072   initialize_texture_map(&mat->texture1_map);
00073   initialize_texture_map(&mat->texture1_mask);
00074   initialize_texture_map(&mat->texture2_map);
00075   initialize_texture_map(&mat->texture2_mask);
00076   initialize_texture_map(&mat->opacity_map);
00077   initialize_texture_map(&mat->opacity_mask);
00078   initialize_texture_map(&mat->bump_map);
00079   initialize_texture_map(&mat->bump_mask);
00080   initialize_texture_map(&mat->specular_map);
00081   initialize_texture_map(&mat->specular_mask);
00082   initialize_texture_map(&mat->shininess_map);
00083   initialize_texture_map(&mat->shininess_mask);
00084   initialize_texture_map(&mat->self_illum_map);
00085   initialize_texture_map(&mat->self_illum_mask);
00086   initialize_texture_map(&mat->reflection_map);
00087   initialize_texture_map(&mat->reflection_mask);
00088   
00089   return(mat);
00090 }
00091 
00092 
00096 void
00097 lib3ds_material_free(Lib3dsMaterial *material)
00098 {
00099   memset(material, 0, sizeof(Lib3dsMaterial));
00100   free(material);
00101 }
00102 
00103 
00104 static Lib3dsBool
00105 color_read(Lib3dsRgba rgb, Lib3dsIo *io)
00106 {
00107   Lib3dsChunk c;
00108   Lib3dsWord chunk;
00109   Lib3dsBool have_lin=LIB3DS_FALSE;
00110 
00111   if (!lib3ds_chunk_read_start(&c, 0, io)) {
00112     return(LIB3DS_FALSE);
00113   }
00114 
00115   while ((chunk=lib3ds_chunk_read_next(&c, io))!=0) {
00116     switch (chunk) {
00117       case LIB3DS_LIN_COLOR_24:
00118         {
00119           int i;
00120           for (i=0; i<3; ++i) {
00121             rgb[i]=1.0f*lib3ds_io_read_byte(io)/255.0f;
00122           }
00123           rgb[3]=1.0f;
00124         }
00125         have_lin=LIB3DS_TRUE;
00126         break;
00127       case LIB3DS_COLOR_24:
00128         /* gamma corrected color chunk
00129            replaced in 3ds R3 by LIN_COLOR_24 */
00130         if (!have_lin) {
00131           int i;
00132           for (i=0; i<3; ++i) {
00133             rgb[i]=1.0f*lib3ds_io_read_byte(io)/255.0f;
00134           }
00135           rgb[3]=1.0f;
00136         }
00137         break;
00138       case LIB3DS_LIN_COLOR_F:
00139         {
00140           int i;
00141           for (i=0; i<3; ++i) {
00142             rgb[i]=lib3ds_io_read_float(io);
00143           }
00144           rgb[3]=1.0f;
00145         }
00146         have_lin=LIB3DS_TRUE;
00147         break;
00148       case LIB3DS_COLOR_F:
00149         if (!have_lin) {
00150           int i;
00151           for (i=0; i<3; ++i) {
00152             rgb[i]=lib3ds_io_read_float(io);
00153           }
00154           rgb[3]=1.0f;
00155         }
00156         break;
00157       default:
00158         lib3ds_chunk_unknown(chunk);
00159     }
00160   }
00161   
00162   lib3ds_chunk_read_end(&c, io);
00163   return(LIB3DS_TRUE);
00164 }
00165 
00166 
00167 static Lib3dsBool
00168 int_percentage_read(Lib3dsFloat *p, Lib3dsIo *io)
00169 {
00170   Lib3dsChunk c;
00171   Lib3dsWord chunk;
00172 
00173   if (!lib3ds_chunk_read_start(&c, 0, io)) {
00174     return(LIB3DS_FALSE);
00175   }
00176 
00177   while ((chunk=lib3ds_chunk_read_next(&c, io))!=0) {
00178     switch (chunk) {
00179       case LIB3DS_INT_PERCENTAGE:
00180         {
00181           Lib3dsIntw i=lib3ds_io_read_intw(io);
00182           *p=(Lib3dsFloat)(1.0*i/100.0);
00183         }
00184         break;
00185       default:
00186         lib3ds_chunk_unknown(chunk);
00187     }
00188   }
00189   
00190   lib3ds_chunk_read_end(&c, io);
00191   return(LIB3DS_TRUE);
00192 }
00193 
00194 
00195 static Lib3dsBool
00196 texture_map_read(Lib3dsTextureMap *map, Lib3dsIo *io)
00197 {
00198   Lib3dsChunk c;
00199   Lib3dsWord chunk;
00200 
00201   if (!lib3ds_chunk_read_start(&c, 0, io)) {
00202     return(LIB3DS_FALSE);
00203   }
00204 
00205   while ((chunk=lib3ds_chunk_read_next(&c, io))!=0) {
00206     switch (chunk) {
00207       case LIB3DS_INT_PERCENTAGE:
00208         {
00209           map->percent=1.0f*lib3ds_io_read_intw(io)/100.0f;
00210         }
00211         break;
00212       case LIB3DS_MAT_MAPNAME:
00213         {
00214           if (!lib3ds_io_read_string(io, map->name, 64)) {
00215             return(LIB3DS_FALSE);
00216           }
00217           lib3ds_chunk_dump_info("  NAME=%s", map->name);
00218         }
00219         break;
00220       case LIB3DS_MAT_MAP_TILING:
00221         {
00222           map->flags=lib3ds_io_read_word(io);
00223         }
00224         break;
00225       case LIB3DS_MAT_MAP_TEXBLUR:
00226         {
00227           map->blur=lib3ds_io_read_float(io);
00228         }
00229         break;
00230       case LIB3DS_MAT_MAP_USCALE:
00231         {
00232           map->scale[0]=lib3ds_io_read_float(io);
00233         }
00234         break;
00235       case LIB3DS_MAT_MAP_VSCALE:
00236         {
00237           map->scale[1]=lib3ds_io_read_float(io);
00238         }
00239         break;
00240       case LIB3DS_MAT_MAP_UOFFSET:
00241         {
00242           map->offset[0]=lib3ds_io_read_float(io);
00243         }
00244         break;
00245       case LIB3DS_MAT_MAP_VOFFSET:
00246         {
00247           map->offset[1]=lib3ds_io_read_float(io);
00248         }
00249         break;
00250       case LIB3DS_MAT_MAP_ANG:
00251         {
00252           map->rotation=lib3ds_io_read_float(io);
00253         }
00254         break;
00255       case LIB3DS_MAT_MAP_COL1:
00256         {
00257           map->tint_1[0]=1.0f*lib3ds_io_read_byte(io)/255.0f;
00258           map->tint_1[1]=1.0f*lib3ds_io_read_byte(io)/255.0f;
00259           map->tint_1[2]=1.0f*lib3ds_io_read_byte(io)/255.0f;
00260         }
00261         break;
00262       case LIB3DS_MAT_MAP_COL2:
00263         {
00264           map->tint_2[0]=1.0f*lib3ds_io_read_byte(io)/255.0f;
00265           map->tint_2[1]=1.0f*lib3ds_io_read_byte(io)/255.0f;
00266           map->tint_2[2]=1.0f*lib3ds_io_read_byte(io)/255.0f;
00267         }
00268         break;
00269       case LIB3DS_MAT_MAP_RCOL:
00270         {
00271           map->tint_r[0]=1.0f*lib3ds_io_read_byte(io)/255.0f;
00272           map->tint_r[1]=1.0f*lib3ds_io_read_byte(io)/255.0f;
00273           map->tint_r[2]=1.0f*lib3ds_io_read_byte(io)/255.0f;
00274         }
00275         break;
00276       case LIB3DS_MAT_MAP_GCOL:
00277         {
00278           map->tint_g[0]=1.0f*lib3ds_io_read_byte(io)/255.0f;
00279           map->tint_g[1]=1.0f*lib3ds_io_read_byte(io)/255.0f;
00280           map->tint_g[2]=1.0f*lib3ds_io_read_byte(io)/255.0f;
00281         }
00282         break;
00283       case LIB3DS_MAT_MAP_BCOL:
00284         {
00285           map->tint_b[0]=1.0f*lib3ds_io_read_byte(io)/255.0f;
00286           map->tint_b[1]=1.0f*lib3ds_io_read_byte(io)/255.0f;
00287           map->tint_b[2]=1.0f*lib3ds_io_read_byte(io)/255.0f;
00288         }
00289         break;
00290       default:
00291         lib3ds_chunk_unknown(chunk);
00292     }
00293   }
00294   
00295   lib3ds_chunk_read_end(&c, io);
00296   return(LIB3DS_TRUE);
00297 }
00298 
00299 
00303 static void
00304 texture_dump(const char *maptype, Lib3dsTextureMap *texture)
00305 {
00306   ASSERT(texture);
00307   if (strlen(texture->name)==0) {
00308     return;
00309   }
00310   printf("  %s:\n", maptype);
00311   printf("    name:        %s\n", texture->name);
00312   printf("    flags:       %X\n", (unsigned)texture->flags);
00313   printf("    percent:     %f\n", texture->percent);
00314   printf("    blur:        %f\n", texture->blur);
00315   printf("    scale:       (%f, %f)\n", texture->scale[0], texture->scale[1]);
00316   printf("    offset:      (%f, %f)\n", texture->offset[0], texture->offset[1]);
00317   printf("    rotation:    %f\n", texture->rotation);
00318   printf("    tint_1:      (%f, %f, %f)\n",
00319     texture->tint_1[0], texture->tint_1[1], texture->tint_1[2]);
00320   printf("    tint_2:      (%f, %f, %f)\n",
00321     texture->tint_2[0], texture->tint_2[1], texture->tint_2[2]);
00322   printf("    tint_r:      (%f, %f, %f)\n",
00323     texture->tint_r[0], texture->tint_r[1], texture->tint_r[2]);
00324   printf("    tint_g:      (%f, %f, %f)\n",
00325     texture->tint_g[0], texture->tint_g[1], texture->tint_g[2]);
00326   printf("    tint_b:      (%f, %f, %f)\n",
00327     texture->tint_b[0], texture->tint_b[1], texture->tint_b[2]);
00328 }
00329 
00330 
00334 void
00335 lib3ds_material_dump(Lib3dsMaterial *material)
00336 {
00337   ASSERT(material);
00338   printf("  name:          %s\n", material->name);
00339   printf("  ambient:       (%f, %f, %f)\n",
00340     material->ambient[0], material->ambient[1], material->ambient[2]);
00341   printf("  diffuse:       (%f, %f, %f)\n",
00342     material->diffuse[0], material->diffuse[1], material->diffuse[2]);
00343   printf("  specular:      (%f, %f, %f)\n",
00344     material->specular[0], material->specular[1], material->specular[2]);
00345   printf("  shininess:     %f\n", material->shininess);
00346   printf("  shin_strength: %f\n", material->shin_strength);
00347   printf("  use_blur:      %s\n", material->use_blur ? "yes" : "no");
00348   printf("  blur:          %f\n", material->blur);
00349   printf("  falloff:       %f\n", material->falloff);
00350   printf("  additive:      %s\n", material->additive ? "yes" : "no");
00351   printf("  use_falloff:   %s\n", material->use_falloff ? "yes" : "no");
00352   printf("  self_illum:    %s\n", material->self_illum ? "yes" : "no");
00353   printf("  self_ilpct:    %f\n", material->self_ilpct);
00354   printf("  shading:       %d\n", material->shading);
00355   printf("  soften:        %s\n", material->soften ? "yes" : "no");
00356   printf("  face_map:      %s\n", material->face_map ? "yes" : "no");
00357   printf("  two_sided:     %s\n", material->two_sided ? "yes" : "no");
00358   printf("  map_decal:     %s\n", material->map_decal ? "yes" : "no");
00359   printf("  use_wire:      %s\n", material->use_wire ? "yes" : "no");
00360   printf("  use_wire_abs:  %s\n", material->use_wire_abs ? "yes" : "no");
00361   printf("  wire_size:     %f\n", material->wire_size);
00362   texture_dump("texture1_map", &material->texture1_map);
00363   texture_dump("texture1_mask", &material->texture1_mask);
00364   texture_dump("texture2_map", &material->texture2_map);
00365   texture_dump("texture2_mask", &material->texture2_mask);
00366   texture_dump("opacity_map", &material->opacity_map);
00367   texture_dump("opacity_mask", &material->opacity_mask);
00368   texture_dump("bump_map", &material->bump_map);
00369   texture_dump("bump_mask", &material->bump_mask);
00370   texture_dump("specular_map", &material->specular_map);
00371   texture_dump("specular_mask", &material->specular_mask);
00372   texture_dump("shininess_map", &material->shininess_map);
00373   texture_dump("shininess_mask", &material->shininess_mask);
00374   texture_dump("self_illum_map", &material->self_illum_map);
00375   texture_dump("self_illum_mask", &material->self_illum_mask);
00376   texture_dump("reflection_map", &material->reflection_map);
00377   texture_dump("reflection_mask", &material->reflection_mask);
00378   printf("  autorefl_map:\n");
00379   printf("    flags        %X\n", (unsigned)material->autorefl_map.flags);
00380   printf("    level        %d\n", (int)material->autorefl_map.level);
00381   printf("    size         %d\n", (int)material->autorefl_map.size);
00382   printf("    frame_step   %d\n", (int)material->autorefl_map.frame_step);
00383   printf("\n");
00384 }
00385 
00386 
00390 Lib3dsBool
00391 lib3ds_material_read(Lib3dsMaterial *material, Lib3dsIo *io)
00392 {
00393   Lib3dsChunk c;
00394   Lib3dsWord chunk;
00395 
00396   ASSERT(material);
00397   if (!lib3ds_chunk_read_start(&c, LIB3DS_MAT_ENTRY, io)) {
00398     return(LIB3DS_FALSE);
00399   }
00400 
00401   while ((chunk=lib3ds_chunk_read_next(&c, io))!=0) {
00402     switch (chunk) {
00403       case LIB3DS_MAT_NAME:
00404         {
00405           if (!lib3ds_io_read_string(io, material->name, 64)) {
00406             return(LIB3DS_FALSE);
00407           }
00408           lib3ds_chunk_dump_info("  NAME=%s", material->name);
00409         }
00410         break;
00411       case LIB3DS_MAT_AMBIENT:
00412         {
00413           lib3ds_chunk_read_reset(&c, io);
00414           if (!color_read(material->ambient, io)) {
00415             return(LIB3DS_FALSE);
00416           }
00417         }
00418         break;
00419       case LIB3DS_MAT_DIFFUSE:
00420         {
00421           lib3ds_chunk_read_reset(&c, io);
00422           if (!color_read(material->diffuse, io)) {
00423             return(LIB3DS_FALSE);
00424           }
00425         }
00426         break;
00427       case LIB3DS_MAT_SPECULAR:
00428         {
00429           lib3ds_chunk_read_reset(&c, io);
00430           if (!color_read(material->specular, io)) {
00431             return(LIB3DS_FALSE);
00432           }
00433         }
00434         break;
00435       case LIB3DS_MAT_SHININESS:
00436         {
00437           lib3ds_chunk_read_reset(&c, io);
00438           if (!int_percentage_read(&material->shininess, io)) {
00439             return(LIB3DS_FALSE);
00440           }
00441         }
00442         break;
00443       case LIB3DS_MAT_SHIN2PCT:
00444         {
00445           lib3ds_chunk_read_reset(&c, io);
00446           if (!int_percentage_read(&material->shin_strength, io)) {
00447             return(LIB3DS_FALSE);
00448           }
00449         }
00450         break;
00451       case LIB3DS_MAT_TRANSPARENCY:
00452         {
00453           lib3ds_chunk_read_reset(&c, io);
00454           if (!int_percentage_read(&material->transparency, io)) {
00455             return(LIB3DS_FALSE);
00456           }
00457         }
00458         break;
00459       case LIB3DS_MAT_XPFALL:
00460         {
00461           lib3ds_chunk_read_reset(&c, io);
00462           if (!int_percentage_read(&material->falloff, io)) {
00463             return(LIB3DS_FALSE);
00464           }
00465         }
00466         break;
00467       case LIB3DS_MAT_SELF_ILPCT:
00468         {
00469           lib3ds_chunk_read_reset(&c, io);
00470           if (!int_percentage_read(&material->self_ilpct, io)) {
00471             return(LIB3DS_FALSE);
00472           }
00473         }
00474         break;
00475       case LIB3DS_MAT_USE_XPFALL:
00476         {
00477           material->use_falloff=LIB3DS_TRUE;
00478         }
00479         break;
00480       case LIB3DS_MAT_REFBLUR:
00481         {
00482           lib3ds_chunk_read_reset(&c, io);
00483           if (!int_percentage_read(&material->blur, io)) {
00484             return(LIB3DS_FALSE);
00485           }
00486         }
00487         break;
00488       case LIB3DS_MAT_USE_REFBLUR:
00489         {
00490           material->use_blur=LIB3DS_TRUE;
00491         }
00492         break;
00493       case LIB3DS_MAT_SHADING:
00494         {
00495           material->shading=lib3ds_io_read_intw(io);
00496         }
00497         break;
00498       case LIB3DS_MAT_SELF_ILLUM:
00499         {
00500           material->self_illum=LIB3DS_TRUE;
00501         }
00502         break;
00503       case LIB3DS_MAT_TWO_SIDE:
00504         {
00505           material->two_sided=LIB3DS_TRUE;
00506         }
00507         break;
00508       case LIB3DS_MAT_DECAL:
00509         {
00510           material->map_decal=LIB3DS_TRUE;
00511         }
00512         break;
00513       case LIB3DS_MAT_ADDITIVE:
00514         {
00515           material->additive=LIB3DS_TRUE;
00516         }
00517         break;
00518       case LIB3DS_MAT_FACEMAP:
00519         {
00520           material->face_map=LIB3DS_TRUE;
00521         }
00522         break;
00523       case LIB3DS_MAT_PHONGSOFT:
00524         {
00525           material->soften=LIB3DS_TRUE;
00526         }
00527         break;
00528       case LIB3DS_MAT_WIRE:
00529         {
00530           material->use_wire=LIB3DS_TRUE;
00531         }
00532         break;
00533       case LIB3DS_MAT_WIREABS:
00534         {
00535           material->use_wire_abs=LIB3DS_TRUE;
00536         }
00537         break;
00538       case LIB3DS_MAT_WIRE_SIZE:
00539         {
00540           material->wire_size=lib3ds_io_read_float(io);
00541         }
00542         break;
00543       case LIB3DS_MAT_TEXMAP:
00544         {
00545           lib3ds_chunk_read_reset(&c, io);
00546           if (!texture_map_read(&material->texture1_map, io)) {
00547             return(LIB3DS_FALSE);
00548           }
00549         }
00550         break;
00551       case LIB3DS_MAT_TEXMASK:
00552         {
00553           lib3ds_chunk_read_reset(&c, io);
00554           if (!texture_map_read(&material->texture1_mask, io)) {
00555             return(LIB3DS_FALSE);
00556           }
00557         }
00558         break;
00559       case LIB3DS_MAT_TEX2MAP:
00560         {
00561           lib3ds_chunk_read_reset(&c, io);
00562           if (!texture_map_read(&material->texture2_map, io)) {
00563             return(LIB3DS_FALSE);
00564           }
00565         }
00566         break;
00567       case LIB3DS_MAT_TEX2MASK:
00568         {
00569           lib3ds_chunk_read_reset(&c, io);
00570           if (!texture_map_read(&material->texture2_mask, io)) {
00571             return(LIB3DS_FALSE);
00572           }
00573         }
00574         break;
00575       case LIB3DS_MAT_OPACMAP:
00576         {
00577           lib3ds_chunk_read_reset(&c, io);
00578           if (!texture_map_read(&material->opacity_map, io)) {
00579             return(LIB3DS_FALSE);
00580           }
00581         }
00582         break;
00583       case LIB3DS_MAT_OPACMASK:
00584         {
00585           lib3ds_chunk_read_reset(&c, io);
00586           if (!texture_map_read(&material->opacity_mask, io)) {
00587             return(LIB3DS_FALSE);
00588           }
00589         }
00590         break;
00591       case LIB3DS_MAT_BUMPMAP:
00592         {
00593           lib3ds_chunk_read_reset(&c, io);
00594           if (!texture_map_read(&material->bump_map, io)) {
00595             return(LIB3DS_FALSE);
00596           }
00597         }
00598         break;
00599       case LIB3DS_MAT_BUMPMASK:
00600         {
00601           lib3ds_chunk_read_reset(&c, io);
00602           if (!texture_map_read(&material->bump_mask, io)) {
00603             return(LIB3DS_FALSE);
00604           }
00605         }
00606         break;
00607       case LIB3DS_MAT_SPECMAP:
00608         {
00609           lib3ds_chunk_read_reset(&c, io);
00610           if (!texture_map_read(&material->specular_map, io)) {
00611             return(LIB3DS_FALSE);
00612           }
00613         }
00614         break;
00615       case LIB3DS_MAT_SPECMASK:
00616         {
00617           lib3ds_chunk_read_reset(&c, io);
00618           if (!texture_map_read(&material->specular_mask, io)) {
00619             return(LIB3DS_FALSE);
00620           }
00621         }
00622         break;
00623       case LIB3DS_MAT_SHINMAP:
00624         {
00625           lib3ds_chunk_read_reset(&c, io);
00626           if (!texture_map_read(&material->shininess_map, io)) {
00627             return(LIB3DS_FALSE);
00628           }
00629         }
00630         break;
00631       case LIB3DS_MAT_SHINMASK:
00632         {
00633           lib3ds_chunk_read_reset(&c, io);
00634           if (!texture_map_read(&material->shininess_mask, io)) {
00635             return(LIB3DS_FALSE);
00636           }
00637         }
00638         break;
00639       case LIB3DS_MAT_SELFIMAP:
00640         {
00641           lib3ds_chunk_read_reset(&c, io);
00642           if (!texture_map_read(&material->self_illum_map, io)) {
00643             return(LIB3DS_FALSE);
00644           }
00645         }
00646         break;
00647       case LIB3DS_MAT_SELFIMASK:
00648         {
00649           lib3ds_chunk_read_reset(&c, io);
00650           if (!texture_map_read(&material->self_illum_mask, io)) {
00651             return(LIB3DS_FALSE);
00652           }
00653         }
00654         break;
00655       case LIB3DS_MAT_REFLMAP:
00656         {
00657           lib3ds_chunk_read_reset(&c, io);
00658           if (!texture_map_read(&material->reflection_map, io)) {
00659             return(LIB3DS_FALSE);
00660           }
00661         }
00662         break;
00663       case LIB3DS_MAT_REFLMASK:
00664         {
00665           lib3ds_chunk_read_reset(&c, io);
00666           if (!texture_map_read(&material->reflection_mask, io)) {
00667             return(LIB3DS_FALSE);
00668           }
00669         }
00670         break;
00671       case LIB3DS_MAT_ACUBIC:
00672         {
00673           lib3ds_io_read_intb(io);
00674           material->autorefl_map.level=lib3ds_io_read_intb(io);
00675           material->autorefl_map.flags=lib3ds_io_read_intw(io);
00676           material->autorefl_map.size=lib3ds_io_read_intd(io);
00677           material->autorefl_map.frame_step=lib3ds_io_read_intd(io);
00678         }
00679         break;
00680       default:
00681         lib3ds_chunk_unknown(chunk);
00682     }
00683   }
00684 
00685   lib3ds_chunk_read_end(&c, io);
00686   return(LIB3DS_TRUE);
00687 }
00688 
00689 
00690 static Lib3dsBool
00691 color_write(Lib3dsRgba rgb, Lib3dsIo *io)
00692 {
00693   Lib3dsChunk c;
00694 
00695   c.chunk=LIB3DS_COLOR_24;
00696   c.size=9;
00697   lib3ds_chunk_write(&c,io);
00698   lib3ds_io_write_byte(io, (Lib3dsByte)floor(255.0*rgb[0]+0.5));
00699   lib3ds_io_write_byte(io, (Lib3dsByte)floor(255.0*rgb[1]+0.5));
00700   lib3ds_io_write_byte(io, (Lib3dsByte)floor(255.0*rgb[2]+0.5));
00701 
00702   c.chunk=LIB3DS_LIN_COLOR_24;
00703   c.size=9;
00704   lib3ds_chunk_write(&c,io);
00705   lib3ds_io_write_byte(io, (Lib3dsByte)floor(255.0*rgb[0]+0.5));
00706   lib3ds_io_write_byte(io, (Lib3dsByte)floor(255.0*rgb[1]+0.5));
00707   lib3ds_io_write_byte(io, (Lib3dsByte)floor(255.0*rgb[2]+0.5));
00708 
00709   return(LIB3DS_TRUE);
00710 }
00711 
00712 
00713 static Lib3dsBool
00714 int_percentage_write(Lib3dsFloat p, Lib3dsIo *io)
00715 {
00716   Lib3dsChunk c;
00717 
00718   c.chunk=LIB3DS_INT_PERCENTAGE;
00719   c.size=8;
00720   lib3ds_chunk_write(&c,io);
00721   lib3ds_io_write_intw(io, (Lib3dsByte)floor(100.0*p+0.5));
00722 
00723   return(LIB3DS_TRUE);
00724 }
00725 
00726 
00727 static Lib3dsBool
00728 texture_map_write(Lib3dsWord chunk, Lib3dsTextureMap *map, Lib3dsIo *io)
00729 {
00730   Lib3dsChunk c;
00731 
00732   if (strlen(map->name)==0) {
00733     return(LIB3DS_TRUE);
00734   }
00735   c.chunk=chunk;
00736   if (!lib3ds_chunk_write_start(&c,io)) {
00737     return(LIB3DS_FALSE);
00738   }
00739   
00740   int_percentage_write(map->percent,io);
00741 
00742   { /*---- LIB3DS_MAT_MAPNAME ----*/
00743     Lib3dsChunk c;
00744     c.chunk=LIB3DS_MAT_MAPNAME;
00745     c.size=6+(Lib3dsDword)strlen(map->name)+1;
00746     lib3ds_chunk_write(&c,io);
00747     lib3ds_io_write_string(io, map->name);
00748   }
00749 
00750   { /*---- LIB3DS_MAT_MAP_TILING ----*/
00751     Lib3dsChunk c;
00752     c.chunk=LIB3DS_MAT_MAP_TILING;
00753     c.size=8;
00754     lib3ds_chunk_write(&c,io);
00755     lib3ds_io_write_word(io, (Lib3dsWord)map->flags);
00756   }
00757   
00758   { /*---- LIB3DS_MAT_MAP_TEXBLUR ----*/
00759     Lib3dsChunk c;
00760     c.chunk=LIB3DS_MAT_MAP_TEXBLUR;
00761     c.size=10;
00762     lib3ds_chunk_write(&c,io);
00763     lib3ds_io_write_float(io, map->blur);
00764   }
00765 
00766   { /*---- LIB3DS_MAT_MAP_USCALE ----*/
00767     Lib3dsChunk c;
00768     c.chunk=LIB3DS_MAT_MAP_USCALE;
00769     c.size=10;
00770     lib3ds_chunk_write(&c,io);
00771     lib3ds_io_write_float(io, map->scale[0]);
00772   }
00773 
00774   { /*---- LIB3DS_MAT_MAP_VSCALE ----*/
00775     Lib3dsChunk c;
00776     c.chunk=LIB3DS_MAT_MAP_VSCALE;
00777     c.size=10;
00778     lib3ds_chunk_write(&c,io);
00779     lib3ds_io_write_float(io, map->scale[1]);
00780   }
00781 
00782   { /*---- LIB3DS_MAT_MAP_UOFFSET ----*/
00783     Lib3dsChunk c;
00784     c.chunk=LIB3DS_MAT_MAP_UOFFSET;
00785     c.size=10;
00786     lib3ds_chunk_write(&c,io);
00787     lib3ds_io_write_float(io, map->offset[0]);
00788   }
00789 
00790   { /*---- LIB3DS_MAT_MAP_VOFFSET ----*/
00791     Lib3dsChunk c;
00792     c.chunk=LIB3DS_MAT_MAP_VOFFSET;
00793     c.size=10;
00794     lib3ds_chunk_write(&c,io);
00795     lib3ds_io_write_float(io, map->offset[1]);
00796   }
00797 
00798   { /*---- LIB3DS_MAT_MAP_ANG ----*/
00799     Lib3dsChunk c;
00800     c.chunk=LIB3DS_MAT_MAP_ANG;
00801     c.size=10;
00802     lib3ds_chunk_write(&c,io);
00803     lib3ds_io_write_float(io, map->rotation);
00804   }
00805 
00806   { /*---- LIB3DS_MAT_MAP_COL1 ----*/
00807     Lib3dsChunk c;
00808     c.chunk=LIB3DS_MAT_MAP_COL1;
00809     c.size=9;
00810     lib3ds_chunk_write(&c,io);
00811     lib3ds_io_write_byte(io, (Lib3dsByte)floor(255.0*map->tint_1[0]+0.5));
00812     lib3ds_io_write_byte(io, (Lib3dsByte)floor(255.0*map->tint_1[1]+0.5));
00813     lib3ds_io_write_byte(io, (Lib3dsByte)floor(255.0*map->tint_1[2]+0.5));
00814   }
00815 
00816   { /*---- LIB3DS_MAT_MAP_COL2 ----*/
00817     Lib3dsChunk c;
00818     c.chunk=LIB3DS_MAT_MAP_COL2;
00819     c.size=9;
00820     lib3ds_chunk_write(&c,io);
00821     lib3ds_io_write_byte(io, (Lib3dsByte)floor(255.0*map->tint_2[0]+0.5));
00822     lib3ds_io_write_byte(io, (Lib3dsByte)floor(255.0*map->tint_2[1]+0.5));
00823     lib3ds_io_write_byte(io, (Lib3dsByte)floor(255.0*map->tint_2[2]+0.5));
00824   }
00825   
00826   { /*---- LIB3DS_MAT_MAP_RCOL ----*/
00827     Lib3dsChunk c;
00828     c.chunk=LIB3DS_MAT_MAP_RCOL;
00829     c.size=9;
00830     lib3ds_chunk_write(&c,io);
00831     lib3ds_io_write_byte(io, (Lib3dsByte)floor(255.0*map->tint_r[0]+0.5));
00832     lib3ds_io_write_byte(io, (Lib3dsByte)floor(255.0*map->tint_r[1]+0.5));
00833     lib3ds_io_write_byte(io, (Lib3dsByte)floor(255.0*map->tint_r[2]+0.5));
00834   }
00835 
00836   { /*---- LIB3DS_MAT_MAP_GCOL ----*/
00837     Lib3dsChunk c;
00838     c.chunk=LIB3DS_MAT_MAP_GCOL;
00839     c.size=9;
00840     lib3ds_chunk_write(&c,io);
00841     lib3ds_io_write_byte(io, (Lib3dsByte)floor(255.0*map->tint_g[0]+0.5));
00842     lib3ds_io_write_byte(io, (Lib3dsByte)floor(255.0*map->tint_g[1]+0.5));
00843     lib3ds_io_write_byte(io, (Lib3dsByte)floor(255.0*map->tint_g[2]+0.5));
00844   }
00845   
00846   { /*---- LIB3DS_MAT_MAP_BCOL ----*/
00847     Lib3dsChunk c;
00848     c.chunk=LIB3DS_MAT_MAP_BCOL;
00849     c.size=9;
00850     lib3ds_chunk_write(&c,io);
00851     lib3ds_io_write_byte(io, (Lib3dsByte)floor(255.0*map->tint_b[0]+0.5));
00852     lib3ds_io_write_byte(io, (Lib3dsByte)floor(255.0*map->tint_b[1]+0.5));
00853     lib3ds_io_write_byte(io, (Lib3dsByte)floor(255.0*map->tint_b[2]+0.5));
00854   }
00855 
00856   if (!lib3ds_chunk_write_end(&c,io)) {
00857     return(LIB3DS_FALSE);
00858   }
00859   return(LIB3DS_TRUE);
00860 }
00861 
00862 
00866 Lib3dsBool
00867 lib3ds_material_write(Lib3dsMaterial *material, Lib3dsIo *io)
00868 {
00869   Lib3dsChunk c;
00870 
00871   c.chunk=LIB3DS_MAT_ENTRY;
00872   if (!lib3ds_chunk_write_start(&c,io)) {
00873     return(LIB3DS_FALSE);
00874   }
00875 
00876   { /*---- LIB3DS_MAT_NAME ----*/
00877     Lib3dsChunk c;
00878     c.chunk=LIB3DS_MAT_NAME;
00879     c.size=6+(Lib3dsDword)strlen(material->name)+1;
00880     lib3ds_chunk_write(&c,io);
00881     lib3ds_io_write_string(io, material->name);
00882   }
00883 
00884   { /*---- LIB3DS_MAT_AMBIENT ----*/
00885     Lib3dsChunk c;
00886     c.chunk=LIB3DS_MAT_AMBIENT;
00887     c.size=24;
00888     lib3ds_chunk_write(&c,io);
00889     color_write(material->ambient,io);
00890   }
00891 
00892   { /*---- LIB3DS_MAT_DIFFUSE ----*/
00893     Lib3dsChunk c;
00894     c.chunk=LIB3DS_MAT_DIFFUSE;
00895     c.size=24;
00896     lib3ds_chunk_write(&c,io);
00897     color_write(material->diffuse,io);
00898   }
00899 
00900   { /*---- LIB3DS_MAT_SPECULAR ----*/
00901     Lib3dsChunk c;
00902     c.chunk=LIB3DS_MAT_SPECULAR;
00903     c.size=24;
00904     lib3ds_chunk_write(&c,io);
00905     color_write(material->specular,io);
00906   }
00907 
00908   { /*---- LIB3DS_MAT_SHININESS ----*/
00909     Lib3dsChunk c;
00910     c.chunk=LIB3DS_MAT_SHININESS;
00911     c.size=14;
00912     lib3ds_chunk_write(&c,io);
00913     int_percentage_write(material->shininess,io);
00914   }
00915 
00916   { /*---- LIB3DS_MAT_SHIN2PCT ----*/
00917     Lib3dsChunk c;
00918     c.chunk=LIB3DS_MAT_SHIN2PCT;
00919     c.size=14;
00920     lib3ds_chunk_write(&c,io);
00921     int_percentage_write(material->shin_strength,io);
00922   }
00923 
00924   { /*---- LIB3DS_MAT_TRANSPARENCY ----*/
00925     Lib3dsChunk c;
00926     c.chunk=LIB3DS_MAT_TRANSPARENCY;
00927     c.size=14;
00928     lib3ds_chunk_write(&c,io);
00929     int_percentage_write(material->transparency,io);
00930   }
00931 
00932   { /*---- LIB3DS_MAT_XPFALL ----*/
00933     Lib3dsChunk c;
00934     c.chunk=LIB3DS_MAT_XPFALL;
00935     c.size=14;
00936     lib3ds_chunk_write(&c,io);
00937     int_percentage_write(material->falloff,io);
00938   }
00939 
00940   if (material->use_falloff) { /*---- LIB3DS_MAT_USE_XPFALL ----*/
00941     Lib3dsChunk c;
00942     c.chunk=LIB3DS_MAT_USE_XPFALL;
00943     c.size=6;
00944     lib3ds_chunk_write(&c,io);
00945   }
00946 
00947   { /*---- LIB3DS_MAT_SHADING ----*/
00948     Lib3dsChunk c;
00949     c.chunk=LIB3DS_MAT_SHADING;
00950     c.size=8;
00951     lib3ds_chunk_write(&c,io);
00952     lib3ds_io_write_intw(io, material->shading);
00953   }
00954 
00955   { /*---- LIB3DS_MAT_REFBLUR ----*/
00956     Lib3dsChunk c;
00957     c.chunk=LIB3DS_MAT_REFBLUR;
00958     c.size=14;
00959     lib3ds_chunk_write(&c,io);
00960     int_percentage_write(material->blur,io);
00961   }
00962 
00963   if (material->use_blur) { /*---- LIB3DS_MAT_USE_REFBLUR ----*/
00964     Lib3dsChunk c;
00965     c.chunk=LIB3DS_MAT_USE_REFBLUR;
00966     c.size=6;
00967     lib3ds_chunk_write(&c,io);
00968   }
00969 
00970   if (material->self_illum) { /*---- LIB3DS_MAT_SELF_ILLUM ----*/
00971     Lib3dsChunk c;
00972     c.chunk=LIB3DS_MAT_SELF_ILLUM;
00973     c.size=6;
00974     lib3ds_chunk_write(&c,io);
00975   }
00976 
00977   if (material->two_sided) { /*---- LIB3DS_MAT_TWO_SIDE ----*/
00978     Lib3dsChunk c;
00979     c.chunk=LIB3DS_MAT_TWO_SIDE;
00980     c.size=6;
00981     lib3ds_chunk_write(&c,io);
00982   }
00983   
00984   if (material->map_decal) { /*---- LIB3DS_MAT_DECAL ----*/
00985     Lib3dsChunk c;
00986     c.chunk=LIB3DS_MAT_DECAL;
00987     c.size=6;
00988     lib3ds_chunk_write(&c,io);
00989   }
00990 
00991   if (material->additive) { /*---- LIB3DS_MAT_ADDITIVE ----*/
00992     Lib3dsChunk c;
00993     c.chunk=LIB3DS_MAT_ADDITIVE;
00994     c.size=6;
00995     lib3ds_chunk_write(&c,io);
00996   }
00997 
00998   if (material->use_wire) { /*---- LIB3DS_MAT_WIRE ----*/
00999     Lib3dsChunk c;
01000     c.chunk=LIB3DS_MAT_WIRE;
01001     c.size=6;
01002     lib3ds_chunk_write(&c,io);
01003   }
01004 
01005   if (material->use_wire_abs) { /*---- LIB3DS_MAT_WIREABS ----*/
01006     Lib3dsChunk c;
01007     c.chunk=LIB3DS_MAT_WIREABS;
01008     c.size=6;
01009     lib3ds_chunk_write(&c,io);
01010   }
01011 
01012   { /*---- LIB3DS_MAT_WIRE_SIZE ----*/
01013     Lib3dsChunk c;
01014     c.chunk=LIB3DS_MAT_WIRE_SIZE;
01015     c.size=10;
01016     lib3ds_chunk_write(&c,io);
01017     lib3ds_io_write_float(io, material->wire_size);
01018   }
01019 
01020   if (material->face_map) { /*---- LIB3DS_MAT_FACEMAP ----*/
01021     Lib3dsChunk c;
01022     c.chunk=LIB3DS_MAT_FACEMAP;
01023     c.size=6;
01024     lib3ds_chunk_write(&c,io);
01025   }
01026 
01027   if (material->soften) { /*---- LIB3DS_MAT_PHONGSOFT ----*/
01028     Lib3dsChunk c;
01029     c.chunk=LIB3DS_MAT_PHONGSOFT;
01030     c.size=6;
01031     lib3ds_chunk_write(&c,io);
01032   }
01033 
01034   if (!texture_map_write(LIB3DS_MAT_TEXMAP, &material->texture1_map, io)) {
01035     return(LIB3DS_FALSE);
01036   }
01037   if (!texture_map_write(LIB3DS_MAT_TEXMASK, &material->texture1_mask, io)) {
01038     return(LIB3DS_FALSE);
01039   }
01040   if (!texture_map_write(LIB3DS_MAT_TEX2MAP, &material->texture2_map, io)) {
01041     return(LIB3DS_FALSE);
01042   }
01043   if (!texture_map_write(LIB3DS_MAT_TEX2MASK, &material->texture2_mask, io)) {
01044     return(LIB3DS_FALSE);
01045   }
01046   if (!texture_map_write(LIB3DS_MAT_OPACMAP, &material->opacity_map, io)) {
01047     return(LIB3DS_FALSE);
01048   }
01049   if (!texture_map_write(LIB3DS_MAT_OPACMASK, &material->opacity_mask, io)) {
01050     return(LIB3DS_FALSE);
01051   }
01052   if (!texture_map_write(LIB3DS_MAT_BUMPMAP, &material->bump_map, io)) {
01053     return(LIB3DS_FALSE);
01054   }
01055   if (!texture_map_write(LIB3DS_MAT_BUMPMASK, &material->bump_mask, io)) {
01056     return(LIB3DS_FALSE);
01057   }
01058   if (!texture_map_write(LIB3DS_MAT_SPECMAP, &material->specular_map, io)) {
01059     return(LIB3DS_FALSE);
01060   }
01061   if (!texture_map_write(LIB3DS_MAT_SPECMASK, &material->specular_mask, io)) {
01062     return(LIB3DS_FALSE);
01063   }
01064   if (!texture_map_write(LIB3DS_MAT_SHINMAP, &material->shininess_map, io)) {
01065     return(LIB3DS_FALSE);
01066   }
01067   if (!texture_map_write(LIB3DS_MAT_SHINMASK, &material->shininess_mask, io)) {
01068     return(LIB3DS_FALSE);
01069   }
01070   if (!texture_map_write(LIB3DS_MAT_SELFIMAP, &material->self_illum_map, io)) {
01071     return(LIB3DS_FALSE);
01072   }
01073   if (!texture_map_write(LIB3DS_MAT_SELFIMASK, &material->self_illum_mask, io)) {
01074     return(LIB3DS_FALSE);
01075   }
01076   if (!texture_map_write(LIB3DS_MAT_REFLMAP,  &material->reflection_map, io)) {
01077     return(LIB3DS_FALSE);
01078   }
01079   if (!texture_map_write(LIB3DS_MAT_REFLMASK,  &material->reflection_mask, io)) {
01080     return(LIB3DS_FALSE);
01081   }
01082 
01083   if (!lib3ds_chunk_write_end(&c,io)) {
01084     return(LIB3DS_FALSE);
01085   }
01086   return(LIB3DS_TRUE);
01087 }
01088 
01089 

Hosted by
SourceForge.net Logo
Generated at Wed Jun 20 18:51:36 2007 by Doxygen 1.5.2