osg::Geometry* ShapeVisitor_VisualizerCreator::createGridGeometry( int size, int noOfLines, osg::Vec3f center )
{

	osg::Geometry* geom = new osg::Geometry();
	osg::Vec3Array* positionsOfLines = new osg::Vec3Array;

	geom->setVertexArray( positionsOfLines );

	// position of borders
	osg::Vec3f dif1( ( osg::Vec3f::value_type )( -size/2 ), ( osg::Vec3f::value_type )( size/2 ), -10 ); // top left
	osg::Vec3f dif2( ( osg::Vec3f::value_type )( -size/2 ), ( osg::Vec3f::value_type )( -size/2 ), -10 );
	osg::Vec3f dif3( ( osg::Vec3f::value_type )( size/2 ), ( osg::Vec3f::value_type )( size/2 ), -10 );

	// increment for creating points of mesh at border
	osg::Vec3f incrementX( ( osg::Vec3f::value_type )( size/noOfLines ), 0, 0 );
	osg::Vec3f incrementY( 0, ( osg::Vec3f::value_type )( -size/noOfLines ), 0 );

	// computing and saving positions of points at border of mesh
	for ( int i=0; i<2; i++ ) {

		osg::Vec3f base1 = center + dif1;
		osg::Vec3f base2 = center + dif2;

		// computing positions at x axis
		for ( int j=0; j<noOfLines; j++ ) {
			positionsOfLines->push_back( base1 + incrementX );
			base1 += incrementX;
			positionsOfLines->push_back( base2 + incrementX + incrementY );
			base2 += incrementX;
		}

		base1 = center + dif1;
		base2 = center + dif3;

		// computing positions at y axis
		for ( int j=0; j<noOfLines; j++ ) {
			positionsOfLines->push_back( base1 + incrementY );
			base1 += incrementY;
			positionsOfLines->push_back( base2 + incrementY + incrementX );
			base2 += incrementY;
		}

		// connecting two corresponding points at border of mesh
		for ( int k=0; k<noOfLines*4; k=k+2 ) {
			osg::DrawElementsUInt* line = new osg::DrawElementsUInt( osg::PrimitiveSet::LINES, 0 );
			line->push_back( k );
			line->push_back( k+1 );
			geom->addPrimitiveSet( line );
		}
	}

	return geom;
}
void CSmokeTrailProjectile::Draw()
{
	inArray=true;
	float age=gs->frameNum+gu->timeOffset-creationTime;

	if(drawTrail){
		float3 dif(pos1-camera->pos2);
		dif.Normalize();
		float3 odir1(dif.cross(dir1));
		odir1.Normalize();
		float3 dif2(pos2-camera->pos2);
		dif2.Normalize();
		float3 odir2(dif2.cross(dir2));
		odir2.Normalize();

		unsigned char col[4];
		float a1=(1-float(age)/(lifeTime))*255;
		if(lastSegment)
			a1=0;
		a1*=0.7f+fabs(dif.dot(dir1));
		float alpha=min(255.f,max(0.f,a1));
		col[0]=(unsigned char) (color*alpha);
		col[1]=(unsigned char) (color*alpha);
		col[2]=(unsigned char) (color*alpha);
		col[3]=(unsigned char)alpha;

		unsigned char col2[4];
		float a2=(1-float(age+8)/(lifeTime))*255;
		if(firstSegment)
			a2=0;
		a2*=0.7f+fabs(dif2.dot(dir2));
		alpha=min(255.f,max(0.f,a2));
		col2[0]=(unsigned char) (color*alpha);
		col2[1]=(unsigned char) (color*alpha);
		col2[2]=(unsigned char) (color*alpha);
		col2[3]=(unsigned char)alpha;

		float size=1+(age*(1.0f/lifeTime))*orgSize;
		float size2=1+((age+8)*(1.0f/lifeTime))*orgSize;

		if(drawSegmented){
			float3 dif3(midpos-camera->pos2);
			dif3.Normalize();
			float3 odir3(dif3.cross(middir));
			odir3.Normalize();
			float size3=0.2f+((age+4)*(1.0f/lifeTime))*orgSize;

			unsigned char col3[4];
			float a2=(1-float(age+4)/(lifeTime))*255;
			a2*=0.7f+fabs(dif3.dot(middir));
			alpha=min(255.f,max(0.f,a2));
			col3[0]=(unsigned char) (color*alpha);
			col3[1]=(unsigned char) (color*alpha);
			col3[2]=(unsigned char) (color*alpha);
			col3[3]=(unsigned char)alpha;

			float midtexx = ph->smoketrailtex.xstart + (ph->smoketrailtex.xend - ph->smoketrailtex.xstart)*0.5f;

			va->AddVertexTC(pos1-odir1*size,ph->smoketrailtex.xstart,ph->smoketrailtex.ystart,col);
			va->AddVertexTC(pos1+odir1*size,ph->smoketrailtex.xstart,ph->smoketrailtex.yend,col);
			va->AddVertexTC(midpos+odir3*size3,midtexx,ph->smoketrailtex.yend,col3);
			va->AddVertexTC(midpos-odir3*size3,midtexx,ph->smoketrailtex.ystart,col3);

			va->AddVertexTC(midpos-odir3*size3,midtexx,ph->smoketrailtex.ystart,col3);
			va->AddVertexTC(midpos+odir3*size3,midtexx,ph->smoketrailtex.yend,col3);
			va->AddVertexTC(pos2+odir2*size2,ph->smoketrailtex.xend,ph->smoketrailtex.yend,col2);
			va->AddVertexTC(pos2-odir2*size2,ph->smoketrailtex.xend,ph->smoketrailtex.ystart,col2);
		} else {
			va->AddVertexTC(pos1-odir1*size,ph->smoketrailtex.xstart,ph->smoketrailtex.ystart,col);
			va->AddVertexTC(pos1+odir1*size,ph->smoketrailtex.xstart,ph->smoketrailtex.yend,col);
			va->AddVertexTC(pos2+odir2*size2,ph->smoketrailtex.xend,ph->smoketrailtex.yend,col2);
			va->AddVertexTC(pos2-odir2*size2,ph->smoketrailtex.xend,ph->smoketrailtex.ystart,col2);
		}
	} else {	//draw as particles
		unsigned char col[4];
		for(int a=0;a<8;++a){
			float a1=1-float(age+a)/lifeTime;
			float alpha=min(255.f,max(0.f,a1*255));
			col[0]=(unsigned char) (color*alpha);
			col[1]=(unsigned char) (color*alpha);
			col[2]=(unsigned char) (color*alpha);
			col[3]=(unsigned char)alpha;
			float size=((0.2f+(age+a)*(1.0f/lifeTime))*orgSize)*1.2f;

			float3 pos=CalcBeizer(a/8.0f,pos1,dirpos1,dirpos2,pos2);
			va->AddVertexTC(pos1+( camera->up+camera->right)*size, ph->smoketex[0].xstart, ph->smoketex[0].ystart, col);
			va->AddVertexTC(pos1+( camera->up-camera->right)*size, ph->smoketex[0].xend, ph->smoketex[0].ystart, col);
			va->AddVertexTC(pos1+(-camera->up-camera->right)*size, ph->smoketex[0].xend, ph->smoketex[0].ystart, col);
			va->AddVertexTC(pos1+(-camera->up+camera->right)*size, ph->smoketex[0].xstart, ph->smoketex[0].ystart, col);
		}
	}
	if(drawCallbacker)
		drawCallbacker->DrawCallback();
}