OSG仿真案例(5)——创建火光、爆炸(碎片)

创建火光、爆炸(碎片)

所使用的头文件#include "Include_mymap.h"

#pragma once
#include <osgGA/CameraManipulator>
#include <osg/LineSegment>
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
#include <osg/Node>
#include <osg/Matrixd>
#include <osg/Matrix>
#include <osg/Material>
#include <osg/MatrixTransform>
#include <osg/Group>
#include <osg/Geometry>
#include <osg/Geode>
#include <osg/PositionAttitudeTransform>
#include <memory>
#include <osg/StateAttribute>
#include <osg/Point>
#include <osgDB/Registry>
#include <osgUtil/Optimizer>
#include <osgUtil/Simplifier>
#include <osgUtil/SmoothingVisitor>
#include <osgUtil/IntersectVisitor>
#include <osg/TextureCubeMap>
#include <osg/TexGen>
#include <osg/ShapeDrawable>

#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>
#include <osgGA/StateSetManipulator>
#include <osgDB/WriteFile>
#include <osgDB/ReadFile>
#include <osg/CullFace>
#include <osgParticle/PrecipitationEffect>
#include <osgParticle/ExplosionEffect>
#include <osgParticle/ExplosionDebrisEffect>
#include <osgParticle/FireEffect>
using namespace std;
using namespace osg;

#ifdef _DEBUG
#pragma comment(lib, "osgd.lib")
#pragma comment(lib, "osgDBd.lib")
#pragma comment(lib, "osgViewerd.lib")
#pragma comment(lib, "OpenThreadsd.lib")
#pragma comment(lib, "osgGAd.lib")
#pragma comment(lib, "osgUtild.lib")
#pragma comment(lib, "osgTextd.lib")
#pragma comment(lib, "osgWidgetd.lib") 
#pragma comment(lib, "glu32.lib") 
#pragma comment(lib, "opengl32.lib")
#else
#pragma comment(lib, "osg.lib")
#pragma comment(lib, "osgDB.lib")
#pragma comment(lib, "osgViewer.lib")
#pragma comment(lib, "OpenThreads.lib")
#pragma comment(lib, "osgGA.lib")
#pragma comment(lib, "osgUtil.lib")
#pragma comment(lib, "osgText.lib")
#pragma comment(lib, "osgWidget.lib")
#pragma comment(lib, "glu32.lib") 
#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "osgShadow.lib")
#pragma comment(lib, "osgAnimation.lib")
#pragma comment(lib, "osgParticle.lib")
#endif;

所使用的函数

#include <osgParticle/PrecipitationEffect>
#include <osgParticle/Particle>

#include <osgParticle/LinearInterpolator>
#include <osgParticle/ParticleSystem>
#include < osgParticle/RandomRateCounter>
#include <osgParticle/PointPlacer>
#include <osgParticle/RadialShooter>
#include <osgParticle/ModularEmitter>
#include <osgParticle/ParticleSystemUpdater>
#include < osgParticle/ModularProgram>
#include < osgParticle/FluidFrictionOperator>
#include < osgParticle/AccelOperator>
#include < osgParticle/MultiSegmentPlacer>
#include < osgParticle/BoxPlacer>
#include < osgParticle/ExplosionOperator>

