Ejemplo n.º 1
0
void
SVLocusSet::
getIntersectingEdgeNodes(
    const LocusIndexType inputLocusIndex,
    const NodeIndexType inputRemoteNodeIndex,
    const EdgeMapType& remoteIntersectNodeToLocalNodeMap,
    const LocusSetIndexerType& remoteIntersectNodes,
    std::vector<EdgeInfoType>& edges) const
{
    typedef EdgeMapType::const_iterator rliter_t;
    typedef std::pair<rliter_t,rliter_t> rlmap_range_t;

    edges.clear();

    // find all nodes, from the remoteIntersectNodes set, which intersect this function's input node:
    //
    // for this application, inputLocus is an input set isolated from the rest of the graph, so nodes
    // intersected in the inputLocus are filtered out
    //
    std::set<NodeAddressType> edgeIntersectRemoteTemp;
    getNodeIntersectCore(inputLocusIndex,inputRemoteNodeIndex,remoteIntersectNodes,inputLocusIndex,edgeIntersectRemoteTemp);

    for (const NodeAddressType& remoteIsectAddy : edgeIntersectRemoteTemp)
    {
        // find what local nodes the remote nodes trace back to:
        const rlmap_range_t remoteIsectRange(remoteIntersectNodeToLocalNodeMap.equal_range(remoteIsectAddy));
        assert(remoteIsectRange.first != remoteIntersectNodeToLocalNodeMap.end());
        for (rliter_t riter(remoteIsectRange.first); riter != remoteIsectRange.second; ++riter)
        {
            const NodeAddressType localIntersectAddy(std::make_pair(remoteIsectAddy.first,riter->second));
            edges.push_back(std::make_pair(localIntersectAddy,remoteIsectAddy.second));
        }
    }
}
Ejemplo n.º 2
0
static bool
buildGeodesicSphereData( const float radius, const unsigned int subdivisions, osg::Geometry* geom )
{
    unsigned int subdivide( subdivisions );
    if( subdivisions > 5 )
    {
        // Would create index array too large for use with DrawElementsUShort.
        // For now, clamp. In the future, just use DrawElementsUInt.
        osg::notify( osg::WARN ) << "makeGeodesicSphere: Clamping subdivisions to 5." << std::endl;
        subdivide = 5;
    }

    GLfloat vertData[] = {
        0.000000, 0.850651, 0.525731,
        0.000000, 0.850651, -0.525731,
        0.000000, -0.850651, -0.525731,
        0.000000, -0.850651, 0.525731,
        0.525731, 0.000000, 0.850651,
        0.525731, 0.000000, -0.850651,
        -0.525731, 0.000000, -0.850651,
        -0.525731, 0.000000, 0.850651,
        0.850651, 0.525731, 0.000000,
        0.850651, -0.525731, 0.000000,
        -0.850651, -0.525731, 0.000000,
        -0.850651, 0.525731, 0.000000 };

    int faces = 20;
    int _numVerts = 12;
    int _numIndices = faces * 3;

    // Data is initially in "golden mean" coordinate system.
    // Rotate around y so that 2 verts exist at (0,0,+/-1).
    {
        //osg::Vec3 v0( 0.525731, 0.000000, 0.850651 );
        //osg::Vec3 v1( 0, 0, 1 );
        //const double angle( acos( v0 * v1 ) );
        const double sinAngle( 0.525731 );
        const double cosAngle( 0.850651 );

        int idx;
        for( idx=0; idx<_numVerts*3; idx+=3 )
        {
            double x( vertData[ idx ] );
            double z( vertData[ idx+2 ] );
            vertData[ idx ] = x * cosAngle + z * -sinAngle;
            vertData[ idx+2 ] = x * sinAngle + z * cosAngle;
        }
    }


    int vertsSize = _numVerts * 3;
    GLfloat* _vertices = new GLfloat[ vertsSize ];
    memcpy( _vertices, vertData, sizeof( vertData ) );

    GLushort* _indices = new GLushort[ _numIndices ];
    GLushort* indexPtr = _indices;
    *indexPtr++ = 0;
    *indexPtr++ = 7;
    *indexPtr++ = 4;
    *indexPtr++ = 0;
    *indexPtr++ = 4;
    *indexPtr++ = 8;
    *indexPtr++ = 0;
    *indexPtr++ = 8;
    *indexPtr++ = 1;
    *indexPtr++ = 0;
    *indexPtr++ = 1;
    *indexPtr++ = 11;
    *indexPtr++ = 0;
    *indexPtr++ = 11;
    *indexPtr++ = 7;
    *indexPtr++ = 2;
    *indexPtr++ = 6;
    *indexPtr++ = 5;
    *indexPtr++ = 2;
    *indexPtr++ = 5;
    *indexPtr++ = 9;
    *indexPtr++ = 2;
    *indexPtr++ = 9;
    *indexPtr++ = 3;
    *indexPtr++ = 2;
    *indexPtr++ = 3;
    *indexPtr++ = 10;
    *indexPtr++ = 2;
    *indexPtr++ = 10;
    *indexPtr++ = 6;
    *indexPtr++ = 7;
    *indexPtr++ = 3;
    *indexPtr++ = 4;
    *indexPtr++ = 4;
    *indexPtr++ = 3;
    *indexPtr++ = 9;
    *indexPtr++ = 4;
    *indexPtr++ = 9;
    *indexPtr++ = 8;
    *indexPtr++ = 8;
    *indexPtr++ = 9;
    *indexPtr++ = 5;
    *indexPtr++ = 8;
    *indexPtr++ = 5;
    *indexPtr++ = 1;
    *indexPtr++ = 1;
    *indexPtr++ = 5;
    *indexPtr++ = 6;
    *indexPtr++ = 1;
    *indexPtr++ = 6;
    *indexPtr++ = 11;
    *indexPtr++ = 11;
    *indexPtr++ = 6;
    *indexPtr++ = 10;
    *indexPtr++ = 11;
    *indexPtr++ = 10;
    *indexPtr++ = 7;
    *indexPtr++ = 7;
    *indexPtr++ = 10;
    *indexPtr++ = 3;

    GLuint _idxStart = 0;
    GLuint _idxEnd = 11;


    // Subdivide as requested
    int idx;
    for (idx = subdivide; idx; idx--)
    {
        // Make a map of edges
        typedef std::map< unsigned int, GLushort> EdgeMapType;
        EdgeMapType edgeMap;
        indexPtr = _indices;
        int f;
        for (f=faces; f; f--)
        {
            unsigned int key = makeKey(indexPtr[0], indexPtr[1]);
            if (edgeMap.find( key ) == edgeMap.end())
                edgeMap[key] = ++_idxEnd;

            key = makeKey(indexPtr[1], indexPtr[2]);
            if (edgeMap.find( key ) == edgeMap.end())
                edgeMap[key] = ++_idxEnd;
            
            key = makeKey(indexPtr[2], indexPtr[0]);
            if (edgeMap.find( key ) == edgeMap.end())
                edgeMap[key] = ++_idxEnd;

            indexPtr += 3;
        }

        GLfloat* oldVerts = _vertices;
        GLushort* oldIndices = _indices;

        _numVerts += (int)(faces * 1.5f);
        int newFaces = faces * 4;
        _numIndices = newFaces * 3;

        // Create new indices
        _indices = new GLushort[ _numIndices ];
        GLushort* oldIdxPtr = oldIndices;
        indexPtr = _indices;
        for (f=faces; f; f--)
        {
            GLushort vertA = *oldIdxPtr++;
            GLushort vertB = *oldIdxPtr++;
            GLushort vertC = *oldIdxPtr++;
            GLushort edgeAB = edgeMap[ makeKey(vertA,vertB) ];
            GLushort edgeBC = edgeMap[ makeKey(vertB,vertC) ];
            GLushort edgeCA = edgeMap[ makeKey(vertC,vertA) ];

            *indexPtr++ = vertA;
            *indexPtr++ = edgeAB;
            *indexPtr++ = edgeCA;
            *indexPtr++ = edgeAB;
            *indexPtr++ = vertB;
            *indexPtr++ = edgeBC;
            *indexPtr++ = edgeAB;
            *indexPtr++ = edgeBC;
            *indexPtr++ = edgeCA;
            *indexPtr++ = edgeCA;
            *indexPtr++ = edgeBC;
            *indexPtr++ = vertC;
        }

        // Copy old vertices into new vertices
        _vertices = new GLfloat[ _numVerts * 3 ];
        memcpy( _vertices, oldVerts, vertsSize * sizeof( GLfloat ) );

        // Create new vertices at midpoint of each edge
        EdgeMapType::const_iterator it = edgeMap.begin();
        while (it != edgeMap.end())
        {
            GLushort idxA, idxB;
            idxA = ((*it).first) >> 16;
            idxB = ((*it).first) & 0xffff;

            GLfloat* dest = &(_vertices[ ((*it).second * 3) ]);
            GLfloat* srcA = &(_vertices[idxA*3]);
            GLfloat* srcB = &(_vertices[idxB*3]);
            average3fv( dest, srcA, srcB );

            it++;
        }


        faces = newFaces;
        vertsSize = _numVerts * 3;
        delete[] oldVerts;
        delete[] oldIndices;
    }


    //
    // Create normal array by making vertices unit length
    GLfloat* _normals = new GLfloat[ _numVerts * 3 ];
    GLfloat* vertPtr = _vertices;
    GLfloat* normPtr = _normals;
    for (idx = _numVerts; idx; idx--)
    {
        osg::Vec3 v( vertPtr[0], vertPtr[1], vertPtr[2] );
        float lengthInv = (float)( 1. / v.length() );
        *normPtr++ = *vertPtr++ * lengthInv;
        *normPtr++ = *vertPtr++ * lengthInv;
        *normPtr++ = *vertPtr++ * lengthInv;
    }

    //
    // Scale vertices out to the specified radius
    vertPtr = _vertices;
    normPtr = _normals;
    for (idx = _numVerts*3; idx; idx--)
        *vertPtr++ = *normPtr++ * radius;

    //
    // Texture coordinates are identical to normals for cube mapping
    GLfloat* _texCoords = new GLfloat[ _numVerts * 3 ];
    memcpy( _texCoords, _normals, _numVerts * 3 * sizeof( GLfloat) );


    // Convert to OSG
    {
        osg::Vec3Array* osgV = new osg::Vec3Array;
        osg::Vec3Array* osgN = new osg::Vec3Array;
        osg::Vec3Array* osgTC = new osg::Vec3Array;
        osgV->resize( _numVerts );
        osgN->resize( _numVerts );
        osgTC->resize( _numVerts );

        geom->setVertexArray( osgV );
        geom->setNormalArray( osgN );
        geom->setNormalBinding( osg::Geometry::BIND_PER_VERTEX );
        geom->setTexCoordArray( 0, osgTC );

        osg::Vec4Array* osgC = new osg::Vec4Array;
        osgC->push_back( osg::Vec4( 1., 1., 1., 1. ) );
        geom->setColorArray( osgC );
        geom->setColorBinding( osg::Geometry::BIND_OVERALL );

        vertPtr = _vertices;
        normPtr = _normals;
        GLfloat* tcPtr = _texCoords;
        int idx;
        for( idx=0; idx<_numVerts; idx++ )
        {
            (*osgV)[ idx ].x() = *vertPtr++;
            (*osgV)[ idx ].y() = *vertPtr++;
            (*osgV)[ idx ].z() = *vertPtr++;
            (*osgN)[ idx ].x() = *normPtr++;
            (*osgN)[ idx ].y() = *normPtr++;
            (*osgN)[ idx ].z() = *normPtr++;
            (*osgTC)[ idx ].x() = *tcPtr++;
            (*osgTC)[ idx ].y() = *tcPtr++;
            (*osgTC)[ idx ].z() = *tcPtr++;
        }

        osg::UShortArray* osgIdx = new osg::UShortArray;
        osgIdx->resize( _numIndices );
        indexPtr = _indices;
        for( idx=0; idx<_numIndices; idx++ )
        {
            (*osgIdx)[ idx ] = *indexPtr++;
        }

        geom->addPrimitiveSet( new osg::DrawElementsUShort( GL_TRIANGLES, _numIndices, _indices ) );
    }


    delete[] _indices;
    delete[] _vertices;
    delete[] _normals;
    delete[] _texCoords;

    osg::notify( osg::INFO ) << "makeGeodesicSphere: numVertices: " << _numVerts << std::endl;
    return( true );
}