天天看點

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