void createExplosion(osg::ref_ptr<osg::MatrixTransform> explosion)
{
    // 创建粒子对象,设置其属性并交由粒子系统使用。
    osgParticle::Particle explosionTempalte;

    explosionTempalte.setShape(osgParticle::Particle::QUAD);
    explosionTempalte.setLifeTime(1.25);                                    // 单位:秒
    explosionTempalte.setSizeRange(osgParticle::rangef(3.0f, 300.0f));   // 单位:米
    explosionTempalte.setAlphaRange(osgParticle::rangef(1, 0));
    explosionTempalte.setColorRange(osgParticle::rangev4(osg::Vec4(1.0f, 0.2f, 0.0f, 1.0f),
        osg::Vec4(0.1f, 0.1f, 0.1f, 0)));
    explosionTempalte.setMass(2.0f);                                        //单位:千克
    explosionTempalte.setRadius(0.5f);

    explosionTempalte.setSizeInterpolator(new osgParticle::LinearInterpolator);
    explosionTempalte.setAlphaInterpolator(new osgParticle::LinearInterpolator);
    explosionTempalte.setColorInterpolator(new osgParticle::LinearInterpolator);


    // 创建并初始化粒子系统。
    osg::ref_ptr<osgParticle::ParticleSystem> explosionParticleSystem = new osgParticle::ParticleSystem;
    explosionParticleSystem->setDataVariance(osg::Node::DYNAMIC);

    // 设置为粒子系统的缺省粒子对象。
    explosionParticleSystem->setDefaultParticleTemplate(explosionTempalte);

    // 设置材质,是否放射粒子,以及是否使用光照。
    explosionParticleSystem->setDefaultAttributes("Texture/smoke.rgb", true, false);

    osg::ref_ptr<osg::Geode> geode = new osg::Geode;
    geode->addDrawable(explosionParticleSystem);
    explosion->addChild(geode);

    // 获取放射极中缺省计数器的句柄,调整每帧增加的新粒子数目
    osg::ref_ptr<osgParticle::RandomRateCounter> particleGenerateRate = new osgParticle::RandomRateCounter();

    // 每秒新生成的粒子范围
    particleGenerateRate->setDataVariance(osg::Node::DYNAMIC);
    particleGenerateRate->setRateRange(500, 600);


    // 自定义一个放置器,这里创建并初始化一个点放置器
    osg::ref_ptr<osgParticle::BoxPlacer> particlePlacer = new osgParticle::BoxPlacer;
    particlePlacer->setCenter(osg::Vec3(0.0f, 0.0f, 10.0f));
    particlePlacer->setXRange(-1, 1);
    particlePlacer->setYRange(-1, 1);
    particlePlacer->setZRange(0, 1);
    particlePlacer->setDataVariance(osg::Node::DYNAMIC);

    // 自定义一个弧度发射器
    osg::ref_ptr<osgParticle::RadialShooter> particleShooter = new osgParticle::RadialShooter;

    // 设置发射器的属性
    particleShooter->setDataVariance(osg::Node::DYNAMIC);

    // xy平面夹角
    particleShooter->setThetaRange(0.0f, osg::PI_2);

    // 弧度值,与Z 轴夹角
    //particleShooter->setPhiRange(osg::PI,-osg::PI);
    particleShooter->setInitialSpeedRange(10.0, 20.0f);                          //单位:米/秒

                                                                                 //创建标准放射极对
    osg::ref_ptr<osgParticle::ModularEmitter> emitter = new osgParticle::ModularEmitter;
    emitter->setDataVariance(osg::Node::DYNAMIC);
    emitter->setCullingActive(false);
    emitter->setStartTime(2);
    emitter->setLifeTime(1.3);
    emitter->setEndless(false);

    // 将放射极对象与粒子系统关联。
    emitter->setParticleSystem(explosionParticleSystem);
    // 设置计数器
    emitter->setCounter(particleGenerateRate);
    // 设置放置器
    emitter->setPlacer(particlePlacer);
    // 设置发射器
    emitter->setShooter(particleShooter);
    // 把放射极添加为变换节点
    explosion->addChild(emitter);
    // 添加更新器,以实现每帧的粒子管理。
    osg::ref_ptr<osgParticle::ParticleSystemUpdater> particleSystemUpdater = new osgParticle::ParticleSystemUpdater;
    // 将更新器与粒子系统对象关联。
    particleSystemUpdater->addParticleSystem(explosionParticleSystem);
    // 将更新器节点添加到场景中。
    explosion->addChild(particleSystemUpdater);

    // 创建标准编程器对象并与粒子系统相关联。
    osg::ref_ptr<osgParticle::ModularProgram> particleMoveProgram = new osgParticle::ModularProgram;
    particleMoveProgram->setParticleSystem(explosionParticleSystem);

    osg::ref_ptr<osgParticle::ExplosionOperator> operatorExplosion = new osgParticle::ExplosionOperator;
    operatorExplosion->setRadius(100.0f);
    operatorExplosion->setMagnitude(500.0f);
    operatorExplosion->setEpsilon(20.0f);
    operatorExplosion->setSigma(30.0);

    particleMoveProgram->addOperator(operatorExplosion);

    // 最后,将编程器添加到场景中。
    explosion->addChild(particleMoveProgram);
}

