Пример #1
0
void CodeWriter::writePushPop(VmCommandType cmd, string segment, int index)
{
    if (cmd == VmCommandType::C_PUSH)
        writePush(segment, index);
    else
        writePop(segment, index);
}
Пример #2
0
bool
FltExportVisitor::complete( const osg::Node& node )
{
    // Always write final pop level
    writePop();
    // Done writing records, close the record data temp file.
    _recordsStr.close();

    // Write OpenFlight file front matter: header, vertex palette, etc.
    writeHeader( node.getName() );

    writeColorPalette();
    _materialPalette->write( _dos );
    _texturePalette->write( _dos );
    _lightSourcePalette->write( _dos );
    _vertexPalette->write( _dos );

    // Write Comment ancillary record and specify the _dos DataOutputStream.
    writeComment( node, &_dos );

    // Copy record data temp file into final OpenFlight file.
    // Yee-uck. TBD need better stream copy routine.
    char buf;
    std::ifstream recIn;
    recIn.open( _recordsTempName.c_str(), std::ios::in | std::ios::binary );
    while (!recIn.eof() )
    {
        recIn.read( &buf, 1 );
        if (recIn.good())
            _dos << buf;
    }
    recIn.close();

    return true;
}
void
FltExportVisitor::handleDrawElements( const osg::DrawElements* de, const osg::Geometry& geom, const osg::Geode& geode )
{
    GLenum mode = de->getMode();

    int n( 0 );
    bool useMesh( false );
    switch( mode )
    {
    case GL_TRIANGLE_STRIP:
    case GL_TRIANGLE_FAN:
    case GL_QUAD_STRIP:
        n = de->getNumIndices();
        useMesh = true;
        break;
    case GL_POINTS:
        n = 1;
        break;
    case GL_LINES:
        n = 2;
        break;
    case GL_TRIANGLES:
        n = 3;
        break;
    case GL_QUADS:
        n = 4;
        break;
    case GL_LINE_STRIP:
    case GL_LINE_LOOP:
    case GL_POLYGON:
    default:
        n = de->getNumIndices();
        break;
    }

    // Push and pop subfaces if polygon offset is on.
    SubfaceHelper subface( *this, getCurrentStateSet() );

    if (useMesh)
    {
        std::vector< unsigned int > indices;
        int idx;
        for (idx=0; idx<n; idx++)
            indices.push_back( de->index( idx ) );
        writeMeshPrimitive( indices, mode );
    }
    else
    {
        unsigned int first( 0 );
        while (first+n <= de->getNumIndices())
        {
            // Need:
            // * Geode for record name (but also need to handle
            //   multi Geometry objects and multi PrimitiveSet objects;
            //   all Face records can't have the same name).
            // * Mode
            writeFace( geode, geom, mode );

            writeMatrix( geode.getUserData() );
            writeComment( geode );
            writeMultitexture( geom );
            writePush();

            // Write vertex list records.
            std::vector<unsigned int> indices;
            int idx;
            for(idx=0; idx<n; idx++)
                indices.push_back( de->index( first+idx ) );
            int numVerts = writeVertexList( indices, n );
            first += n;

            writeUVList( numVerts, geom );

            writePop();
        }
    }
}
void
FltExportVisitor::handleDrawArrayLengths( const osg::DrawArrayLengths* dal, const osg::Geometry& geom, const osg::Geode& geode )
{
    GLint first = dal->getFirst();
    GLenum mode = dal->getMode();

    int n( 0 );
    bool useMesh( false );
    switch( mode )
    {
    case GL_TRIANGLE_STRIP:
    case GL_TRIANGLE_FAN:
    case GL_QUAD_STRIP:
        useMesh = true;
        break;
    case GL_POINTS:
        n = 1;
        break;
    case GL_LINES:
        n = 2;
        break;
    case GL_TRIANGLES:
        n = 3;
        break;
    case GL_QUADS:
        n = 4;
        break;
    case GL_LINE_STRIP:
    case GL_LINE_LOOP:
    case GL_POLYGON:
    default:
        break;
    }

    // Push and pop subfaces if polygon offset is on.
    SubfaceHelper subface( *this, getCurrentStateSet() );

    if (useMesh)
    {
        int idx( 0 );
        for( osg::DrawArrayLengths::const_iterator itr=dal->begin();
             itr!=dal->end(); itr++ )
        {
            std::vector< unsigned int > indices;
            int jdx;
            for (jdx=0; jdx<(*itr); idx++, jdx++)
                indices.push_back( idx );
            writeMeshPrimitive( indices, mode );
        }
    }
    else
    {
        // Hm. You wouldn't usually use DrawArrayLengths for non-strip/fan prims...
        for( osg::DrawArrayLengths::const_iterator itr=dal->begin();
             itr!=dal->end(); itr++ )
        {
            while (first+n <= *itr)
            {
                writeFace( geode, geom, mode );

                writeMatrix( geode.getUserData() );
                writeComment( geode );
                writeMultitexture( geom );
                writePush();

                // Write vertex list records.
                int numVerts;
                if (n == 0)
                {
                    numVerts = writeVertexList( first, *itr );
                    first += *itr;
                }
                else
                {
                    numVerts = writeVertexList( first, n );
                    first += n;
                }

                writeUVList( numVerts, geom );

                writePop();
            }

            first += *itr;
        }
    }
}
void
FltExportVisitor::handleDrawArrays( const osg::DrawArrays* da, const osg::Geometry& geom, const osg::Geode& geode )
{
    GLint first = da->getFirst();
    GLsizei count = da->getCount();
    GLenum mode = da->getMode();

    int n( 0 );
    bool useMesh( false );
    switch( mode )
    {
    case GL_TRIANGLE_STRIP:
    case GL_TRIANGLE_FAN:
    case GL_QUAD_STRIP:
        useMesh = true;
        break;
    case GL_POINTS:
        n = 1;
        break;
    case GL_LINES:
        n = 2;
        break;
    case GL_TRIANGLES:
        n = 3;
        break;
    case GL_QUADS:
        n = 4;
        break;
    case GL_LINE_STRIP:
    case GL_LINE_LOOP:
    case GL_POLYGON:
    default:
        n = count;
        break;
    }

    if (useMesh)
    {
        std::vector< unsigned int > indices;
        int jdx;
        for (jdx=0; jdx<count; jdx++)
            indices.push_back( first+jdx );
        writeMeshPrimitive( indices, mode );
    }
    else
    {
        const unsigned int max( first+count );
        while ((unsigned int)( first+n ) <= max)
        {
            writeFace( geode, geom, mode );

            writeMatrix( geode.getUserData() );
            writeComment( geode );
            writeMultitexture( geom );
            writePush();

            // Write vertex list records.
            int numVerts = writeVertexList( first, n );
            first += n;

            writeUVList( numVerts, geom );

            writePop();
        }
    }
}
void
FltExportVisitor::writeLightPoint(const osgSim::LightPointNode *lpn)
{
    enum Directionality
    {
        OMNIDIRECTIONAL = 0,
        UNIDIRECTIONAL  = 1,
        BIDIRECTIONAL   = 2
    };
    enum DisplayMode
    {
        RASTER = 0,
        CALLIG = 1,
        EITHER = 2
    };
    enum Modes
    {
        ENABLE  = 0,
        DISABLE = 1
    };
    enum Flags
    {
        NO_BACK_COLOR = 0x80000000u >> 1,
        CALLIGRAPHIC  = 0x80000000u >> 3,
        REFLECTIVE    = 0x80000000u >> 4,
        PERSPECTIVE   = 0x80000000u >> 8,
        FLASHING      = 0x80000000u >> 9,
        ROTATING      = 0x80000000u >> 10,
        ROTATE_CC     = 0x80000000u >> 11,
        VISIBLE_DAY   = 0x80000000u >> 15,
        VISIBLE_DUSK  = 0x80000000u >> 16,
        VISIBLE_NIGHT = 0x80000000u >> 17
    };
    int32 flags(NO_BACK_COLOR);

    if (lpn->getNumLightPoints() == 0)
        return;

    // In OSG, each LightPoint within a LightPointNode  can have different appearance
    // parameters, but in OpenFlight, a Light Point Record contains a list of homogeneous
    // vertices. To be correct, we'd have to look at all LightPoints in the LightPointNode
    // and spew out multiple FLT records for each group that shared common appearance
    // parameters. Instead, we cheat: We take the first LightPoint and use its appearance
    // parameters for all LightPoints in the LightPointNode.
    const osgSim::LightPoint &lp0 = lpn->getLightPoint(0);

    // No really good mapping between OSG and FLT light point animations.
    float32 animPeriod(0.f);
    float32 animEnabled(0.f);
    float32 animPhaseDelay(0.f);
    if (lp0._blinkSequence != NULL)
    {
        flags         |= FLASHING;
        animPeriod     = 4.f;
        animEnabled    = 2.f;
        animPhaseDelay = lp0._blinkSequence->getPhaseShift();
    }

    // Note that true bidirectional light points are currently unsupported (they are unavailable
    // in OSG, so we never write them out to FLT as BIDIRECTIONAL.
    int32                           directionality(OMNIDIRECTIONAL);
    float32                         horizLobe(360.f);
    float32                         vertLobe(360.f);
    float32                         lobeRoll(0.f);
    const osgSim::DirectionalSector *ds = dynamic_cast<osgSim::DirectionalSector*>(lp0._sector.get());
    if (ds)
    {
        directionality = UNIDIRECTIONAL;
        horizLobe      = osg::RadiansToDegrees(ds->getHorizLobeAngle());
        vertLobe       = osg::RadiansToDegrees(ds->getVertLobeAngle());
        lobeRoll       = osg::RadiansToDegrees(ds->getLobeRollAngle());
    }

    {
        // Braces req'd to invoke idHelper destructor (and potentially
        // write LongID record) before Push Record.

        const uint16 length(156);
        IdHelper     id(*this, lpn->getName());

        _records->writeInt16((int16) LIGHT_POINT_OP);
        _records->writeInt16(length);
        _records->writeID(id);
        _records->writeInt16(0);   // Surface material code
        _records->writeInt16(0);   // Feature ID
        _records->writeUInt32(~0u);   // OpenFlight erronously say -1, so will assume ~0u is OK.  Back color for bidirectional
        _records->writeInt32(EITHER);   // Display mode
        _records->writeFloat32(lp0._intensity);   // Intensity
        _records->writeFloat32(0.f);   // Back intensity TBD
        _records->writeFloat32(0.f);   // min defocus
        _records->writeFloat32(0.f);   // max defocus
        _records->writeInt32(DISABLE);   // Fading mode
        _records->writeInt32(DISABLE);   // Fog punch mode
        _records->writeInt32(DISABLE);   // Directional mode
        _records->writeInt32(0);   // Range mode
        _records->writeFloat32(lpn->getMinPixelSize());   // min pixel size
        _records->writeFloat32(lpn->getMaxPixelSize());   // max pixel size
        _records->writeFloat32(lp0._radius * 2.f);   // Actual size
        _records->writeFloat32(1.f);   // transparent falloff pixel size
        _records->writeFloat32(1.f);   // Transparent falloff exponent
        _records->writeFloat32(1.f);   // Transparent falloff scalar
        _records->writeFloat32(0.f);   // Transparent falloff clamp
        _records->writeFloat32(1.f);   // Fog scalar
        _records->writeFloat32(0.f);   // Reserved
        _records->writeFloat32(0.f);   // Size difference threshold
        _records->writeInt32(directionality);   // Directionality
        _records->writeFloat32(horizLobe);   // Horizontal lobe angle
        _records->writeFloat32(vertLobe);   // Vertical lobe angle
        _records->writeFloat32(lobeRoll);   // Lobe roll angle
        _records->writeFloat32(0.f);   // Directional falloff exponent
        _records->writeFloat32(0.f);   // Directional ambient intensity
        _records->writeFloat32(animPeriod);   // Animation period in seconds
        _records->writeFloat32(animPhaseDelay);   // Animation phase delay in seconds
        _records->writeFloat32(animEnabled);   // Animation enabled period in seconds
        _records->writeFloat32(1.f);   // Significance
        _records->writeInt32(0);   // Calligraphic draw order
        _records->writeInt32(flags);   // Flags
        _records->writeVec3f(osg::Vec3f(0.f, 0.f, 0.f));     // Axis of rotation
    }

    {
        osg::ref_ptr<osg::Vec3dArray> v = new osg::Vec3dArray(lpn->getNumLightPoints());
        osg::ref_ptr<osg::Vec4Array>  c = new osg::Vec4Array(lpn->getNumLightPoints());
        osg::ref_ptr<osg::Vec3Array>  n = new osg::Vec3Array(lpn->getNumLightPoints());
        osg::Vec3f                    normal(0.f, 0.f, 1.f);

        unsigned int idx;

        for (idx = 0; idx < lpn->getNumLightPoints(); idx++)
        {
            const osgSim::LightPoint &lp = lpn->getLightPoint(idx);
            (*v)[idx] = lp._position;
            (*c)[idx] = lp._color;

            const osgSim::DirectionalSector *ds = dynamic_cast<osgSim::DirectionalSector*>(lp._sector.get());
            if (ds)
                normal = ds->getDirection();

            (*n)[idx] = normal;
        }

        _vertexPalette->add((const osg::Array*)NULL, v.get(), c.get(), n.get(), NULL, true, true, false);
    }

    writeMatrix(lpn->getUserData());
    writeComment(*lpn);
    writePush();
    writeVertexList(0, lpn->getNumLightPoints());
    writePop();
}
Пример #7
0
// Billboards also go through this code. The Geode is passed
// to writeFace and writeMesh. If those methods successfully cast
// the Geode to a Billboard, then they set the template mode
// bit accordingly.
void
FltExportVisitor::apply( osg::Geode& node )
{
    _firstNode = false;
    ScopedStatePushPop guard( this, node.getStateSet() );

    unsigned int idx;
    for (idx=0; idx<node.getNumDrawables(); idx++)
    {
        osg::Geometry* geom = node.getDrawable( idx )->asGeometry();
        if (!geom)
        {
            std::string warning( "fltexp: Non-Geometry Drawable encountered. Ignoring." );
            osg::notify( osg::WARN ) << warning << std::endl;
            _fltOpt->getWriteResult().warn( warning );
            continue;
        }

        ScopedStatePushPop drawableGuard( this, geom->getStateSet() );

        // Push and pop subfaces if polygon offset is on.
        SubfaceHelper subface( *this, getCurrentStateSet() );

        if (atLeastOneFace( *geom ))
        {
            // If at least one record will be a Face record, then we
            //   need to write to the vertex palette.
            _vertexPalette->add( *geom );

            // Iterate over all PrimitiveSets and output Face records.
            unsigned int jdx;
            for (jdx=0; jdx < geom->getNumPrimitiveSets(); jdx++)
            {
                osg::PrimitiveSet* prim = geom->getPrimitiveSet( jdx );
                if ( isMesh( prim->getMode() ) )
                    continue;

                if (prim->getType() == osg::PrimitiveSet::DrawArraysPrimitiveType)
                    handleDrawArrays( dynamic_cast<osg::DrawArrays*>( prim ), *geom, node );
                else if (prim->getType() == osg::PrimitiveSet::DrawArrayLengthsPrimitiveType)
                    handleDrawArrayLengths( dynamic_cast<osg::DrawArrayLengths*>( prim ), *geom, node );
                else if ( (prim->getType() == osg::PrimitiveSet::DrawElementsUBytePrimitiveType) ||
                          (prim->getType() == osg::PrimitiveSet::DrawElementsUShortPrimitiveType) ||
                          (prim->getType() == osg::PrimitiveSet::DrawElementsUIntPrimitiveType) )
                    handleDrawElements( dynamic_cast<osg::DrawElements*>( prim ), *geom, node );
                else
                {
                    std::string warning( "fltexp: Unknown PrimitiveSet type." );
                    osg::notify( osg::WARN ) << warning << std::endl;
                    _fltOpt->getWriteResult().warn( warning );
                    return;
                }
            }
        }

        if (atLeastOneMesh( *geom ))
        {
            // If at least one Mesh record, write out preamble mesh records
            //   followed by a Mesh Primitive record per PrimitiveSet.
            writeMesh( node, *geom );

            writeMatrix( node.getUserData() );
            writeComment( node );
            writeMultitexture( *geom );
            writeLocalVertexPool( *geom );

            writePush();

            unsigned int jdx;
            for (jdx=0; jdx < geom->getNumPrimitiveSets(); jdx++)
            {
                osg::PrimitiveSet* prim = geom->getPrimitiveSet( jdx );
                if ( !isMesh( prim->getMode() ) )
                    continue;

                if (prim->getType() == osg::PrimitiveSet::DrawArraysPrimitiveType)
                    handleDrawArrays( dynamic_cast<osg::DrawArrays*>( prim ), *geom, node );
                else if (prim->getType() == osg::PrimitiveSet::DrawArrayLengthsPrimitiveType)
                    handleDrawArrayLengths( dynamic_cast<osg::DrawArrayLengths*>( prim ), *geom, node );
                else if ( (prim->getType() == osg::PrimitiveSet::DrawElementsUBytePrimitiveType) ||
                          (prim->getType() == osg::PrimitiveSet::DrawElementsUShortPrimitiveType) ||
                          (prim->getType() == osg::PrimitiveSet::DrawElementsUIntPrimitiveType) )
                    handleDrawElements( dynamic_cast<osg::DrawElements*>( prim ), *geom, node );
                else
                {
                    std::string warning( "fltexp: Unknown PrimitiveSet type." );
                    osg::notify( osg::WARN ) << warning << std::endl;
                    _fltOpt->getWriteResult().warn( warning );
                    return;
                }
            }

            writePop();
        }
    }

    // Would traverse here if this node could have children.
    //   traverse( (osg::Node&)node );
}