function on frame change
-
On 19/08/2014 at 16:42, xxxxxxxx wrote:
last question... can a scene hook plugin generate object?
-
On 20/08/2014 at 12:13, xxxxxxxx wrote:
Hello,
SceneHookData::Execute()
[URL-REMOVED] is called in athread context
[URL-REMOVED] so you should not modify the scene within that function.A way to be sure is to use a core message. Simply define your own message by using a new plugin ID:
const Int32 EXAMPLE_MESSAGE_ID = 1016549;
In the SceneHookData::Execute() call
SpecialEventAdd
[URL-REMOVED]to send this message.virtual EXECUTIONRESULT Execute(BaseSceneHook* node, BaseDocument* doc, BaseThread* bt, Int32 priority, EXECUTIONFLAGS flags) { const EXECUTIONFLAGS newFrame = EXECUTIONFLAGS_CACHEBUILDING | EXECUTIONFLAGS_EXPRESSION | EXECUTIONFLAGS_ANIMATION; if (flags == newFrame) { **SpecialEventAdd(EXAMPLE_MESSAGE_ID, 0, 0);** } return EXECUTIONRESULT_OK; };
Finally you can catch the message in a
MessageData
[URL-REMOVED] plugin:class SimpleMessageData : public MessageData { virtual Bool CoreMessage(Int32 id, const BaseContainer &bc) { switch (id) { case **EXAMPLE_MESSAGE_ID** : { // do something with the scene BaseDocument * doc = GetActiveDocument(); if (doc) { Random rnd; rnd.Init(GeGetMilliSeconds()); const Vector pos = Vector(rnd.Get01() * 1000.0, rnd.Get01() * 1000.0, rnd.Get01() * 1000.0); BaseObject * cube = BaseObject::Alloc(Ocube); cube->SetAbsPos(pos); doc->InsertObject(cube, nullptr, nullptr); EventAdd(); } break; } } return true; } };
best wishes,
Sebastian
[URL-REMOVED] @maxon: This section contained a non-resolving link which has been removed.
-
On 21/08/2014 at 05:02, xxxxxxxx wrote:
thankyou... but is it possible to cach a message with a generator object (an objectdata)?
cause the situation is this.
i have my generator plug in that generate a specific geometry that react to time changes (like the ocean for example).. now in the viewport it work fine with a simple objectdata that listen to frame changes in the GetVirtualObject function and react properly. in the picture viewer this dosn't happen.. you are telling me that for this kind of thing i need 3 separate object (sceene hook, messagedata and objectdata)?? thankyou very much and sorry for my english
-
On 21/08/2014 at 07:31, xxxxxxxx wrote:
Originally posted by xxxxxxxx
thankyou... but is it possible to cach a message with a generator object (an objectdata)?cause the situation is this.i
have my generator plug in that generate a specific geometry that react
to time changes (like the ocean for example).. now in the viewport it
work fine with a simple objectdata that listen to frame changes in the
GetVirtualObject function and react properly. in the picture viewer this
dosn't happen.. you are telling me that for this kind of thing i need 3
separate object (sceene hook, messagedata and objectdata)?? thankyou
very much and sorry for my englishYou don't need all those extra plugins. Do it the way CactusDan suggested. Check the frame change in the Execute() function of the ObjectData, there you can make whatever data changes you need in your object and let GetVirtualObjects handle building the object. Don't look for a frame change in GVO because if you do, GVO will only execute once, when the frame changes. It isn't supposed to work like that, GVO is called by Cinema whenever it needs to get your virtual object - e.g. if you rotate the viewport. So it has to be called multiple times per frame.
If you make the changes to any data used by GVO in the Execute function then that only happens once per frame but GVO can be called many times.
If it doesn't work correctly in the picture viewer it may be that whatever data you are using isn't being copied over to the new document which is created whenever you render to the PV. It's difficult to say without seeing the way your plugin works, but suppose you have a set of data used to build the object. If that data is held in a class-level variable, you will need to override CopyTo() and copy the data to the destination object there.
-
On 22/08/2014 at 18:27, xxxxxxxx wrote:
there are some things that i don't understand.
1. if i override the execute funtion nothing happen.. cinema don't call it. i also overrided the addtoexecution but cinema don't call it neither.
2. if i check the frame changes in the GVO all is fine (in the viewport).. the structure is this:
the frame is changed? yes, modify and return obj.
No, return obj as isso the system can cal it whenever he want but it will modify the object only when the frame change.
3. the pictures viewer ignore all the data changed by the users and the time value from doc->GetTime().Get() he render always the frame 0. all the data are stored in a basecontainer exept 3 pointers.
whats wrong? thank you all for all by the way
-
On 27/08/2014 at 13:25, xxxxxxxx wrote:
someone please! i can't really make the Execute() method work.. i don't know how to make cinema call it. the picture viewer don't see any changes to the data in the base container and i have another problem.. when i disable the object and then re-enable it cinema crash. it might be because i have some array as member variable? here some code:
HEADER:
class sea : public ObjectData
{
INSTANCEOF(Sea, ObjectData);public:
Vector* grid;
waveD* wave;
String* debug = NewObj(String);
PolygonObject* obj;
BaseContainer* data;void Updatesea();
void Buildwavedata();
void Buildgeo();Bool Init(GeListNode* node);
virtual void Free(GeListNode* node);virtual BaseObject* GetVirtualObjects(BaseObject* op, HierarchyHelp *hh);
static NodeData* Alloc(void) { return NewObjClear(sea); }
};INIT method
Bool sea::Init(GeListNode* node)
{
BaseObject* op = (BaseObject* )node;
data = op->GetDataInstance();
if (!data)
return false;
data->SetInt32(RES, 150);
data->SetInt32(ANGLE, 89);
data->SetFloat(FREQ_MIN, 0.02);
data->SetFloat(FREQ_MAX, 20);
data->SetFloat(DIRECTION, 0);
data->SetFloat(DIR_TOLLERANCE, 90);
data->SetFloat(STATE, 1);
data->SetFloat(Q, 4);
data->SetInt32(WAVE_NUM, 100);
obj = PolygonObject::Alloc(pcount(), polycount());
grid = NewMem(Vector, pcount());
Buildwavedata();
Buildgeo();
Updatesea();
return true;
}GVO method
BaseObject* sea::GetVirtualObjects(BaseObject* op, HierarchyHelp *hh)
{
BaseDocument* doc = GetActiveDocument();
Int32 oldFrame = data->GetInt32(FRAME);
Int32 fps = doc->GetFps();
Int32 curFrame = doc->GetTime().GetFrame(fps);if (oldFrame != curFrame)
{
clock_t startTime = clock();Updatesea();
Float elaps = Float(clock() - startTime) / (Float)CLOCKS_PER_SEC;
GePrint(debug->FloatToString(elaps));data->SetInt32(FRAME, curFrame);
}
return obj;
} -
On 27/08/2014 at 21:30, xxxxxxxx wrote:
Try this:
1. I think you need to get the document using hh to get the current frame to update:
BaseDocument *doc = hh->GetDocument();
2. Define the curFrame and oldFrame as class level variables.
In GVO, update the curFrame as such:curFrame = doc->GetTime().GetFrame(doc->GetFps()); data->SetInt32(FRAME, curFrame); oldFrame = curFrame;
This will animate the document.
-
On 28/08/2014 at 04:28, xxxxxxxx wrote:
Howdy,
Originally posted by xxxxxxxx
...someone please! i can't really make the Execute() method work.. i don't know how to make cinema call it...
The Execute() function of an ObjectData() is not called by default by Cinema 4D. You have to use the AddToExecution() function to tell Cinema 4D to call the Execute() function.
Bool MyObject::AddToExecution(BaseObject *op, PriorityLIst *list) { list->Add(op, EXECUTIONPRIORITY_EXPRESSION, EXECUTIONFLAGS_0); return true; }
Adios,
Cactus Dan -
On 29/08/2014 at 07:05, xxxxxxxx wrote:
Howdy,_<_t_>_
Originally posted by aerydna...someone please! i can't really make the Execute() method work.. i don't know how to make cinema call it... _/tr>
The Execute() function of an ObjectData() is not called by default by Cinema 4D. You have to use the AddToExecution() function to tell Cinema 4D to call the Execute() function.
_h="99%">|Bool MyObject::AddToExecution(BaseObject \*op, PriorityLIst \*list) { list->Add(op, EXECUTIONPRIORITY_EXPRESSION, EXECUTIONFLAGS_0); return true; } <\_<\_t\_>\_> --- Adios, Cactus Dan \_<\_t\_>\_div> as i wrote a couple of message ago.. i tried that way using different flag and priority and nothing happened. thankyou anyway
-
On 29/08/2014 at 07:06, xxxxxxxx wrote:
Originally posted by xxxxxxxx
Try this:
1. I think you need to get the document using hh to get the current frame to update:
BaseDocument *doc = hh->GetDocument();
2. Define the curFrame and oldFrame as class level variables.
In GVO, update the curFrame as such:curFrame = doc->GetTime().GetFrame(doc->GetFps()); data->SetInt32(FRAME, curFrame); oldFrame = curFrame;
This will animate the document.
thank you i'll try it
-
On 29/08/2014 at 07:07, xxxxxxxx wrote:
Howdy,
Well, then you must've done something wrong in your code. Can you post the code you used?
Adios,
Cactus Dan -
On 29/08/2014 at 13:36, xxxxxxxx wrote:
Originally posted by xxxxxxxx
Howdy,
Well, then you must've done something wrong in your code. Can you post the code you used?
Adios,
Cactus DanBool sea::AddToExecution(BaseObject* op, PriorityList* list)
{
list->Add(op, EXECUTIONPRIORITY_ANIMATION, EXECUTIONFLAGS_0);
return true;
}EXECUTIONRESULT sea::Execute(BaseObject* op, BaseDocument* doc, BaseThread* bt, Int32 priority, EXECUTIONFLAGS flags)
{
GePrint("ciao");
return EXECUTIONRESULT_OK;
} -
On 30/08/2014 at 04:28, xxxxxxxx wrote:
In the function registering the plugin you also have to set the OBJECT_CALLADDEXECUTION flag so that AddToExecution() is called.
-
On 31/08/2014 at 05:31, xxxxxxxx wrote:
Howdy,
Originally posted by xxxxxxxx
In the function registering the plugin you also have to set the OBJECT_CALLADDEXECUTION flag so that AddToExecution() is called.
Yep, that would certainly explain why it wasn't working for you.
Adios,
Cactus Dan