void createExplosionDebris(osg::ref_ptr<osg::MatrixTransform> explosionDebris,
    char* texture,
    float life,
    float minSize,
    float maxSize,
    float minNum,
    float maxNum,
    float minSpeed,
    float maxSpeed)
{
    // 创建粒子对象,设置其属性并交由粒子系统使用。
    osgParticle::Particle explosionDebrisTempalte;

    explosionDebrisTempalte.setShape(osgParticle::Particle::QUAD);
    explosionDebrisTempalte.setLifeTime(life);                                           // 单位:秒
    explosionDebrisTempalte.setSizeRange(osgParticle::rangef(minSize, maxSize));        // 单位:米
    explosionDebrisTempalte.setAlphaRange(osgParticle::rangef(1.0f, 1.0f));
    //      explosionDebrisTempalte.setColorRange(osgParticle::rangev4(osg::Vec4(0.5f, 0.5f, 0.0f, 1.0f),
    //          osg::Vec4(0.2f, 0.2f, 0.2f, 1.0f)));
    explosionDebrisTempalte.setMass(12.5f);                                               //单位:千克
    explosionDebrisTempalte.setRadius(0.33f);

    explosionDebrisTempalte.setSizeInterpolator(new osgParticle::LinearInterpolator);
    explosionDebrisTempalte.setAlphaInterpolator(new osgParticle::LinearInterpolator);
    explosionDebrisTempalte.setColorInterpolator(new osgParticle::LinearInterpolator);

    // 创建并初始化粒子系统。
    osg::ref_ptr<osgParticle::ParticleSystem> explosionDebrisParticleSystem = new osgParticle::ParticleSystem;

    explosionDebrisParticleSystem->setDataVariance(osg::Node::DYNAMIC);


    // 设置为粒子系统的缺省粒子对象。
    explosionDebrisParticleSystem->setDefaultParticleTemplate(explosionDebrisTempalte);


    // 设置材质,是否放射粒子,以及是否使用光照。
    explosionDebrisParticleSystem->setDefaultAttributes(texture, false, false);

    osg::ref_ptr<osg::Geode> geode = new osg::Geode;
    geode->addDrawable(explosionDebrisParticleSystem);
    explosionDebris->addChild(geode);

    // 获取放射极中缺省计数器的句柄,调整每帧增加的新粒子数目
    osg::ref_ptr<osgParticle::RandomRateCounter> particleDebrisGenerateRate = new osgParticle::RandomRateCounter();

    // 每秒新生成的粒子范围
    particleDebrisGenerateRate->setDataVariance(osg::Node::DYNAMIC);
    particleDebrisGenerateRate->setRateRange(minNum, maxNum);

    // 自定义一个放置器,这里创建并初始化一个点放置器
    osg::ref_ptr<osgParticle::BoxPlacer> particleDebrisPlacer = new osgParticle::BoxPlacer;
    particleDebrisPlacer->setCenter(osg::Vec3(0.0f, 0.0f, 10.0f));
    particleDebrisPlacer->setXRange(-1, 1);
    particleDebrisPlacer->setYRange(-1, 1);
    particleDebrisPlacer->setZRange(0, 1);
    particleDebrisPlacer->setDataVariance(osg::Node::DYNAMIC);

    // 自定义一个弧度发射器
    osg::ref_ptr<osgParticle::RadialShooter> particleDebrisShooter = new osgParticle::RadialShooter;

    // 设置发射器的属性
    particleDebrisShooter->setDataVariance(osg::Node::DYNAMIC);

    // xy平面夹角
    particleDebrisShooter->setThetaRange(0.0f, osg::PI_2);

    // 弧度值,与Z 轴夹角
    //particleShooter->setPhiRange(osg::PI,-osg::PI);
    particleDebrisShooter->setInitialSpeedRange(minSpeed, maxSpeed);                          //单位:米/秒

                                                                                              //创建标准放射极对
    osg::ref_ptr<osgParticle::ModularEmitter> emitterDebris = new osgParticle::ModularEmitter;

    emitterDebris->setDataVariance(osg::Node::DYNAMIC);
    emitterDebris->setCullingActive(false);
    emitterDebris->setStartTime(2.3);
    emitterDebris->setLifeTime(0.3);
    emitterDebris->setEndless(false);

    // 将放射极对象与粒子系统关联。
    emitterDebris->setParticleSystem(explosionDebrisParticleSystem);

    // 设置计数器
    emitterDebris->setCounter(particleDebrisGenerateRate);

    // 设置放置器
    emitterDebris->setPlacer(particleDebrisPlacer);

    // 设置发射器
    emitterDebris->setShooter(particleDebrisShooter);

    // 把放射极添加为变换节点
    explosionDebris->addChild(emitterDebris);

    // 添加更新器,以实现每帧的粒子管理。
    osg::ref_ptr<osgParticle::ParticleSystemUpdater> particleDebrisSystemUpdater = new osgParticle::ParticleSystemUpdater;

    // 将更新器节点添加到场景中。
    explosionDebris->addChild(particleDebrisSystemUpdater);

    // 将更新器与粒子系统对象关联。
    particleDebrisSystemUpdater->addParticleSystem(explosionDebrisParticleSystem);

    // 创建标准编程器对象并与粒子系统相关联。
    osg::ref_ptr<osgParticle::ModularProgram> particleDebrisMoveProgram = new osgParticle::ModularProgram;

    // 创建标准编程器对象并与粒子系统相关联。
    particleDebrisMoveProgram->setParticleSystem(explosionDebrisParticleSystem);

    // 设置碎片重力
    osg::ref_ptr<osgParticle::AccelOperator> op_gravity = new osgParticle::AccelOperator;
    op_gravity->setToGravity();
    particleDebrisMoveProgram->addOperator(op_gravity);

    // 设置空气阻力
    osg::ref_ptr<osgParticle::FluidFrictionOperator> op_fluid_air = new osgParticle::FluidFrictionOperator;
    op_fluid_air->setFluidToAir();
    particleDebrisMoveProgram->addOperator(op_fluid_air);

    // 最后,将编程器添加到场景中。
    explosionDebris->addChild(particleDebrisMoveProgram);
}
 
