Ejemplo n.º 1
0
void
FindNamedNode::apply( osg::Node& node )
{
    bool match = (
        ( ( _method == EXACT_MATCH ) &&
            ( node.getName() == _name ) ) ||
        ( ( _method == CONTAINS ) &&
            ( node.getName().find( _name ) != std::string::npos ) ) );

    if( match )
    {
        // Copy the NodePath, so we can alter it if necessary.
        osg::NodePath np = getNodePath();

        if( !_includeTargetNode )
            // Calling code has requested that the target node
            // be removed from the node paths.
            np.pop_back();

        NodeAndPath nap( &node, np );
        _napl.push_back( nap );
    }

    traverse( node );
}
Ejemplo n.º 2
0
void WriterNodeVisitor::apply3DSMatrixNode(osg::Node &node, const osg::Matrix * m, const char * const prefix)
{
    // Note: Creating a mesh instance with no transform and then copying the matrix doesn't work (matrix seems to be a temporary/computed value)
    Lib3dsMeshInstanceNode * parent = _cur3dsNode;
    Lib3dsMeshInstanceNode * node3ds = NULL;
    if (m)
    {
        osg::Vec3 osgScl, osgPos;
        osg::Quat osgRot, osgSo;
        m->decompose(osgPos, osgRot, osgScl, osgSo);

        float pos[3];
        float scl[3];
        float rot[4];
        copyOsgVectorToLib3dsVector(pos, osgPos);
        copyOsgVectorToLib3dsVector(scl, osgScl);
        copyOsgQuatToLib3dsQuat(rot, osgRot);
        node3ds = lib3ds_node_new_mesh_instance(NULL, getUniqueName(node.getName().empty() ? node.className() : node.getName(), true, prefix).c_str(), pos, scl, rot);
    }
    else
    {
        node3ds = lib3ds_node_new_mesh_instance(NULL, getUniqueName(node.getName().empty() ? node.className() : node.getName(), true, prefix).c_str(), NULL, NULL, NULL);
    }

    lib3ds_file_append_node(_file3ds, reinterpret_cast<Lib3dsNode*>(node3ds), reinterpret_cast<Lib3dsNode*>(parent));
    _cur3dsNode = node3ds;
}
Ejemplo n.º 3
0
 void apply( osg::Node& node )
 {
     if ( !node.getName().empty() )
     {
         output() << node.getName() << std::endl;
         enter();
         traverse( node );
         leave();
     }
     else osgUtil::PrintVisitor::apply(node);
 }
