Nehe OpenGL Tutorial with OpenSceneGraph-40th lesson

Source: Internet
Author: User
Tags addchild constant traits
Brief Introduction

Nehe Tutorial In this lesson to show us how to simulate the movement of a rope, simply, that is, the rope first discretization, think of it as a tight arrangement of points, each two points with elastic constraints. In fact, this is the simple idea of finite element. The content of this class is the same as that of last class, which is mainly related to physics and mathematics, and has little to do with graphic images. Implement

First we also create the geometry in the scene:

	Root->addchild (Createground ());   Ground
	Root->addchild (Createropeshadow ());///Rope Shadow
	Root->addchild (Createrope ());   Rope

Next, set the update callback for each geometry:

osg::geode* Createrope () {Osg::geode *geode = new Osg::geode;
	Osg::geometry *geometry = new Osg::geometry;
	Geometry->setupdatecallback (new Ropeupdatecallback);
	Osg::vec3array *vertexarray = new Osg::vec3array;

	Osg::vec3array *colorarray = new Osg::vec3array;

	Colorarray->push_back (OSG::VEC3 (1, 1, 0));
		for (int a = 0; a < ropesimulation->numofmasses-1; ++a) {mass* Mass1 = Ropesimulation->getmass (a);

		vector3d* POS1 = &mass1->pos;
		mass* Mass2 = Ropesimulation->getmass (A + 1);

		vector3d* Pos2 = &mass2->pos;	
		Vertexarray->push_back (OSG::VEC3 (pos1->x, Pos1->y, pos1->z));
	Vertexarray->push_back (OSG::VEC3 (pos2->x, Pos2->y, pos2->z));
	} geometry->setvertexarray (Vertexarray);
	Geometry->setcolorarray (Colorarray, Osg::array::bind_overall);
	Geometry->getorcreatestateset ()->setmode (gl_lighting, Osg::stateattribute::off);
	Geometry->getorcreatestateset ()->setmode (Gl_depth_test, false); geometry-&Gt;getorcreatestateset ()->setattributeandmodes (new Osg::linewidth (4.0));
	Geometry->addprimitiveset (new OSG::D rawarrays (osg::P rimitiveset::lines, 0, Vertexarray->size ()));
	Geode->adddrawable (geometry);
return geode; }

Update the parameters of the rope in the frame loop:

		Case (Osgga::guieventadapter::frame):
			{
				double dt = 0.0;
				_currenttick = Osg::timer::instance ()->tick ();
				if (_currenttick!= _lasttick)
				{		
					dt = osg::timer::instance ()->delta_s (_lasttick, _currenttick);
					_lasttick = _currenttick;
				}

				Ropesimulation->setropeconnectionvel (ropeconnectionvel);		

				float Maxpossible_dt = 0.002f;										

				int numofiterations = (int) (DT/MAXPOSSIBLE_DT) + 1;			
				if (numofiterations!= 0)
					dt = dt/numofiterations;	

				for (int a = 0; a < numofiterations ++a)
					ropesimulation->operate (DT);
			}

Add each section to the scene root node and compile the program:


Attached: This lesson source code (source code may exist errors and deficiencies, for reference only)