void createFireBall(osg::ref_ptr<osg::MatrixTransform> smokeNode)
{
    // 创建粒子对象,设置其属性并交由粒子系统使用。
    osgParticle::Particle particleTempalte;

    particleTempalte.setShape(osgParticle::Particle::QUAD);
    particleTempalte.setLifeTime(1.5);                             // 单位:秒
    particleTempalte.setSizeRange(osgParticle::rangef(3.0f, 1.0f));   // 单位:米
    particleTempalte.setAlphaRange(osgParticle::rangef(1, 0));
    particleTempalte.setColorRange(osgParticle::rangev4(osg::Vec4(1.0f, 0.2f, 0.0f, 1.0f),
        osg::Vec4(0.1f, 0.1f, 0.1f, 0)));

    particleTempalte.setPosition(osg::Vec3(0.0f, 0.0f, 0.0f));
    particleTempalte.setVelocity(osg::Vec3(0.0f, 0.0f, 0.0f));
    particleTempalte.setMass(0.1f);                               //单位:千克
    particleTempalte.setRadius(0.2f);

    particleTempalte.setSizeInterpolator(new osgParticle::LinearInterpolator);
    particleTempalte.setAlphaInterpolator(new osgParticle::LinearInterpolator);
    particleTempalte.setColorInterpolator(new osgParticle::LinearInterpolator);

    // 创建并初始化粒子系统。
    osg::ref_ptr<osgParticle::ParticleSystem> particleSystem = new osgParticle::ParticleSystem;
    particleSystem->setDataVariance(osg::Node::STATIC);

    // 设置材质,是否放射粒子,以及是否使用光照。
    particleSystem->setDefaultAttributes("Texture/smoke.rgb", true, false);

    osg::ref_ptr<osg::Geode> geode = new osg::Geode;
    geode->addDrawable(particleSystem);
    smokeNode->addChild(geode);

    //设置为粒子系统的缺省粒子对象。
    particleSystem->setDefaultParticleTemplate(particleTempalte);

    //获取放射极中缺省计数器的句柄,调整每帧增加的新粒子数目
    osg::ref_ptr<osgParticle::RandomRateCounter> particleGenerateRate = new osgParticle::RandomRateCounter();
    particleGenerateRate->setRateRange(100, 500);

    // 每秒新生成的粒子范围
    particleGenerateRate->setDataVariance(osg::Node::DYNAMIC);

    // 自定义一个放置器,这里创建并初始化一个点放置器
    osg::ref_ptr<osgParticle::BoxPlacer> particlePlacer = new osgParticle::BoxPlacer;
    particlePlacer->setCenter(osg::Vec3(0.0f, 0.0f, 0.0f));
    particlePlacer->setXRange(-1, 1);
    particlePlacer->setYRange(-1, 1);
    particlePlacer->setZRange(0, 1);
    particlePlacer->setDataVariance(osg::Node::DYNAMIC);

    // 自定义一个弧度发射器
    osg::ref_ptr<osgParticle::RadialShooter> particleShooter = new osgParticle::RadialShooter;

    // 设置发射器的属性
    particleShooter->setDataVariance(osg::Node::DYNAMIC);
    particleShooter->setThetaRange(0.0, osg::PI_4);

    // 弧度值,与Z 轴夹角
    //  particleShooter->setPhiRange(0.0f,osg::PI_2);
    particleShooter->setInitialSpeedRange(10.0f, 20.0f);                          //单位:米/秒

                                                                                  //创建标准放射极对象
    osg::ref_ptr<osgParticle::ModularEmitter> emitter = new osgParticle::ModularEmitter;
    emitter->setDataVariance(osg::Node::DYNAMIC);
    emitter->setCullingActive(false);
    emitter->setStartTime(0.3);

    // 将放射极对象与粒子系统关联。
    emitter->setParticleSystem(particleSystem);

    // 设置计数器
    emitter->setCounter(particleGenerateRate);

    // 设置放置器
    emitter->setPlacer(particlePlacer);

    // 设置发射器
    emitter->setShooter(particleShooter);

    // 把放射极添加为变换节点
    smokeNode->addChild(emitter);

    // 添加更新器,以实现每帧的粒子管理。
    osg::ref_ptr<osgParticle::ParticleSystemUpdater> particleSystemUpdater = new osgParticle::ParticleSystemUpdater;

    // 将更新器与粒子系统对象关联。
    particleSystemUpdater->addParticleSystem(particleSystem);

    // 将更新器节点添加到场景中。
    smokeNode->addChild(particleSystemUpdater);

    // 创建标准编程器对象并与粒子系统相关联。
    osg::ref_ptr<osgParticle::ModularProgram> particleMoveProgram = new osgParticle::ModularProgram;
    particleMoveProgram->setParticleSystem(particleSystem);

    // 最后,将编程器添加到场景中。
    smokeNode->addChild(particleMoveProgram);
}

