bool boundSort(const osg::ref_ptr< osg::Node> &i, const osg::ref_ptr< osg::Node> &j)
{
    osg::BoundingSphere bsI = i->getBound();
    osg::BoundingSphere bsJ = j->getBound();

    return bsI.center().x() < bsJ.center().x();
}
Example #2
0
int main( int argc, char **argv )
{

    // use an ArgumentParser object to manage the program arguments.
    osg::ArgumentParser arguments(&argc,argv);

    // set up the usage document, in case we need to print out how to use this program.
    arguments.getApplicationUsage()->setApplicationName(arguments.getApplicationName());
    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ...");
    arguments.getApplicationUsage()->addCommandLineOption("--image <filename>","Load an image and render it on a quad");
    arguments.getApplicationUsage()->addCommandLineOption("--dem <filename>","Load an image/DEM and render it on a HeightField");
    arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display command line parameters");
    arguments.getApplicationUsage()->addCommandLineOption("--help-env","Display environmental variables available");
    arguments.getApplicationUsage()->addCommandLineOption("--help-keys","Display keyboard & mouse bindings available");
    arguments.getApplicationUsage()->addCommandLineOption("--help-all","Display all command line, env vars and keyboard & mouse bindings.");

    arguments.getApplicationUsage()->addCommandLineOption("--dragger <draggername>","Use the specified dragger for manipulation [TabPlaneDragger, TabPlaneTrackballDragger, TrackballDragger, Translate1DDragger, Translate2DDragger, TranslateAxisDragger, TabBoxDragger, TranslatePlaneDragger, Scale1DDragger, Scale2DDragger, RotateCylinderDragger, RotateSphereDragger]");
    arguments.getApplicationUsage()->addCommandLineOption("--fixedDraggerSize","Fix the size of the dragger geometry in the screen space");

    bool fixedSizeInScreen = false;
    while (arguments.read("--fixedDraggerSize")) { fixedSizeInScreen = true; }


    // construct the viewer.
    osgViewer::Viewer viewer(arguments);

    // add the window size toggle handler
    viewer.addEventHandler(new osgViewer::WindowSizeHandler);

    // get details on keyboard and mouse bindings used by the viewer.
    viewer.getUsage(*arguments.getApplicationUsage());


    if (arguments.read("--test-NodeMask"))
    {
        const osg::ref_ptr<osg::Group> group = new osg::Group();
        group->setNodeMask(0);

        const osg::ref_ptr<osgManipulator::AntiSquish> antiSquish = new osgManipulator::AntiSquish();

        group->addChild(antiSquish.get());

        const osg::ref_ptr<osg::Node> node = new osg::Node();
        node->setInitialBound(osg::BoundingSphere(osg::Vec3(0.0, 0.0, 0.0), 1.0));

        antiSquish->addChild(node.get());

        group->getBound();

        return 1;
    }



    // if user request help write it out to cout.
    bool helpAll = arguments.read("--help-all");
    unsigned int helpType = ((helpAll || arguments.read("-h") || arguments.read("--help"))? osg::ApplicationUsage::COMMAND_LINE_OPTION : 0 ) |
                            ((helpAll ||  arguments.read("--help-env"))? osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE : 0 ) |
                            ((helpAll ||  arguments.read("--help-keys"))? osg::ApplicationUsage::KEYBOARD_MOUSE_BINDING : 0 );
    if (helpType)
    {
        arguments.getApplicationUsage()->write(std::cout, helpType);
        return 1;
    }

    // report any errors if they have occurred when parsing the program arguments.
    if (arguments.errors())
    {
        arguments.writeErrorMessages(std::cout);
        return 1;
    }

    std::string dragger_name = "TabBoxDragger";
    arguments.read("--dragger", dragger_name);

    osg::Timer_t start_tick = osg::Timer::instance()->tick();

    // read the scene from the list of file specified command line args.
    osg::ref_ptr<osg::Node> loadedModel = osgDB::readRefNodeFiles(arguments);

    // if no model has been successfully loaded report failure.
    bool tragger2Scene(true);
    if (!loadedModel)
    {
        //std::cout << arguments.getApplicationName() <<": No data loaded" << std::endl;
        //return 1;
        loadedModel = createDemoScene(fixedSizeInScreen);
        tragger2Scene=false;
    }

    // any option left unread are converted into errors to write out later.
    arguments.reportRemainingOptionsAsUnrecognized();

    // report any errors if they have occurred when parsing the program arguments.
    if (arguments.errors())
    {
        arguments.writeErrorMessages(std::cout);
    }

    osg::Timer_t end_tick = osg::Timer::instance()->tick();

    std::cout << "Time to load = "<<osg::Timer::instance()->delta_s(start_tick,end_tick)<<std::endl;


    // optimize the scene graph, remove redundant nodes and state etc.
    osgUtil::Optimizer optimizer;
    optimizer.optimize(loadedModel);


    // pass the loaded scene graph to the viewer.
    if ( tragger2Scene ) {
        viewer.setSceneData(addDraggerToScene(loadedModel.get(), dragger_name, fixedSizeInScreen));
    } else {
        viewer.setSceneData(loadedModel);
    }


    return viewer.run();
}
Example #3
0
osg::ref_ptr<osg::Node> decorate_with_clip_node(const osg::ref_ptr<osg::Node>& subgraph)
{
    osg::ref_ptr<osg::Group> rootnode = new osg::Group;

    // create wireframe view of the model so the user can see
    // what parts are being culled away.
    osg::StateSet* stateset = new osg::StateSet;
    //osg::Material* material = new osg::Material;
    osg::PolygonMode* polymode = new osg::PolygonMode;
    polymode->setMode(osg::PolygonMode::FRONT_AND_BACK,osg::PolygonMode::LINE);
    stateset->setAttributeAndModes(polymode,osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON);

    osg::Group* wireframe_subgraph = new osg::Group;
    wireframe_subgraph->setStateSet(stateset);
    wireframe_subgraph->addChild(subgraph);
    rootnode->addChild(wireframe_subgraph);

/*
    // simple approach to adding a clipnode above a subgraph.

    // create clipped part.
    osg::ClipNode* clipped_subgraph = new osg::ClipNode;

    osg::BoundingSphere bs = subgraph->getBound();
    bs.radius()*= 0.4f;

    osg::BoundingBox bb;
    bb.expandBy(bs);


    clipped_subgraph->createClipBox(bb);
    clipped_subgraph->addChild(subgraph);
    rootnode->addChild(clipped_subgraph);
*/


    // more complex approach to managing ClipNode, allowing
    // ClipNode node to be transformed independently from the subgraph
    // that it is clipping.

    osg::MatrixTransform* transform= new osg::MatrixTransform;

    osg::NodeCallback* nc = new osg::AnimationPathCallback(subgraph->getBound().center(),osg::Vec3(0.0f,0.0f,1.0f),osg::inDegrees(45.0f));
    transform->setUpdateCallback(nc);

    osg::ClipNode* clipnode = new osg::ClipNode;
    osg::BoundingSphere bs = subgraph->getBound();
    bs.radius()*= 0.4f;

    osg::BoundingBox bb;
    bb.expandBy(bs);

    clipnode->createClipBox(bb);
    clipnode->setCullingActive(false);

    transform->addChild(clipnode);
    rootnode->addChild(transform);


    // create clipped part.
    osg::Group* clipped_subgraph = new osg::Group;

    clipped_subgraph->setStateSet(clipnode->getStateSet());
    clipped_subgraph->addChild(subgraph);
    rootnode->addChild(clipped_subgraph);

    return rootnode;
}
Example #4
0
//创建预渲染场景
osg::ref_ptr<osg::Node> createPreRenderSubGraph(osg::ref_ptr<osg::Node> subgraph, 
												unsigned tex_width, 
												unsigned tex_height, 
												osg::Camera::RenderTargetImplementation renderImplementation,
												bool useImage)
{
	if (!subgraph) return 0;

	//创建一个包含预渲camera的 Group 节点
	osg::ref_ptr<osg::Group> parent = new osg::Group;

	//创建纹理,用来绑定相机渲染的结果
	osg::ref_ptr<osg::Texture> texture = 0;
	{
		osg::ref_ptr<osg::Texture2D> texture2D = new osg::Texture2D;
		texture2D->setTextureSize(tex_width, tex_height);
		texture2D->setInternalFormat(GL_RGBA);
		texture2D->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR);
		texture2D->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR);

		texture = texture2D;
	} 

	//创建一个用来浏览的四边形几何体
	{ 
		osg::ref_ptr<osg::Geometry> polyGeom = new osg::Geometry();
		//设置该几何体不使用显示列表
		polyGeom->setSupportsDisplayList(false);

		float height = 100.0f;
		float width = 200.0f;

		//创建顶点数组,并添加数据
		osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array;
		vertices->push_back( osg::Vec3(0.0f,0.0f,0.0f) );
		vertices->push_back( osg::Vec3(width,0.0f,0.0f) );		
		vertices->push_back( osg::Vec3(width,0.0f,height) );
		vertices->push_back( osg::Vec3(0.0f,0.0f,height) );

		//创建纹理数组,并添加数据
		osg::ref_ptr<osg::Vec2Array> texcoords = new osg::Vec2Array();
		texcoords->push_back( osg::Vec2(0.0f,0.0f) );
		texcoords->push_back( osg::Vec2(1.0f,0.0f) );
		texcoords->push_back( osg::Vec2(1.0f,1.0f) );
		texcoords->push_back( osg::Vec2(0.0f,1.0f) );

		polyGeom->setVertexArray(vertices.get());

		//使用vbo扩展
// 		{
// 			osg::ref_ptr<osg::VertexBufferObject> vbObject = new osg::VertexBufferObject;
// 			vertices->setVertexBufferObject(vbObject);
// 
// 			polyGeom->setUseVertexBufferObjects(true);
// 		}

		polyGeom->setTexCoordArray(0,texcoords.get());

		//创建颜色数组,并设置绑定方式及添加数据
// 		osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array;
// 		colors->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
// 		polyGeom->setColorArray(colors.get());
// 		polyGeom->setColorBinding(osg::Geometry::BIND_OVERALL);

		polyGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,vertices->size()));

		//现在我们需要将纹理附加到该几何体上,我们创建一个包含该纹理的StateSet
		osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet;

		stateset->setTextureAttributeAndModes(0, texture,osg::StateAttribute::ON);

		polyGeom->setStateSet(stateset);

		osg::ref_ptr<osg::Geode> geode = new osg::Geode();
		geode->addDrawable(polyGeom.get());

		parent->addChild(geode.get());

	}

	// 需要创建一个相机节点,用来渲染到该纹理(RTT)
	{    
		osg::ref_ptr<osg::Camera> camera = new osg::Camera;

		//设置背景色及清除颜色和深度缓存
		camera->setClearColor(osg::Vec4(0.1f,0.1f,0.3f,1.0f));
		camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

		//获得该节点的范围盒
		const osg::BoundingSphere& bs = subgraph->getBound();
		if (!bs.valid())
		{
			return subgraph.get();
		}

		float znear = 1.0f*bs.radius();
		float zfar  = 3.0f*bs.radius();

		float proj_top   = 0.25f*znear;
		float proj_right = 0.5f*znear;

		znear *= 0.9f;
		zfar *= 1.1f;

		//设置投影矩阵.
	//	camera->setProjectionMatrixAsFrustum(-proj_right,proj_right,-proj_top,proj_top,znear,zfar);

		//将相机对准该子场景
		camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
	//	camera->setViewMatrixAsLookAt(bs.center()-osg::Vec3(0.0f,2.0f,0.0f)*bs.radius(),bs.center(),osg::Vec3(0.0f,0.0f,1.0f));

		//设置视口
		camera->setViewport(0,0,tex_width,tex_height);

		//设置相机的渲染序列
		camera->setRenderOrder(osg::Camera::PRE_RENDER);

		//设置相机渲染通过 OpenGL frame buffer object 实现
		camera->setRenderTargetImplementation(renderImplementation);


		if (useImage)
		{
			osg::ref_ptr<osg::Image> image = new osg::Image;
			//image->allocateImage(tex_width, tex_height, 1, GL_RGBA, GL_UNSIGNED_BYTE);
			image->allocateImage(tex_width, tex_height, 1, GL_RGBA, GL_FLOAT);

			//将Image附加到相机的COLOR_BUFFER
			camera->attach(osg::Camera::COLOR_BUFFER, image.get());

			//添加相机的绘制后回调,修改images数据
			camera->setPostDrawCallback(new MyCameraPostDrawCallback(image.get()));

			//这里我们不直接将相机的COLOR_BUFFER附加到该纹理上,是为了修改渲染后的图像数据
			texture->setImage(0, image.get());
		}
		else
		{
			//直接将该纹理附加到相机的颜色缓存.
			camera->attach(osg::Camera::COLOR_BUFFER, texture.get());
		}

		//添加要绘制的子场景
		camera->addChild(subgraph.get());

		parent->addChild(camera.get());

	}    

	return parent.get();
}
Example #5
0
osg::ref_ptr<osg::Node> createRoom(const osg::ref_ptr<osg::Node>& loadedModel)
{
    // default scale for this model.
    osg::BoundingSphere bs(osg::Vec3(0.0f,0.0f,0.0f),1.0f);

    osg::Group* root = new osg::Group;

    if (loadedModel)
    {
        const osg::BoundingSphere& loaded_bs = loadedModel->getBound();

        osg::PositionAttitudeTransform* pat = new osg::PositionAttitudeTransform();
        pat->setPivotPoint(loaded_bs.center());

        pat->setUpdateCallback(new ModelTransformCallback(loaded_bs));
        pat->addChild(loadedModel);

        bs = pat->getBound();

        root->addChild(pat);

    }

    bs.radius()*=1.5f;

    // create a bounding box, which we'll use to size the room.
    osg::BoundingBox bb;
    bb.expandBy(bs);


    // create statesets.
    osg::StateSet* rootStateSet = new osg::StateSet;
    root->setStateSet(rootStateSet);

    osg::StateSet* wall = new osg::StateSet;
    wall->setMode(GL_CULL_FACE,osg::StateAttribute::ON);

    osg::StateSet* floor = new osg::StateSet;
    floor->setMode(GL_CULL_FACE,osg::StateAttribute::ON);

    osg::StateSet* roof = new osg::StateSet;
    roof->setMode(GL_CULL_FACE,osg::StateAttribute::ON);

    osg::Geode* geode = new osg::Geode;

    // create front side.
    geode->addDrawable(createWall(bb.corner(0),
                                  bb.corner(4),
                                  bb.corner(1),
                                  wall));

    // right side
    geode->addDrawable(createWall(bb.corner(1),
                                  bb.corner(5),
                                  bb.corner(3),
                                  wall));

    // left side
    geode->addDrawable(createWall(bb.corner(2),
                                  bb.corner(6),
                                  bb.corner(0),
                                  wall));
    // back side
    geode->addDrawable(createWall(bb.corner(3),
                                  bb.corner(7),
                                  bb.corner(2),
                                  wall));

    // floor
    geode->addDrawable(createWall(bb.corner(0),
                                  bb.corner(1),
                                  bb.corner(2),
                                  floor));

    // roof
    geode->addDrawable(createWall(bb.corner(6),
                                  bb.corner(7),
                                  bb.corner(4),
                                  roof));

    root->addChild(geode);

    root->addChild(createLights(bb,rootStateSet));

    return root;

}