Creating Spheres



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

    On 12/11/2009 at 09:23, xxxxxxxx wrote:

    Does anyone see any problems that would cause C4D to crash in my code?

    Thanks,

    ~Shawn



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

    On 12/11/2009 at 11:43, xxxxxxxx wrote:

    I'd do it this way. Note the allocation checks, checks for existence, and the check for 'doc' before doc->StartUndo(). Also, not sure if this is your intention, but once you remove the objects from the document, if they are no longer necessary, you still need to free them - otherwise subsequent allocations into those pointers will leave unfreed/unreferenced objects in memory!

    Unfortunately, this is one reason that I don't have a great love of C/C++ - the programmer takes control of all memory management as well as tracking pointer validation.

    /////////////////////////////////////////////////////////////   
    // Planet   
      
    #include "c4d.h"   
    #include "c4d_symbols.h"   
    #include "oplanet.h"   
    #include "c4d_basetag.h"   
    #include "c4d_basematerial.h"   
      
    // be sure to use a unique ID obtained from www.plugincafe.com   
    #define ID_PLANET_OBJECT 1024532   
      
    class Planet : public ObjectData   
    {   
         public:   
              virtual Bool Init(GeListNode *node);   
              virtual Bool GetDEnabling(GeListNode *node, const DescID &id;,GeData &t;_data,LONG flags,const BaseContainer *itemdesc);   
              virtual Bool Message(GeListNode *node, LONG type, void *t_data);   
              Bool CreatePlanet(DescriptionCommand* dc, BaseObject* op);   
              Bool UpdatePlanet(DescriptionCommand* dc, BaseObject* op);   
              static NodeData *Alloc(void) { return gNew Planet;}   
      
              TextureTag* surfaceTextTag;   
              TextureTag* cloudsTextTag;   
              TextureTag* atmTextTag;   
              BaseObject* surface;   
              Material* surfaceMat;   
              BaseObject* clouds;   
              Material* cloudsMat;   
              BaseObject* atmosphere;   
              Material* atmosphereMat;   
              Bool planetCreated;   
              LONG test;   
    };   
      
    // initialize settings   
    Bool Planet::Init(GeListNode *node)   
    {   
         //Called when a new instance of the node plugin has been allocated. You can use this function to for example fill the BaseContainer of the connected node with default values:   
         BaseContainer* bc = ((BaseObject* )node)->GetDataInstance();   
         if (!bc)     return false;   
         bc->SetBool(ENABLE_CRATERS, TRUE);   
         bc->SetBool(ENABLE_ATMOSPHERE, TRUE);   
         bc->SetBool(HAS_RINGS, FALSE);   
         planetCreated = FALSE;   
         test = 0;   
         return TRUE;   
    }   
    Bool Planet::GetDEnabling(GeListNode *node, const DescID &id;,GeData &t;_data,LONG flags,const BaseContainer *itemdesc)   
    {        
         // Enable/disable our parameters   
         BaseContainer *bc=((BaseList2D* )node)->GetDataInstance();   
         BaseObject* op = static_cast<BaseTag*>(node)->GetObject();   
         if (!op)          return FALSE;   
         switch (id[0].id)   
         {   
              case SURFACE_PRESETS:   
                   return bc->GetBool(USE_PRESET);   
              case CRATER_AMOUNT:   
                   if (bc->GetBool(ENABLE_CRATERS)&&!bc->GetBool(USE_PRESET))     return TRUE;   
              case CRATER_SIZE:   
                   if (bc->GetBool(ENABLE_CRATERS)&&!bc->GetBool(USE_PRESET))     return TRUE;   
              case SURFACE_MAP:   
                   return !bc->GetBool(USE_PRESET);   
              case ELEVATION_MAP:   
                   return !bc->GetBool(USE_PRESET);   
              case ELEVATION_STRENGTH:   
                   return !bc->GetBool(USE_PRESET);   
              case ENABLE_CRATERS:   
                   return !bc->GetBool(USE_PRESET);   
              case CLOUD_MAP:   
                   return !bc->GetBool(USE_PRESET2);   
              case CLOUD_BRIGHTNESS:   
                   return !bc->GetBool(USE_PRESET2);   
              case CLOUD_THICKNESS:   
                   return !bc->GetBool(USE_PRESET2);   
              case CLOUD_PRESETS:   
                   return bc->GetBool(USE_PRESET2);   
              case ATMOSPHERIC_COLOR:   
                   return bc->GetBool(ENABLE_ATMOSPHERE);   
              case ATMOSPHERIC_BRIGHTNESS:   
                   return bc->GetBool(ENABLE_ATMOSPHERE);   
              case ATMOSPHERIC_GLOW:   
                   return bc->GetBool(ENABLE_ATMOSPHERE);   
              case RING_COLOR:   
                   return bc->GetBool(HAS_RINGS);   
              case CREATE_PLANET:   
                   return !planetCreated;   
         }   
         return TRUE;   
    }   
    Bool Planet::Message(GeListNode *node, LONG type, void *t_data)   
    {        
         if (!node)     return FALSE;   
         if (type == MSG_DESCRIPTION_COMMAND)   
              return CreatePlanet(static_cast<DescriptionCommand*>(t_data), static_cast<BaseObject*>(node));   
         if (type == MSG_DESCRIPTION_CHECKUPDATE)   
              return UpdatePlanet(static_cast<DescriptionCommand*>(t_data), static_cast<BaseObject*>(node));   
         return TRUE;   
    }   
    Bool Planet::CreatePlanet(DescriptionCommand* dc, BaseObject* op)   
    {   
         if (!dc)      return TRUE;   
         if (!op)      return FALSE;   
         LONG id =     dc->id[0].id;   
      
         //declarations   
         surfaceTextTag = TextureTag::Alloc();   
         if (!surfaceTextTag)     return FALSE;   
         cloudsTextTag = TextureTag::Alloc();   
         if (!cloudsTextTag)     return FALSE;   
         atmTextTag = TextureTag::Alloc();   
         if (!atmTextTag)     return FALSE;   
         atmosphere = BaseObject::Alloc(Osphere);   
         if (!atmosphere)     return FALSE;   
         atmosphereMat = Material::Alloc();   
         if (!atmosphereMat)     return FALSE;   
         clouds = BaseObject::Alloc(Osphere);   
         if (!clouds)     return FALSE;   
         cloudsMat = Material::Alloc();   
         if (!cloudsMat)     return FALSE;   
         surface = BaseObject::Alloc(Osphere);   
         if (!surface)     return FALSE;   
         surfaceMat = Material::Alloc();   
         if (!surfaceMat)     return FALSE;   
         BaseDocument* doc = op->GetDocument();   
         if (!doc)     return FALSE;   
         doc->StartUndo();   
      
         BaseObject* prnt = doc->GetActiveObject();   
         BaseTag* tp = BaseTag::Alloc(Tphong);   
         if (!tp)          return FALSE;   
         //If Create Planet button is pressed...   
         if (id == CREATE_PLANET)   
         {   
              /////////create the atmosphere sphere//////////////////////////////////////////////////////   
              atmosphere->SetName("Atmosphere");        
              atmosphereMat->SetName ("Atmosphere");   
              atmosphere->SetParameter(PRIM_SPHERE_RAD,200.8,NULL);   
              /////////create and insert the clouds sphere///////////////////////////////////////////////   
              clouds->SetName("Clouds");   
              cloudsMat->SetName ("Clouds");   
              clouds->SetParameter(PRIM_SPHERE_RAD,200.4,NULL);   
              clouds->InsertTag(tp,0);//phong tag   
              clouds->InsertTag(cloudsTextTag,0);   
              cloudsTextTag->SetMaterial(cloudsMat);   
              doc->InsertMaterial(cloudsMat,NULL,TRUE);   
              if (clouds) doc->InsertObject(clouds, prnt, NULL, FALSE);   
              GePrint("Clouds Created");   
              /////////create and insert the surface sphere///////////////////////////////////////////////   
              surface->SetName("Surface");   
              surfaceMat->SetName ("Surface");   
              surface->SetParameter(PRIM_SPHERE_RAD,200,NULL);   
              surface->InsertTag(tp,0);//phong tag   
              surface->InsertTag(surfaceTextTag,0);   
              surfaceTextTag->SetMaterial(surfaceMat);   
              doc->InsertMaterial(surfaceMat,NULL,TRUE);   
              if (surface) doc->InsertObject(surface, prnt, NULL, FALSE);   
              GePrint("Surface Created");   
              //A planet was created   
              planetCreated = TRUE;   
              doc->EndUndo();   
         }   
         return TRUE;   
    }   
    Bool Planet::UpdatePlanet(DescriptionCommand* dc, BaseObject* op)   
    {   
         if (!dc) return TRUE;   
         if (!op) return FALSE;   
            
         BaseDocument* doc = op->GetDocument();   
         if (!doc)     return FALSE;   
         doc->StartUndo();   
         BaseObject* prnt = doc->GetActiveObject();   
         BaseTag* tp = BaseTag::Alloc(Tphong);   
         if (!tp)     return FALSE;   
         //Enable-Disable Atmosphere/////////////////////////////////////////////////////////   
         if (op->GetDataInstance()->GetBool(ENABLE_ATMOSPHERE)==TRUE)   
         {   
              if (atmTextTag)   
              {   
                   if (atmosphere)     atmosphere->InsertTag(atmTextTag,0);   
                   atmTextTag->SetMaterial(atmosphereMat);   
              }   
              if (atmosphereMat)   
              {   
                   doc->InsertMaterial(atmosphereMat,NULL,TRUE);   
                   atmosphereMat->SetChannelState(CHANNEL_TRANSPARENCY,TRUE);   
                   atmosphereMat->SetChannelState(CHANNEL_GLOW,TRUE);   
                   atmosphereMat->Update(TRUE,TRUE);   
              }   
              if (atmosphere)   
              {   
                   atmosphere->InsertTag(tp,0); //phong tag   
                   doc->InsertObject(atmosphere, prnt, NULL, FALSE);   
              }   
              GePrint("Atmosphere Created");   
              GePrint("Atmosphere Enabled");   
         }   
         else   
         {   
              if (atmosphere) atmosphere->Remove();   
              if (atmosphereMat)   
              {   
                   atmosphereMat->SetChannelState(CHANNEL_GLOW,FALSE);   
                   GePrint("Atmosphere Disabled");   
                   atmosphereMat->Remove();   
              }   
              if (atmTextTag) atmTextTag->Remove();   
         }   
         /////////////////////////////////////////////////////////////////////////////////////   
         if (atmosphereMat)     atmosphereMat->SetParameter(MATERIAL_GLOW_OUTERSTRENGTH,op->GetDataInstance()->GetReal(ATMOSPHERIC_BRIGHTNESS),NULL);   
         return TRUE;   
    }   
    Bool RegisterPlanet(void)   
    {   
          // decide by name if the plugin shall be registered - just for user convenience   
          GePrint("-----------------------------------------------------------------------------------------");   
          GePrint("Planet X Generator 1.0 - Copyright 2009 - Shawn Foster");   
          GePrint("-----------------------------------------------------------------------------------------");   
          String name=GeLoadString(IDS_PLANET_OBJECT); if (!name.Content()) return TRUE;   
          return RegisterObjectPlugin(ID_PLANET_OBJECT,name,OBJECT_GENERATOR|OBJECT_INPUT,Planet::Alloc,"oplanet","Planet.tif",0);   
    }
    


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

    On 12/11/2009 at 12:14, xxxxxxxx wrote:

    I also notice that there is no doc->EndUndo() in UpdatePlanet() and no AddUndo()s either. Maybe you should comment out the doc->StartUndo() until it is needed.



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

    On 12/11/2009 at 15:53, xxxxxxxx wrote:

    Thanks Robert,,, I have decided that in the UpdatePlanet function I am going to use GetDown, GetNext, and GetFirstMaterial to reference the materials and objects in the scene.

    I am running in to one problem though...

    The GetFirstMaterial() function is derived from the BaseMaterial, but my materials are from the Material Class.. Is it possible to use GetFirstMaterial on materials from the Material class?

    ~Shawn



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

    On 12/11/2009 at 16:14, xxxxxxxx wrote:

    You should be able to up-cast the BaseMaterial* returned by GetFirstMaterial() to Material* without any issues. Just use a C cast (Material* ) or a C++ one static_cast_<_material*_>_



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

    On 12/11/2009 at 19:38, xxxxxxxx wrote:

    Could you give me a code snippet of how that would look?

    Thanks,

    ~Shawn



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

    On 12/11/2009 at 19:54, xxxxxxxx wrote:

    // supposing that we're looking for the surfaceMat   
    for (BaseMaterial* mat = doc->GetFirstMaterial(); mat; mat = mat->GetNext())   
    {   
         if (mat->GetName() == "whatever")   
         {   
              surfaceMat = static_cast<Material*>(mat);   
              break;   
         }   
    }
    


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

    On 13/11/2009 at 06:49, xxxxxxxx wrote:

    great thanks Robert...

    Now I need to change the fresnel settings of the color channel on a material.    so I am trying to use

    atmosphereMat->SetParameter(MATERIAL_COLOR_SHADER,?,NULL);

    But i am not sure what to put in the ? part....     or do I need to use a different constant other than MATERIAL_COLOR_SHADER?

    ~Shawn



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

    On 13/11/2009 at 15:48, xxxxxxxx wrote:

    I would expect that you should be able to get away with:

    atmosphereMat->SetParameter(MATERIAL_COLOR_SHADER,GeData(shader),NULL);

    where shader is a pointer to the shader being added to the SHADERLINK.



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

    On 13/11/2009 at 15:53, xxxxxxxx wrote:

    so would that shader be (Xfresnel) ?

    ~Shawn



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

    On 13/11/2009 at 16:01, xxxxxxxx wrote:

    This is what I tried.. and I still get nothing in the TEXTURE field of the Color Channel.

    atmosphereMat->SetParameter(MATERIAL_COLOR_SHADER,GeData(Xfresnel),NULL);

    Any other thoughts?

    Thanks a lot for your help. :)

    ~Shawn



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

    On 13/11/2009 at 16:04, xxxxxxxx wrote:

    No, I think it will need to be an actual allocated shader:

    PluginShader* shader = PluginShader::Alloc(Xfresnel);

    Also, there is another way from c4d_basechannel using HandleShaderPopup(). No experience with it though.



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

    On 13/11/2009 at 16:08, xxxxxxxx wrote:

    I will try it out and let you know.

    Thanks again Robert.

    ~Shawn



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

    On 13/11/2009 at 16:14, xxxxxxxx wrote:

    declared with ...

    PluginShader* fresnel = PluginShader::Alloc(Xfresnel);

    then used ...

    atmosphereMat->SetParameter(MATERIAL_COLOR_SHADER,GeData(fresnel),NULL);

    and got this error..

    c:\users he fosters\desktop\cinema4dr11010\plugins\#planet\source\object\planet.cpp(318) : error C2440: '<function-style-cast>' : cannot convert from 'PluginShader *' to 'GeData'
    2>        No constructor could take the source type, or constructor overload resolution was ambiguous



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

    On 13/11/2009 at 16:53, xxxxxxxx wrote:

    You might want to try going through the BaseContainer then:

    atmosphereMat->GetDataInstance()->SetLink(MATERIAL_COLOR_SHADER, fresnel);

    GeData() can't handle general pointers (only BaseLink* ).



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

    On 13/11/2009 at 17:11, xxxxxxxx wrote:

    hmmm... well it comiles fine but still nothing shows up in the texture field.... that stinks.

    ~Shawn



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

    On 13/11/2009 at 17:49, xxxxxxxx wrote:

    I think you may be stuck with HandleShaderPopup() then. I couldn't find anything here, in the docs, or in the cinema4dsdk that describes how to set a channel shader.

    It is also possible that you need to insert the shader into the material:

    atmosphereMat->InsertShader(fresnel, NULL);

    Then try to set the link. Again, I don't see any examples or more explicit information on this.



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

    On 13/11/2009 at 17:53, xxxxxxxx wrote:

    atmosphereMat->InsertShader(fresnel, NULL);

    that worked,,    WOO HOO!    Now I jus tneed to figure out how to change the colors in the shader..   LOL...

    Thanks a million Robert.

    ~Shawn



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

    On 13/11/2009 at 19:54, xxxxxxxx wrote:

    LOL.. okay so after a few hours of searching a trying, I am at somewhat of a loss again..   How would I change the color of the knots that are in the fresnel shader?

    ~Shawn



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

    On 13/11/2009 at 20:38, xxxxxxxx wrote:

    Here's what I have so far..   This inserts the fresnel shader in to the material for both the color channel and the transparency channel.   And with the current code it completely removes the color knots from the gradient in both fresnel shaders. So I feel like I'm on the right track.. any help would be greatly appreciated. :)

      
              atmosphereMat->InsertShader(fresnelColor, NULL);   
              atmosphereMat->InsertShader(fresnelTrans, NULL);   
              atmosphereMat->GetDataInstance()->SetLink(MATERIAL_COLOR_SHADER, fresnelColor);   
              atmosphereMat->GetDataInstance()->SetLink(MATERIAL_TRANSPARENCY_SHADER, fresnelTrans);   
              fresnelColor->SetParameter(SLA_FRESNEL_GRADIENT,ATMOSPHERIC_COLOR, 0);   
              fresnelTrans->SetParameter(SLA_FRESNEL_GRADIENT,Vector (0,0,0), 1);   
      
    

Log in to reply