火光效果

int ShowFire()
{
    osgViewer::Viewer viewer;
    osg::ref_ptr<osg::Group> root = new osg::Group();
    root->addChild(osgDB::readNodeFile("MySceneGrassAndStreet.osg"));  //草地
    osg::ref_ptr<osg::MatrixTransform> fireball = new osg::MatrixTransform();

    createFireBall(fireball);
    fireball->setMatrix(osg::Matrix::translate(0, 0, 0));//表示位置的移动(x,y,z)方便表示,向各自的方向移动x.y.z.的距离(比如(0, 0, 1)表示向z轴移动一个单位)
 
    root->addChild(fireball);

    osgUtil::Simplifier simplifier(0.3f, 4.0f);
    osgUtil::Optimizer optimzer;
    optimzer.optimize(root.get());
    viewer.setSceneData(root.get());

    //添加一个事件句柄 相当于添加一个响应 响应鼠标或是键盘 响应L键(控制灯光开关)
    viewer.addEventHandler(new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()));

    //窗口大小变化事件 添加窗口大小改变的句柄 这里响应的是F键
    viewer.addEventHandler(new osgViewer::WindowSizeHandler);

    //添加一些常用状态设置  添加常用的状态操作,这里会响应S键、W键等等 
    viewer.addEventHandler(new osgViewer::StatsHandler);

    viewer.realize();
    viewer.run();
    return 0;
}

