Question



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

    On 29/05/2010 at 20:52, xxxxxxxx wrote:

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

    ---------
    Okay,  so I have created the following within GetVirtualObjects() :

      
    BaseObject *Space::GetVirtualObjects(BaseObject* op, HierarchyHelp* hh)
      
    {
    	BaseDocument *doc = op->GetDocument();
    	
    	//DEFINE TEXTURE TAG
    	spaceTextTag = TextureTag::Alloc();
    	if (!spaceTextTag) return false;
      
    	//DEFINE MATERIAL
    	spaceMat = Material::Alloc();
    	if (!spaceMat) return false;
      
    	//DEFINE SHADER
    	starField = PluginShader::Alloc(1025338);
    	if (!starField) return FALSE;
      
    	//SET MATERIAL NAME
    	spaceMat->SetName("Space");
      
    	space->InsertTag(spaceTextTag,0);
    	spaceTextTag->SetMaterial(spaceMat);
    	
    	TextureTag* myTag = (TextureTag* )(space->GetFirstTag());
    	if (!myTag) return FALSE;
      
    	if (doc->GetFirstMaterial() && doc->GetFirstMaterial()->GetName() == "Space")
    	{
    		doc->GetFirstMaterial()->Remove();
    		doc->InsertMaterial(spaceMat, NULL, 1);
    	}
    	else
    	{
    		doc->InsertMaterial(spaceMat, NULL, 1);
    	}
      
    	//INSERT AND SETUP THE NOISE SHADER FOR THE DISPLACEMENT CHANNEL
    	spaceMat->InsertShader(starField, NULL);
    	spaceMat->GetDataInstance()->SetLink(MATERIAL_COLOR_SHADER,starField); 
    	
        return space;
      
    }
      
    
    

    The purpose of this is so that my object takes on the functions of the sky object without actually having to add a sky object as a child of my object.  The problem here is that because GetVirtualObjects is called over and over this setup continuously creates a new material in the material manager.  My question is how can I make it so it only creates one material and then does not create any more?  Or better yet, is there a way to add the material to my object (Space Object) and have it effect the virtual sky that is being created behind the scenes?

    Thanks,

    ~Shawn



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

    On 30/05/2010 at 08:17, xxxxxxxx wrote:

    It is not valid nor thread-safe to change the real scene in any way from within GetVirtualObjects! You have to find another way to accomplish this.



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

    On 30/05/2010 at 09:13, xxxxxxxx wrote:

    So would I use GetVirtualObjects to create the sky object?  Then do all of the material related things outside of GetVirtualObjects?

    Or am I wrong in using getvirtualobjects to create the sky object?

    I want my object to basically take on the role of a sky object.

    It would be more logical to me if I could add a material to my object and have that effect the hidden sky object.

    Any thoughts on how I could achieve this safely?

    ~Shawn



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

    On 31/05/2010 at 05:45, xxxxxxxx wrote:

    Materials have to be created outside of GetVirtualObjects(). The best place would be usally during the MSG_MENUPREPARE message. It's called after the menu entry for the object has been called. Create the sky object within GetVirtualObjects() and assign the material. It is also important to check if the object along with its material is copied across documents because the same material can not exist in two seperate documents. This is done through the MSG_MULTI_MARKMATERIALS message and its MarkMaterials structure.

    Here is complete example of such a generator. I have added some comments to make it easier to understand:

      
    class MySky : public ObjectData  
    {  
      public:  
          virtual Bool Init(GeListNode *node);  
          virtual Bool Read(GeListNode *node, HyperFile *hf, LONG level);  
          virtual Bool Write(GeListNode *node, HyperFile *hf);  
          virtual Bool CopyTo(NodeData *dest, GeListNode *snode, GeListNode *dnode, LONG flags, AliasTrans *trn);  
          virtual Bool Message(GeListNode *node, LONG type, void *data);  
          virtual BaseObject *GetVirtualObjects(BaseObject *op, HierarchyHelp *hh);  
      
          static NodeData *Alloc(void) { return gNew MySky; }  
      
          //the BaseLink containing the link to the material  
          //must be handled through CopyTo, Read, Write  
          AutoAlloc<BaseLink> matlink;  
    };  
      
      
    Bool MySky::Init(GeListNode *node)  
    {  
      if (!matlink) return FALSE;  
      
      return TRUE;  
    }  
      
    Bool MySky::Read(GeListNode *node, HyperFile *hf, LONG level)  
    {  
      return matlink->Read(hf);  
    }  
      
    Bool MySky::Write(GeListNode *node, HyperFile *hf)  
    {  
      return matlink->Write(hf);  
    }  
      
    Bool MySky::CopyTo(NodeData *dest, GeListNode *snode, GeListNode *dnode, LONG flags, AliasTrans *trn)  
    {  
      return matlink->CopyTo(((MySky* )dest)->matlink, flags, trn);  
    }  
      
    Bool MySky::Message(GeListNode *node, LONG type, void *data)  
    {  
      switch (type)  
      {  
          //create the material after the menu entry of the object has been called  
          //save the material pointer as BaseLink  
          case MSG_MENUPREPARE:  
              {  
                  BaseDocument *doc = (BaseDocument* )data;  
      
                  Material *mat = (Material* )matlink->GetLink(doc, Mmaterial);  
      
                  if (!mat)  
                  {  
                      mat = Material::Alloc();  
                      if (!mat) return FALSE;  
                      doc->InsertMaterial(mat, NULL, NULL);  
      
                      matlink->SetLink(mat);  
                  }  
              }  
              break;  
      
          //must be checked because CINEMA 4D can have several documents open  
          //objects and their materials can be copied across these docuemnts  
          //the MarkMaterials structure contains the old and new material  
          case MSG_MULTI_MARKMATERIALS:  
              {  
                  Material* mat;  
                  MarkMaterials* mm = (MarkMaterials* )data;  
                  BaseDocument* doc = GetDocument(node);  
      
                  if (mm)  
                  {  
                      mat = (Material* )matlink->GetLink(doc, Mmaterial);  
                      if (mat == mm->omat)   
                      {  
                          doc->StartUndo();  
                          doc->AddUndo(UNDO_CHANGE_SMALL, node);  
                          matlink->SetLink(mm->nmat);  
                          doc->EndUndo();  
                      }  
                  }  
                  else  
                  {  
                      mat = (Material* )matlink->GetLink(doc, Mmaterial);  
                      if (mat) mat->SetBit(BIT_MATMARK);  
                  }  
              }  
              break;  
      }  
      
      return TRUE;  
    }  
      
    BaseObject* MySky::GetVirtualObjects(BaseObject *op, HierarchyHelp *hh)  
    {  
      Bool dirty = op->CheckCache(hh) || op->IsDirty(DIRTY_DATA);  
      if (!dirty) return op->GetCache(hh);  
      
      BaseObject *sky = NULL;  
      TextureTag *ttag = NULL;  
        
      sky = BaseObject::Alloc(Osky);  
      if (!sky) goto Error;  
      
      //create the texture tag for the material  
      ttag = (TextureTag* )sky->MakeTag(Ttexture, NULL);  
      if (!ttag)    goto Error;  
      
      //set the material  
      ttag->SetMaterial((Material* )matlink->GetLink(hh->GetDocument(), Mmaterial));  
      
      return sky;  
      
    Error:  
      blDelete(sky);  
      blDelete(ttag);  
      return NULL;  
    }  
    

    cheers,
    Matthias



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

    On 31/05/2010 at 05:48, xxxxxxxx wrote:

    awesome Thanks Matthias..  you are still the man..    LOL   ~Shawn


Log in to reply