Ejemplo n.º 4
0
// ### provide a name to node
std::string daeWriter::getNodeName(const osg::Node &node, const std::string &defaultName)
{
    std::string nodeName;

    if (node.getName().empty())
        nodeName = uniquify(defaultName);
    else
        nodeName = uniquify(node.getName());

    return nodeName;
}
void SimpleDotVisitor::handle(osg::Node &node, int id)
{
    std::stringstream label;

    label << "<top> Node";
    if (!node.getName().empty())
    {
        label << "| " << node.getName();
    }

    drawNode(id, "record", "solid", label.str(), "black", "white");
}
Ejemplo n.º 6
0
osgDB::ReaderWriter::WriteResult
ReaderWriterDAE::writeNode( const osg::Node& node,
        const std::string& fname, const osgDB::ReaderWriter::Options* options ) const
{
    SERIALIZER();

    bool bOwnDAE = false;
    DAE* pDAE = NULL;

    std::string ext( osgDB::getLowerCaseFileExtension(fname) );
    if( ! acceptsExtension(ext) ) return WriteResult::FILE_NOT_HANDLED;

    // Process options
    osgDAE::daeWriter::Options pluginOptions;
    std::string srcDirectory( osgDB::getFilePath(node.getName().empty() ? fname : node.getName()) );        // Base dir when relativising images paths
    if( options )
    {
        pDAE = (DAE*)options->getPluginData("DAE");

        const std::string & baseDir = options->getPluginStringData("baseImageDir");        // Rename "srcModelPath" (and call getFilePath() on it)?
        if (!baseDir.empty()) srcDirectory = baseDir;

        const std::string & relativiseImagesPathNbUpDirs = options->getPluginStringData("DAE-relativiseImagesPathNbUpDirs");
        if (!relativiseImagesPathNbUpDirs.empty()) {
            std::istringstream iss(relativiseImagesPathNbUpDirs);
            iss >> pluginOptions.relativiseImagesPathNbUpDirs;
        }

        // Sukender's note: I don't know why DAE seems to accept comma-sparated options instead of space-separated options as other ReaderWriters. However, to avoid breaking compatibility, here's a workaround:
        std::string optString( options->getOptionString() );
        for(std::string::iterator it=optString.begin(); it!=optString.end(); ++it) {
            if (*it == ' ') *it = ',';
        }
        std::istringstream iss( optString );
        std::string opt;

        //while (iss >> opt)
        while( std::getline( iss, opt, ',' ) )
        {
            if( opt == "polygon") pluginOptions.usePolygons = true;
            else if (opt == "GoogleMode") pluginOptions.googleMode = true;
            else if (opt == "NoExtras") pluginOptions.writeExtras = false;
            else if (opt == "daeEarthTex") pluginOptions.earthTex = true;
            else if (opt == "daeZUpAxis") {}    // Nothing (old option)
            else if (opt == "daeLinkOriginalTexturesNoForce") { pluginOptions.linkOrignialTextures = true; pluginOptions.forceTexture = false; }
            else if (opt == "daeLinkOriginalTexturesForce")   { pluginOptions.linkOrignialTextures = true; pluginOptions.forceTexture = true; }
            else if (opt == "daeNamesUseCodepage") pluginOptions.namesUseCodepage = true;
            else if (!opt.empty())
            {
                OSG_NOTICE << std::endl << "COLLADA dae plugin: unrecognized option \"" << opt <<  std::endl;
            }
        }
    }
Ejemplo n.º 7
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;
}
Ejemplo n.º 8
0
	virtual void apply (osg::Node& node) {
		if (node.getName() == m_NameToFind) {
			m_FoundNode = &node;
		} else {
			traverse(node);
		}
	}
 void FindNode::apply(osg::Node &node)
 {
     if(node.getName() == name)
         this->node = &node;
     else
         traverse(node);
 }
Ejemplo n.º 10
0
		virtual void apply(osg::Node& node)
		{
			if (m_name == node.getName()) {
				m_found = & node;
				return;
			}
			traverse (node);
		}
Ejemplo n.º 11
0
 virtual void apply(osg::Node& node)
 {
     if (node.getName()==_name)
     {
         _foundNodes.push_back(&node);
     }
     traverse(node);
 }
Ejemplo n.º 12
0
    // This method gets called for every node in the scene
    //   graph. Check each node to see if its name matches
    //   out target. If so, save the node's address.
    virtual void apply( osg::Node& node )
    {
        if (node.getName() == _name)
            _node = &node;

        // Keep traversing the rest of the scene graph.
        traverse( node );
    }
Ejemplo n.º 13
0
    // This method gets called for every node in the scene
    //   graph. Check each node to see if its name matches
    //   out target. If so, save the node's address.
    virtual void apply( osg::Node& node )
    {
        if (node.getName() == _name)
            foundNodeList.push_back(&node);

        // Keep traversing the rest of the scene graph.
        traverse( node );
    }
