Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Recent
    • Tags
    • Users
    • Login

    Problem using GetVirtualObjects()

    Scheduled Pinned Locked Moved SDK Help
    7 Posts 0 Posters 559 Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • H Offline
      Helper
      last edited by

      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

      1 Reply Last reply Reply Quote 0
      • H Offline
        Helper
        last edited by

        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,

        1 Reply Last reply Reply Quote 0
        • H Offline
          Helper
          last edited by

          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.)

          1 Reply Last reply Reply Quote 0
          • H Offline
            Helper
            last edited by

            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 ?  
            
            1 Reply Last reply Reply Quote 0
            • H Offline
              Helper
              last edited by

              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.

              1 Reply Last reply Reply Quote 0
              • H Offline
                Helper
                last edited by

                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 ?

                1 Reply Last reply Reply Quote 0
                • H Offline
                  Helper
                  last edited by

                  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.

                  1 Reply Last reply Reply Quote 0
                  • First post
                    Last post