Wrong Particle Effect

I use the code below to implement the “steam” particle, however, the steam can not rise along the Z axis. What is wrong? :blush:

PandaFramework framework;
NodePath camera,render;
TexturePool*  myTexturePool = TexturePool::get_global_ptr();
PT(AsyncTaskManager) taskMgr = AsyncTaskManager::get_global_ptr();
PT(ClockObject) globalClock = ClockObject::get_global_clock();
ParticleSystemManager* particleMgr;
PhysicsManager* physicsMgr;

AsyncTask::DoneStatus particleTask(GenericAsyncTask* task, void* data) {
    double dt = globalClock->get_dt();
    particleMgr->do_particles(dt);
    physicsMgr->do_physics(dt);

    return AsyncTask::DS_cont;
}

int main(int argc, char *argv[]) {
    framework.open_framework(argc, argv);
    framework.set_window_title("Particle");
    WindowFramework *window = framework.open_window();
    if (window != (WindowFramework *)NULL) {

        window->enable_keyboard();
        window->setup_trackball();

        camera = window->get_camera_group();
        render = window->get_render();

        particleMgr = new ParticleSystemManager();
        physicsMgr = new PhysicsManager();
        PT(LinearEulerIntegrator) lIntegrator = new LinearEulerIntegrator();
        PT(AngularEulerIntegrator) aIntegrator = new AngularEulerIntegrator();
        physicsMgr->attach_linear_integrator(lIntegrator);
        physicsMgr->attach_angular_integrator(aIntegrator);

        PT(ParticleSystem) particle = new ParticleSystem(10000);

        //set PhysicalNode & ForceNode
        PT(PhysicalNode) physics = new PhysicalNode("physics");
        PT(ForceNode) forceGroup = new ForceNode("force");
        NodePath physicsNP = NodePath(physics);
        NodePath forceNP = NodePath(forceGroup);
        particle->set_render_parent(physics);
        physics->add_physical(particle);

        particle->get_render_parent().set_pos(0.0,0.0,0.0);
        particle->get_render_parent().set_hpr(0.0,0.0,0.0);
        particle->get_render_parent().set_scale(1.000, 1.000, 1.000);

        //Particles parameters
        PT(PointParticleFactory) factory = new PointParticleFactory();
        PT(SpriteParticleRenderer) particleRender = new SpriteParticleRenderer();
        PT(DiscEmitter) emitter = new DiscEmitter();

        particle->set_factory(factory);
        particle->set_renderer(particleRender);
        particle->set_emitter(emitter);

        particle->set_birth_rate(0.25);
        particle->set_litter_size(20);
        particle->set_litter_spread(0);
        particle->set_system_lifespan(0.0);
        particle->set_local_velocity_flag(true);
        particle->set_system_grows_older_flag(false);

        //Factory parameters
        factory->set_lifespan_base(0.1);
        factory->set_lifespan_spread(0.0);
        factory->set_mass_base(1.0);
        factory->set_mass_spread(0.0);
        factory->set_terminal_velocity_base(400.0);
        factory->set_terminal_velocity_spread(0.0);

        //Renderer parameters
        particleRender->set_alpha_mode(BaseParticleRenderer::PR_ALPHA_OUT);
        particleRender->set_user_alpha(0.10);

        //Sprite parameters
        PT(Texture) texture;
        texture = myTexturePool->load_texture("steam.png");
        particleRender->set_texture(texture);
        particleRender->set_color(Colorf(1.00, 0.00, 0.00, 1.00));
        particleRender->set_x_scale_flag(true);
        particleRender->set_y_scale_flag(true);
        particleRender->set_anim_angle_flag(false);
        particleRender->set_initial_x_scale(0.0025);
        particleRender->set_final_x_scale(0.0025000);
        particleRender->set_initial_y_scale(0.0025);
        particleRender->set_final_y_scale(0.0025000);
        particleRender->set_nonanimated_theta(0.0);
        particleRender->set_alpha_blend_method(BaseParticleRenderer::PP_NO_BLEND);
        particleRender->set_alpha_disable(false);

        //Emitter parameters
        emitter->set_emission_type(BaseParticleEmitter::ET_EXPLICIT);
        emitter->set_amplitude(1.0);
        emitter->set_amplitude_spread(0.75);
        emitter->set_offset_force(LVector3f(0.0000, 0.0000, 1.0000));
        emitter->set_explicit_launch_vector(LVector3f(0.0000, 0.0000, 0.0000));
        emitter->set_radiate_origin(LPoint3f(0.0000, 0.0000, 0.0000));
        emitter->set_radius(0.5);

        PT(LinearVectorForce) offset = new LinearVectorForce(emitter->get_offset_force());
        PT(LinearNoiseForce) noise = new LinearNoiseForce(0.1500);

        offset->set_vector_masks(false,false,true);
        noise->set_vector_masks(true,true,false);

        offset->set_active(true);
        noise->set_active(true);

        particle->add_linear_force(offset);
        particle->add_linear_force(noise);

        forceGroup->add_force(offset);
        forceGroup->add_force(noise);

        forceNP.reparent_to(render);

        physicsMgr->attach_physical(particle);
        particleMgr->attach_particlesystem(particle);

        particle->get_render_parent().reparent_to(render);

        taskMgr->add(new GenericAsyncTask("generates the particle", &particleTask, (void*) NULL));

        Thread *current_thread = Thread::get_current_thread();
        while(framework.do_frame(current_thread)) {
               CIntervalManager::get_global_ptr()->step();
        }
    } else {
    	nout << "Could not load the window!\n";
    }
    framework.close_all_windows();
    framework.close_framework();
    return (0);
}

Perhaps it’s due to your choice of the DiscEmitter, which sends particles out from a point within a plane?

David

I have tried to replace DiskEmitter with SphereVolumeEmitter and SphereSurfaceEmitter, they only send particles within the sphere.

By the way, I found these parameters from the “steam” PTF.

In that PTF, it uses DiskEmitter and works well.

What is wrong with C++ code? :blush:

Ah, you’re right, my apologies. The DiscEmitter works because the steam.ptf applies an offset_force along the Z axis, which is perpendicular to the disc. (The same thing would work with the SphereVolumeEmitter or SphereSurfaceEmitter.)

I see that you are attempting to add an explicit LinearVectorForce to apply the offset_force. This isn’t necessary; it will be applied automatically.

The problem in your case is the factory lifespan. You have:

factory->set_lifespan_base(0.1);

while the steam.ptf sets this value to 8. Your particles are immediately dying before they get a chance to move anywhere. :slight_smile:

David

Oh, it is my careless mistake.

It works now, thank you!!! :smiley: