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

Reply via email to