Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    Where to plug in external controllers?

    Scheduled Pinned Locked Moved SDK Help
    4 Posts 0 Posters 359 Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • H Offline
      Helper
      last edited by

      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

      1 Reply Last reply Reply Quote 0
      • H Offline
        Helper
        last edited by

        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

        1 Reply Last reply Reply Quote 0
        • H Offline
          Helper
          last edited by

          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

          1 Reply Last reply Reply Quote 0
          • H Offline
            Helper
            last edited by

            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

            1 Reply Last reply Reply Quote 0
            • First post
              Last post