Problem using GetVirtualObjects()



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 15/06/2011 at 15:30, xxxxxxxx wrote:

    User Information:
    Cinema 4D Version:   R12 
    Platform:      
    Language(s) :     C++  ;

    ---------
    I have a problem when using GetVirtualObjects to generate geometry in the particle system I'm writing. The particles behave correctly, and I can display geometry by making an object the child of the emitter. Everything works fine and the objects move as intended until I stop the animation. At that point, the generated objects disappear from the screen.

    Here's the relevant code from GetVirtualObjects() :

      
    if(bc->GetBool(PARTICLES_EMITTER_GEOMETRY))   
    {   
         // generate geometry if required   
         BaseObject *orig = NULL, *sph1 = NULL;   
         Matrix genmx;   
      
         orig = op->GetDown();                                        // first child of the emitter   
         if(orig)   
         {   
              basenull = BaseObject::Alloc(Onull);               // create a null object to hold multiple copies of the generated object   
              if(basenull)   
              {   
                   for (i = 0; i < particleCount; i++)               // for each particle   
                   {   
                        if(pt[i].alive)                                   // if particle is still active   
                        {   
                             sph1 = static_cast<BaseObject*>(orig->GetClone(COPYFLAGS_0, NULL));          // clone the child object   
                             genmx = op->GetMg();                    // get the matrix of the emitter   
                             genmx.off = pt[i].off;                    // set the cloned object's location to the particle location   
                             sph1->SetMg(genmx);   
                             sph1->InsertUnderLast(basenull);     // insert it under the null object   
                        }   
                   }   
              }   
         }   
    }   
      
    if(bc->GetBool(PARTICLES_EMITTER_GEOMETRY) && basenull)   
    {   
         return basenull;     // return the object chain   
    }   
    else   
            return NULL;   
    

    As you can see, all I'm doing is clone the child object of the emitter for each particle to be displayed and return those clones from GetVirtualObjects(). This all works... until I stop the animation. All the clones then immediately disappear.

    Am I doing this right? I must be missing some vital step (or doing it completely the wrong way!).

    Many thanks,

    Steve



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 16/06/2011 at 01:31, xxxxxxxx wrote:

    Seems correct to me.
    When stopping the animation, you still see the particles, right ? But not the geometry ?
    Maybe because your particles are "not alive" anymore ?

    I'm also wondering why they got an "alive" attribute. Do you not free the particles when they die, so they are kept but nothing is done with them ?!

    Cheers,



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 16/06/2011 at 03:42, xxxxxxxx wrote:

    Originally posted by xxxxxxxx

    Seems correct to me.
    When stoppting the animation, you still see the particles, right ? But not the geometry ...
    Maybe because you particles are "not alive" anymore ?

    That's correct. The particles are still alive and if I start the animation again from the paused frame, the geometry reappears.

    Thinking about it some more, what I'm doing is ensuring that GetVirtualObjects only does its thing once per frame. This is to ensure that particles are not generated multiple times per frame. The geometry is only being generated once per frame also. My assumption - which I think must be incorrect - is that for any frame the geometry, once displayed on screen, would remain visible until the next frame was drawn. However, it looks as if the geometry doesn't "persist" (the only way I can put it) and therefore disappears as soon a screen redraw takes place.

    (The 'alive' attribute is there to govern whether the particle is displayed or not. There's a reason I need that in the further development work I want to do with this. It doesn't necessarily mean the particle is dead forever.)



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 16/06/2011 at 03:58, xxxxxxxx wrote:

    I think I see the error. ;-)

    else   
        
        
                return NULL;
    
    You return NULL ! Return the old cache here :)  
    Or better, see below, do ever return basenull.  
      
    >  
    

    (The 'alive' attribute is there to govern whether the particle is
    displayed or not. There's a reason I need that in the further
    development work I want to do with this. It doesn't necessarily mean the
    particle is dead forever.)

    Okei ;D Just thought, it would be pretty inperformant to leave the dead particles in the memory. ^^  
      
    >__Originally posted by xxxxxxxx__
    

    Thinking about it some more, what I'm doing is ensuring that GetVirtualObjects only does its thing once per frame

    Uhm, yes once per frame. There was a thread some time ago about executing once per frame in an ObjectData plugin, right ?  
    But this is just important for the calculation, so the Calculation of the particles shouldm only be done once per frame.  
    But getting the Geometry for the particles should be done whenever cinema 4d wants to refresh your object.  
    So, GetVirtualObjects() should ever return a rebuilt version of the Geometry. Why else should Cinema 4D Ask for a new Cache ?  
    


  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 16/06/2011 at 04:07, xxxxxxxx wrote:

    It isn't the 'return NULL' statement. That only gets returned if no geometry is to be generated at all (i.e the user turned it off or there's no child object of the emitter).

    I think it must be the 'once per frame' thing but I haven't tried it yet.



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 16/06/2011 at 05:51, xxxxxxxx wrote:

    But, where do you check if it was already executed in the current Frame ?
    In GetVirtualObjects() ? If yes, what do you return if it did already calculate ?



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 16/06/2011 at 06:07, xxxxxxxx wrote:

    It's working now, what I was doing was only generating geometry when GetVirtualObjects was first called in a new frame. That works fine for the particle calculation but not for geometry (which I should have realised).

    Returning the geometry whenever requested now works fine.

    Thanks for your comments, they're much appreciated as it's helped to clarify my thinking on this.


Log in to reply