爆炸(碎片)

int ShowExplosion()
{
    osgViewer::Viewer viewer;
    osg::ref_ptr<osg::Group> root = new osg::Group();
    root->addChild(osgDB::readNodeFile("MySceneGrassAndStreet.osg"));  //草地
    double size = 1.01;
    {
        osg::ref_ptr<osg::MatrixTransform> explosionball = new osg::MatrixTransform();
        createExplosion(explosionball);
        explosionball->setMatrix(osg::Matrix::translate(0, 0, 0));
        root->addChild(explosionball);
        explosionball->setMatrix(osg::Matrix::translate(0, 0, 0)*osg::Matrix::scale(size, size, size)* osg::Matrix::rotate(osg::inDegrees(0.0f), 0.0f, 0.0f, 1.0f));
    }   
    {
        //爆炸碎片
        float life_time;
        float min_size;
        float max_size;
        float min_num;
        float max_num;
        float min_speed;
        float max_speed;

        osg::ref_ptr<osg::MatrixTransform> explosionDebris = new osg::MatrixTransform();
        root->addChild(explosionDebris);

        life_time = -1.0f;
        min_size = (rand() % 3) + 2.0f;
        max_size = (rand() % 3) + 2.0f;
        min_num = (rand() % 10) + 10.0f;
        max_num = (rand() % 20) + 20.0f;
        min_speed = (rand() % 1000) + 1000.0f;
        max_speed = (rand() % 1000) + 2000.0f;
        createExplosionDebris(explosionDebris, "Texture/Debris1.sgi", life_time, min_size, max_size, min_num, max_num, min_speed, max_speed);
        createExplosionDebris(explosionDebris, "Texture/Debris2.sgi", life_time, min_size, max_size, min_num, max_num, min_speed, max_speed);
        createExplosionDebris(explosionDebris, "Texture/Debris3.sgi", life_time, min_size, max_size, min_num, max_num, min_speed, max_speed);
        createExplosionDebris(explosionDebris, "Texture/Debris4.sgi", life_time, min_size, max_size, min_num, max_num, min_speed, max_speed);
        createExplosionDebris(explosionDebris, "Texture/Debris5.sgi", life_time, min_size, max_size, min_num, max_num, min_speed, max_speed);
        createExplosionDebris(explosionDebris, "Texture/Debris6.sgi", life_time, min_size, max_size, min_num, max_num, min_speed, max_speed);
        createExplosionDebris(explosionDebris, "Texture/Debris7.sgi", life_time, min_size, max_size, min_num, max_num, min_speed, max_speed);
        createExplosionDebris(explosionDebris, "Texture/Debris8.sgi", life_time, min_size, max_size, min_num, max_num, min_speed, max_speed);
        createExplosionDebris(explosionDebris, "Texture/Debris9.sgi", life_time, min_size, max_size, min_num, max_num, min_speed, max_speed);
        createExplosionDebris(explosionDebris, "Texture/Debris10.sgi", life_time, min_size, max_size, min_num, max_num, min_speed, max_speed);
        explosionDebris->setMatrix(osg::Matrix::translate(0, 0, 0)*osg::Matrix::scale(size, size, size)* osg::Matrix::rotate(osg::inDegrees(0.0f), 0.0f, 0.0f, 1.0f));  
    }
    osgUtil::Simplifier simplifier(0.3f, 4.0f);
    osgUtil::Optimizer optimzer;
    optimzer.optimize(root.get());
    viewer.setSceneData(root.get());
    //添加一个事件句柄 相当于添加一个响应 响应鼠标或是键盘 响应L键(控制灯光开关)
    viewer.addEventHandler(new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()));
    //窗口大小变化事件 添加窗口大小改变的句柄 这里响应的是F键
    viewer.addEventHandler(new osgViewer::WindowSizeHandler);
    //添加一些常用状态设置  添加常用的状态操作,这里会响应S键、W键等等 
    viewer.addEventHandler(new osgViewer::StatsHandler);
    viewer.realize();
    viewer.run();
    return 0;
}