#include ". /osgnehe.h "#include <QtCore/QTimer> #include <QtGui/QApplication> #include <QtGui/QVBoxLayout> Include <osgViewer/Viewer> #include <osgDB/ReadFile> #include <osgQt/GraphicsWindowQt> #include <osg/MatrixTransform> #include <osg/LineWidth> #include "Physics2.h"////////////////////////////////// ropesimulation* ropesimulation = new Ropesimulation (.//Particles ( Masses) 0.05f,//per particle has A Weight grams 10000.0f,//Springconstant in the Rope 0.05f,//N  Ormal Length of Springs in the Rope 0.2f,//Spring Inner friction Constant vector3d (0, -9.81f, 0),//gravitational Acceleration 0.02f,//Air friction Constant 100.0f,//Ground Repel Constant 0.2f,///Ground Slide Fricti					On Constant 2.0f,//Ground absoption constant-1.5f); The Height of Ground bool Initialize () {Ropesimulation->getmass (ropesimulation->numofmasses-1)->vel.z = 10.0f;
return true; }//////////////////////////////////////////////////////////////////////////class Groundupdatecallback:public OSG ::D rawable::updatecallback {public:virtual void update (osg::nodevisitor*, OSG::D rawable* d) {osg::geometry *geomet
		ry = dynamic_cast<osg::geometry*> (d);

		if (!geometry) return;
		Osg::vec3array *vertexarray = dynamic_cast<osg::vec3array*> (Geometry->getvertexarray ());

		if (!vertexarray) return;
		
		Vertexarray->clear ();
		Vertexarray->push_back (OSG::VEC3, Ropesimulation->groundheight, 20));
		Vertexarray->push_back (OSG::VEC3 ( -20, Ropesimulation->groundheight, 20));
		Vertexarray->push_back (OSG::VEC3 ( -20, Ropesimulation->groundheight,-20));
	
		Vertexarray->push_back (OSG::VEC3, Ropesimulation->groundheight,-20));
		Geometry->setvertexarray (Vertexarray);
	Vertexarray->dirty ();



}

}; Class Ropeshadowupdatecallback:public OSG::D rawable::updatecallback {public:virtual void update (osg::nodevisitor*, OSG::D rawable* d) {osg::geometry *geometry = Dynamic_
		Cast<osg::geometry*> (d);

		if (!geometry) return;
		Osg::vec3array *vertexarray = dynamic_cast<osg::vec3array*> (Geometry->getvertexarray ());

		if (!vertexarray) return;

		Vertexarray->clear ();
			for (int a = 0; a < ropesimulation->numofmasses-1; ++a) {mass* Mass1 = Ropesimulation->getmass (a);

			vector3d* POS1 = &mass1->pos;
			mass* Mass2 = Ropesimulation->getmass (A + 1);
			vector3d* Pos2 = &mass2->pos;		Vertexarray->push_back (OSG::VEC3 (pos1->x, Ropesimulation->groundheight, pos1->z)); Draw Shadow at Groundheight vertexarray->push_back (OSG::VEC3 (pos2->x, Ropesimulation->groundheight, pos2-		&GT;Z));
		Draw Shadow at Groundheight} geometry->setvertexarray (Vertexarray);
	Vertexarray->dirty ();


}

}; Class Ropeupdatecallback:public OSG::D Rawable::updatecallbacK {public:virtual void update (osg::nodevisitor*, OSG::D rawable* d) {osg::geometry *geometry = dynamic_cast<osg:
		:geometry*> (d);

		if (!geometry) return;
		Osg::vec3array *vertexarray = dynamic_cast<osg::vec3array*> (Geometry->getvertexarray ());

		if (!vertexarray) return;

		Vertexarray->clear ();
			for (int a = 0; a < ropesimulation->numofmasses-1; ++a) {mass* Mass1 = Ropesimulation->getmass (a);

			vector3d* POS1 = &mass1->pos;
			mass* Mass2 = Ropesimulation->getmass (A + 1);

			vector3d* Pos2 = &mass2->pos;	
			Vertexarray->push_back (OSG::VEC3 (pos1->x, Pos1->y, pos1->z));
		Vertexarray->push_back (OSG::VEC3 (pos2->x, Pos2->y, pos2->z));
		} geometry->setvertexarray (Vertexarray);
	Vertexarray->dirty ();





}

};
	osg::geode* Createground () {Osg::geode *geode = new Osg::geode;
	Osg::geometry *geometry = new Osg::geometry;
	Geometry->setupdatecallback (new Groundupdatecallback); Osg:: Vec3array *vertexarray = new Osg::vec3array;
	
	Osg::vec3array *colorarray = new Osg::vec3array;
	Colorarray->push_back (OSG::VEC3 (0, 0, 1.0));
	Vertexarray->push_back (OSG::VEC3, Ropesimulation->groundheight, 20));
	Colorarray->push_back (OSG::VEC3 (0, 0, 1.0));
	Vertexarray->push_back (OSG::VEC3 ( -20, Ropesimulation->groundheight, 20));
	Colorarray->push_back (OSG::VEC3 (0,0,0));
	Vertexarray->push_back (OSG::VEC3 ( -20, Ropesimulation->groundheight,-20));
	Colorarray->push_back (OSG::VEC3 (0,0,0));

	Vertexarray->push_back (OSG::VEC3, Ropesimulation->groundheight,-20));
	Geometry->setvertexarray (Vertexarray);
	Geometry->setcolorarray (Colorarray, Osg::array::bind_per_vertex);
	Geometry->getorcreatestateset ()->setmode (gl_lighting, Osg::stateattribute::off);
	Geometry->addprimitiveset (new OSG::D rawarrays (osg::P rimitiveset::quads, 0, Vertexarray->size ()));
	Geode->adddrawable (geometry);
