Sign in to follow this  

Particle System returning wrong reference to emitter

This topic is 4854 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Particle System returning wrong reference to emitter… Here is my problem, I just set my self up a nifty particle system…please read.. Class Particle; //actual particles Class Emitter; //contains, emits, and updates its own particles Class Particle_System; //contains and updates particle emitters, emitters are handled with a STL vector I have function in Particle_System that returns a reference of a newly created Particle_Emitter: Particle_Emitter *CreateEmitterFromFile(char *in_file); Now, in the game engine I declare to particle_emitter pointers: Particle_Emitter *emitter_0; Particle_Emitter *emitter_1; Now when I call the CreateFromFile function on both of those, I don’t get any problems, other than it might be returning incorrect reference.(keep in mind that both emitters are created from the same file) Then I call a function that emits particles from the particle_emitter: Vector pos(0.0, 0.0, 0.0); Vector vel(0.0, -9.0, 0.0); Vector frc(0.0, 0.0, 0.0); emitter_0->Emit(pos, vel, frc); Vector pos2(0.0, 0.0, 0.0); Vector vel2(0.0, -9.0, 0.0); emitter_0->Emit(pos2 ve2l, frc); The problem? – When I try to update them through the particle_system only the last particle_emitter gets updated CORRECTLY ( the other one gets updated, but its particles don’t move ) sometimes only the last emitter’s particles draw. I Need My Code? – Simplified Particle
class Particle{
    public:
    bool active;
    bool stationary;
    
    float max_life;
    float cur_life;
    float cur_alpha;
    
    Vector pos;
    Vector frc;
    Vector vel;
    
    bool Activate(Vector _pos, Vector _vel, Vector _frc, float _max_life, bool _stationary);
    void Deactivate();
    void Update(float spf);
    void Draw();
};

/*those functions are pretty much self explanitory and work correctly*/

Particle_Emitter
class Particle_Emitter{
    public:
    int max_particles;
    int index;  //emitter index used by particle_system
    
    float size; //particel diameter from left to right
    float max_life;
    float respawn_time; //time between each particle release
    float time_since_last_release; //self-explanitory
    
    bool stationary;
    
    Particle *particle;
    
    Texture texture;
    
    void Emit(Vector pos, Vector vel, Vector frc);
    void Update(float spf);
    void Draw();
    bool CreateFromFile(char *in_file_path);
    void Destroy();
};

////////////////FUNCTIONS//////////////

void Particle_Emitter::Emit(Vector pos, Vector vel, Vector frc){
    if(time_since_last_release > respawn_time){
        time_since_last_release = 0.0;
        for(int i=0; i<max_particles; i++){
            if(particle[i].Activate(pos, vel, frc, max_life, stationary) == true){
                i = max_particles;  //break out of loop
            }
        }
    }
}

void Particle_Emitter::Update(float spf){
    time_since_last_release += spf; 
    for(int i=0; i<max_particles; i++){
        particle[i].Update(spf);
    }
}

void Particle_Emitter::Draw(){
    texture.Bind();
    glPushMatrix();
    glScalef(size, size, size);
    
    glBegin(GL_QUADS);
    for(int i=0; i<max_particles; i++){
        particle[i].Draw();
    }
    glEnd();
    glPopMatrix();
}

bool Particle_Emitter::CreateFromFile(char *in_file_path){
    FILE * in_file = fopen(in_file_path, "rt");
    char tex_path[100];
    //char b;
    if(in_file == NULL){
        return false;
    }
    
    fscanf(in_file, "%d", &max_particles);
    fscanf(in_file, "%f", &size);
    fscanf(in_file, "%f", &max_life);
    fscanf(in_file, "%f", &respawn_time);
    fscanf(in_file, "%i", &stationary);
    fscanf(in_file, "%s", &tex_path);
    /*if(b == 0){
        stationary = false;
    }
    else{
        stationary = true;
    }*/
    fclose(in_file);
    texture.Load(tex_path);
    particle = new(Particle[max_particles]);
    
    return true;
}

void Particle_Emitter::Destroy(){
    delete[] particle;
    //particle = NULL;
}

Particle_System
class Particle_System{
    public:
    int num_emitters;            //current amount of emitters
    int num_created_emitters;   //total number of emitter ever created
    vector<Particle_Emitter> emitter;
    
    Particle_Emitter *CreateEmitterFromFile(char *in_file_path);
    
    void Activate();
    void Deactivate();
    void DestroyEmitter(int emitter_index);
    void Update(float spf);
    void Draw();
};

/////////////////////FUNCTIONS/////////////////////

///THE ONE THAT MIGHT BE BROKEN////////////////////

Particle_Emitter *Particle_System::CreateEmitterFromFile(char *in_file_path){
    Particle_Emitter temp_emitter;
    if(temp_emitter.CreateFromFile(in_file_path) == false){
        //temp_emitter = NULL;
        return NULL;//temp_emitter;
    }
    
    temp_emitter.index = num_created_emitters;
    
    emitter.push_back(temp_emitter);
    temp_emitter.Destroy();
    num_emitters++;
    num_created_emitters++;
    
    return &emitter.at(num_emitters - 1);
}

void Particle_System::Activate(){
    num_emitters = 0;
    num_created_emitters = 0;
}

void Particle_System::Deactivate(){
   /* for(int i=0; i<num_emitters; i++){
        emitter[i].Destroy();
    }*/
};

void Particle_System::DestroyEmitter(int emitter_index){
    for(int i=0; i<num_emitters; i++){
        if(emitter[i].index == emitter_index){
            emitter.erase(emitter.begin() + i);
            num_emitters--;
            i = num_emitters;
        }
    }
}

void Particle_System::Update(float spf){
    for(int i=0; i<num_emitters; i++){
        emitter.at(i).Update(spf);
    }
}

void Particle_System::Draw(){
    float modelview[16];
    int i,j;
    glPushMatrix();

    glGetFloatv(GL_MODELVIEW_MATRIX , modelview);

    for( i=0; i<3; i++ ){ 
	   for( j=0; j<3; j++ ) {
		  if ( i==j )
			 modelview[i*4+j] = 1.0;
		  else
			 modelview[i*4+j] = 0.0;
	   }
    }
    
    glLoadMatrixf(modelview);

    for(i=0; i<num_emitters; i++){
        emitter[i].Draw();
    }

    glPopMatrix();
}


This is the first time that I’ve ever used pointers or references like that, and I don’t know if by having emitter be handled by an ‘STL vector’ is causing a problem. I’ve tried so many different pointer/reference combinations to try and fix the problem and I think I narrowed it down to the function Particle_Emitter *CreatFromFile(char *in_file) in the process, Help is appreciated!

Share this post


Link to post
Share on other sites
When you destroy the temporary emitter temp_emitter it destroys also the particles it has pointers to. When a copy is made of temp_emitter it copies the pointers to particles. It does NOT copy the particles. So you have pointers to particles which are already destroyed. Code works only partially because particles (objects) are still in memory but maybe overwritten at any moment (probably by new particles you create).

Share this post


Link to post
Share on other sites
so should i call CreateFromFile from the 'STl vector' emitter after i add the temp emitter?

eg;


Particle_Emitter temp_emitter;
emmiter.push_back(temp_emitter);

emitter.at(index_of_newly_created_emitter).CreateFromFile(blah);

Share this post


Link to post
Share on other sites

This topic is 4854 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this