天天看点

osg demo22 conduit 喷泉效果

//Conduit.h
#pragma once

#include <osgViewer/Viewer>
#include <osg/Group>
#include <osg/Geode>
#include <osgParticle/Particle>
#include <osgParticle/PointPlacer>
#include <osgParticle/ParticleSystem>
#include <osgParticle/ParticleSystemUpdater>
#include <osgParticle/ModularProgram>
#include <osgParticle/ModularEmitter>
#include <osgParticle/RandomRateCounter>
#include <osgParticle/RadialShooter>
#include <osgParticle/AccelOperator>
#include <osgParticle/FluidFrictionOperator>



class  Conduit
{
public:
	Conduit(void);
	~Conduit(void);

	//创建喷泉
	osgParticle::ParticleSystem* CreateConduitScene(osg::Group* root);
	//粒子数目
	float m_fTheNum;
	//粒子大小
	float m_fTheSize;
	//粒子速度
	float m_fTheSpeech;
	//创建喷泉
	osg::Node* CreateConduit(osg::Group *root);
	//喷泉的具体位置
	osg::Vec3 m_VecPosition;
};
//***********************************************************************************************************************************************
//Conduit.cpp
           
#include "Conduit.h"




Conduit::Conduit(void):m_fTheNum(800),m_fTheSize(0.2),m_fTheSpeech(100)
{
	m_VecPosition.set(15,64,3);
}




Conduit::~Conduit(void)
{
}


osgParticle::ParticleSystem* Conduit::CreateConduitScene(osg::Group* root)
{
	osgParticle::Particle ptemplate;
	//生命周期为2,对喷泉已经够了
	ptemplate.setLifeTime(2);
	//设置图形变化范围
	ptemplate.setSizeRange(osgParticle::rangef(0.1f,0.1f));
	//设置透明度变化范围
	ptemplate.setAlphaRange(osgParticle::rangef(1.0f,0.5f));
	//设置颜色范围
	ptemplate.setColorRange(osgParticle::rangev4(
		osg::Vec4(0.7f,1.0f,1.0f,1.5f),
		osg::Vec4(0.8f,0.8f,1.0f,0.0f)
		));


	//设置半径
	ptemplate.setRadius(m_fTheSize);
	//设置重量
	ptemplate.setMass(0.05f);


	osgParticle::ParticleSystem *ps = new osgParticle::ParticleSystem;
	ps->setDefaultAttributes("Images/smoke.rgb",false,false);
	//加入模板
	ps->setDefaultParticleTemplate(ptemplate);
	//建立发射器,中包含发射枪,数目及位置设定
	osgParticle::ModularEmitter *emitter = new osgParticle::ModularEmitter;


	//加入模板及总属性
	emitter->setParticleSystem(ps);
	//数目变化
	osgParticle::RandomRateCounter *counter = new osgParticle::RandomRateCounter;
	//数目变化,当前场景中的粒子数目
	counter->setRateRange(m_fTheNum,m_fTheNum);
	//加入到发射器中
	emitter->setCounter(counter);
	//设置位置
	osgParticle::PointPlacer *placer = new osgParticle::PointPlacer;
	placer->setCenter(m_VecPosition);
	//加入发射器中
	emitter->setPlacer(placer);
	//设置发手枪,可以设置初速度等
	osgParticle::RadialShooter* shooter = new osgParticle::RadialShooter;
	//设置初速度
	shooter->setInitialSpeedRange(m_fTheSpeech,0);
	emitter->setShooter(shooter);


	root->addChild(emitter);


	//设置影响操作
	osgParticle::ModularProgram* program = new osgParticle::ModularProgram;
	program->setParticleSystem(ps);


	//速度操作
	osgParticle::AccelOperator *op1 = new osgParticle::AccelOperator;
	op1->setToGravity();
	program->addOperator(op1);


	osgParticle::FluidFrictionOperator *op3 = new osgParticle::FluidFrictionOperator;


	op3->setFluidToAir();


	program->addOperator(op3);


	root->addChild(program);


	osg::Geode *geode = new osg::Geode;


	geode->addDrawable(ps);
	root->addChild(geode);
	return ps;
}




osg::Node* Conduit::CreateConduit(osg::Group* root)
{
	osgParticle::ParticleSystem *ps2 =CreateConduitScene(root);


	osgParticle::ParticleSystemUpdater *psu = new osgParticle::ParticleSystemUpdater;
	
	psu->addParticleSystem(ps2);


	return psu;


}
           
//***********************************************************************************************************************************************
           
//main.cpp
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
#include "Conduit.h"


int main(int ,char**)
{
	osg::ref_ptr<osgViewer::Viewer>viewer = new osgViewer::Viewer();
	osg::Group* node = new osg::Group;
	//申请喷泉对象
	Conduit od;
	//设置位置
	od.m_VecPosition.set(0,0,0);
	//加入到场景当中,就开始喷了
	node->addChild(od.CreateConduit(node));
	viewer->setSceneData(node);
	viewer->realize();
	viewer->run();
	return 0;
}
           
osg