Where to plug in external controllers?
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 12/09/2007 at 22:45, xxxxxxxx wrote:
User Information:
Cinema 4D Version: R10
Platform: Windows ; Mac OSX ;
Language(s) : C++ ;---------
I'm thinking about a connection for external controllers like Jog/Shuttle-controls, MIDI-controllers etc. to control arbitrary properties/objects like ie. the current frame, the camera viewing angle, the rotation/transformation of a object, the current birth rate of a particle emitter.The Spacemouse integration seems to be a dialog, that has to be opened to work (I assume to get access to the event loop), and can control the camera only, right?
What I would like to do though is to control things that are set at runtime by the user, and which at some way could interact with expresso.
So I was thinking of an object that synchronizes it's "user data" with the external controller, so this data could be keyframed and could interact with XPresso.
However, such an object doesn't have acess to the event loop, right?So, what would be the right architecture to achieve this?
How to map a midi hardware slider to a Cinema slider?Any thoughs are appreciated!
Kabe
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 13/09/2007 at 00:44, xxxxxxxx wrote:
As I said on the usermeeting in Cologne I will ask the developers how to do this.
cheers,
Matthias -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 14/01/2008 at 23:36, xxxxxxxx wrote:
Any news on this topic?
Thanks
Kabe
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 04/02/2008 at 09:09, xxxxxxxx wrote:
Sorry that it took so long, here a crude example how to use MIDI on Windows to control the X postion of an object.
>
\> ///////////////////////////////////////////////////////////// \> // CINEMA 4D SDK // \> ///////////////////////////////////////////////////////////// \> // (c) 1989-2004 MAXON Computer GmbH, all rights reserved // \> ///////////////////////////////////////////////////////////// \> \> // example code for a menu/manager plugin \> \> // be sure to use a unique ID obtained from www.plugincafe.com \> #define ID_ASYNCTEST 1000955 \> \> #include <Windows.h> \> #include <stdio.h> \> #include "c4d.h" \> #include "c4d_symbols.h" \> \> \> void CALLBACK midiCallback(HMIDIIN handle, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2) \> { \> BaseDocument \*doc = GetActiveDocument(); \> if(!doc) return; \> \> BaseObject \*op = doc->GetActiveObject(); \> if(!op) return; \> \> switch(uMsg) \> { \> case MIM_DATA: \> { \> // CHAR buffer[80]; \> // sprintf(buffer, "0x%08X 0x%02X 0x%02X 0x%02X\r\n", dwParam2, dwParam1 & 0x000000FF, (dwParam1>>8) & 0x000000FF, (dwParam1>>16) & 0x000000FF); \> // String output(buffer); \> // GePrint(output); \> \> Real pos = (dwParam1>>16) & 0x000000FF; \> op->SetPos(Vector(pos,0,0)); \> op->Message(MSG_UPDATE); \> EventAdd(); \> \> break; \> } \> } \> } \> \> class AsyncDialog : public GeDialog \> { \> private: \> HMIDIIN handle; \> \> public: \> AsyncDialog(void); \> virtual Bool CreateLayout(void); \> virtual void DestroyWindow(void); \> }; \> \> AsyncDialog::AsyncDialog(void) \> { \> } \> \> Bool AsyncDialog::CreateLayout(void) \> { \> LONG NumDevs = midiInGetNumDevs(); \> MIDIINCAPS mdc; \> \> if(NumDevs>0) \> { \> /\* Open default MIDI In device \*/ \> midiInOpen(&handle;, 0, (DWORD)midiCallback, NULL, CALLBACK_FUNCTION); \> midiInStart(handle); \> } \> else GePrint("no MIDI-IN device"); \> \> // first call the parent instance \> Bool res = GeDialog::CreateLayout(); \> \> SetTitle("MIDI-IN"); \> \> return res; \> } \> \> void AsyncDialog::DestroyWindow() \> { \> midiInStop(handle); \> midiInClose(handle); \> } \> \> class AsyncTest : public CommandData \> { \> private: \> AsyncDialog dlg; \> public: \> virtual Bool Execute(BaseDocument \*doc); \> virtual LONG GetState(BaseDocument \*doc); \> virtual Bool RestoreLayout(void \*secret); \> }; \> \> LONG AsyncTest::GetState(BaseDocument \*doc) \> { \> return CMD_ENABLED; \> } \> \> Bool AsyncTest::Execute(BaseDocument \*doc) \> { \> return dlg.Open(TRUE,ID_ASYNCTEST,-1,-1); \> } \> \> Bool AsyncTest::RestoreLayout(void \*secret) \> { \> return dlg.RestoreLayout(ID_ASYNCTEST,0,secret); \> } \> \> Bool RegisterAsyncTest(void) \> { \> // decide by name if the plugin shall be registered - just for user convenience \> String name=GeLoadString(IDS_ASYNCTEST); if (!name.Content()) return TRUE; \> return RegisterCommandPlugin(ID_ASYNCTEST,name,0,NULL,String("C++ SDK Menu Test Plugin"),gNew AsyncTest); \> } \>
So basically you have to establish somehow a callback function and obtain your document, object etc.
I could look into how you can control descriptions if needed but I think you should be able to figure this out on yourself.
cheers,
Matthias