保存火光

int SaveOnleFire()
{
        osgViewer::Viewer viewer;
    osg::ref_ptr<osg::Group> root = new osg::Group();
    osg::ref_ptr<osg::MatrixTransform> fireball = new osg::MatrixTransform();

    createFireBall(fireball);
    fireball->setMatrix(osg::Matrix::translate(0, 0, 0));//表示位置的移动(x,y,z)方便表示,向各自的方向移动x.y.z.的距离(比如(0, 0, 1)表示向z轴移动一个单位)

    root->addChild(fireball);

    osgDB::writeNodeFile(*(root.get()), "MySceneaFire.osg");
    return 0;
}

保存爆炸效果

int SaveOnlyExplosion()
{
    osgViewer::Viewer viewer;
    osg::ref_ptr<osg::Group> root = new osg::Group();
    double size = 1.01;
    {
        osg::ref_ptr<osg::MatrixTransform> explosionball = new osg::MatrixTransform();
        createExplosion(explosionball);
        explosionball->setMatrix(osg::Matrix::translate(0, 0, 0));
        root->addChild(explosionball);
        explosionball->setMatrix(osg::Matrix::translate(0, 0, 0)*osg::Matrix::scale(size, size, size)* osg::Matrix::rotate(osg::inDegrees(0.0f), 0.0f, 0.0f, 1.0f));
    }
    {
        //爆炸碎片
        float life_time;
        float min_size;
        float max_size;
        float min_num;
        float max_num;
        float min_speed;
        float max_speed;

        osg::ref_ptr<osg::MatrixTransform> explosionDebris = new osg::MatrixTransform();
        root->addChild(explosionDebris);

        life_time = -1.0f;
        min_size = (rand() % 3) + 2.0f;
        max_size = (rand() % 3) + 2.0f;
        min_num = (rand() % 10) + 10.0f;
        max_num = (rand() % 20) + 20.0f;
        min_speed = (rand() % 1000) + 1000.0f;
        max_speed = (rand() % 1000) + 2000.0f;
        createExplosionDebris(explosionDebris, "Texture/Debris1.sgi", life_time, min_size, max_size, min_num, max_num, min_speed, max_speed);
        createExplosionDebris(explosionDebris, "Texture/Debris2.sgi", life_time, min_size, max_size, min_num, max_num, min_speed, max_speed);
        createExplosionDebris(explosionDebris, "Texture/Debris3.sgi", life_time, min_size, max_size, min_num, max_num, min_speed, max_speed);
        createExplosionDebris(explosionDebris, "Texture/Debris4.sgi", life_time, min_size, max_size, min_num, max_num, min_speed, max_speed);
        createExplosionDebris(explosionDebris, "Texture/Debris5.sgi", life_time, min_size, max_size, min_num, max_num, min_speed, max_speed);
        createExplosionDebris(explosionDebris, "Texture/Debris6.sgi", life_time, min_size, max_size, min_num, max_num, min_speed, max_speed);
        createExplosionDebris(explosionDebris, "Texture/Debris7.sgi", life_time, min_size, max_size, min_num, max_num, min_speed, max_speed);
        createExplosionDebris(explosionDebris, "Texture/Debris8.sgi", life_time, min_size, max_size, min_num, max_num, min_speed, max_speed);
        createExplosionDebris(explosionDebris, "Texture/Debris9.sgi", life_time, min_size, max_size, min_num, max_num, min_speed, max_speed);
        createExplosionDebris(explosionDebris, "Texture/Debris10.sgi", life_time, min_size, max_size, min_num, max_num, min_speed, max_speed);
        explosionDebris->setMatrix(osg::Matrix::translate(0, 0, 0)*osg::Matrix::scale(size, size, size)* osg::Matrix::rotate(osg::inDegrees(0.0f), 0.0f, 0.0f, 1.0f));
    }

    osgDB::writeNodeFile(*(root.get()), "MyScenea.osg");
    return 0;
}
  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

rexinx

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值