Animatable control not working (DESC_ANIMATE_ON)
-
Hi.
I am struggling to update existing plugins to be animatable.
Plugins are geometry generator derived from ObjectData.
Panel is generated with GetDDescription() callback.
And internal data are handled via GetDParameter() and SetDParameter() callbacks.Below is simplified example.
I need to animate the internal parameter (Float m_value).
It doesn't work when set to DESC_ANIMATE_ON.
Animation of Value parameter appears in panel with the animate diamond icon, but it doesn't switch to red state when clicking on it.#define CTL_VAL_ID 1001 //=========================================================================================================== // class //=========================================================================================================== class TestData : public ObjectData { INSTANCEOF(TestData, ObjectData); // Cinema4D hierarchy public: // create static NodeData* Create() { return NewObjClear(TestData); } //---------------------------------------------------------- // DATA //---------------------------------------------------------- Float m_value = 15; //---------------------------------------------------------- // panel //---------------------------------------------------------- Bool GetDDescription(GeListNode* node, Description* description, DESCFLAGS_DESC& flags) { // validation if (node == nullptr || description == nullptr) return false; // load the description for Obase if (description->LoadDescription(Obase) == false) return false; // load all parameters if (description->GetSingleDescID() == nullptr) { // const DescID cid = DescLevel(CTL_VAL_ID, DTYPE_REAL, 0); //--------------------------------------------------------------------- BaseContainer bc = GetCustomDataTypeDefault(DTYPE_REAL); //--------------------------------------------- bc.SetInt32(DESC_UNIT, e_CtlUnitType::flt); bc.SetString(DESC_NAME, String("Value: ")); bc.SetInt32(DESC_SCALEH, 1); //--------------------------------------------- // animate ON bc.SetInt32(DESC_ANIMATE, DESC_ANIMATE_ON); //--------------------------------------------- // set parameter description->SetParameter(cid, bc, DescLevel(ID_OBJECTPROPERTIES)); } // controls loaded into tool description flags |= DESCFLAGS_DESC::LOADED; // base class return SUPER::GetDDescription(node, description, flags); } //---------------------------------------------------------- Bool GetDParameter(GeListNode* node, const DescID& id, GeData& t_data, DESCFLAGS_GET& flags) override { // shortcuts BaseContainer* bc = static_cast<BaseObject*>(node)->GetDataInstance(); //----------------------------------------- // parameter value to bc (get from bc) if (CTL_VAL_ID == id[0].id) { bc->SetFloat(CTL_VAL_ID, m_value); return true; } //--------------------- // base return SUPER::GetDParameter(node, id, t_data, flags); } //---------------------------------------------------------- Bool SetDParameter(GeListNode* node, const DescID& id, const GeData& t_data, DESCFLAGS_SET& flags) override { //----------------------------------------- // parameter value from bc (set in bc) C4dControls controls(t_data); if (CTL_VAL_ID == id[0].id) { m_value = t_data.GetFloat(); return true; } //----------------------------------------- // base return SUPER::SetDParameter(node, id, t_data, flags); } }; RegisterObjectPlugin(1060016, String("#$44 Test Nurbs"), OBJECT_GENERATOR | OBJECT_USECACHECOLOR, TestData::Create, maxon::String(""), nullptr, 0);
-
hi,
thanks for your question. GetDDescription can be called for a single parameter. In your code, you are simply not checking if the single parameter is your "value" parameter. I cannot dig into the code to really understand why this is blocking the creation of the track, but this is the issue.@wtools3d said in Animatable control not working (DESC_ANIMATE_ON):
if (description->GetSingleDescID() == nullptr)
This part should be replaced by a better check
const DescID* singleid = description->GetSingleDescID(); const DescID cid = DescLevel(CTL_VAL_ID, DTYPE_REAL, 0); if (!singleid || cid.IsPartOf(*singleid, nullptr)) { BaseContainer bc = GetCustomDataTypeDefault(DTYPE_REAL); // etc ......
One more remark, as
m_value
is a class parameter, be aware that you might need to implement Read/Write/CopyTo functions so the parameter is correctly loaded, saved, or copied. In your case, i do not understand why you are copying the value to this parameter but i got the feeling that if you save your document and load it back the values stored in the base container will be override by the default one (15).Cheers,
Manuel -
Yes, this condition was the issue!
It was a copy-paste part from some C4D example without deeper thinking.
Now it works as expected also with animations!Regarding the value as a class parameter, it is of course handled for read-write copy.
Our plugins are ported into more applications not just for C4D. Using its own data management so that's why the Get-Set callback are used.Thank you for your quick and useful help, as usual
Regards,
Viktor