i am suppose to implement flocking but im not sure how can anyone help?? Puck. h:
#ifndef PUCK_H #define PUCK_H #include <osg/Group> #include <osg/Geode> #include <osg/Geometry> #include <osg/ShapeDrawable> #include <osg/MatrixTransform> #include <iostream> #include <osgViewer/Viewer> #include "Obstacle.h" using namespace osg; using namespace osgViewer; using namespace std; class Puck { public: Puck(Group *root, Obstacle** obstacles, int ob_count, double x, double y); }; #endif obstacle.h: #ifndef OBSTACLE_H #define OBSTACLE_H #include <osg/Group> #include <osg/Geode> #include <osg/Geometry> #include <osg/ShapeDrawable> #include <osg/MatrixTransform> #include <osgViewer/Viewer> using namespace osg; using namespace osgViewer; class Obstacle { public: double x,y; double radius; Obstacle(Group *root, double x, double y, double radius); }; #endif obstacle.cpp: #include "Obstacle.h" Obstacle::Obstacle(Group *root, double x_pos, double y_pos, double r) { x = x_pos; y = y_pos; radius = r; Cylinder *shape=new Cylinder(Vec3(x,y,0),radius,0.1); ShapeDrawable *draw=new ShapeDrawable(shape); draw->setColor(Vec4(1,0,1,0)); Geode *geode=new Geode(); geode->addDrawable(draw); MatrixTransform *T=new MatrixTransform(); T->addChild(geode); root->addChild(T); } puck.cpp: #include "Puck.h" #ifndef M_PI #define M_PI 3.1415 #endif class TranslateCB : public osg::NodeCallback { private: double _dx,_dy; double _dirx,_diry; double _inc; double _theta; double _radius; double _x,_y; Obstacle** obstacles; int ob_count; public: TranslateCB() : _dx( 0. ), _dy( 0. ), _dirx(1), _diry(0), _inc(0.2), _theta(0) {} TranslateCB(Obstacle** ob, int count, double r, double x, double y) : _dx( 0. ), _dy( 0. ), _dirx(2.0*rand()/RAND_MAX-1), _diry(2.0*rand()/RAND_MAX-1), _inc(0.001), _theta(0) { obstacles = ob; ob_count = count; _radius = r; _x = x; _y = y; } virtual void operator()( osg::Node* node, osg::NodeVisitor* nv ) { osg::MatrixTransform* mt = dynamic_cast<osg::MatrixTransform*>( node ); osg::Matrix mR, mT; mT.makeTranslate( _dx , _dy, 0. ); mt->setMatrix( mT ); double ob_dirx; double ob_diry; double ob_dist; _theta = 0; double min = 4; for(int i = 0; i < ob_count; i++) { ob_dirx = (_x+_dx) - obstacles[i]->x; ob_diry = (_y+_dy) - obstacles[i]->y; ob_dist = sqrt(ob_dirx*ob_dirx+ob_diry*ob_diry); //normalise directions double ob_norm = sqrt(ob_dirx*ob_dirx+ob_diry*ob_diry); ob_dirx = (ob_dirx)/ob_norm; ob_diry = (ob_diry)/ob_norm; double norm = sqrt(_dirx*_dirx+_diry*_diry); _dirx = (_dirx)/norm; _diry = (_diry)/norm; //calculate angle between direction travelling, and direction to obstacle double angle = acos(_dirx*ob_dirx + _diry*ob_diry); //calculate closest distance between puck and obstacle if continues on same path double min_dist = ob_dist*sin(angle); if(min_dist < _radius + obstacles[i]->radius && ob_dist < min+obstacles[i]->radius) { min = ob_dist; if(ob_dist < _radius + obstacles[i]->radius){ _theta = 0; } else if(angle < M_PI/2){ _theta = -0.3; } else{ _theta = 0.3; } } } //change direction accordingly _dirx = _dirx*cos(_theta) + _diry*sin(_theta); _diry = _diry*cos(_theta) - _dirx*sin(_theta); _dx += _inc*_dirx; if((_x+_dx > 10 && _dirx > 0) || (_x+_dx < -10 && _dirx < 0)) { _dirx = -_dirx; _diry += (0.2*rand()/RAND_MAX-0.1); //add randomness to bounce } _dy += _inc*_diry; if((_y+_dy > 10 && _diry > 0) || (_y+_dy < -10 && _diry < 0)) { _diry = -_diry; _dirx += (0.2*rand()/RAND_MAX-0.1); //add randomness to bounce } traverse( node, nv ); } }; Puck::Puck(Group *root, Obstacle** obstacles, int ob_count, double x, double y) { // geometry double radius = 0.2; Cylinder *shape=new Cylinder(Vec3(x,y,0),radius,0.1); ShapeDrawable *draw=new ShapeDrawable(shape); draw->setColor(Vec4(1,0,0,1)); Geode *geode=new Geode(); geode->addDrawable(draw); // transformation MatrixTransform *T=new MatrixTransform(); T->setUpdateCallback(new TranslateCB(obstacles,ob_count,radius,x,y)); T->addChild(geode); root->addChild(T); } mainThread.cpp: #include <osg/Group> #include <osg/Geode> #include <osg/Geometry> #include <osg/ShapeDrawable> #include <osg/MatrixTransform> #include <osgViewer/Viewer> #include "Puck.h" #include "Obstacle.h" #ifndef M_PI #define M_PI 3.1415 #endif using namespace osg; using namespace osgViewer; int main() { Viewer *viewer=new Viewer(); osg::Group *root=new Group(); //Create the plane Geode *gplane=new Geode(); Box *plane=new Box(Vec3(0,0,0),20,20,0.01); ShapeDrawable *pdraw=new ShapeDrawable(plane); pdraw->setColor(Vec4(0,0,2,0)); gplane->addDrawable(pdraw); root->addChild(gplane); //Create objects int ob_count = 3; Obstacle **obstacles = new Obstacle*[ob_count]; srand ( time(NULL) ); for(int i = 0; i < ob_count; i++) { /*double x = 14.0*rand()/RAND_MAX-7; double y = 14.0*rand()/RAND_MAX-7; double radius = 0.4+1.6*rand()/RAND_MAX;*/ double x = -5 + (i * 3); double y = 0; double radius = 1; obstacles[i] = new Obstacle(root,x,y,radius); cout << obstacles[i]->x << " " << obstacles[i]->y << " " << obstacles[i]->radius << "\n"; } int p_count = 5; Puck **pucks = new Puck*[p_count]; for (int i = 0; i < p_count; i++) { Puck *puck=new Puck(root,obstacles,ob_count,0,0); } //Display viewer->setSceneData(root); viewer->setUpViewInWindow(100,100,512,512); viewer->run(); } ------------------ Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=35870#35870 _______________________________________________ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org