Ejemplo n.º 14
0
void FindNode::apply( osg::Node& node )
{
	if (m_strName.compare(node.getName()) == 0)
	{
		m_pNode = &node;
		return;
	}
	traverse(node);
}
Ejemplo n.º 15
0
void daeWriter::setRootNode(const osg::Node &node)
{
    std::string fname = osgDB::findDataFile(node.getName());

    // create Asset with root node providing meta data
    createAssetTag(node);

    const_cast<osg::Node*>(&node)->accept(_animatedNodeCollector);
}
Ejemplo n.º 16
0
 void applyNode(osg::Node& node)
 {
     std::string lowerName = Misc::StringUtils::lowerCase(node.getName());
     if ((lowerName.size() >= mFilter.size() && lowerName.compare(0, mFilter.size(), mFilter) == 0)
             || (lowerName.size() >= mFilter2.size() && lowerName.compare(0, mFilter2.size(), mFilter2) == 0))
         mToCopy.push_back(&node);
     else
         traverse(node);
 }
Ejemplo n.º 17
0
 virtual void apply(osg::Node& node)
 {
    if(node.getName() == mName)
    {
       mNode = &node;
    }
    else
    {
       traverse(node);
    }
 }
Ejemplo n.º 18
0
 void apply(::osg::Node &node)
 {
     // Just stop if the node is not a PositionAttitudeTransform to prevent
     // traversing the hole graph.
     // The assumption here is that all custom nodes are always added
     // to a group child node of the transformation nodes.
     if(!getTransform(&node,false))
         return;
     names.push_back(std::string(node.getName()));
     traverse(node);
 }
