1 /* Code for writing AC3D format files, constructs one object per Geode
2 * since geodes only have 1 material, and AC3D allows multiple materials you
3 * may not get an exact vopy of an ac3d file used as input.
4 *
5 * originally by Roger James.
6 * upgraded to different types of Geometry primitive by Geoff Michel.
7 * Old GeoSet parsing code is commented out - will be removed eventually.
8 */
9 #include <assert.h>
10 #include <list>
11 #include <osg/Material>
12 #include <osg/Texture2D>
13 #include <osg/Drawable>
14 #include <osg/Geometry>
15 #include <limits>
16 #include <iomanip>
17
18 #include "Exception.h"
19 #include "Geode.h"
20
21 using namespace ac3d;
22 using namespace std;
23
24
25
OutputVertex(int Index,const osg::IndexArray * pVertexIndices,const osg::Vec2 * pTexCoords,const osg::IndexArray * pTexIndices,ostream & fout)26 void Geode::OutputVertex(int Index, const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices, ostream& fout)
27 {
28 int LocalTexIndex;
29 int LocalVertexIndex;
30 if (NULL == pVertexIndices)
31 LocalVertexIndex = Index;
32 else
33 LocalVertexIndex = pVertexIndices->index(Index);
34 if (NULL != pTexCoords)
35 {
36 // Got some tex coords
37 // Check for an index
38 if (NULL != pTexIndices)
39 // Access tex coord array indirectly
40 LocalTexIndex = pTexIndices->index(Index);
41 else
42 LocalTexIndex = Index;
43 fout << LocalVertexIndex << " " << pTexCoords[LocalTexIndex][0] << " " << pTexCoords[LocalTexIndex][1] << std::endl;
44 }
45 else
46 fout << LocalVertexIndex << " 0 0" << std::endl;
47 }
48
OutputLines(const int iCurrentMaterial,const unsigned int surfaceFlags,const osg::IndexArray * pVertexIndices,const osg::Vec2 * pTexCoords,const osg::IndexArray * pTexIndices,const osg::DrawArrays * drawArray,ostream & fout)49 void Geode::OutputLines(const int iCurrentMaterial, const unsigned int surfaceFlags,
50 const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawArrays* drawArray, ostream& fout)
51 {
52 unsigned int indexEnd = drawArray->getFirst() + drawArray->getCount();
53 for(unsigned int vindex=drawArray->getFirst(); vindex<indexEnd; vindex+=2)
54 {
55 OutputSurfHead(iCurrentMaterial,surfaceFlags,2, fout);
56 OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout);
57 OutputVertex(vindex+1, pVertexIndices, pTexCoords, pTexIndices, fout);
58 }
59 }
OutputLineStrip(const int iCurrentMaterial,const unsigned int surfaceFlags,const osg::IndexArray * pVertexIndices,const osg::Vec2 * pTexCoords,const osg::IndexArray * pTexIndices,const osg::DrawArrays * drawArray,ostream & fout)60 void Geode::OutputLineStrip(const int iCurrentMaterial, const unsigned int surfaceFlags,
61 const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawArrays* drawArray, ostream& fout)
62 {
63 unsigned int indexEnd = drawArray->getFirst() + drawArray->getCount();
64 OutputSurfHead(iCurrentMaterial,surfaceFlags,indexEnd-drawArray->getFirst(), fout);
65 for(unsigned int vindex=drawArray->getFirst(); vindex<indexEnd; ++vindex)
66 {
67 OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout);
68 }
69 }
OutputLineLoop(const int iCurrentMaterial,const unsigned int surfaceFlags,const osg::IndexArray * pVertexIndices,const osg::Vec2 * pTexCoords,const osg::IndexArray * pTexIndices,const osg::DrawArrays * drawArray,ostream & fout)70 void Geode::OutputLineLoop(const int iCurrentMaterial, const unsigned int surfaceFlags,
71 const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawArrays* drawArray, ostream& fout)
72 {
73 unsigned int indexEnd = drawArray->getFirst() + drawArray->getCount();
74 OutputSurfHead(iCurrentMaterial,surfaceFlags,indexEnd-drawArray->getFirst(), fout);
75 for(unsigned int vindex=drawArray->getFirst(); vindex<indexEnd; ++vindex)
76 {
77 OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout);
78 }
79 }
OutputTriangle(const int iCurrentMaterial,const unsigned int surfaceFlags,const osg::IndexArray * pVertexIndices,const osg::Vec2 * pTexCoords,const osg::IndexArray * pTexIndices,const osg::DrawArrays * drawArray,ostream & fout)80 void Geode::OutputTriangle(const int iCurrentMaterial, const unsigned int surfaceFlags,
81 const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawArrays* drawArray, ostream& fout)
82 {
83 unsigned int primCount = 0;
84 unsigned int indexEnd = drawArray->getFirst() + drawArray->getCount();
85 for(unsigned int vindex=drawArray->getFirst(); vindex<indexEnd; ++vindex,++primCount)
86 {
87
88 if ((primCount%3) == 0)
89 {
90 OutputSurfHead(iCurrentMaterial,surfaceFlags,3, fout);
91 }
92 OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout);
93 }
94 }
OutputTriangleStrip(const int iCurrentMaterial,const unsigned int surfaceFlags,const osg::IndexArray * pVertexIndices,const osg::Vec2 * pTexCoords,const osg::IndexArray * pTexIndices,const osg::DrawArrays * drawArray,std::ostream & fout)95 void Geode::OutputTriangleStrip(const int iCurrentMaterial, const unsigned int surfaceFlags,
96 const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawArrays* drawArray, std::ostream& fout)
97 {
98 unsigned int indexEnd = drawArray->getFirst() + drawArray->getCount();
99 unsigned int evenodd=0;
100 for(unsigned int vindex=drawArray->getFirst(); vindex<indexEnd-2; ++vindex, evenodd++)
101 {
102
103 OutputSurfHead(iCurrentMaterial,surfaceFlags,3, fout);
104 if (evenodd%2==0) {
105 OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout);
106 OutputVertex(vindex+1, pVertexIndices, pTexCoords, pTexIndices, fout);
107 } else {
108 OutputVertex(vindex+1, pVertexIndices, pTexCoords, pTexIndices, fout);
109 OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout);
110 }
111 OutputVertex(vindex+2, pVertexIndices, pTexCoords, pTexIndices, fout);
112 }
113 }
OutputTriangleFan(const int iCurrentMaterial,const unsigned int surfaceFlags,const osg::IndexArray * pVertexIndices,const osg::Vec2 * pTexCoords,const osg::IndexArray * pTexIndices,const osg::DrawArrays * drawArray,std::ostream & fout)114 void Geode::OutputTriangleFan(const int iCurrentMaterial, const unsigned int surfaceFlags,
115 const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawArrays* drawArray, std::ostream& fout)
116 {
117 unsigned int indexEnd = drawArray->getFirst() + drawArray->getCount();
118 for(unsigned int vindex=drawArray->getFirst()+1; vindex<indexEnd-1; ++vindex)
119 {
120 OutputSurfHead(iCurrentMaterial,surfaceFlags,3, fout);
121 OutputVertex(drawArray->getFirst(), pVertexIndices, pTexCoords, pTexIndices, fout);
122 OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout);
123 OutputVertex(vindex+1, pVertexIndices, pTexCoords, pTexIndices, fout);
124 }
125 }
OutputQuads(const int iCurrentMaterial,const unsigned int surfaceFlags,const osg::IndexArray * pVertexIndices,const osg::Vec2 * pTexCoords,const osg::IndexArray * pTexIndices,const osg::DrawArrays * drawArray,std::ostream & fout)126 void Geode::OutputQuads(const int iCurrentMaterial, const unsigned int surfaceFlags,
127 const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawArrays* drawArray, std::ostream& fout)
128 {
129 unsigned int primCount = 0;
130 unsigned int indexEnd = drawArray->getFirst() + drawArray->getCount();
131 for(unsigned int vindex=drawArray->getFirst(); vindex<indexEnd; ++vindex,++primCount)
132 {
133
134 if ((primCount%4) == 0)
135 {
136 OutputSurfHead(iCurrentMaterial,surfaceFlags,4, fout);
137 }
138 OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout);
139 }
140 }
OutputQuadStrip(const int iCurrentMaterial,const unsigned int surfaceFlags,const osg::IndexArray * pVertexIndices,const osg::Vec2 * pTexCoords,const osg::IndexArray * pTexIndices,const osg::DrawArrays * drawArray,std::ostream & fout)141 void Geode::OutputQuadStrip(const int iCurrentMaterial, const unsigned int surfaceFlags,
142 const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawArrays* drawArray, std::ostream& fout)
143 {
144 unsigned int indexEnd = drawArray->getFirst() + drawArray->getCount();
145 for(unsigned int vindex=drawArray->getFirst(); vindex<indexEnd-2; vindex+=2)
146 {
147 OutputSurfHead(iCurrentMaterial,surfaceFlags,4, fout);
148 OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout);
149 OutputVertex(vindex+1, pVertexIndices, pTexCoords, pTexIndices, fout);
150 OutputVertex(vindex+3, pVertexIndices, pTexCoords, pTexIndices, fout);
151 OutputVertex(vindex+2, pVertexIndices, pTexCoords, pTexIndices, fout);
152 }
153 }
OutputPolygon(const int iCurrentMaterial,const unsigned int surfaceFlags,const osg::IndexArray * pVertexIndices,const osg::Vec2 * pTexCoords,const osg::IndexArray * pTexIndices,const osg::DrawArrays * drawArray,std::ostream & fout)154 void Geode::OutputPolygon(const int iCurrentMaterial, const unsigned int surfaceFlags,
155 const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawArrays* drawArray, std::ostream& fout)
156 {
157 unsigned int indexEnd = drawArray->getFirst() + drawArray->getCount();
158 OutputSurfHead(iCurrentMaterial,surfaceFlags,drawArray->getCount(), fout);
159 for(unsigned int vindex=drawArray->getFirst(); vindex<indexEnd; vindex++)
160 {
161 OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout);
162 }
163 }
164 //======= draw array length cases
OutputLineDARR(const int iCurrentMaterial,const unsigned int surfaceFlags,const osg::IndexArray * pVertexIndices,const osg::Vec2 * pTexCoords,const osg::IndexArray * pTexIndices,const osg::DrawArrayLengths * drawArrayLengths,ostream & fout)165 void Geode::OutputLineDARR(const int iCurrentMaterial, const unsigned int surfaceFlags,
166 const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawArrayLengths* drawArrayLengths, ostream& fout)
167 {
168 unsigned int vindex = drawArrayLengths->getFirst();
169 for(osg::DrawArrayLengths::const_iterator primItr = drawArrayLengths->begin(); primItr <drawArrayLengths->end(); ++primItr)
170 {
171 unsigned int localPrimLength;
172 localPrimLength = 2;
173
174 for(GLsizei primCount = 0; primCount < *primItr; ++primCount)
175 {
176 if ((primCount%localPrimLength)==0)
177 {
178 OutputSurfHead(iCurrentMaterial,surfaceFlags,localPrimLength, fout);
179 }
180 OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout);
181 ++vindex;
182 }
183
184 }
185 }
186
OutputTriangleDARR(const int iCurrentMaterial,const unsigned int surfaceFlags,const osg::IndexArray * pVertexIndices,const osg::Vec2 * pTexCoords,const osg::IndexArray * pTexIndices,const osg::DrawArrayLengths * drawArrayLengths,ostream & fout)187 void Geode::OutputTriangleDARR(const int iCurrentMaterial, const unsigned int surfaceFlags,
188 const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawArrayLengths* drawArrayLengths, ostream& fout)
189 {
190 unsigned int vindex = drawArrayLengths->getFirst();
191 for(osg::DrawArrayLengths::const_iterator primItr = drawArrayLengths->begin(); primItr <drawArrayLengths->end(); ++primItr)
192 {
193 unsigned int localPrimLength;
194 localPrimLength = 3;
195
196 for(GLsizei primCount = 0; primCount < *primItr; ++primCount)
197 {
198 if ((primCount%localPrimLength)==0)
199 {
200 OutputSurfHead(iCurrentMaterial,surfaceFlags,localPrimLength, fout);
201 }
202 OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout);
203 ++vindex;
204 }
205
206 }
207 }
208
OutputQuadsDARR(const int iCurrentMaterial,const unsigned int surfaceFlags,const osg::IndexArray * pVertexIndices,const osg::Vec2 * pTexCoords,const osg::IndexArray * pTexIndices,const osg::DrawArrayLengths * drawArrayLengths,ostream & fout)209 void Geode::OutputQuadsDARR(const int iCurrentMaterial, const unsigned int surfaceFlags,
210 const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawArrayLengths* drawArrayLengths, ostream& fout)
211 {
212 unsigned int vindex = drawArrayLengths->getFirst();
213 for(osg::DrawArrayLengths::const_iterator primItr = drawArrayLengths->begin(); primItr <drawArrayLengths->end()-4; primItr+=4)
214 {
215 unsigned int localPrimLength;
216 localPrimLength = 4;
217
218 for(GLsizei primCount = 0; primCount < *primItr; ++primCount)
219 {
220 OutputSurfHead(iCurrentMaterial,surfaceFlags,localPrimLength, fout);
221 OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout);
222 OutputVertex(vindex+1, pVertexIndices, pTexCoords, pTexIndices, fout);
223 OutputVertex(vindex+2, pVertexIndices, pTexCoords, pTexIndices, fout);
224 OutputVertex(vindex+3, pVertexIndices, pTexCoords, pTexIndices, fout);
225 vindex+=4;
226 }
227
228 }
229 }
OutputQuadStripDARR(const int iCurrentMaterial,const unsigned int surfaceFlags,const osg::IndexArray * pVertexIndices,const osg::Vec2 * pTexCoords,const osg::IndexArray * pTexIndices,const osg::DrawArrayLengths * drawArrayLengths,ostream & fout)230 void Geode::OutputQuadStripDARR(const int iCurrentMaterial, const unsigned int surfaceFlags,
231 const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawArrayLengths* drawArrayLengths, ostream& fout)
232 {
233 unsigned int vindex = drawArrayLengths->getFirst();
234 for(osg::DrawArrayLengths::const_iterator primItr = drawArrayLengths->begin(); primItr <drawArrayLengths->end()-2; primItr+=2)
235 {
236 unsigned int localPrimLength;
237 localPrimLength = *primItr;
238
239 for(GLsizei primCount = 0; primCount < *primItr; ++primCount)
240 {
241 OutputSurfHead(iCurrentMaterial,surfaceFlags,localPrimLength, fout);
242 OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout);
243 OutputVertex(vindex+1, pVertexIndices, pTexCoords, pTexIndices, fout);
244 OutputVertex(vindex+3, pVertexIndices, pTexCoords, pTexIndices, fout);
245 OutputVertex(vindex+2, pVertexIndices, pTexCoords, pTexIndices, fout);
246 vindex+=2;
247 }
248
249 }
250 }
OutputPolygonDARR(const int iCurrentMaterial,const unsigned int surfaceFlags,const osg::IndexArray * pVertexIndices,const osg::Vec2 * pTexCoords,const osg::IndexArray * pTexIndices,const osg::DrawArrayLengths * drawArrayLengths,ostream & fout)251 void Geode::OutputPolygonDARR(const int iCurrentMaterial, const unsigned int surfaceFlags,
252 const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawArrayLengths* drawArrayLengths, ostream& fout)
253 {
254 unsigned int vindex = drawArrayLengths->getFirst();
255 for(osg::DrawArrayLengths::const_iterator primItr = drawArrayLengths->begin(); primItr <drawArrayLengths->end(); ++primItr)
256 {
257 unsigned int localPrimLength;
258 localPrimLength = *primItr;
259
260 for(GLsizei primCount = 0; primCount < *primItr; ++primCount)
261 {
262 if ((primCount%localPrimLength)==0)
263 {
264 OutputSurfHead(iCurrentMaterial,surfaceFlags,localPrimLength, fout);
265 }
266 OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout);
267 ++vindex;
268 }
269
270 }
271 }
OutputTriangleStripDARR(const int iCurrentMaterial,const unsigned int surfaceFlags,const osg::IndexArray * pVertexIndices,const osg::Vec2 * pTexCoords,const osg::IndexArray * pTexIndices,const osg::DrawArrayLengths * drawArrayLengths,ostream & fout)272 void Geode::OutputTriangleStripDARR(const int iCurrentMaterial, const unsigned int surfaceFlags,
273 const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawArrayLengths* drawArrayLengths, ostream& fout)
274 {
275 unsigned int vindex = drawArrayLengths->getFirst();
276 for(osg::DrawArrayLengths::const_iterator primItr = drawArrayLengths->begin(); primItr <drawArrayLengths->end(); ++primItr)
277 {
278 // RFJ!!!!!!!!!! fixes for indexing
279 int localPrimLength= *primItr;
280 bool evenodd=true;
281
282 for(GLsizei primCount = 0; primCount < localPrimLength - 2; ++primCount)
283 {
284 OutputSurfHead(iCurrentMaterial, surfaceFlags, 3, fout);
285 if (evenodd) {
286 OutputVertex(vindex + primCount, pVertexIndices, pTexCoords, pTexIndices, fout);
287 OutputVertex(vindex + primCount + 1, pVertexIndices, pTexCoords, pTexIndices, fout);
288 } else {
289 OutputVertex(vindex + primCount + 1 , pVertexIndices, pTexCoords, pTexIndices, fout);
290 OutputVertex(vindex + primCount, pVertexIndices, pTexCoords, pTexIndices, fout);
291 }
292 OutputVertex(vindex + primCount + 2, pVertexIndices, pTexCoords, pTexIndices, fout);
293 evenodd=!evenodd;
294 }
295 vindex += localPrimLength;
296 }
297 }
OutputTriangleFanDARR(const int iCurrentMaterial,const unsigned int surfaceFlags,const osg::IndexArray * pVertexIndices,const osg::Vec2 * pTexCoords,const osg::IndexArray * pTexIndices,const osg::DrawArrayLengths * drawArrayLengths,ostream & fout)298 void Geode::OutputTriangleFanDARR(const int iCurrentMaterial, const unsigned int surfaceFlags,
299 const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,const osg::DrawArrayLengths* drawArrayLengths, ostream& fout)
300 {
301 unsigned int vindex = drawArrayLengths->getFirst();
302 for(osg::DrawArrayLengths::const_iterator primItr = drawArrayLengths->begin(); primItr <drawArrayLengths->end(); ++primItr)
303 {
304 int localPrimLength = *primItr;
305
306 for(GLsizei primCount = 0; primCount < localPrimLength - 2; primCount++)
307 {
308 OutputSurfHead(iCurrentMaterial,surfaceFlags,3, fout);
309 OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout);
310 OutputVertex(vindex+1+primCount, pVertexIndices, pTexCoords, pTexIndices, fout);
311 OutputVertex(vindex+2+primCount, pVertexIndices, pTexCoords, pTexIndices, fout);
312 }
313 vindex += localPrimLength;
314 }
315 }
316
317 // DrawElements .... Ubyte
OutputTriangleDelsUByte(const int iCurrentMaterial,const unsigned int surfaceFlags,const osg::IndexArray * pVertexIndices,const osg::Vec2 * pTexCoords,const osg::IndexArray * pTexIndices,const osg::DrawElementsUByte * drawElements,ostream & fout)318 void Geode::OutputTriangleDelsUByte(const int iCurrentMaterial, const unsigned int surfaceFlags,
319 const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,
320 const osg::DrawElementsUByte* drawElements, ostream& fout)
321 {
322 unsigned int primLength =3;
323
324 unsigned int primCount = 0;
325 for(osg::DrawElementsUByte::const_iterator primItr=drawElements->begin(); primItr<drawElements->end(); ++primCount,++primItr)
326 {
327 if ((primCount%primLength) == 0)
328 {
329 OutputSurfHead(iCurrentMaterial,surfaceFlags,primLength, fout);
330 }
331
332 unsigned int vindex=*primItr;
333 OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout);
334 }
335 }
OutputTriangleStripDelsUByte(const int iCurrentMaterial,const unsigned int surfaceFlags,const osg::IndexArray * pVertexIndices,const osg::Vec2 * pTexCoords,const osg::IndexArray * pTexIndices,const osg::DrawElementsUByte * drawElements,ostream & fout)336 void Geode::OutputTriangleStripDelsUByte(const int iCurrentMaterial, const unsigned int surfaceFlags,
337 const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,
338 const osg::DrawElementsUByte* drawElements, ostream& fout)
339 {
340 unsigned int localPrimLength = 3;
341 bool evenodd=true;
342 for(osg::DrawElementsUByte::const_iterator primItr=drawElements->begin(); primItr<drawElements->end()-2; ++primItr)
343 {
344
345 unsigned int vindex=*primItr;
346 unsigned int vindexp1=*(primItr+1);
347 unsigned int vindexp2=*(primItr+2);
348 OutputSurfHead(iCurrentMaterial,surfaceFlags,localPrimLength, fout);
349 if (evenodd) {
350 OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout);
351 OutputVertex(vindexp1, pVertexIndices, pTexCoords, pTexIndices, fout);
352 } else {
353 OutputVertex(vindexp1, pVertexIndices, pTexCoords, pTexIndices, fout);
354 OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout);
355 }
356 OutputVertex(vindexp2, pVertexIndices, pTexCoords, pTexIndices, fout);
357 evenodd=!evenodd;
358 }
359 }
OutputTriangleFanDelsUByte(const int iCurrentMaterial,const unsigned int surfaceFlags,const osg::IndexArray * pVertexIndices,const osg::Vec2 * pTexCoords,const osg::IndexArray * pTexIndices,const osg::DrawElementsUByte * drawElements,ostream & fout)360 void Geode::OutputTriangleFanDelsUByte(const int iCurrentMaterial, const unsigned int surfaceFlags,
361 const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,
362 const osg::DrawElementsUByte* drawElements, ostream& fout)
363 {
364 const unsigned int localPrimLength = 3;
365 unsigned int vindex=*(drawElements->begin());
366 for(osg::DrawElementsUByte::const_iterator primItr=drawElements->begin(); primItr<drawElements->end()-2; ++primItr)
367 {
368 unsigned int vindexp1=*(primItr+1);
369 unsigned int vindexp2=*(primItr+2);
370 OutputSurfHead(iCurrentMaterial,surfaceFlags,localPrimLength, fout);
371
372 OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout);
373 OutputVertex(vindexp1, pVertexIndices, pTexCoords, pTexIndices, fout);
374 OutputVertex(vindexp2, pVertexIndices, pTexCoords, pTexIndices, fout);
375 }
376 }
OutputQuadStripDelsUByte(const int iCurrentMaterial,const unsigned int surfaceFlags,const osg::IndexArray * pVertexIndices,const osg::Vec2 * pTexCoords,const osg::IndexArray * pTexIndices,const osg::DrawElementsUByte * drawElements,ostream & fout)377 void Geode::OutputQuadStripDelsUByte(const int iCurrentMaterial, const unsigned int surfaceFlags,
378 const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,
379 const osg::DrawElementsUByte* drawElements, ostream& fout)
380 {
381 const unsigned int localPrimLength=4;
382 for(osg::DrawElementsUByte::const_iterator primItr=drawElements->begin(); primItr<drawElements->end()-3; primItr+=2)
383 {
384 unsigned int vindex=*primItr;
385
386 unsigned int vindexp1=*(primItr+1);
387 unsigned int vindexp2=*(primItr+3);
388 unsigned int vindexp3=*(primItr+2);
389 OutputSurfHead(iCurrentMaterial,surfaceFlags,localPrimLength, fout);
390
391 OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout);
392 OutputVertex(vindexp1, pVertexIndices, pTexCoords, pTexIndices, fout);
393 OutputVertex(vindexp2, pVertexIndices, pTexCoords, pTexIndices, fout);
394 OutputVertex(vindexp3, pVertexIndices, pTexCoords, pTexIndices, fout);
395 }
396 }
OutputQuadsDelsUByte(const int iCurrentMaterial,const unsigned int surfaceFlags,const osg::IndexArray * pVertexIndices,const osg::Vec2 * pTexCoords,const osg::IndexArray * pTexIndices,const osg::DrawElementsUByte * drawElements,ostream & fout)397 void Geode::OutputQuadsDelsUByte(const int iCurrentMaterial, const unsigned int surfaceFlags,
398 const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,
399 const osg::DrawElementsUByte* drawElements, ostream& fout)
400 {
401 const unsigned int localPrimLength=4;
402 for(osg::DrawElementsUByte::const_iterator primItr=drawElements->begin(); primItr<drawElements->end()-3; primItr+=4)
403 {
404 unsigned int vindex=*primItr;
405
406 unsigned int vindexp1=*(primItr+1);
407 unsigned int vindexp2=*(primItr+2);
408 unsigned int vindexp3=*(primItr+3);
409 OutputSurfHead(iCurrentMaterial,surfaceFlags,localPrimLength, fout);
410
411 OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout);
412 OutputVertex(vindexp1, pVertexIndices, pTexCoords, pTexIndices, fout);
413 OutputVertex(vindexp2, pVertexIndices, pTexCoords, pTexIndices, fout);
414 OutputVertex(vindexp3, pVertexIndices, pTexCoords, pTexIndices, fout);
415 }
416 }
OutputPolygonDelsUByte(const int iCurrentMaterial,const unsigned int surfaceFlags,const osg::IndexArray * pVertexIndices,const osg::Vec2 * pTexCoords,const osg::IndexArray * pTexIndices,const osg::DrawElementsUByte * drawElements,ostream & fout)417 void Geode::OutputPolygonDelsUByte(const int iCurrentMaterial, const unsigned int surfaceFlags,
418 const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,
419 const osg::DrawElementsUByte* drawElements, ostream& fout)
420 {
421 unsigned int primLength =drawElements->size();
422 unsigned int primCount = 0;
423
424 OutputSurfHead(iCurrentMaterial,surfaceFlags,primLength, fout);
425 for(osg::DrawElementsUByte::const_iterator primItr=drawElements->begin(); primItr<drawElements->end(); ++primCount,++primItr)
426 {
427 unsigned int vindex=*primItr;
428 OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout);
429 }
430 }
431 // DrawElements .... UShort
OutputTriangleDelsUShort(const int iCurrentMaterial,const unsigned int surfaceFlags,const osg::IndexArray * pVertexIndices,const osg::Vec2 * pTexCoords,const osg::IndexArray * pTexIndices,const osg::DrawElementsUShort * drawElements,ostream & fout)432 void Geode::OutputTriangleDelsUShort(const int iCurrentMaterial, const unsigned int surfaceFlags,
433 const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,
434 const osg::DrawElementsUShort* drawElements, ostream& fout)
435 {
436 unsigned int primLength =3;
437
438 unsigned int primCount = 0;
439 for(osg::DrawElementsUShort::const_iterator primItr=drawElements->begin(); primItr<drawElements->end(); ++primCount,++primItr)
440 {
441
442 if ((primCount%primLength) == 0)
443 {
444 OutputSurfHead(iCurrentMaterial,surfaceFlags,primLength, fout);
445 }
446
447 unsigned int vindex=*primItr;
448 OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout);
449 }
450 }
OutputTriangleStripDelsUShort(const int iCurrentMaterial,const unsigned int surfaceFlags,const osg::IndexArray * pVertexIndices,const osg::Vec2 * pTexCoords,const osg::IndexArray * pTexIndices,const osg::DrawElementsUShort * drawElements,ostream & fout)451 void Geode::OutputTriangleStripDelsUShort(const int iCurrentMaterial, const unsigned int surfaceFlags,
452 const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,
453 const osg::DrawElementsUShort* drawElements, ostream& fout)
454 {
455 unsigned int localPrimLength = 3;
456 bool evenodd=true;
457 for(osg::DrawElementsUShort::const_iterator primItr=drawElements->begin(); primItr<drawElements->end()-2; ++primItr)
458 {
459 unsigned int vindex=*primItr;
460 unsigned int vindexp1=*(primItr+1);
461 unsigned int vindexp2=*(primItr+2);
462 OutputSurfHead(iCurrentMaterial,surfaceFlags,localPrimLength, fout);
463 if (evenodd) {
464 OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout);
465 OutputVertex(vindexp1, pVertexIndices, pTexCoords, pTexIndices, fout);
466 } else {
467 OutputVertex(vindexp1, pVertexIndices, pTexCoords, pTexIndices, fout);
468 OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout);
469 }
470 OutputVertex(vindexp2, pVertexIndices, pTexCoords, pTexIndices, fout);
471 evenodd=!evenodd;
472 }
473 }
OutputTriangleFanDelsUShort(const int iCurrentMaterial,const unsigned int surfaceFlags,const osg::IndexArray * pVertexIndices,const osg::Vec2 * pTexCoords,const osg::IndexArray * pTexIndices,const osg::DrawElementsUShort * drawElements,ostream & fout)474 void Geode::OutputTriangleFanDelsUShort(const int iCurrentMaterial, const unsigned int surfaceFlags,
475 const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,
476 const osg::DrawElementsUShort* drawElements, ostream& fout)
477 {
478 const unsigned int localPrimLength = 3;
479 unsigned int vindex=*(drawElements->begin());
480 for(osg::DrawElementsUShort::const_iterator primItr=drawElements->begin(); primItr<drawElements->end()-2; ++primItr)
481 {
482 unsigned int vindexp1=*(primItr+1);
483 unsigned int vindexp2=*(primItr+2);
484 OutputSurfHead(iCurrentMaterial,surfaceFlags,localPrimLength, fout);
485
486 OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout);
487 OutputVertex(vindexp1, pVertexIndices, pTexCoords, pTexIndices, fout);
488 OutputVertex(vindexp2, pVertexIndices, pTexCoords, pTexIndices, fout);
489 }
490 }
OutputQuadStripDelsUShort(const int iCurrentMaterial,const unsigned int surfaceFlags,const osg::IndexArray * pVertexIndices,const osg::Vec2 * pTexCoords,const osg::IndexArray * pTexIndices,const osg::DrawElementsUShort * drawElements,ostream & fout)491 void Geode::OutputQuadStripDelsUShort(const int iCurrentMaterial, const unsigned int surfaceFlags,
492 const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,
493 const osg::DrawElementsUShort* drawElements, ostream& fout)
494 {
495 const unsigned int localPrimLength=4;
496 for(osg::DrawElementsUShort::const_iterator primItr=drawElements->begin(); primItr<drawElements->end()-3; primItr+=2)
497 {
498 unsigned int vindex=*primItr;
499
500 unsigned int vindexp1=*(primItr+1);
501 unsigned int vindexp2=*(primItr+3);
502 unsigned int vindexp3=*(primItr+2);
503 OutputSurfHead(iCurrentMaterial,surfaceFlags,localPrimLength, fout);
504
505 OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout);
506 OutputVertex(vindexp1, pVertexIndices, pTexCoords, pTexIndices, fout);
507 OutputVertex(vindexp2, pVertexIndices, pTexCoords, pTexIndices, fout);
508 OutputVertex(vindexp3, pVertexIndices, pTexCoords, pTexIndices, fout);
509 }
510 }
OutputQuadsDelsUShort(const int iCurrentMaterial,const unsigned int surfaceFlags,const osg::IndexArray * pVertexIndices,const osg::Vec2 * pTexCoords,const osg::IndexArray * pTexIndices,const osg::DrawElementsUShort * drawElements,ostream & fout)511 void Geode::OutputQuadsDelsUShort(const int iCurrentMaterial, const unsigned int surfaceFlags,
512 const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,
513 const osg::DrawElementsUShort* drawElements, ostream& fout)
514 {
515 const unsigned int localPrimLength=4;
516 for(osg::DrawElementsUShort::const_iterator primItr=drawElements->begin(); primItr<drawElements->end()-3; primItr+=4)
517 {
518 unsigned int vindex=*primItr;
519
520 unsigned int vindexp1=*(primItr+1);
521 unsigned int vindexp2=*(primItr+2);
522 unsigned int vindexp3=*(primItr+3);
523 OutputSurfHead(iCurrentMaterial,surfaceFlags,localPrimLength, fout);
524
525 OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout);
526 OutputVertex(vindexp1, pVertexIndices, pTexCoords, pTexIndices, fout);
527 OutputVertex(vindexp2, pVertexIndices, pTexCoords, pTexIndices, fout);
528 OutputVertex(vindexp3, pVertexIndices, pTexCoords, pTexIndices, fout);
529 }
530 }
OutputPolygonDelsUShort(const int iCurrentMaterial,const unsigned int surfaceFlags,const osg::IndexArray * pVertexIndices,const osg::Vec2 * pTexCoords,const osg::IndexArray * pTexIndices,const osg::DrawElementsUShort * drawElements,ostream & fout)531 void Geode::OutputPolygonDelsUShort(const int iCurrentMaterial, const unsigned int surfaceFlags,
532 const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,
533 const osg::DrawElementsUShort* drawElements, ostream& fout)
534 {
535 unsigned int primLength =drawElements->size();
536 unsigned int primCount = 0;
537
538 OutputSurfHead(iCurrentMaterial,surfaceFlags,primLength, fout);
539 for(osg::DrawElementsUShort::const_iterator primItr=drawElements->begin(); primItr<drawElements->end(); ++primCount,++primItr)
540 {
541 unsigned int vindex=*primItr;
542 OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout);
543 }
544 }
545 // DrawElements .... UInt
OutputTriangleDelsUInt(const int iCurrentMaterial,const unsigned int surfaceFlags,const osg::IndexArray * pVertexIndices,const osg::Vec2 * pTexCoords,const osg::IndexArray * pTexIndices,const osg::DrawElementsUInt * drawElements,ostream & fout)546 void Geode::OutputTriangleDelsUInt(const int iCurrentMaterial, const unsigned int surfaceFlags,
547 const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,
548 const osg::DrawElementsUInt* drawElements, ostream& fout)
549 {
550 unsigned int primLength =3;
551
552 unsigned int primCount = 0;
553 for(osg::DrawElementsUInt::const_iterator primItr=drawElements->begin(); primItr<drawElements->end(); ++primCount,++primItr)
554 {
555
556 if ((primCount%primLength) == 0)
557 {
558 OutputSurfHead(iCurrentMaterial,surfaceFlags,primLength, fout);
559 }
560
561 unsigned int vindex=*primItr;
562 OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout);
563 }
564 }
OutputTriangleStripDelsUInt(const int iCurrentMaterial,const unsigned int surfaceFlags,const osg::IndexArray * pVertexIndices,const osg::Vec2 * pTexCoords,const osg::IndexArray * pTexIndices,const osg::DrawElementsUInt * drawElements,ostream & fout)565 void Geode::OutputTriangleStripDelsUInt(const int iCurrentMaterial, const unsigned int surfaceFlags,
566 const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,
567 const osg::DrawElementsUInt* drawElements, ostream& fout)
568 {
569 unsigned int localPrimLength = 3;
570 bool evenodd=true;
571 for(osg::DrawElementsUInt::const_iterator primItr=drawElements->begin(); primItr<drawElements->end()-2; ++primItr)
572 {
573
574 unsigned int vindex=*primItr;
575 unsigned int vindexp1=*(primItr+1);
576 unsigned int vindexp2=*(primItr+2);
577 OutputSurfHead(iCurrentMaterial,surfaceFlags,localPrimLength, fout);
578 if (evenodd) {
579 OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout);
580 OutputVertex(vindexp1, pVertexIndices, pTexCoords, pTexIndices, fout);
581 } else {
582 OutputVertex(vindexp1, pVertexIndices, pTexCoords, pTexIndices, fout);
583 OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout);
584 }
585 OutputVertex(vindexp2, pVertexIndices, pTexCoords, pTexIndices, fout);
586 evenodd=!evenodd;
587 }
588 }
OutputTriangleFanDelsUInt(const int iCurrentMaterial,const unsigned int surfaceFlags,const osg::IndexArray * pVertexIndices,const osg::Vec2 * pTexCoords,const osg::IndexArray * pTexIndices,const osg::DrawElementsUInt * drawElements,ostream & fout)589 void Geode::OutputTriangleFanDelsUInt(const int iCurrentMaterial, const unsigned int surfaceFlags,
590 const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,
591 const osg::DrawElementsUInt* drawElements, ostream& fout)
592 {
593 const unsigned int localPrimLength = 3;
594 unsigned int vindex=*(drawElements->begin());
595 for(osg::DrawElementsUInt::const_iterator primItr=drawElements->begin(); primItr<drawElements->end()-2; ++primItr)
596 {
597 unsigned int vindexp1=*(primItr+1);
598 unsigned int vindexp2=*(primItr+2);
599 OutputSurfHead(iCurrentMaterial,surfaceFlags,localPrimLength, fout);
600
601 OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout);
602 OutputVertex(vindexp1, pVertexIndices, pTexCoords, pTexIndices, fout);
603 OutputVertex(vindexp2, pVertexIndices, pTexCoords, pTexIndices, fout);
604 }
605 }
OutputQuadStripDelsUInt(const int iCurrentMaterial,const unsigned int surfaceFlags,const osg::IndexArray * pVertexIndices,const osg::Vec2 * pTexCoords,const osg::IndexArray * pTexIndices,const osg::DrawElementsUInt * drawElements,ostream & fout)606 void Geode::OutputQuadStripDelsUInt(const int iCurrentMaterial, const unsigned int surfaceFlags,
607 const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,
608 const osg::DrawElementsUInt* drawElements, ostream& fout)
609 {
610 const unsigned int localPrimLength = 4;
611 for(osg::DrawElementsUInt::const_iterator primItr=drawElements->begin(); primItr<drawElements->end()-3; primItr+=2)
612 {
613 unsigned int vindex=*primItr;
614
615 unsigned int vindexp1=*(primItr+1);
616 unsigned int vindexp2=*(primItr+3);
617 unsigned int vindexp3=*(primItr+2);
618 OutputSurfHead(iCurrentMaterial,surfaceFlags,localPrimLength, fout);
619
620 OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout);
621 OutputVertex(vindexp1, pVertexIndices, pTexCoords, pTexIndices, fout);
622 OutputVertex(vindexp2, pVertexIndices, pTexCoords, pTexIndices, fout);
623 OutputVertex(vindexp3, pVertexIndices, pTexCoords, pTexIndices, fout);
624 }
625 }
OutputQuadsDelsUInt(const int iCurrentMaterial,const unsigned int surfaceFlags,const osg::IndexArray * pVertexIndices,const osg::Vec2 * pTexCoords,const osg::IndexArray * pTexIndices,const osg::DrawElementsUInt * drawElements,ostream & fout)626 void Geode::OutputQuadsDelsUInt(const int iCurrentMaterial, const unsigned int surfaceFlags,
627 const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,
628 const osg::DrawElementsUInt* drawElements, ostream& fout)
629 {
630 const unsigned int localPrimLength=4;
631 for(osg::DrawElementsUInt::const_iterator primItr=drawElements->begin(); primItr<drawElements->end()-3; primItr+=4)
632 {
633 unsigned int vindex=*primItr;
634
635 unsigned int vindexp1=*(primItr+1);
636 unsigned int vindexp2=*(primItr+2);
637 unsigned int vindexp3=*(primItr+3);
638 OutputSurfHead(iCurrentMaterial,surfaceFlags,localPrimLength, fout);
639
640 OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout);
641 OutputVertex(vindexp1, pVertexIndices, pTexCoords, pTexIndices, fout);
642 OutputVertex(vindexp2, pVertexIndices, pTexCoords, pTexIndices, fout);
643 OutputVertex(vindexp3, pVertexIndices, pTexCoords, pTexIndices, fout);
644 }
645 }
OutputPolygonDelsUInt(const int iCurrentMaterial,const unsigned int surfaceFlags,const osg::IndexArray * pVertexIndices,const osg::Vec2 * pTexCoords,const osg::IndexArray * pTexIndices,const osg::DrawElementsUInt * drawElements,ostream & fout)646 void Geode::OutputPolygonDelsUInt(const int iCurrentMaterial, const unsigned int surfaceFlags,
647 const osg::IndexArray *pVertexIndices, const osg::Vec2 *pTexCoords, const osg::IndexArray *pTexIndices,
648 const osg::DrawElementsUInt* drawElements, ostream& fout)
649 {
650 unsigned int primLength =drawElements->size();
651 unsigned int primCount = 0;
652
653 OutputSurfHead(iCurrentMaterial,surfaceFlags,primLength, fout);
654 for(osg::DrawElementsUInt::const_iterator primItr=drawElements->begin(); primItr<drawElements->end(); ++primCount,++primItr)
655 {
656 unsigned int vindex=*primItr;
657 OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout);
658 }
659 }
660
661
ProcessMaterial(ostream & fout,const unsigned int igeode)662 const int Geode::ProcessMaterial(ostream& fout, const unsigned int igeode)
663 {
664 // outputs materials from one geode
665 // extended for multiple geode models, GWM 2003.
666 // called before all the geometry as ac3d expects all materials in the header.
667 // returns number of materials made
668 unsigned int i;
669 const unsigned int iNumDrawables = getNumDrawables();
670 const osg::StateSet::RefAttributePair* pRAP;
671 unsigned int iNumMaterials=0;
672 // Let ac3d optimise the file
673 // whiz round and get a list of materials
674 // these may be duplicates of materials on other Geode/geometry sets.
675
676 // Scan for materials
677 for (i = 0; i < iNumDrawables; i++)
678 {
679 const osg::Drawable* Drawable = getDrawable(i);
680 if (Drawable) {
681 const osg::StateSet* theState = Drawable->getStateSet();
682 if (theState) {
683 pRAP = theState->getAttributePair(osg::StateAttribute::MATERIAL);
684 if (NULL != pRAP)
685 {
686 const osg::Material *pMaterial = dynamic_cast<const osg::Material*>(pRAP->first.get());
687 if (NULL != pMaterial)
688 {
689 const osg::Vec4& Diffuse = pMaterial->getDiffuse(osg::Material::FRONT_AND_BACK);
690 const osg::Vec4& Ambient = pMaterial->getAmbient(osg::Material::FRONT_AND_BACK);
691 const osg::Vec4& Emissive = pMaterial->getEmission(osg::Material::FRONT_AND_BACK);
692 const osg::Vec4& Specular = pMaterial->getSpecular(osg::Material::FRONT_AND_BACK);
693 fout << "MATERIAL "
694 << "\"osg"<<igeode<<"mat"<<i
695 << "\" rgb " << Diffuse[0] << " " << Diffuse[1] << " " << Diffuse[2] << " "
696 << "amb " << Ambient[0] << " " << Ambient[1] << " " << Ambient[2] << " "
697 << "emis " << Emissive[0] << " " << Emissive[1] << " " << Emissive[2] << " "
698 << "spec " << Specular[0] << " " << Specular[1] << " " << Specular[2] << " "
699 << "shi " << (int)pMaterial->getShininess(osg::Material::FRONT_AND_BACK) << " "
700 << "trans " << 1.0 - Diffuse[3] << std::endl;
701 iNumMaterials++;
702 }
703 }
704 }
705 }
706 }
707 return iNumMaterials;
708 }
ProcessGeometry(ostream & fout,const unsigned int ioffset)709 void Geode::ProcessGeometry(ostream& fout, const unsigned int ioffset)
710 {
711 // outputs one geode
712 // extended for multiple geode models, GWM 2003.
713 unsigned int i, j; //, k, m;
714 const unsigned int iNumDrawables = getNumDrawables();
715 int iNumMaterials = 0;
716 const osg::StateSet::RefAttributePair* pRAP=NULL;
717 // Let ac3d optimise the file
718 // whiz round and get a list of materails
719 // write them out
720 // write out an object for each drawable.
721 // Write out world object
722 int ngeometry=0; // not all drawables are geometry, text is not converted to facets.
723 for (i = 0; i < iNumDrawables; i++)
724 { // so here we count the geometries to be converted to AC3D
725 const osg::Drawable* Drawable = getDrawable(i);
726 if (Drawable) {
727 const osg::Geometry *pGeometry = Drawable->asGeometry();
728 if (NULL != pGeometry) ngeometry++;
729 }
730 }
731 if (ngeometry>1) { // create a group
732 fout << "OBJECT group" << std::endl;
733 fout << "kids " << ngeometry << std::endl;
734 }
735
736 // Process each drawable in turn
737 for (i = 0; i < iNumDrawables; i++)
738 {
739 const osg::Drawable* Drawable = getDrawable(i);
740 if (Drawable) {
741 const osg::StateSet* theState = Drawable->getStateSet();
742 const osg::Geometry *pGeometry = Drawable->asGeometry();
743 if (NULL != pGeometry)
744 {
745 int iCurrentMaterial = -1;
746
747 if (theState) {
748 pRAP = theState->getAttributePair(osg::StateAttribute::MATERIAL);
749 if (NULL != pRAP)
750 {
751 iCurrentMaterial = ioffset+iNumMaterials;
752 iNumMaterials++;
753 }
754 }
755
756 //const osg::Vec3Array
757 const osg::Array *pVertexArray = pGeometry->getVertexArray();
758 if (NULL != pVertexArray)
759 {
760 const unsigned int iNumVertices = pVertexArray->getNumElements(); // size();
761 const osg::IndexArray *pVertexIndices = 0;
762 const osg::IndexArray * pTexIndices = 0;
763 const osg::Vec2 *pTexCoords = NULL;
764 fout << "OBJECT poly" << std::endl;
765 fout << "name \"" << getName() << "\"" << std::endl;
766
767 // Use zero offset co-ordinate as location IS OPTIONAL
768 // fout << "loc " << "0 0 0" << std::endl;
769 /* you could have an offset for the coordinates; it was suggested that the first coord would do.
770 if((*pVertexArray).getType()==osg::Array::Vec3ArrayType) {
771 const osg::Vec3Array *verts=static_cast<const osg::Vec3Array*>(pVertexArray);
772 fout << (*verts)[0][0] << " " << (*verts)[0][1] << " " << (*verts)[0][2] << std::endl;
773 } else if((*pVertexArray).getType()==osg::Array::Vec2ArrayType) {
774 const osg::Vec2Array *verts=static_cast<const osg::Vec2Array*>(pVertexArray);
775 fout << (*verts)[0][0] << " " << (*verts)[0][1] << " " << 0 << std::endl;
776 } else if((*pVertexArray).getType()==osg::Array::Vec4ArrayType) {
777 const osg::Vec4Array *verts=static_cast<const osg::Vec4Array*>(pVertexArray);
778 fout << (*verts)[0][0] << " " << (*verts)[0][1] << " " << (*verts)[0][2] << std::endl;
779 }
780 << (*pVertexArray)[0][0] << " "
781 << (*pVertexArray)[0][1] << " "
782 << (*pVertexArray)[0][2] << std::endl; */
783
784 // Check for a texture
785 if (theState)
786 {
787 const osg::StateSet::TextureAttributeList& TextureAttributeList = theState->getTextureAttributeList();
788 if (TextureAttributeList.size() > 0)
789 {
790 // Check for a single mode of GL_TEXTURE_2D and ON
791 const osg::StateSet::AttributeList& AttributeList = TextureAttributeList[0];
792 // assert(AttributeList.size() == 1);
793 const osg::Texture2D *pTexture2D = dynamic_cast<const osg::Texture2D*>(AttributeList.begin()->second.first.get());
794 // assert(NULL != pTexture2D);
795 if (NULL != pTexture2D)
796 {
797 pTexCoords = (const osg::Vec2*)pGeometry->getTexCoordArray(0)->getDataPointer();
798
799 // OK now see if I can calcualate the repeats
800 osg::Texture::WrapMode eWrapMode_s = pTexture2D->getWrap(osg::Texture::WRAP_S);
801 //osg::Texture::WrapMode eWrapMode_t = pTexture2D->getWrap(osg::Texture::WRAP_T);
802
803 if (eWrapMode_s == osg::Texture::REPEAT)
804 {
805 if (NULL != pTexCoords)
806 {
807 // Find max min s coords
808 float fMin = std::numeric_limits<float>::max();
809 float fMax = std::numeric_limits<float>::min();
810 unsigned int iNumTexCoords = pGeometry->getTexCoordArray(0)->getNumElements();
811
812 for (j = 0; j < iNumTexCoords; j++)
813 {
814 if (pTexCoords[j][0] > fMax)
815 fMax = pTexCoords[j][0];
816 if (pTexCoords[j][0] < fMin)
817 fMin = pTexCoords[j][0];
818 }
819 fMin = std::numeric_limits<float>::max();
820 fMax = std::numeric_limits<float>::min();
821 for (j = 0; j < iNumTexCoords; j++)
822 {
823 if (pTexCoords[j][1] > fMax)
824 fMax = pTexCoords[j][1];
825 if (pTexCoords[j][1] < fMin)
826 fMin = pTexCoords[j][1];
827 }
828 }
829 }
830
831 { // replace back slash with / for ac3d convention GWM Sep 2003
832 std::string fname=pTexture2D->getImage()->getFileName();
833 unsigned int pos;
834 for (pos=0; pos< fname.length(); pos++) {
835 if (fname[pos] == '\\') fname[pos]='/';
836 }
837 fout << "texture \"" << fname << "\"" << std::endl;
838 }
839 // Temp frig
840 fout << "texrep 1 1" << std::endl;
841 fout << "texoff 0 0" << std::endl;
842 }
843 }
844 }
845
846 fout << "numvert " << iNumVertices << std::endl;
847 for (j = 0; j < iNumVertices; j++)
848 { // use 3 types of osg::Vec for coordinates....
849 if((*pVertexArray).getType()==osg::Array::Vec3ArrayType) {
850 const osg::Vec3Array *verts=static_cast<const osg::Vec3Array*>(pVertexArray);
851 fout << (*verts)[j][0] << " " << (*verts)[j][1] << " " << (*verts)[j][2] << std::endl;
852 } else if((*pVertexArray).getType()==osg::Array::Vec2ArrayType) {
853 const osg::Vec2Array *verts=static_cast<const osg::Vec2Array*>(pVertexArray);
854 fout << (*verts)[j][0] << " " << (*verts)[j][1] << " " << 0 << std::endl;
855 } else if((*pVertexArray).getType()==osg::Array::Vec4ArrayType) {
856 const osg::Vec4Array *verts=static_cast<const osg::Vec4Array*>(pVertexArray);
857 fout << (*verts)[j][0] << " " << (*verts)[j][1] << " " << (*verts)[j][2] << std::endl;
858 }
859 }
860
861
862 // Generate a surface for each primitive
863 unsigned int iNumSurfaces = 0; // complex tri-strip etc prims use more triangles
864 osg::Geometry::PrimitiveSetList::const_iterator pItr;
865 for(pItr = pGeometry->getPrimitiveSetList().begin(); pItr != pGeometry->getPrimitiveSetList().end(); ++pItr) {
866 const osg::PrimitiveSet* primitiveset = pItr->get();
867 //const osg::PrimitiveSet::Type type = primitiveset->getType();
868 unsigned int iNumPrimitives = primitiveset->getNumPrimitives();
869 unsigned int iNumIndices = primitiveset->getNumIndices();
870 GLenum mode=primitiveset->getMode();
871 switch(mode) {
872 case(osg::PrimitiveSet::POINTS):
873 iNumSurfaces+=1; // all points go in one big list
874 break;
875 case(osg::PrimitiveSet::LINES): // each line is a pair of vertices
876 case(osg::PrimitiveSet::TRIANGLES): // each tri = 3 verts
877 case(osg::PrimitiveSet::QUADS):
878 case(osg::PrimitiveSet::LINE_LOOP):
879 case(osg::PrimitiveSet::LINE_STRIP):
880 case(osg::PrimitiveSet::POLYGON):
881 iNumSurfaces+=iNumPrimitives;
882 break;
883 case(osg::PrimitiveSet::TRIANGLE_STRIP):
884 case(osg::PrimitiveSet::TRIANGLE_FAN):
885 iNumSurfaces+=iNumIndices-2*iNumPrimitives;
886 break;
887 case(osg::PrimitiveSet::QUAD_STRIP):
888 iNumSurfaces+=(iNumIndices-2*iNumPrimitives)/2;
889 break;
890 default:
891 break; // unknown shape
892 }
893 }
894 fout << "numsurf " << iNumSurfaces << std::endl;
895
896 for(pItr = pGeometry->getPrimitiveSetList().begin(); pItr != pGeometry->getPrimitiveSetList().end(); ++pItr)
897 {
898 const osg::PrimitiveSet* primitiveset = pItr->get();
899 GLenum mode=primitiveset->getMode();
900
901 unsigned int surfaceFlags = 0x00;
902
903 switch(mode)
904 {
905 case(osg::PrimitiveSet::POINTS):
906 surfaceFlags = 0x02;
907 break;
908 case(osg::PrimitiveSet::LINES):
909 surfaceFlags = 0x02;
910 break;
911 case(osg::PrimitiveSet::TRIANGLES):
912 break;
913 case(osg::PrimitiveSet::QUADS):
914 break;
915 default:
916 break; // compute later when =0.
917 }
918
919 // osg::StateAttribute::GLModeValue backface =theState->getMode(osg::StateAttribute::CULLFACE);
920 // if (backface==osg::StateAttribute::ON) surfaceFlags |= 0x10;
921 // else if (backface==osg::StateAttribute::OFF) surfaceFlags &= 0x0f;
922 const osg::DrawArrays* drawArray = static_cast<const osg::DrawArrays*>(primitiveset);
923 switch(primitiveset->getType())
924 {
925 case(osg::PrimitiveSet::DrawArraysPrimitiveType):
926 {
927 switch(mode)
928 {
929 case(osg::PrimitiveSet::POINTS):
930 break;
931 case(osg::PrimitiveSet::LINES):
932 OutputLines(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawArray, fout);
933 break;
934 case(osg::PrimitiveSet::LINE_LOOP):
935 OutputLineLoop(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawArray, fout);
936 break;
937 case(osg::PrimitiveSet::LINE_STRIP):
938 OutputLineStrip(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawArray, fout);
939 break;
940 case(osg::PrimitiveSet::TRIANGLES):
941 OutputTriangle(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawArray, fout);
942 break;
943 case(osg::PrimitiveSet::QUADS):
944 OutputQuads(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawArray, fout);
945 break;
946 case(osg::PrimitiveSet::TRIANGLE_STRIP):
947 OutputTriangleStrip(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawArray, fout);
948 break;
949 case(osg::PrimitiveSet::TRIANGLE_FAN):
950 OutputTriangleFan(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawArray, fout);
951 break;
952 case(osg::PrimitiveSet::QUAD_STRIP):
953 OutputQuadStrip(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawArray, fout);
954 break;
955 case(osg::PrimitiveSet::POLYGON):
956 OutputPolygon(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawArray, fout);
957 break;
958 default:
959 break; // unknown shape
960 }
961 break;
962 }
963 case(osg::PrimitiveSet::DrawArrayLengthsPrimitiveType):
964 {
965
966 const osg::DrawArrayLengths* drawArrayLengths = static_cast<const osg::DrawArrayLengths*>(primitiveset);
967 switch(mode)
968 {
969 case(osg::PrimitiveSet::LINES):
970 OutputLineDARR(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawArrayLengths, fout);
971 break;
972 case(osg::PrimitiveSet::TRIANGLES):
973 OutputTriangleDARR(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawArrayLengths, fout);
974 break;
975 case(osg::PrimitiveSet::QUADS):
976 OutputQuadsDARR(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawArrayLengths, fout);
977 break;
978 case(osg::PrimitiveSet::TRIANGLE_STRIP):
979 OutputTriangleStripDARR(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawArrayLengths, fout);
980 break;
981 case(osg::PrimitiveSet::TRIANGLE_FAN):
982 OutputTriangleFanDARR(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawArrayLengths, fout);
983 break;
984 case(osg::PrimitiveSet::QUAD_STRIP):
985 OutputQuadStripDARR(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawArrayLengths, fout);
986 break;
987 case(osg::PrimitiveSet::POLYGON):
988 OutputPolygonDARR(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawArrayLengths, fout);
989 break;
990 default:
991 break; // unknown shape
992 }
993 break;
994 }
995 case(osg::PrimitiveSet::DrawElementsUBytePrimitiveType):
996 {
997 const osg::DrawElementsUByte* drawElements = static_cast<const osg::DrawElementsUByte*>(primitiveset);
998 switch(mode)
999 {
1000 case(osg::PrimitiveSet::TRIANGLES):
1001 OutputTriangleDelsUByte(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawElements, fout);
1002 break;
1003 case(osg::PrimitiveSet::QUADS):
1004 OutputQuadsDelsUByte(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawElements, fout);
1005 break;
1006 case(osg::PrimitiveSet::TRIANGLE_STRIP):
1007 OutputTriangleStripDelsUByte(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawElements, fout);
1008 break;
1009 case(osg::PrimitiveSet::TRIANGLE_FAN):
1010 OutputTriangleFanDelsUByte(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawElements, fout);
1011 break;
1012 case(osg::PrimitiveSet::QUAD_STRIP):
1013 OutputQuadStripDelsUByte(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawElements, fout);
1014 break;
1015 case(osg::PrimitiveSet::POLYGON):
1016 OutputPolygonDelsUByte(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawElements, fout);
1017 break;
1018 default:
1019 break; // unknown shape
1020 }
1021
1022 break;
1023 }
1024 case(osg::PrimitiveSet::DrawElementsUShortPrimitiveType):
1025 {
1026 const osg::DrawElementsUShort* drawElements = static_cast<const osg::DrawElementsUShort*>(primitiveset);
1027 switch(mode)
1028 {
1029 case(osg::PrimitiveSet::TRIANGLES):
1030 OutputTriangleDelsUShort(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawElements, fout);
1031 break;
1032 case(osg::PrimitiveSet::QUADS):
1033 OutputQuadsDelsUShort(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawElements, fout);
1034 break;
1035 case(osg::PrimitiveSet::TRIANGLE_STRIP):
1036 OutputTriangleStripDelsUShort(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawElements, fout);
1037 break;
1038 case(osg::PrimitiveSet::TRIANGLE_FAN):
1039 OutputTriangleFanDelsUShort(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawElements, fout);
1040 break;
1041 case(osg::PrimitiveSet::QUAD_STRIP):
1042 OutputQuadStripDelsUShort(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawElements, fout);
1043 break;
1044 case(osg::PrimitiveSet::POLYGON):
1045 OutputPolygonDelsUShort(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawElements, fout);
1046 break;
1047 default:
1048 break; // unknown shape
1049 }
1050 /* if (primLength == 0)
1051 if (primLength == 0)
1052 primLength = primitiveset->getNumIndices();
1053
1054 const osg::DrawElementsUShort* drawElements = static_cast<const osg::DrawElementsUShort*>(primitiveset);
1055
1056 unsigned int primCount = 0;
1057
1058 for(osg::DrawElementsUShort::const_iterator primItr=drawElements->begin(); primItr!=drawElements->end(); ++primCount,++primItr)
1059 {
1060
1061 if ((primCount%primLength) == 0)
1062 {
1063 OutputSurfHead(iCurrentMaterial,surfaceFlags,primLength, fout);
1064 }
1065
1066 unsigned int vindex=*primItr;
1067 OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout);
1068 } */
1069
1070 break;
1071 }
1072 case(osg::PrimitiveSet::DrawElementsUIntPrimitiveType):
1073 {
1074 const osg::DrawElementsUInt* drawElements = static_cast<const osg::DrawElementsUInt*>(primitiveset);
1075 switch(mode)
1076 {
1077 case(osg::PrimitiveSet::TRIANGLES):
1078 OutputTriangleDelsUInt(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawElements, fout);
1079 break;
1080 case(osg::PrimitiveSet::QUADS):
1081 OutputQuadsDelsUInt(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawElements, fout);
1082 break;
1083 case(osg::PrimitiveSet::TRIANGLE_STRIP):
1084 OutputTriangleStripDelsUInt(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawElements, fout);
1085 break;
1086 case(osg::PrimitiveSet::TRIANGLE_FAN):
1087 OutputTriangleFanDelsUInt(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawElements, fout);
1088 break;
1089 case(osg::PrimitiveSet::QUAD_STRIP):
1090 OutputQuadStripDelsUInt(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawElements, fout);
1091 break;
1092 case(osg::PrimitiveSet::POLYGON):
1093 OutputPolygonDelsUInt(iCurrentMaterial,surfaceFlags, pVertexIndices, pTexCoords, pTexIndices, drawElements, fout);
1094 break;
1095 default:
1096 break; // unknown shape
1097 }
1098 /* if (primLength == 0)
1099 if (primLength == 0)
1100 primLength = primitiveset->getNumIndices();
1101
1102 const osg::DrawElementsUInt* drawElements = static_cast<const osg::DrawElementsUInt*>(primitiveset);
1103
1104 unsigned int primCount=0;
1105 for(osg::DrawElementsUInt::const_iterator primItr=drawElements->begin(); primItr!=drawElements->end(); ++primCount,++primItr)
1106 {
1107
1108 if ((primCount%primLength)==0)
1109 {
1110 OutputSurfHead(iCurrentMaterial,surfaceFlags,primLength, fout);
1111 }
1112
1113 unsigned int vindex=*primItr;
1114 OutputVertex(vindex, pVertexIndices, pTexCoords, pTexIndices, fout);
1115 } */
1116
1117 break;
1118 }
1119 default:
1120 {
1121 break;
1122 }
1123 }
1124 }
1125 }
1126 fout << "kids 0" << endl;
1127 }
1128 }
1129 else
1130 { // not sure what else it could be, but perhaps, perhaps, perhaps.
1131 }
1132 }
1133 }
1134