1 /*
2 PLIB - A Suite of Portable Game Libraries
3 Copyright (C) 1998,2002 Steve Baker
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19 For further information visit http://plib.sourceforge.net
20
21 $Id: ssgSaveOBJ.cxx 1568 2002-09-02 06:05:49Z sjbaker $
22 */
23
24 //
25 // Wavefront OBJ export for SSG/PLIB
26 // Ported from IVCON by Dave McClurg (dpm@efn.org) in March-2000
27 //
28
29 #include "ssgLocal.h"
30
31 static FILE *fileout ;
32 static int total_vert ;
33 static int total_normal ;
34
save_vtx_table(ssgVtxTable * vt)35 static void save_vtx_table ( ssgVtxTable *vt )
36 {
37 float w = 1.0f ;
38 short iv1, iv2;
39
40 GLenum mode = vt -> getPrimitiveType () ;
41 //fprintf ( fileout, "g test\n" ); wk: Pfusch fixme: is this necessary? NIV135
42
43 if (( mode == GL_LINES ) || ( mode == GL_LINE_LOOP) || ( mode == GL_LINE_STRIP))
44 {
45 int num_vert = vt -> getNumVertices () ;
46
47 // V: vertex coordinates.
48 for ( int i = 0; i < num_vert; i++ ) {
49 sgVec3 vert ;
50 sgCopyVec3 ( vert, vt -> getVertex ( i ) ) ;
51 fprintf ( fileout, "v %f %f %f %f\n",
52 vert[0], vert[1], vert[2], w );
53 }
54
55
56
57 // L: lines.
58 fprintf ( fileout, "\n" );
59 int num_lines = vt -> getNumLines () ;
60 for ( int j = 0; j < num_lines; j ++ )
61 { vt -> getLine ( j, &iv1, &iv2 ) ;
62 fprintf ( fileout, "l %d %d\n",
63 total_vert + j + 1,
64 total_vert + j + 2 );
65 }
66
67 total_vert += num_vert ;
68 }
69 else if ( mode == GL_TRIANGLES ||
70 mode == GL_TRIANGLE_FAN ||
71 mode == GL_TRIANGLE_STRIP )
72 {
73 int num_vert = vt -> getNumVertices () ;
74
75 // V: vertex coordinates.
76 for ( int i = 0; i < num_vert; i++ ) {
77 sgVec3 vert ;
78 sgCopyVec3 ( vert, vt -> getVertex ( i ) ) ;
79 fprintf ( fileout, "v %f %f %f %f\n",
80 vert[0], vert[1], vert[2], w );
81 }
82
83 // VN: Vertex face normal vectors.
84 bool haveNormals = ( vt -> getNumNormals () >= num_vert ) ;
85 if ( haveNormals )
86 {
87 fprintf ( fileout, "\n" );
88 for ( int i = 0; i < num_vert; i++ ) {
89 sgVec3 vert ;
90 sgCopyVec3 ( vert, vt -> getNormal ( i ) ) ;
91 fprintf ( fileout, "vn %f %f %f\n",
92 vert[0], vert[1], vert[2] );
93 }
94 }
95
96 // F: faces.
97 fprintf ( fileout, "\n" );
98 int num_face = vt -> getNumTriangles () ;
99 for ( int j = 0; j < num_face; j++ )
100 {
101 short face[3];
102 vt -> getTriangle ( j, &face[0], &face[1], &face[2] ) ;
103
104 fprintf ( fileout, "f" );
105 for ( int ivert = 0; ivert < 3; ivert++ ) {
106 if ( haveNormals )
107 fprintf ( fileout, " %d//%d",
108 total_vert + face[ivert] + 1,
109 total_normal + face[ivert] + 1 );
110 else
111 fprintf ( fileout, " %d",
112 total_vert + face[ivert] + 1 );
113 }
114 fprintf ( fileout, "\n" );
115 }
116
117 total_vert += num_vert ;
118 if ( haveNormals )
119 total_normal += num_vert ;
120 }
121 }
122
123
save_entities(ssgEntity * e)124 static void save_entities ( ssgEntity *e )
125 {
126 if ( e -> isAKindOf ( ssgTypeBranch() ) )
127 {
128 ssgBranch *br = (ssgBranch *) e ;
129
130 for ( int i = 0 ; i < br -> getNumKids () ; i++ )
131 save_entities ( br -> getKid ( i ) ) ;
132 }
133 else
134 if ( e -> isAKindOf ( ssgTypeVtxTable() ) )
135 {
136 ssgVtxTable *vt = (ssgVtxTable *) e ;
137 save_vtx_table ( vt ) ;
138 }
139 }
140
141
142 /******************************************************************************/
143
ssgSaveOBJ(const char * filename,ssgEntity * ent)144 int ssgSaveOBJ ( const char *filename, ssgEntity *ent )
145
146 /******************************************************************************/
147
148 /*
149 Purpose:
150
151 OBJ_WRITE writes a Wavefront OBJ file.
152
153 Example:
154
155 # magnolia.obj
156
157 mtllib ./vp.mtl
158
159 g
160 v -3.269770 -39.572201 0.876128
161 v -3.263720 -39.507999 2.160890
162 ...
163 v 0.000000 -9.988540 0.000000
164 g stem
165 s 1
166 usemtl brownskn
167 f 8 9 11 10
168 f 12 13 15 14
169 ...
170 f 788 806 774
171
172 Modified:
173
174 01 September 1998
175
176 Author:
177
178 John Burkardt
179 */
180 {
181 fileout = fopen ( filename, "wa" ) ;
182
183 if ( fileout == NULL )
184 {
185 ulSetError ( UL_WARNING, "ssgSaveOBJ: Failed to open '%s' for writing", filename ) ;
186 return FALSE ;
187 }
188
189 /*
190 Initialize.
191 */
192 fprintf ( fileout, "# %s created by SSG.\n", filename );
193 fprintf ( fileout, "\n" );
194 fprintf ( fileout, "g SSG\n" );
195 fprintf ( fileout, "\n" );
196
197 total_vert = 0 ;
198 total_normal = 0 ;
199
200 save_entities ( ent ) ;
201
202 /*
203 Close.
204 */
205 fclose ( fileout ) ;
206 return TRUE;
207 }
208