1 //
2 // 3DS2BZW
3 //
4 // Author: Anonymous
5 // Date: Aug 26, 2004
6 //
7 // Utility program to convert 3DS model
8 // files into BZFlag 1.12 meshy goodness.
9 //
10 // To use the program, you might type this:
11 //
12 // ./3ds2bzw model.3ds > model.bzw
13 //
14 // NOTE: this program requires lib3ds to
15 // compile. to compile the program,
16 // use something like this:
17 //
18 // gcc -O3 -W -Wall -o 3ds2bzw 3ds2bzw.c -l3ds -lm
19 //
20 
21 
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <math.h>
26 #include <lib3ds/file.h>
27 #include <lib3ds/camera.h>
28 #include <lib3ds/mesh.h>
29 #include <lib3ds/node.h>
30 #include <lib3ds/material.h>
31 #include <lib3ds/matrix.h>
32 #include <lib3ds/mesh.h>
33 #include <lib3ds/vector.h>
34 #include <lib3ds/light.h>
35 
36 
37 static Lib3dsFile *File3DS = NULL;
38 
39 
40 static int Invert = 0;
41 static int ColorSwap = 0;
42 static int Colors = 1;
43 static int Ambient = 1;
44 static int Diffuse = 1;
45 static int Specular = 1;
46 static int Shininess = 1;
47 static int Normals = 1;
48 static int Textures = 1;
49 
50 
51 //////////////////////////////////////////////////////////////////////////////
52 
53 int
main(int argc,char ** argv)54 main (int argc, char **argv)
55 {
56     Lib3dsMesh *mesh;
57     const char *execname = argv[0];
58 
59     // collect the options
60     while (argc > 1)
61     {
62         if (strcmp ("-i", argv[1]) == 0)
63             Invert = 1;
64         else if (strcmp ("-cs", argv[1]) == 0)
65             ColorSwap = 1;
66         else if (strcmp ("-t", argv[1]) == 0)
67             Textures = 0;
68         else if (strcmp ("-n", argv[1]) == 0)
69             Normals = 0;
70         else if (strcmp ("-c", argv[1]) == 0)
71             Colors = 0;
72         else if (strcmp ("-a", argv[1]) == 0)
73             Ambient = 0;
74         else if (strcmp ("-d", argv[1]) == 0)
75             Diffuse = 0;
76         else if (strcmp ("-s", argv[1]) == 0)
77             Specular = 0;
78         else if (strcmp ("-sh", argv[1]) == 0)
79             Shininess = 0;
80         else
81             break;
82         argc--;
83         argv++;
84     }
85 
86     // print the help message
87     if (argc != 2)
88     {
89         printf ("\n");
90         printf ("usage:  %s [opts] <filename>\n", execname);
91         printf ("\n");
92         printf ("  -t    disable textures\n");
93         printf ("  -n    disable normals\n");
94         printf ("  -c    disable all colors\n");
95         printf ("  -a    disable ambient\n");
96         printf ("  -d    disable diffuse\n");
97         printf ("  -s    disable specular\n");
98         printf ("  -sh   disable shininess\n");
99         printf ("  -i    invert normals\n");
100         printf ("  -cs   swap ambient and diffuse\n");
101         printf ("\n");
102         return 1;
103     }
104 
105     // load the file
106     File3DS = lib3ds_file_load (argv[1]);
107     if (File3DS == NULL)
108     {
109         printf ("Problems loading file\n");
110         return 1;
111     }
112 
113     // evaluate the first frame
114     lib3ds_file_eval (File3DS, 0.0f /* the frame time */ );
115 
116     // dump all of the meshes
117     for (mesh = File3DS->meshes; mesh != NULL; mesh = mesh->next)
118     {
119         // FIXME - Lib3dsMatrix* matrix = &mesh->matrix;
120         // comments on statistics
121         unsigned int i;
122         printf ("mesh  # %s\n", mesh->name);
123         printf ("# vertices:  %i\n", (int) mesh->points);
124         if (Normals)
125             printf ("# normals:   %i\n", (int) mesh->faces * 3);
126         if (Textures)
127             printf ("# texcoords: %i\n", (int) mesh->texels);
128         printf ("# faces:     %i\n", (int) mesh->faces);
129 
130         // vertices
131         for (i = 0; i < mesh->points; i++)
132         {
133             Lib3dsPoint *point = &(mesh->pointL[i]);
134             printf ("  vertex %f %f %f  # %i\n",
135                     point->pos[0], point->pos[1], point->pos[2], i);
136         }
137 
138         // normals
139         if (Normals)
140         {
141             Lib3dsVector *normals = (Lib3dsVector *)
142                                     malloc (3 * mesh->faces * sizeof (Lib3dsVector));
143             lib3ds_mesh_calculate_normals (mesh, normals);
144             for (i = 0; i < (mesh->faces * 3); i++)
145             {
146                 if (Invert)
147                 {
148                     printf ("  normal %f %f %f  # %i\n",
149                             -normals[i][0], -normals[i][1], -normals[i][2], i);
150                 }
151                 else
152                 {
153                     printf ("  normal %f %f %f  # %i\n",
154                             normals[i][0], normals[i][1], normals[i][2], i);
155                 }
156             }
157             free (normals);
158         }
159 
160         // texcoords
161         if (Textures)
162         {
163             for (i = 0; i < mesh->texels; i++)
164             {
165                 Lib3dsTexel *texel = &(mesh->texelL[i]);
166                 printf ("  texcoord %f %f  # %i\n", (*texel)[0], (*texel)[1], i);
167             }
168         }
169 
170         // faces
171         for (i = 0; i < mesh->faces; i++)
172         {
173             Lib3dsFace *face = &(mesh->faceL[i]);
174             Lib3dsWord *points = face->points;
175             printf ("  face  # material = %s\n", face->material);
176             printf ("    vertices %i %i %i\n", points[0], points[1], points[2]);
177             if (Normals)
178             {
179                 printf ("    normals %i %i %i\n", (i * 3) + 0, (i * 3) + 1,
180                         (i * 3) + 2);
181             }
182             Lib3dsMaterial *mat =
183                 lib3ds_file_material_by_name (File3DS, face->material);
184             if (mat)
185             {
186                 if (Textures && (mesh->texels != 0))
187                 {
188                     printf ("    texture %s\n", mat->texture1_map.name);
189                     printf ("    texcoords %i %i %i\n", points[0], points[1],
190                             points[2]);
191 
192                     // BZ isn't ready for these, yet...
193                     // printf (" #texture %s\n", material->texture2_map.name);
194                     // printf (" #texture %s\n", material->texture1_mask.name);
195                     // printf (" #texture %s\n", material->texture2_mask.name);
196                 }
197                 if (Colors)
198                 {
199                     Lib3dsRgba *ambient = &mat->ambient;
200                     Lib3dsRgba *diffuse = &mat->diffuse;
201                     if (ColorSwap)
202                     {
203                         ambient = &mat->diffuse;
204                         diffuse = &mat->ambient;
205                     }
206                     if (Ambient)
207                     {
208                         printf ("    ambient %f %f %f %f\n", (*ambient)[0],
209                                 (*ambient)[1], (*ambient)[2], (*ambient)[3]);
210                     }
211                     if (Diffuse)
212                     {
213                         printf ("    diffuse %f %f %f %f\n", (*diffuse)[0],
214                                 (*diffuse)[1], (*diffuse)[2], (*diffuse)[3]);
215                     }
216                     if (Specular)
217                     {
218                         printf ("    specular %f %f %f %f\n", mat->specular[0],
219                                 mat->specular[1], mat->specular[2], mat->specular[3]);
220                     }
221                     if (Shininess)
222                         printf ("    shininess %f\n", mat->shininess);
223                 }
224             }
225             printf ("  endface\n");
226         }
227 
228         printf ("end  # %s\n\n", mesh->name);
229     }
230 
231     lib3ds_file_free (File3DS);
232 
233     return 0;
234 }
235 
236 //////////////////////////////////////////////////////////////////////////////
237 
238 // Local Variables: ***
239 // mode: C++ ***
240 // tab-width: 4 ***
241 // c-basic-offset: 4 ***
242 // indent-tabs-mode: nil ***
243 // End: ***
244 // ex: shiftwidth=4 tabstop=4
245