Ejemplo n.º 19
0
void TileMapper::apply(osg::Node& node)
{
    if (node.getName()=="TileContent") 
    {
        _containsGeode = true;
        return;
    }

    if (isCulled(node))
	return;

    // push the culling mode.
    pushCurrentMask();

    traverse(node);

    // pop the culling mode.
    popCurrentMask();
}
void jrOSGHighlightVisitor::apply(osg::Node &node) {
	if (node.getName().find("LowerArm_Rotator") != std::string::npos) {

		std::cout << "highlighting: " << node.getName() << std::endl;
		osgFX::Scribe* scribe = new osgFX::Scribe();
		osg::Group* parent = node.getParent(0);
		
		scribe->setName("highlighted");
		scribe->setWireframeColor(osg::Vec4(0,1,0,0.5));
		scribe->addChild(&node);
		
		parent->replaceChild(&node, scribe);

		parent = node.getParent(0);
		
		osg::MatrixTransform* transform = new osg::MatrixTransform;
		
		const double angle = 0.1;
		const osg::Vec3d axis(-1, 0, 0);
		transform->setMatrix(osg::Matrix::rotate(angle, axis));
		transform->setName("trans");
		transform->addChild(&node);
		parent->replaceChild(&node, transform);
	} 	
	else if (node.getName().find("highlighted") != std::string::npos) {
		std::cout << "removing highlight on: " << node.getName() << std::endl;
		osg::Group* parent = node.getParent(0);
		osgFX::Scribe* scribe = dynamic_cast<osgFX::Scribe*>(&node);
		parent->replaceChild(&node, scribe->getChild(0));
		return;
	} 
	else if (node.getName().find("trans") != std::string::npos) {
		std::cout << "altering: " << node.getName() << std::endl;
		osg::Group* parent = node.getParent(0);
		osg::MatrixTransform* transform = dynamic_cast<osg::MatrixTransform*>(&node);
	
		osg::Quat currentRotate = transform->getMatrix().getRotate();
		osg::Matrix currentMatrix = transform->getMatrix();
		osg::Vec4 currentVec = currentRotate.asVec4();

		std::cout << "current: " << currentVec[3] << " " << std::endl;

		const double angle = currentVec[3] + 0.1;
		const osg::Vec3d axis(-1, 0, 0);
		transform->setMatrix(osg::Matrix::rotate(angle, axis));

		std::cout << "current: " << angle << " " << std::endl;


		//currentRotate.set(currentVec[0] + 0.1,0,0,0);
		//currentMatrix.setRotate(currentRotate);

		//transform->setMatrix(currentMatrix);
			
		//transform.setMatrix());
		parent->replaceChild(&node, transform);
		return;
	}




	traverse(node);
}
osgDB::ReaderWriter::WriteResult ReaderWriterFBX::writeNode(
    const osg::Node& node,
    const std::string& filename,
    const Options* options) const
{
    try
    {
        std::string ext = osgDB::getLowerCaseFileExtension(filename);
        if (!acceptsExtension(ext)) return WriteResult::FILE_NOT_HANDLED;

        osg::ref_ptr<Options> localOptions = options ?
            static_cast<Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options;
        localOptions->getDatabasePathList().push_front(osgDB::getFilePath(filename));

        KFbxSdkManager* pSdkManager = KFbxSdkManager::Create();

        if (!pSdkManager)
        {
            return WriteResult::ERROR_IN_WRITING_FILE;
        }

        CleanUpFbx cleanUpFbx(pSdkManager);

        pSdkManager->SetIOSettings(KFbxIOSettings::Create(pSdkManager, IOSROOT));

        bool useFbxRoot = false;
        if (options)
        {
            std::istringstream iss(options->getOptionString());
            std::string opt;
            while (iss >> opt)
            {
                if (opt == "Embedded")
                {
                    pSdkManager->GetIOSettings()->SetBoolProp(EXP_FBX_EMBEDDED, true);
                }
                else if (opt == "UseFbxRoot")
                {
                    useFbxRoot = true;
                }
            }
        }

        KFbxScene* pScene = KFbxScene::Create(pSdkManager, "");
        pluginfbx::WriterNodeVisitor writerNodeVisitor(pScene, pSdkManager, filename,
            options, osgDB::getFilePath(node.getName().empty() ? filename : node.getName()));
        if (useFbxRoot && isBasicRootNode(node))
        {
            // If root node is a simple group, put all elements under the FBX root
            const osg::Group * osgGroup = node.asGroup();
            for(unsigned int child=0; child<osgGroup->getNumChildren(); ++child) {
                const_cast<osg::Node *>(osgGroup->getChild(child))->accept(writerNodeVisitor);
            }
        }
        else {
            // Normal scene
            const_cast<osg::Node&>(node).accept(writerNodeVisitor);
        }

        KFbxExporter* lExporter = KFbxExporter::Create(pSdkManager, "");
        pScene->GetGlobalSettings().SetAxisSystem(KFbxAxisSystem::eOpenGL);

        // Ensure the directory exists or else the FBX SDK will fail
        if (!osgDB::makeDirectoryForFile(filename)) {
            OSG_NOTICE << "Can't create directory for file '" << filename << "'. FBX SDK may fail creating the file." << std::endl;
        }

        // The FBX SDK interprets the filename as UTF-8
#ifdef OSG_USE_UTF8_FILENAME
        const std::string& utf8filename(filename);
#else
        std::string utf8filename(osgDB::convertStringFromCurrentCodePageToUTF8(filename));
#endif

        if (!lExporter->Initialize(utf8filename.c_str()))
        {
            return std::string(lExporter->GetLastErrorString());
        }
        if (!lExporter->Export(pScene))
        {
            return std::string(lExporter->GetLastErrorString());
        }

        return WriteResult::FILE_SAVED;
    }
    catch (const std::string& s)
    {
        return s;
    }
    catch (const char* s)
    {
        return std::string(s);
    }
    catch (...)
    {
    }

    return WriteResult::ERROR_IN_WRITING_FILE;
}
Ejemplo n.º 22
0
	// Méthode appelée pour chaque nœud du graphe. Si son nom correspond à celui passé
	// en paramètre au constructeur, on sauve l'adresse du nœud dans _node
	virtual void apply( osg::Node& node )
	{
	if (node.getName() == _name)
	_node = &node;
	traverse( node ); // On continue le parcours du graphe
	}
