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
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org