]> icculus.org git repositories - divverent/netradiant.git/blob - tools/quake3/q3map2/convert_obj.c
initial obj support
[divverent/netradiant.git] / tools / quake3 / q3map2 / convert_obj.c
1 /* -------------------------------------------------------------------------------
2
3 Copyright (C) 1999-2007 id Software, Inc. and contributors.
4 For a list of contributors, see the accompanying CONTRIBUTORS file.
5
6 This file is part of GtkRadiant.
7
8 GtkRadiant is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 GtkRadiant 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 General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GtkRadiant; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21
22 ----------------------------------------------------------------------------------
23
24 This code has been altered significantly from its original form, to support
25 several games based on the Quake III Arena engine, in the form of "Q3Map2."
26
27 ------------------------------------------------------------------------------- */
28
29
30
31 /* marker */
32 #define CONVERT_ASE_C
33
34
35
36 /* dependencies */
37 #include "q3map2.h"
38
39
40
41 /*
42 ConvertSurface()
43 converts a bsp drawsurface to an obj chunk
44 */
45
46 int objVertexCount = 0;
47 int objLastShaderNum = -1;
48 static void ConvertSurfaceToOBJ( FILE *f, bspModel_t *model, int modelNum, bspDrawSurface_t *ds, int surfaceNum, vec3_t origin )
49 {
50         int                             i, v, face, a, b, c;
51         bspDrawVert_t   *dv;
52         vec3_t                  normal;
53         char                    name[ 1024 ];
54         int startVert = objVertexCount;
55         
56         /* ignore patches for now */
57         if( ds->surfaceType != MST_PLANAR && ds->surfaceType != MST_TRIANGLE_SOUP )
58                 return;
59
60         fprintf(f, "g mat%dmodel%dsurf%d\r\n", ds->shaderNum, modelNum, surfaceNum);
61         switch( ds->surfaceType )
62         {
63                 case MST_PLANAR:
64                         fprintf( f, "# SURFACETYPE MST_PLANAR\r\n" );
65                         break;
66                 case MST_TRIANGLE_SOUP:
67                         fprintf( f, "# SURFACETYPE MST_TRIANGLE_SOUP\r\n" );
68                         break;
69         }
70
71         /* export shader */
72         if(objLastShaderNum != ds->shaderNum)
73         {
74                 fprintf(f, "usemtl %s\r\n", bspShaders[ds->shaderNum].shader);
75                 objLastShaderNum = ds->shaderNum;
76         }
77         
78         /* export vertex */
79         for( i = 0; i < ds->numVerts; i++ )
80         {
81                 v = i + ds->firstVert;
82                 dv = &bspDrawVerts[ v ];
83                 fprintf(f, "# vertex %d\r\n", i + objVertexCount + 1);
84                 fprintf(f, "v %f %f %f\r\n", dv->xyz[ 0 ], dv->xyz[ 1 ], dv->xyz[ 2 ]);
85                 fprintf(f, "vn %f %f %f\r\n", dv->normal[ 0 ], dv->normal[ 1 ], dv->normal[ 2 ]);
86                 fprintf(f, "vt %f %f\r\n", dv->st[ 0 ], dv->st[ 1 ]);
87                 fprintf(f, "# vt %f %f\r\n", dv->lightmap[0][0], dv->lightmap[0][1]);
88         }
89
90         /* export faces */
91         for( i = 0; i < ds->numIndexes; i += 3 )
92         {
93                 face = (i / 3);
94                 a = bspDrawIndexes[ i + ds->firstIndex ];
95                 c = bspDrawIndexes[ i + ds->firstIndex + 1 ];
96                 b = bspDrawIndexes[ i + ds->firstIndex + 2 ];
97                 fprintf(f, "f %d/%d/%d %d/%d/%d %d/%d/%d\r\n",
98                         a + objVertexCount + 1, a + objVertexCount + 1, a + objVertexCount + 1, 
99                         b + objVertexCount + 1, b + objVertexCount + 1, b + objVertexCount + 1, 
100                         c + objVertexCount + 1, c + objVertexCount + 1, c + objVertexCount + 1
101                 );
102         }
103
104         objVertexCount += ds->numVerts;
105 }
106
107
108
109 /*
110 ConvertModel()
111 exports a bsp model to an ase chunk
112 */
113
114 static void ConvertModelToOBJ( FILE *f, bspModel_t *model, int modelNum, vec3_t origin )
115 {
116         int                                     i, s;
117         bspDrawSurface_t        *ds;
118         
119         
120         /* go through each drawsurf in the model */
121         for( i = 0; i < model->numBSPSurfaces; i++ )
122         {
123                 s = i + model->firstBSPSurface;
124                 ds = &bspDrawSurfaces[ s ];
125                 ConvertSurfaceToOBJ( f, model, modelNum, ds, s, origin );
126         }
127 }
128
129
130
131 /*
132 ConvertShader()
133 exports a bsp shader to an ase chunk
134 */
135
136 static void ConvertShaderToMTL( FILE *f, bspShader_t *shader, int shaderNum )
137 {
138         shaderInfo_t    *si;
139         char                    *c, filename[ 1024 ];
140         
141         
142         /* get shader */
143         si = ShaderInfoForShader( shader->shader );
144         if( si == NULL )
145         {
146                 Sys_Printf( "WARNING: NULL shader in BSP\n" );
147                 return;
148         }
149         
150         /* set bitmap filename */
151         if( si->shaderImage->filename[ 0 ] != '*' )
152                 strcpy( filename, si->shaderImage->filename );
153         else
154                 sprintf( filename, "%s.tga", si->shader );
155         for( c = filename; *c != '\0'; c++ )
156                 if( *c == '/' )
157                         *c = '\\';
158         
159         /* print shader info */
160         fprintf( f, "newmtl %s\r\n", shader->shader );
161         fprintf( f, "Kd %f %f %f\r\n", si->color[ 0 ], si->color[ 1 ], si->color[ 2 ] );
162         if(shadersAsBitmap)
163                 fprintf( f, "map_Kd %s\r\n", shader->shader );
164         else
165                 fprintf( f, "map_Kd %s\r\n", filename );
166 }
167
168
169
170 /*
171 ConvertBSPToASE()
172 exports an 3d studio ase file from the bsp
173 */
174
175 int ConvertBSPToOBJ( char *bspName )
176 {
177         int                             i, modelNum;
178         FILE                    *f, *fmtl;
179         bspShader_t             *shader;
180         bspModel_t              *model;
181         entity_t                *e;
182         vec3_t                  origin;
183         const char              *key;
184         char                    name[ 1024 ], base[ 1024 ];
185         
186         
187         /* note it */
188         Sys_Printf( "--- Convert BSP to OBJ ---\n" );
189
190         /* create the ase filename from the bsp name */
191         strcpy( name, bspName );
192         StripExtension( name );
193         strcat( name, ".obj" );
194         Sys_Printf( "writing %s\n", name );
195         strcpy( mtlname, bspName );
196         StripExtension( mtlname );
197         strcat( mtlname, ".mtl" );
198         Sys_Printf( "writing %s\n", mtlname );
199         
200         ExtractFileBase( bspName, base );
201         strcat( base, ".bsp" );
202         
203         /* open it */
204         f = fopen( name, "wb" );
205         if( f == NULL )
206                 Error( "Open failed on %s\n", name );
207         fmtl = fopen( mtlname, "wb" );
208         if( fmtl == NULL )
209                 Error( "Open failed on %s\n", mtlname );
210         
211         /* print header */
212         fprintf( f, "o %s\r\n", base );
213         fprintf( f, "# Generated by Q3Map2 (ydnar) -convert -format obj\r\n" );
214         fprintf( f, "mtllib %s\r\n", mtlname );
215
216         fprintf( fmtl, "# Generated by Q3Map2 (ydnar) -convert -format obj\r\n" );
217         for( i = 0; i < numBSPShaders; i++ )
218         {
219                 shader = &bspShaders[ i ];
220                 ConvertShaderToMTL( fmtl, shader, i );
221         }
222         
223         /* walk entity list */
224         for( i = 0; i < numEntities; i++ )
225         {
226                 /* get entity and model */
227                 e = &entities[ i ];
228                 if( i == 0 )
229                         modelNum = 0;
230                 else
231                 {
232                         key = ValueForKey( e, "model" );
233                         if( key[ 0 ] != '*' )
234                                 continue;
235                         modelNum = atoi( key + 1 );
236                 }
237                 model = &bspModels[ modelNum ];
238                 
239                 /* get entity origin */
240                 key = ValueForKey( e, "origin" );
241                 if( key[ 0 ] == '\0' )
242                         VectorClear( origin );
243                 else
244                         GetVectorForKey( e, "origin", origin );
245                 
246                 /* convert model */
247                 ConvertModelToOBJ( f, model, modelNum, origin );
248         }
249         
250         /* close the file and return */
251         fclose( f );
252         fclose( fmtl );
253         
254         /* return to sender */
255         return 0;
256 }
257
258
259