Ejemplo n.º 23
0
void FindNodeVisitor::apply(osg::Node &node)
{
    if (node.getName() == m_name)
        m_node = &node;
    traverse(node);
}
void BuildQtTreeView::apply(osg::Node& node)
{
	osg::Geode *geode = 0L;
    bool isGroup = false;
    QString nodeName;
    if(node.className()!="")
        nodeName = "[" + QString::fromStdString(node.className()) + "]";

    if(node.getName()!="")
        nodeName += " " + QString::fromStdString(node.getName());
    if (nodeName.isEmpty())
        nodeName = QObject::tr("[<unknow_type>] <unnamed>");

    TreeViewItem *item = new TreeViewItem(_parents.top());
	item->setCheckState(0, Qt::Checked);
	item->setOsgNode(&node);
    item->setData(0, Qt::DisplayRole, nodeName);

    if (dynamic_cast<osg::PagedLOD*>(&node))
    {
        item->setData(0, Qt::DecorationRole, QIcon(":/icons/TreeView/LOD.png"));
        _parents.push(item);
        isGroup = true;
    }
    else if (dynamic_cast<osg::LOD*>(&node))
    {
        item->setData(0, Qt::DecorationRole, QIcon(":/icons/TreeView/LOD.png"));
        _parents.push(item);
        isGroup = true;
    }
	else if (dynamic_cast<osg::Group*>(&node))
    {
        if (dynamic_cast<osg::MatrixTransform*>(&node))
            item->setData(0, Qt::DecorationRole, QIcon(":/icons/TreeView/Matrix.png"));
        else
            item->setData(0, Qt::DecorationRole, QIcon(":/icons/TreeView/Group.png"));
        _parents.push(item);
        isGroup = true;
    }
	else if (dynamic_cast<osg::Billboard*>(&node))
    {
        item->setData(0, Qt::DecorationRole, QIcon(":/icons/TreeView/Billboard.png"));
	}
	else if ((geode = dynamic_cast<osg::Geode*>(&node)))
    {
        item->setData(0, Qt::DecorationRole, QIcon(":/icons/TreeView/Geode.png"));

		for (unsigned int i=0; i<geode->getNumDrawables(); ++i)
		{
			osg::ref_ptr<osg::Drawable> drawable = geode->getDrawable(i);

			if (drawable.valid())
			{
				TreeViewItem *subItem = new TreeViewItem(item);
				//item->setCheckState(0, Qt::Checked);
				//item->setOsgNode(&node);
				subItem->setOsgObject(drawable.get());
                subItem->setData(0, Qt::DisplayRole, "Drawable");
			}
		}
    }
	else
    {
        item->setData(0, Qt::DecorationRole, QIcon(":/icons/TreeView/Other.png"));
    }

    _maxTreeDepth = std::max<int>(_maxTreeDepth, _parents.size());

    traverse(node);

    if (isGroup)
    {
        _parents.pop();
    }
}
osgDB::ReaderWriter::WriteResult ReaderWriterFBX::writeNode(
    const osg::Node& node,
    const std::string& filename,
    const Options* options) const
{
    try
    {
        std::string ext = osgDB::getLowerCaseFileExtension(filename);
        if (!acceptsExtension(ext)) return WriteResult::FILE_NOT_HANDLED;

        osg::ref_ptr<Options> localOptions = options ?
            static_cast<Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options;
        localOptions->getDatabasePathList().push_front(osgDB::getFilePath(filename));

        FbxManager* pSdkManager = FbxManager::Create();

        if (!pSdkManager)
        {
            return WriteResult::ERROR_IN_WRITING_FILE;
        }

        CleanUpFbx cleanUpFbx(pSdkManager);

        pSdkManager->SetIOSettings(FbxIOSettings::Create(pSdkManager, IOSROOT));

        bool useFbxRoot = false;
        bool ascii(false);
        std::string exportVersion;
        if (options)
        {
            std::istringstream iss(options->getOptionString());
            std::string opt;
            while (iss >> opt)
            {
                if (opt == "Embedded")
                {
                    pSdkManager->GetIOSettings()->SetBoolProp(EXP_FBX_EMBEDDED, true);
                }
                else if (opt == "UseFbxRoot")
                {
                    useFbxRoot = true;
                }
                else if (opt == "FBX-ASCII")
                {
                    ascii = true;
                }
                else if (opt == "FBX-ExportVersion")
                {
                    iss >> exportVersion;
                }
            }
        }

        FbxScene* pScene = FbxScene::Create(pSdkManager, "");

        if (options)
        {
            if (options->getPluginData("FBX-AssetUnitMeter"))
            {
                float unit = *static_cast<const float*>(options->getPluginData("FBX-AssetUnitMeter"));
                FbxSystemUnit kFbxSystemUnit(unit*100);
                pScene->GetGlobalSettings().SetSystemUnit(kFbxSystemUnit);
            }
        }

        pluginfbx::WriterNodeVisitor writerNodeVisitor(pScene, pSdkManager, filename,
            options, osgDB::getFilePath(node.getName().empty() ? filename : node.getName()));
        if (useFbxRoot && isBasicRootNode(node))
        {
            // If root node is a simple group, put all elements under the FBX root
            const osg::Group * osgGroup = node.asGroup();
            for (unsigned int child = 0; child < osgGroup->getNumChildren(); ++child)
            {
                const_cast<osg::Node *>(osgGroup->getChild(child))->accept(writerNodeVisitor);
            }
        }
        else {
            // Normal scene
            const_cast<osg::Node&>(node).accept(writerNodeVisitor);
        }

        FbxDocumentInfo* pDocInfo = pScene->GetDocumentInfo();
        bool needNewDocInfo = pDocInfo != NULL;
        if (needNewDocInfo)
        {
            pDocInfo = FbxDocumentInfo::Create(pSdkManager, "");
        }
        pDocInfo->LastSaved_ApplicationName.Set(FbxString("OpenSceneGraph"));
        pDocInfo->LastSaved_ApplicationVersion.Set(FbxString(osgGetVersion()));
        if (needNewDocInfo)
        {
            pScene->SetDocumentInfo(pDocInfo);
        }

        FbxExporter* lExporter = FbxExporter::Create(pSdkManager, "");
        pScene->GetGlobalSettings().SetAxisSystem(FbxAxisSystem::eOpenGL);

        // Ensure the directory exists or else the FBX SDK will fail
        if (!osgDB::makeDirectoryForFile(filename)) {
            OSG_NOTICE << "Can't create directory for file '" << filename << "'. FBX SDK may fail creating the file." << std::endl;
        }

        // The FBX SDK interprets the filename as UTF-8
#ifdef OSG_USE_UTF8_FILENAME
        const std::string& utf8filename(filename);
#else
        std::string utf8filename(osgDB::convertStringFromCurrentCodePageToUTF8(filename));
#endif

        // Output format selection. Here we only handle "recent" FBX, binary or ASCII.
        // pSdkManager->GetIOPluginRegistry()->GetWriterFormatDescription() / GetReaderFormatCount() gives the following list:
        //FBX binary (*.fbx)
        //FBX ascii (*.fbx)
        //FBX encrypted (*.fbx)
        //FBX 6.0 binary (*.fbx)
        //FBX 6.0 ascii (*.fbx)
        //FBX 6.0 encrypted (*.fbx)
        //AutoCAD DXF (*.dxf)
        //Alias OBJ (*.obj)
        //Collada DAE (*.dae)
        //Biovision BVH (*.bvh)
        //Motion Analysis HTR (*.htr)
        //Motion Analysis TRC (*.trc)
        //Acclaim ASF (*.asf)
        int format = ascii ? pSdkManager->GetIOPluginRegistry()->FindWriterIDByDescription("FBX ascii (*.fbx)") : -1;        // -1 = Default
        if (!lExporter->Initialize(utf8filename.c_str(), format))
        {
#if FBXSDK_VERSION_MAJOR < 2014
            return std::string(lExporter->GetLastErrorString());
#else
            return std::string(lExporter->GetStatus().GetErrorString());
#endif
        }

        if (!exportVersion.empty() && !lExporter->SetFileExportVersion(FbxString(exportVersion.c_str()), FbxSceneRenamer::eNone)) {
            std::stringstream versionsStr;
            char const * const * versions = lExporter->GetCurrentWritableVersions();
            if (versions) for(; *versions; ++versions) versionsStr << " " << *versions;
            OSG_WARN << "Can't set FBX export version to '" << exportVersion << "'. Using default. Available export versions are:" << versionsStr.str() << std::endl;
        }

        if (!lExporter->Export(pScene))
        {
#if FBXSDK_VERSION_MAJOR < 2014
            return std::string(lExporter->GetLastErrorString());
#else
            return std::string(lExporter->GetStatus().GetErrorString());
#endif
        }

        return WriteResult::FILE_SAVED;
    }
Ejemplo n.º 26
0
std::string TransformerGraph::getWorldName(const osg::Node &transformer)
{
    return std::string(transformer.getName());
}
void OsgIconSizeUpdaterVisitor::apply( osg::Node& node )
{
	std::string node_name = node.getName();
	
	if (node_name == "-icon-")
	{
		//get the position of the icon by asking it´s parents
		osg::Group *father_node = node.getParent(0);
		if (std::string("MatrixTransform") == father_node->className())
		{
			osg::MatrixTransform *mt = (osg::MatrixTransform *) father_node;
			osg::Vec3d icon_position = mt->getMatrix().getTrans();
			osg::Matrixd md = mt->getMatrix();

			IconUserData *iud = (IconUserData *)node.getUserData();

			/*float distance = (float) sqrt(pow(icon_position.x() - camera_pos_x, 2) + 
								          pow(icon_position.y() - camera_pos_y, 2) + 
										  pow(icon_position.z() - camera_pos_z, 2));*/

			icon_position.set(osg::Vec3(iud->GetPosition().x, iud->GetPosition().y,	iud->GetPosition().z));


			float distance = (float) sqrt(pow(icon_position.x() - camera_pos_x, 2) + 
								          pow(icon_position.y() - camera_pos_y, 2) + 
										  pow(icon_position.z() - camera_pos_z, 2));

			float final_size = 0.0f;

			if (iud->GetHeight() != 0.0f)
				min_height = iud->GetHeight();
			
			cpw::Point3d<float> op = iud->GetPosition();

			if (distance <= min_distance)
			{
				final_size = max_size;
				md.setTrans(osg::Vec3d(op.x, op.y, op.z + min_height));
			}
			else if (distance >= max_distance)
			{
				final_size = min_size;
				md.setTrans(osg::Vec3d(op.x, op.y, op.z + max_height));
			}
			else if ((min_distance < distance) && (distance < max_distance))
			{
				float increment_distance = max_distance - min_distance;
				float size_difference = max_size - min_size;
				float height_difference = max_height - min_height;
				float final_height;

				final_size = max_size - (size_difference * ((distance-min_distance)/increment_distance));
				final_height = min_height + (height_difference * ((distance-min_distance)/increment_distance));
				md.setTrans(op.x, op.y, op.z + final_height);

				//update the matrix

			}
			
			osg::ref_ptr<osg::StateSet> set = node.getStateSet();
		
			/// Give some size to the points to be able to see the sprite
			osg::ref_ptr<osg::Point> point = new osg::Point();

			mt->setMatrix(md);
		
			point->setSize(final_size);
						
			set->setAttribute(point.get());
		}
	}

	//keep searching
	traverse(node);
}