return geode; } osg::geode* Createropeshadow () {Osg::geode *geode = new Osg::geode;
	Osg::geometry *geometry = new Osg::geometry;
	Geometry->setupdatecallback (new Ropeshadowupdatecallback);
	Osg::vec3array *vertexarray = new Osg::vec3array;

	Osg::vec3array *colorarray = new Osg::vec3array;
	
	Colorarray->push_back (OSG::VEC3 (0, 0, 0));
		for (int a = 0; a < ropesimulation->numofmasses-1; ++a) {mass* Mass1 = Ropesimulation->getmass (a);

		vector3d* POS1 = &mass1->pos;
		mass* Mass2 = Ropesimulation->getmass (A + 1);
		vector3d* Pos2 = &mass2->pos;		Vertexarray->push_back (OSG::VEC3 (pos1->x, Ropesimulation->groundheight, pos1->z)); Draw Shadow at Groundheight vertexarray->push_back (OSG::VEC3 (pos2->x, Ropesimulation->groundheight, pos2-		&GT;Z));
	Draw Shadow at Groundheight} geometry->setvertexarray (Vertexarray);
	Geometry->setcolorarray (Colorarray, Osg::array::bind_overall); Geometry->getorcreatestateset ()->setmode (gl_lighting, Osg::stateattribute:: OFF);
	Geometry->getorcreatestateset ()->setattributeandmodes (new Osg::linewidth (2.0));
	Geometry->addprimitiveset (new OSG::D rawarrays (osg::P rimitiveset::lines, 0, Vertexarray->size ()));
	Geode->adddrawable (geometry);
return geode;
	} osg::geode* Createrope () {Osg::geode *geode = new Osg::geode;
	Osg::geometry *geometry = new Osg::geometry;
	Geometry->setupdatecallback (new Ropeupdatecallback);
	Osg::vec3array *vertexarray = new Osg::vec3array;

	Osg::vec3array *colorarray = new Osg::vec3array;

	Colorarray->push_back (OSG::VEC3 (1, 1, 0));
		for (int a = 0; a < ropesimulation->numofmasses-1; ++a) {mass* Mass1 = Ropesimulation->getmass (a);

		vector3d* POS1 = &mass1->pos;
		mass* Mass2 = Ropesimulation->getmass (A + 1);

		vector3d* Pos2 = &mass2->pos;	
		Vertexarray->push_back (OSG::VEC3 (pos1->x, Pos1->y, pos1->z));
	Vertexarray->push_back (OSG::VEC3 (pos2->x, Pos2->y, pos2->z)); } Geometry->setvertexarray(Vertexarray);
	Geometry->setcolorarray (Colorarray, Osg::array::bind_overall);
	Geometry->getorcreatestateset ()->setmode (gl_lighting, Osg::stateattribute::off);
	Geometry->getorcreatestateset ()->setmode (Gl_depth_test, false);
	Geometry->getorcreatestateset ()->setattributeandmodes (new Osg::linewidth (4.0));
	Geometry->addprimitiveset (new OSG::D rawarrays (osg::P rimitiveset::lines, 0, Vertexarray->size ()));
	Geode->adddrawable (geometry);
return geode; }//////////////////////////////////////////////////////////////////////////Class Manipulatorscenehandler:public
		Osgga::guieventhandler {Public:manipulatorscenehandler () {_lasttick = Osg::timer::instance ()->tick ();
	_currenttick = _lasttick; } public:virtual bool Handle (const osgga::guieventadapter& EA, osgga::guiactionadapter& aa) {Osgviewer::vie
		Wer *viewer = dynamic_cast<osgviewer::viewer*> (&AMP;AA);
		if (!viewer) return false; if (!viewer->getscenedata ()) REturn false;

		if (ea.gethandled ()) return false;

		Osg::group *root = Viewer->getscenedata ()->asgroup ();
				Switch (Ea.geteventtype ()) {case (Osgga::guieventadapter::frame): {Double dt = 0.0;
				_currenttick = Osg::timer::instance ()->tick ();
					if (_currenttick!= _lasttick) {dt = Osg::timer::instance ()->delta_s (_lasttick, _currenttick);
				_lasttick = _currenttick;		

				} ropesimulation->setropeconnectionvel (Ropeconnectionvel);										

				float Maxpossible_dt = 0.002f;			
				int numofiterations = (int) (DT/MAXPOSSIBLE_DT) + 1;	

				if (numofiterations!= 0) dt = dt/numofiterations;
			for (int a = 0; a < numofiterations ++a) ropesimulation->operate (DT);
		} break; Case (Osgga::guieventadapter::keydown): {if (ea.getkey () = = osgga::guieventadapter::key_up) {Ropeconnect	
				Ionvel.z = 1.0f; } if (Ea.getkey () = = Osgga::guieventadapter::key_down) {ropeconnectionvel.z += 1.0f;
				} if (Ea.getkey () = = Osgga::guieventadapter::key_left) {ropeconnectionvel.x = 1.0f;
				} if (Ea.getkey () = = osgga::guieventadapter::key_right) {ropeconnectionvel.x = 1.0f;	
				} if (Ea.getkey () = = osgga::guieventadapter::key_home) {ropeconnectionvel.y = 1.0f;
				} if (Ea.getkey () = = osgga::guieventadapter::key_end) {ropeconnectionvel.y = 1.0f;

		}} break;
		Default:break;
	return false;
	} osg::timer_t _lasttick;
	osg::timer_t _currenttick;
Vector3D Ropeconnectionvel;







}; Class Viewerwidget:public Qwidget, public osgviewer::viewer {public:viewerwidget (osg::node *scene = NULL) {QWidge

		t* renderwidget = Getrenderwidget (Creategraphicswindow (0,0,100,100), scene);
		qvboxlayout* layout = new Qvboxlayout;
		Layout->addwidget (Renderwidget);
		Layout->setcontentsmargins (0, 0, 0, 1);

		SetLayout (layout);
		Connect (&_timer, SIGNAL (timeout ()), this, SLOT (update ())); _tImer.start (10); } qwidget* Getrenderwidget (osgqt::graphicswindowqt* GW, osg::node* scene) {osg::camera* Camera = This->getcamer
		A ();

		Camera->setgraphicscontext (GW);

		Const osg::graphicscontext::traits* Traits = Gw->gettraits ();
		Camera->setclearcolor (OSG::VEC4 (0.0, 0.0, 0.0, 0.5));
		Camera->setviewport (New Osg::viewport (0, 0, traits->width, traits->height)); Camera->setprojectionmatrixasperspective (45.0f, static_cast<double> (traits->width)/static_cast<
		Double> (Traits->height), 0.1f, 100.0f);

		Camera->setviewmatrixaslookat (osg::vec3d (0, 0, 4), osg::vec3d (0, 0, 0), osg::vec3d (0, 1, 0));
		This->setscenedata (Scene);
		This->addeventhandler (new Manipulatorscenehandler);
	return Gw->getglwidget (); osgqt::graphicswindowqt* Creategraphicswindow (int x, int y, int w, int h, const std::string& name= "", bool Window
Decoration=false) {osg::D isplaysettings* ds = osg::D isplaysettings::instance (). get ();		osg::ref_ptr<osg::graphicscontext::traits> Traits = new Osg::graphicscontext::traits;
		Traits->windowname = name;
		Traits->windowdecoration = windowdecoration;
		traits->x = x;
		Traits->y = y;
		Traits->width = W;
		Traits->height = h;
		Traits->doublebuffer = true;
		Traits->alpha = Ds->getminimumnumalphabits ();
		Traits->stencil = Ds->getminimumnumstencilbits ();
		Traits->samplebuffers = Ds->getmultisamples ();

		Traits->samples = Ds->getnummultisamples ();
	return new OSGQT::GRAPHICSWINDOWQT (Traits.get ()); 
	virtual void PaintEvent (qpaintevent* event) {frame ();
} Protected:qtimer _timer;



};

	osg::node* Buildscene () {initialize ();

	Osg::group *root = new Osg::group;
	Root->addchild (Createground ());
	Root->addchild (Createropeshadow ());

	Root->addchild (Createrope ());
return root;
	int main (int argc, char** argv) {qapplication app (argc, argv); viewerwidget* viewwidget = new Viewerwidget (BuiLdscene ());
	Viewwidget->setgeometry (100, 100, 640, 480);
	Viewwidget->show ();
return App.exec ();
 }

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.