2
* This library is open source and may be redistributed and/or modified under
3
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or (at
4
* your option) any later version. The full license is in the LICENSE file
5
* included with this distribution, and on the openscenegraph.org website.
7
* This library is distributed in the hope that it will be useful, but
8
* WITHOUT ANY WARRANTY; without even the implied warranty of
9
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
* OpenSceneGraph Public License for more details.
14
// Copyright(c) 2008 Skew Matrix Software LLC.
17
#include "FltExportVisitor.h"
18
#include "DataOutputStream.h"
20
#include "MaterialPaletteManager.h"
21
#include "TexturePaletteManager.h"
22
#include "VertexPaletteManager.h"
23
#include <osg/CullFace>
24
#include <osg/BlendFunc>
25
#include <osg/Geometry>
27
#include <osg/io_utils>
28
#include <osg/Material>
29
#include <osg/Texture2D>
38
// Bit flags for multitexturing
39
static unsigned int LAYER_1( 0x80000000 >> 0 );
40
static unsigned int LAYER_2( 0x80000000 >> 1 );
41
static unsigned int LAYER_3( 0x80000000 >> 2 );
42
static unsigned int LAYER_4( 0x80000000 >> 3 );
43
static unsigned int LAYER_5( 0x80000000 >> 4 );
44
static unsigned int LAYER_6( 0x80000000 >> 5 );
45
static unsigned int LAYER_7( 0x80000000 >> 6 );
50
FltExportVisitor::isLit( const osg::Geometry& geom ) const
52
const osg::StateSet* ss = getCurrentStateSet();
53
if ( ss->getMode( GL_LIGHTING ) & osg::StateAttribute::ON )
56
return false; //( geom.getNormalBinding() == osg::Geometry::BIND_PER_VERTEX );
60
FltExportVisitor::isTextured( int unit, const osg::Geometry& geom ) const
62
const osg::StateSet* ss = getCurrentStateSet();
63
bool texOn( ss->getTextureMode( unit, GL_TEXTURE_2D ) & osg::StateAttribute::ON );
64
bool hasCoords( geom.getTexCoordArray( unit ) != NULL );
66
return( texOn && hasCoords );
70
FltExportVisitor::isAllMesh( const osg::Geometry& geom ) const
72
// Return true if all primitive types will use Mesh records for output.
74
for (jdx=0; jdx < geom.getNumPrimitiveSets(); jdx++)
76
const osg::PrimitiveSet* prim = geom.getPrimitiveSet( jdx );
77
if( (prim->getMode() != GL_TRIANGLE_STRIP) &&
78
(prim->getMode() != GL_TRIANGLE_FAN) &&
79
(prim->getMode() != GL_QUAD_STRIP) )
86
FltExportVisitor::writeFace( const osg::Geode& geode, const osg::Geometry& geom, GLenum mode )
91
SOLID_NO_BACKFACE = 1,
93
WIREFRAME_NOT_CLOSED = 3,
94
SURROUND_ALTERNATE_COLOR = 4,
95
OMNIDIRECTIONAL_LIGHT = 8,
96
UNIDIRECTIONAL_LIGHT = 9,
97
BIDIRECTIONAL_LIGHT = 10
101
FIXED_NO_ALPHA_BLENDING = 0,
102
FIXED_ALPHA_BLENDING = 1,
103
AXIAL_ROTATE_WITH_ALPHA_BLENDING = 2,
104
POINT_ROTATE_WITH_ALPHA_BLENDING = 4
107
const unsigned int TERRAIN_BIT = 0x80000000u >> 0;
108
const unsigned int NO_COLOR_BIT = 0x80000000u >> 1;
109
const unsigned int NO_ALT_COLOR_BIT = 0x80000000u >> 2;
110
const unsigned int PACKED_COLOR_BIT = 0x80000000u >> 3;
111
const unsigned int FOOTPRINT_BIT = 0x80000000u >> 4; // Terrain culture cutout
112
const unsigned int HIDDEN_BIT = 0x80000000u >> 5;
113
const unsigned int ROOFLINE_BIT = 0x80000000u >> 6;
114
uint32 flags( PACKED_COLOR_BIT );
115
if (geode.getNodeMask() == 0)
118
osg::StateSet const* ss = getCurrentStateSet();
123
FACE_COLOR_LIGHTING = 2,
124
VERTEX_COLOR_LIGHTING = 3
127
osg::Vec4 packedColorRaw( 1., 1., 1., 1. );
128
uint16 transparency( 0 );
129
if (geom.getColorBinding() == osg::Geometry::BIND_PER_VERTEX)
132
lightMode = VERTEX_COLOR_LIGHTING;
134
lightMode = VERTEX_COLOR;
138
const osg::Vec4Array* c = dynamic_cast<const osg::Vec4Array*>( geom.getColorArray() );
139
if (c && (c->size() > 0))
141
packedColorRaw = (*c)[0];
142
transparency = flt::uint16((1. - packedColorRaw[3]) * (double)0xffff);
146
lightMode = FACE_COLOR_LIGHTING;
148
lightMode = FACE_COLOR;
151
packedColor = (int)(packedColorRaw[3]*255) << 24 |
152
(int)(packedColorRaw[2]*255) << 16 | (int)(packedColorRaw[1]*255) << 8 |
153
(int)(packedColorRaw[0]*255);
162
std::string warning( "fltexp: GL_POINTS not supported in FLT export." );
163
osg::notify( osg::WARN ) << warning << std::endl;
164
_fltOpt->getWriteResult().warn( warning );
168
case GL_TRIANGLE_STRIP:
169
case GL_TRIANGLE_FAN:
172
std::string warning( "fltexp: Wrong mode in Face record." );
173
osg::notify( osg::WARN ) << warning << std::endl;
174
_fltOpt->getWriteResult().warn( warning );
180
drawType = WIREFRAME_NOT_CLOSED;
183
drawType = WIREFRAME_CLOSED;
189
// Default to no facet culling
190
drawType = SOLID_NO_BACKFACE;
192
// If facet-culling isn't *dis*abled, check whether the CullFace mode is BACK
193
if (ss->getMode(GL_CULL_FACE) & osg::StateAttribute::ON)
195
osg::CullFace const* cullFace = static_cast<osg::CullFace const*>(
196
ss->getAttribute(osg::StateAttribute::CULLFACE) );
197
if( cullFace->getMode() == osg::CullFace::BACK )
198
drawType = SOLID_BACKFACE;
200
// Note: OpenFlt can't handle FRONT or FRONT_AND_BACK settings, so ignore these(??)
206
// Determine the material properties for the face
207
int16 materialIndex( -1 );
210
osg::Material const* currMaterial = static_cast<osg::Material const*>(
211
ss->getAttribute(osg::StateAttribute::MATERIAL) );
212
materialIndex = _materialPalette->add(currMaterial);
216
int16 textureIndex( -1 );
217
if (isTextured( 0, geom ))
219
const osg::Texture2D* texture = static_cast<const osg::Texture2D*>(
220
ss->getTextureAttribute( 0, osg::StateAttribute::TEXTURE ) );
222
textureIndex = _texturePalette->add( 0, texture );
225
std::string warning( "fltexp: Face is textured, but Texture2D StateAttribute is NULL." );
226
osg::notify( osg::WARN ) << warning << std::endl;
227
_fltOpt->getWriteResult().warn( warning );
231
// Check for blending. We're not a Billboard (TBD?)
232
// so use either FIXED_NO_ALPHA_BLENDING or FIXED_ALPHA_BLENDING.
233
TemplateMode templateMode( FIXED_NO_ALPHA_BLENDING );
234
if ( ss->getMode( GL_BLEND ) & osg::StateAttribute::ON )
236
const osg::BlendFunc* bf = static_cast<const osg::BlendFunc*>(
237
ss->getAttribute(osg::StateAttribute::BLENDFUNC) );
238
if( (bf->getSource() == osg::BlendFunc::SRC_ALPHA) &&
239
(bf->getDestination() == osg::BlendFunc::ONE_MINUS_SRC_ALPHA) )
240
templateMode = FIXED_ALPHA_BLENDING;
245
IdHelper id( *this, geode.getName() );
247
_records->writeInt16( (int16) FACE_OP );
248
_records->writeUInt16( length );
249
_records->writeID( id );
250
_records->writeInt32( 0 ); // IR color code
251
_records->writeInt16( 0 ); // Relative priority
252
_records->writeInt8( drawType ); // Draw type
253
_records->writeInt8( 0 ); // Texture white
254
_records->writeInt16( -1 ); // Color name index
255
_records->writeInt16( -1 ); // Alternate color name index
256
_records->writeInt8( 0 ); // Reserved
257
_records->writeInt8( templateMode ); // Template (billboard)
258
_records->writeInt16( -1 ); // Detail texture pattern index
259
_records->writeInt16( textureIndex ); // Texture pattern index
260
_records->writeInt16( materialIndex ); // Material index
261
_records->writeInt16( 0 ); // Surface material code
262
_records->writeInt16( 0 ); // Feature ID
263
_records->writeInt32( 0 ); // IR material code
264
_records->writeUInt16( transparency ); // Transparency
265
_records->writeInt8( 0 ); // LOD generation control
266
_records->writeInt8( 0 ); // Line style index
267
_records->writeUInt32( flags ); // Flags
268
_records->writeInt8( lightMode ); // Light mode
269
_records->writeFill( 7 ); // Reserved
270
_records->writeUInt32( packedColor ); // Packed color, primary
271
_records->writeUInt32( 0x00ffffff ); // Packed color, alternate
272
_records->writeInt16( -1 ); // Texture mapping index
273
_records->writeInt16( 0 ); // Reserved
274
_records->writeInt32( -1 ); // Primary color index
275
_records->writeInt32( -1 ); // Alternate color index
277
// 15.8: two 2-byte "reserved" fields
278
// 15.9: one 4-byte "reserved" field
279
_records->writeInt16( 0 ); // Reserved
280
_records->writeInt16( -1 ); // Shader index
285
FltExportVisitor::writeMesh( const osg::Geode& geode, const osg::Geometry& geom, GLenum mode )
290
SOLID_NO_BACKFACE = 1,
291
WIREFRAME_CLOSED = 2,
292
WIREFRAME_NOT_CLOSED = 3,
293
SURROUND_ALTERNATE_COLOR = 4,
294
OMNIDIRECTIONAL_LIGHT = 8,
295
UNIDIRECTIONAL_LIGHT = 9,
296
BIDIRECTIONAL_LIGHT = 10
300
FIXED_NO_ALPHA_BLENDING = 0,
301
FIXED_ALPHA_BLENDING = 1,
302
AXIAL_ROTATE_WITH_ALPHA_BLENDING = 2,
303
POINT_ROTATE_WITH_ALPHA_BLENDING = 4
306
const unsigned int TERRAIN_BIT = 0x80000000u >> 0;
307
const unsigned int NO_COLOR_BIT = 0x80000000u >> 1;
308
const unsigned int NO_ALT_COLOR_BIT = 0x80000000u >> 2;
309
const unsigned int PACKED_COLOR_BIT = 0x80000000u >> 3;
310
const unsigned int FOOTPRINT_BIT = 0x80000000u >> 4; // Terrain culture cutout
311
const unsigned int HIDDEN_BIT = 0x80000000u >> 5;
312
const unsigned int ROOFLINE_BIT = 0x80000000u >> 6;
313
uint32 flags( PACKED_COLOR_BIT );
314
if (geode.getNodeMask() == 0)
321
FACE_COLOR_LIGHTING = 2,
322
VERTEX_COLOR_LIGHTING = 3
325
osg::Vec4 packedColorRaw( 1., 1., 1., 1. );
326
uint16 transparency( 0 );
327
if (geom.getColorBinding() == osg::Geometry::BIND_PER_VERTEX)
330
lightMode = VERTEX_COLOR_LIGHTING;
332
lightMode = VERTEX_COLOR;
336
const osg::Vec4Array* c = dynamic_cast<const osg::Vec4Array*>( geom.getColorArray() );
337
if (c && (c->size() > 0))
339
packedColorRaw = (*c)[0];
340
transparency = flt::uint16((1. - packedColorRaw[3]) * (double)0xffff);
344
lightMode = FACE_COLOR_LIGHTING;
346
lightMode = FACE_COLOR;
349
packedColor = (int)(packedColorRaw[3]*255) << 24 |
350
(int)(packedColorRaw[2]*255) << 16 | (int)(packedColorRaw[1]*255) << 8 |
351
(int)(packedColorRaw[0]*255);
355
osg::StateSet const* ss = getCurrentStateSet();
361
std::string warning( "fltexp: GL_POINTS not supported in FLT export." );
362
osg::notify( osg::WARN ) << warning << std::endl;
363
_fltOpt->getWriteResult().warn( warning );
373
std::string warning( "fltexp: Wrong mode in Mesh record." );
374
osg::notify( osg::WARN ) << warning << std::endl;
375
_fltOpt->getWriteResult().warn( warning );
379
case GL_TRIANGLE_STRIP:
380
case GL_TRIANGLE_FAN:
384
// Default to no facet culling
385
drawType = SOLID_NO_BACKFACE;
387
// If facet-culling isn't *dis*abled, check whether the CullFace mode is BACK
388
if (ss->getMode(GL_CULL_FACE) & osg::StateAttribute::ON)
390
osg::CullFace const* cullFace = static_cast<osg::CullFace const*>(
391
ss->getAttribute(osg::StateAttribute::CULLFACE) );
392
if( cullFace->getMode() == osg::CullFace::BACK )
393
drawType = SOLID_BACKFACE;
395
// Note: OpenFlt can't handle FRONT or FRONT_AND_BACK settings, so ignore these(??)
401
// Determine the material properties for the face
402
int16 materialIndex( -1 );
405
osg::Material const* currMaterial = static_cast<osg::Material const*>(
406
ss->getAttribute(osg::StateAttribute::MATERIAL) );
407
materialIndex = _materialPalette->add(currMaterial);
411
int16 textureIndex( -1 );
412
if (isTextured( 0, geom ))
414
const osg::Texture2D* texture = static_cast<const osg::Texture2D*>(
415
ss->getTextureAttribute( 0, osg::StateAttribute::TEXTURE ) );
417
textureIndex = _texturePalette->add( 0, texture );
420
std::string warning( "fltexp: Mesh is textured, but Texture2D StateAttribute is NULL." );
421
osg::notify( osg::WARN ) << warning << std::endl;
422
_fltOpt->getWriteResult().warn( warning );
426
// Check for blending. We're not a Billboard (TBD?)
427
// so use either FIXED_NO_ALPHA_BLENDING or FIXED_ALPHA_BLENDING.
428
TemplateMode templateMode( FIXED_NO_ALPHA_BLENDING );
429
if ( ss->getMode( GL_BLEND ) & osg::StateAttribute::ON )
431
const osg::BlendFunc* bf = static_cast<const osg::BlendFunc*>(
432
ss->getAttribute(osg::StateAttribute::BLENDFUNC) );
433
if( (bf->getSource() == osg::BlendFunc::SRC_ALPHA) &&
434
(bf->getDestination() == osg::BlendFunc::ONE_MINUS_SRC_ALPHA) )
435
templateMode = FIXED_ALPHA_BLENDING;
440
IdHelper id( *this, geode.getName() );
442
_records->writeInt16( (int16) MESH_OP );
443
_records->writeUInt16( length );
444
_records->writeID( id );
445
_records->writeInt32( 0 ); // Reserved
446
_records->writeInt32( 0 ); // IR color code
447
_records->writeInt16( 0 ); // Relative priority
448
_records->writeInt8( drawType ); // Draw type
449
_records->writeInt8( 0 ); // Texture white
450
_records->writeInt16( -1 ); // Color name index
451
_records->writeInt16( -1 ); // Alternate color name index
452
_records->writeInt8( 0 ); // Reserved
453
_records->writeInt8( templateMode ); // Template (billboard)
454
_records->writeInt16( -1 ); // Detail texture pattern index
455
_records->writeInt16( textureIndex ); // Texture pattern index
456
_records->writeInt16( materialIndex ); // Material index
457
_records->writeInt16( 0 ); // Surface material code
458
_records->writeInt16( 0 ); // Feature ID
459
_records->writeInt32( 0 ); // IR material code
460
_records->writeUInt16( transparency ); // Transparency
461
_records->writeInt8( 0 ); // LOD generation control
462
_records->writeInt8( 0 ); // Line style index
463
_records->writeUInt32( flags ); // Flags
464
_records->writeInt8( lightMode ); // Light mode
465
_records->writeFill( 7 ); // Reserved
466
_records->writeUInt32( packedColor ); // Packed color, primary
467
_records->writeUInt32( 0x00ffffff ); // Packed color, alternate
468
_records->writeInt16( -1 ); // Texture mapping index
469
_records->writeInt16( 0 ); // Reserved
470
_records->writeInt32( -1 ); // Primary color index
471
_records->writeInt32( -1 ); // Alternate color index
473
// 15.8: two 2-byte "reserved" fields
474
// 15.9: one 4-byte "reserved" field
475
_records->writeInt16( 0 ); // Reserved
476
_records->writeInt16( -1 ); // Shader index
480
FltExportVisitor::writeVertexList( int first, unsigned int count )
482
_records->writeInt16( (int16) VERTEX_LIST_OP );
483
_records->writeUInt16( 4 + (count*4) );
486
for( idx=0; idx<count; idx++)
487
// I'm imaginining that 'first' will be a 0-based index into the
488
// 'current' set of vertices held by the vertex palette manager.
489
_records->writeInt32( _vertexPalette->byteOffset( first+idx ) );
495
FltExportVisitor::writeVertexList( const std::vector<unsigned int>& indices, unsigned int count )
497
_records->writeInt16( (int16) VERTEX_LIST_OP );
498
_records->writeUInt16( 4 + (count*4) );
501
for( idx=0; idx<count; idx++)
502
// I'm imaginining that 'first' will be a 0-based index into the
503
// 'current' set of vertices held by the vertex palette manager.
504
_records->writeInt32( _vertexPalette->byteOffset( indices[ idx ] ) );
510
FltExportVisitor::writeMeshPrimitive( const std::vector<unsigned int>& indices, GLenum mode )
515
case GL_TRIANGLE_STRIP:
518
case GL_TRIANGLE_FAN:
525
// Warning should already be recorded. Do nothing.
530
uint16 length( 12 + (4 * indices.size()) );
532
_records->writeInt16( (int16) MESH_PRIMITIVE_OP );
533
_records->writeUInt16( length );
534
_records->writeInt16( primType ); // primitive type
535
_records->writeInt16( 4 ); // index size, 4 bytes
536
_records->writeInt32( indices.size() ); // vertex count
538
std::vector<unsigned int>::const_iterator it = indices.begin();
539
while (it != indices.end())
541
_records->writeUInt32( (*it) );
547
FltExportVisitor::writeLocalVertexPool( const osg::Geometry& geom, GLenum mode )
550
static const unsigned int HAS_POSITION = 0x80000000u >> 0;
551
static const unsigned int HAS_COLOR_INDEX = 0x80000000u >> 1;
552
static const unsigned int HAS_RGBA_COLOR = 0x80000000u >> 2;
553
static const unsigned int HAS_NORMAL = 0x80000000u >> 3;
554
static const unsigned int HAS_BASE_UV = 0x80000000u >> 4;
555
static const unsigned int HAS_UV_LAYER1 = 0x80000000u >> 5;
556
static const unsigned int HAS_UV_LAYER2 = 0x80000000u >> 6;
557
static const unsigned int HAS_UV_LAYER3 = 0x80000000u >> 7;
558
static const unsigned int HAS_UV_LAYER4 = 0x80000000u >> 8;
559
static const unsigned int HAS_UV_LAYER5 = 0x80000000u >> 9;
560
static const unsigned int HAS_UV_LAYER6 = 0x80000000u >> 10;
561
static const unsigned int HAS_UV_LAYER7 = 0x80000000u >> 11;
563
const osg::Array* v = geom.getVertexArray();
564
uint32 numVerts( v->getNumElements() );
565
osg::ref_ptr< const osg::Vec3dArray > v3 = VertexPaletteManager::asVec3dArray( v, numVerts );
568
std::string warning( "fltexp: writeLocalVertexPool: VertexArray is not Vec3Array." );
569
osg::notify( osg::WARN ) << warning << std::endl;
570
_fltOpt->getWriteResult().warn( warning );
574
// Compute attribute bits and vertex size.
575
const osg::Array* c = geom.getColorArray();
576
const osg::Array* n = geom.getNormalArray();
577
const osg::Array* t = geom.getTexCoordArray( 0 );
579
osg::ref_ptr< const osg::Vec4Array > c4 = VertexPaletteManager::asVec4Array( c, numVerts );
580
osg::ref_ptr< const osg::Vec3Array > n3 = VertexPaletteManager::asVec3Array( n, numVerts );
581
osg::ref_ptr< const osg::Vec2Array > t2 = VertexPaletteManager::asVec2Array( t, numVerts );
589
std::vector< osg::ref_ptr< const osg::Vec2Array > > mtc;
592
for( ;unit<8; unit++)
593
mtc[ unit ] = VertexPaletteManager::asVec2Array( geom.getTexCoordArray( unit ), numVerts );
595
uint32 attr( HAS_POSITION );
596
unsigned int vertSize( sizeof( float64 ) * 3 );
598
if ( ( c4 != NULL ) && ( geom.getColorBinding() == osg::Geometry::BIND_PER_VERTEX) )
600
attr |= HAS_RGBA_COLOR;
601
vertSize += sizeof( unsigned int );
603
if ( ( n3 != NULL ) && ( geom.getNormalBinding() == osg::Geometry::BIND_PER_VERTEX) )
606
vertSize += ( sizeof( float32 ) * 3 );
611
vertSize += ( sizeof( float32 ) * 2 );
614
if (isTextured( 1, geom ))
616
attr |= HAS_UV_LAYER1;
617
vertSize += ( sizeof( float32 ) * 2 );
619
if (isTextured( 2, geom ))
621
attr |= HAS_UV_LAYER2;
622
vertSize += ( sizeof( float32 ) * 2 );
624
if (isTextured( 3, geom ))
626
attr |= HAS_UV_LAYER3;
627
vertSize += ( sizeof( float32 ) * 2 );
629
if (isTextured( 4, geom ))
631
attr |= HAS_UV_LAYER4;
632
vertSize += ( sizeof( float32 ) * 2 );
634
if (isTextured( 5, geom ))
636
attr |= HAS_UV_LAYER5;
637
vertSize += ( sizeof( float32 ) * 2 );
639
if (isTextured( 6, geom ))
641
attr |= HAS_UV_LAYER6;
642
vertSize += ( sizeof( float32 ) * 2 );
644
if (isTextured( 7, geom ))
646
attr |= HAS_UV_LAYER7;
647
vertSize += ( sizeof( float32 ) * 2 );
650
unsigned int maxVerts = (0xffff - 12) / vertSize;
651
unsigned int thisVertCount = (maxVerts > numVerts) ? numVerts : maxVerts;
652
unsigned int currentIndexLimit = maxVerts;
653
uint16 length( 12 + (vertSize * thisVertCount) );
656
_records->writeInt16( (int16) LOCAL_VERTEX_POOL_OP );
657
_records->writeUInt16( length );
658
_records->writeUInt32( numVerts ); // number of vertices
659
_records->writeUInt32( attr ); // attribute bits
662
for( idx=0; idx<numVerts; idx++ )
664
_records->writeVec3d( (*v3)[ idx ] );
666
if (attr & HAS_RGBA_COLOR)
668
osg::Vec4 color = (*c4)[ idx ];
669
unsigned int packedColor = (int)(color[3]*255) << 24 |
670
(int)(color[2]*255) << 16 | (int)(color[1]*255) << 8 |
672
_records->writeUInt32( packedColor );
675
if (attr & HAS_NORMAL)
676
_records->writeVec3f( (*n3)[ idx ] );
678
if (attr & HAS_BASE_UV)
679
_records->writeVec2f( (*t2)[ idx ] );
681
if (attr & HAS_UV_LAYER1)
682
_records->writeVec2f( (*mtc[1])[ idx ] );
683
if (attr & HAS_UV_LAYER2)
684
_records->writeVec2f( (*mtc[2])[ idx ] );
685
if (attr & HAS_UV_LAYER3)
686
_records->writeVec2f( (*mtc[3])[ idx ] );
687
if (attr & HAS_UV_LAYER4)
688
_records->writeVec2f( (*mtc[4])[ idx ] );
689
if (attr & HAS_UV_LAYER5)
690
_records->writeVec2f( (*mtc[5])[ idx ] );
691
if (attr & HAS_UV_LAYER6)
692
_records->writeVec2f( (*mtc[6])[ idx ] );
693
if (attr & HAS_UV_LAYER7)
694
_records->writeVec2f( (*mtc[7])[ idx ] );
697
// Handle continuation record if necessary.
698
if ( (idx+1 == currentIndexLimit) && (idx+1 < numVerts) )
700
currentIndexLimit += maxVerts;
701
unsigned int remaining( numVerts - (idx+1) );
702
thisVertCount = (maxVerts > remaining) ? remaining : maxVerts;
703
writeContinuationRecord( (vertSize * thisVertCount) );
709
FltExportVisitor::writeMultitexture( const osg::Geometry& geom )
711
unsigned int numLayers( 0 );
714
for( idx=1; idx<8; idx++)
716
if( isTextured( idx, geom ) )
718
flags |= LAYER_1 >> (idx-1);
725
uint16 length( 8 + (8*numLayers) );
727
_records->writeInt16( (int16) MULTITEXTURE_OP );
728
_records->writeUInt16( length );
729
_records->writeInt32( flags );
731
const osg::StateSet* ss = getCurrentStateSet();
732
for( idx=1; idx<8; idx++)
734
if( isTextured( idx, geom ) )
736
int16 textureIndex( -1 );
737
const osg::Texture2D* texture = static_cast<const osg::Texture2D*>(
738
ss->getTextureAttribute( idx, osg::StateAttribute::TEXTURE ) );
740
textureIndex = _texturePalette->add( idx, texture );
743
std::ostringstream warning;
744
warning << "fltexp: No Texture2D for unit " << idx;
745
osg::notify( osg::WARN ) << warning.str() << std::endl;
746
_fltOpt->getWriteResult().warn( warning.str() );
749
// texture index (this value is an unsigned int, but has a -1 default per oflt spec: ugh)
750
_records->writeUInt16( static_cast< uint16 >( textureIndex ) );
751
_records->writeUInt16( 0 ); // TBD effect
752
// mapping index (this value is an unsigned int, but has a -1 default per oflt spec: ugh)
753
_records->writeUInt16( static_cast< uint16 >( -1 ) );
754
_records->writeUInt16( 0 ); // data
760
FltExportVisitor::writeUVList( int numVerts, const osg::Geometry& geom )
762
unsigned int numLayers( 0 );
765
for( idx=1; idx<8; idx++)
767
if( isTextured( idx, geom ) )
769
flags |= LAYER_1 >> (idx-1);
776
uint16 length( 8 + (8*numLayers*numVerts) );
778
_records->writeInt16( (int16) UV_LIST_OP );
779
_records->writeUInt16( length );
780
_records->writeInt32( flags );
782
osg::Vec2 defaultCoord( 0., 0. );
783
const osg::StateSet* ss = getCurrentStateSet();
784
for( idx=1; idx<8; idx++)
786
if( isTextured( idx, geom ) )
788
osg::Array* t = const_cast<osg::Array*>( geom.getTexCoordArray( idx ) );
789
osg::ref_ptr<osg::Vec2Array> t2 = dynamic_cast<osg::Vec2Array*>( t );
792
std::ostringstream warning;
793
warning << "fltexp: No Texture2D for unit " << idx;
794
osg::notify( osg::WARN ) << warning.str() << std::endl;
795
_fltOpt->getWriteResult().warn( warning.str() );
796
t2 = new osg::Vec2Array;
798
else if (t2->getNumElements() != numVerts)
800
std::ostringstream warning;
801
warning << "fltexp: Invalid number of texture coordinates for unit " << idx;
802
osg::notify( osg::WARN ) << warning.str() << std::endl;
803
_fltOpt->getWriteResult().warn( warning.str() );
806
const int size = t2->getNumElements();
808
for( vIdx=0; vIdx<numVerts; vIdx++)
810
osg::Vec2& tc( defaultCoord );
813
_records->writeFloat32( tc[0] );
814
_records->writeFloat32( tc[1] );
823
FltExportVisitor::handleDrawArrays( const osg::DrawArrays* da, const osg::Geometry& geom, const osg::Geode& geode )
825
GLint first = da->getFirst();
826
GLsizei count = da->getCount();
827
GLenum mode = da->getMode();
830
bool useMesh( false );
833
case GL_TRIANGLE_STRIP:
834
case GL_TRIANGLE_FAN:
856
// Push and pop subfaces if polygon offset is on.
857
SubfaceHelper subface( *this, getCurrentStateSet() );
861
writeMesh( geode, geom, mode );
863
writeMatrix( geode.getUserData() );
864
writeComment( geode );
865
writeMultitexture( geom );
866
writeLocalVertexPool( geom, mode );
870
std::vector< unsigned int > indices;
872
for (jdx=0; jdx<count; jdx++)
873
indices.push_back( first+jdx );
874
writeMeshPrimitive( indices, mode );
880
const unsigned int max( first+count );
881
while ((unsigned int)( first+n ) <= max)
884
// * Geode for record name (but also need to handle
885
// multi Geometry objects and multi PrimitiveSet objects;
886
// all Face records can't have the same name).
888
writeFace( geode, geom, mode );
890
writeMatrix( geode.getUserData() );
891
writeComment( geode );
892
writeMultitexture( geom );
895
// Write vertex list records.
896
int numVerts = writeVertexList( first, n );
899
writeUVList( numVerts, geom );
907
FltExportVisitor::handleDrawArrayLengths( const osg::DrawArrayLengths* dal, const osg::Geometry& geom, const osg::Geode& geode )
909
GLint first = dal->getFirst();
910
GLenum mode = dal->getMode();
913
bool useMesh( false );
916
case GL_TRIANGLE_STRIP:
917
case GL_TRIANGLE_FAN:
938
// Push and pop subfaces if polygon offset is on.
939
SubfaceHelper subface( *this, getCurrentStateSet() );
943
writeMesh( geode, geom, mode );
945
writeMatrix( geode.getUserData() );
946
writeComment( geode );
947
writeMultitexture( geom );
948
writeLocalVertexPool( geom, mode );
953
for( osg::DrawArrayLengths::const_iterator itr=dal->begin();
954
itr!=dal->end(); itr++ )
956
std::vector< unsigned int > indices;
958
for (jdx=0; jdx<(*itr); idx++, jdx++)
959
indices.push_back( idx );
960
writeMeshPrimitive( indices, mode );
967
// Hm. You wouldn't usually use DrawArrayLengths for non-strip/fan prims...
968
for( osg::DrawArrayLengths::const_iterator itr=dal->begin();
969
itr!=dal->end(); itr++ )
971
while (first+n <= *itr)
973
writeFace( geode, geom, mode );
975
writeMatrix( geode.getUserData() );
976
writeComment( geode );
977
writeMultitexture( geom );
980
// Write vertex list records.
984
numVerts = writeVertexList( first, *itr );
989
numVerts = writeVertexList( first, n );
993
writeUVList( numVerts, geom );
1004
FltExportVisitor::handleDrawElements( const osg::DrawElements* de, const osg::Geometry& geom, const osg::Geode& geode )
1006
GLenum mode = de->getMode();
1009
bool useMesh( false );
1012
case GL_TRIANGLE_STRIP:
1013
case GL_TRIANGLE_FAN:
1015
n = de->getNumIndices();
1023
n = de->getNumIndices();
1036
// Push and pop subfaces if polygon offset is on.
1037
SubfaceHelper subface( *this, getCurrentStateSet() );
1041
writeMesh( geode, geom, mode );
1043
writeMatrix( geode.getUserData() );
1044
writeComment( geode );
1045
writeMultitexture( geom );
1046
writeLocalVertexPool( geom, mode );
1050
std::vector< unsigned int > indices;
1052
for (idx=0; idx<n; idx++)
1053
indices.push_back( de->index( idx ) );
1054
writeMeshPrimitive( indices, mode );
1060
unsigned int first( 0 );
1061
while (first+n <= de->getNumIndices())
1064
// * Geode for record name (but also need to handle
1065
// multi Geometry objects and multi PrimitiveSet objects;
1066
// all Face records can't have the same name).
1068
writeFace( geode, geom, mode );
1070
writeMatrix( geode.getUserData() );
1071
writeComment( geode );
1072
writeMultitexture( geom );
1075
// Write vertex list records.
1076
std::vector<unsigned int> indices;
1078
for(idx=0; idx<n; idx++)
1079
indices.push_back( de->index( first+idx ) );
1080
int numVerts = writeVertexList( indices, n );
1083
writeUVList( numVerts, geom );