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