Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware 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

    Is it possible to control Camera with keyboard WASD like a FPS game?

    Cinema 4D SDK
    4
    8
    3.2k
    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.
    • A
      AiMiDi
      last edited by

      Hi everybody. I find when edit a interior scene or a huge map, it is hard to navigate through only mouse. The best way to control the camera is like FPS games or UE4.

      There was vitual walkthrough in cinema 4d however it performs laggy and it's not a flying camera,then it was removed.

      My friend write a plugin which make camera read keyboard, however it can only move along the world axis. Besides, it moves about 5 times per sec, laggy too. If anybody knows how to correctly do it, pls tell me thanks.

      I used to take in game footage with a xbox controller, find it works perfectly.
      Desktop 2021.11.04 - 23.01.40.082021114236338.gif

      So if a combine gamepad and real time keying(cappuccino in c4d), animating camera would be much easier.

      These 2 videos demonstrates real time keying with mouse and keyboard to make camera movement and mechanical animations.


      But with a gamepad, we can even achieve this level of control inside the soft ware. Follow character movement, focus on the face, camera shake you name it.

      3D Connexion SpaceMouse can navigate like a gamepad, but not everybody afford that, and using 1 stick simultaneously to move and rotate is not that accurate.

      If you knows how to get the right API, pls leave a comment. That would be really appriciated!

      1 Reply Last reply Reply Quote 1
      • kbarK
        kbar
        last edited by

        Hi,

        To make something like this you would need to create a Tool and a Tag. The Tool would be used to let you access the keyboard and mouse movements and then you would store the recorded information in the Tag. It is too complicated for me to describe how this would be done in one email.

        But you should look at creating a tool, there are examples on github.

        https://github.com/PluginCafe/cinema4d_cpp_sdk_extended/tree/master/plugins/cinema4dsdk/source/tool

        Then create a tag

        https://github.com/PluginCafe/cinema4d_cpp_sdk_extended/tree/master/plugins/cinema4dsdk/source/tag

        And when your tool is "recording" you would store this data in the Tag so that it can be saved and used to drive a camera, for example.

        Virtual Walkthrough is what I would have recommended as well, but it has now been removed from C4D. And you probably wouldn't get any better responsiveness if you were to write your own.

        Best Regards,
        Kent

        https://www.gamelogicdesign.com
        https://www.plugins4d.com

        A 1 Reply Last reply Reply Quote 1
        • ManuelM
          Manuel
          last edited by

          Hi,

          if you want to animate the camera and record it, you need to run the animation inside cinema4D and for each frame record the position of the camera. As the animation is running you can react to the messages EVMSG_TIMECHANGED or EVMSG_DOCUMENTRECALCULATED.

          The problem is that you would need to create a simplified version of your scene so it will run smoothly.

          If you just want to navigate only the viewport, it's more difficult. At cinema4D isn't a real time application, there's no regular event you can rely on to update/record other event. The closest way of doing it would be to have a GeDialog using the Time function, but you should step away from that solution for something you want to be smooth.

          You could also "record" all the position of your camera and from that, create a camera morph setup. Create a camera each 25 frames from the data and add it to the morph setup. This allow to have a smooth animation and still be able to adjust some camera.

          Cheers,
          Manuel

          MAXON SDK Specialist

          MAXON Registered Developer

          A 1 Reply Last reply Reply Quote 1
          • A
            AiMiDi @kbar
            last edited by

            @kbar Thank you so much Mr.Barber, I'm watching your tutorial these days. It's very helpful.
            There is already real time recording which is called cappuccino in Animate bar.
            All I have to do is the camera control.
            Directly modify the position data seems not a good idea, cuz there is input rate limit.
            However when people hold middle mouse to move camera, or hold LMB to move object, they move smoothly.
            I'm thinking if I can remap this behavior of the mouse to keyboard, and move along Object local axis, not view space.
            Thank you again.

            1 Reply Last reply Reply Quote 0
            • A
              AiMiDi @Manuel
              last edited by

              @m_magalhaes Thank you mister, for the solutions! Actually there is real time recording in cinema 4d which is cappuccino in Animate bar.
              And there is key smooth function called Key reducer, the algarithm is same to smooth the spline,
              adaptively reduce key points and adjust the bezier on F-curve. Blender has same function called Decimate.
              But there is no way to smooth the key position on F-curve without delete keys. Such function exists in Blender which called smooth keys.
              Now I'm thinking only controlling camera with keyboard.There is actually way to fly the camera like in FPS game which is using 3D connexion's Space mouse.
              So I think it's actually easy for cinema 4d official to support both keyboard and gamepad.Then c4d users who are also gamers would all cheers!!!
              And thank you agian for offering ideas!

              1 Reply Last reply Reply Quote 0
              • A
                AiMiDi @ferdinand
                last edited by ferdinand

                @ferdinand
                Hello, sir. Recently I also have questions about object axis. I tried to use my keyboard WASD to move the camera along it's own axis, so camera will works like UE4 or a in game flying camera.
                Cinema 4d originally provide a way to navigate as a flying camera, which is using 3D Connexion's Space mouse.
                If Cinema 4d official can also make c4d support keyboard and gamepad, it would be super helpful for creating huge map and interior, and people can animate camera movement with gamepad by real time recording, like people recording cinematic camera motion by using a iphone with blender.

                edit: This posting has been moved by @ferdinand from its original topic

                ferdinandF 1 Reply Last reply Reply Quote 0
                • ferdinandF
                  ferdinand @AiMiDi
                  last edited by

                  Hello @aimidi,

                  without wanting to be rude: Please do not go shopping for answers in other topics. As lined out in the Forum Guidelines we talk internally about every posting marked as 'As-as-Question' anyways, so you will always get the input of the whole team (with a flavor of whoever takes on a specific topic). This will also derail other topics, as your question was only related at best faintly to the other topic.

                  Since I am now already here:

                  My proposal was a GeDialog with a timer and I have skteched up a very simple example below. The major hurdle for what you want to do is the fact that Cinema 4D has no event loop optimized for such thing, which is why you need your own, a timer.

                  What you should not do IMHO is hook into the standard messages of Cinema, as this will make it very hard to get a lag-free input, but I might be wrong, I have not tried. Due to the inaccuracy of clocked functions calls (be it GeDialog or just some system clock) when going the 100 ms, i.e., 10 FPS threshold, you also must work with deltas and cannot 'just move around a camera'.

                  In my example I also did not deal with recording stuff into key-frames. I would not do that while receiving user inputs, but just store the raw data instead (the camera matrices) and then write the data once the 'record' session has ended. Finally, it would be better to implement the whole thing in C++ because performance is key here and move the input (keyboard, gamepad, etc) polling away from the main thread into its own thread and then only update the viewport from the main thread based on that data. You will need a third-party input device library for that as our input polling is bound to the main thread.

                  Finally, when writing the data, you will have to optimize/quantize it, as putting in 1000 keys for moving 1000 frames in a straight line is a bit non-optimal ^^

                  Cheers,
                  Ferdinand

                  The test file:City.c4d
                  The result:


                  The code:

                  import c4d
                  import time
                  
                  class CameraControlDialog (c4d.gui.GeDialog):
                      """
                      """
                      # Translation velocity per second.
                      TRL_VELOCITY = 500
                      # Rotation velocity per second.
                      ROT_VELOCITY = 0.01
                  
                      def CreateLayout(self):
                          """
                          """
                          self.SetTitle("Camera Control Dialog")
                          return True
                  
                      def InitValues(self):
                          """
                          """
                          # Store the document, the render base draw (likely being the
                          # perspective one, you could also retrieve the active base draw
                          # instead) and the camera attached to it.
                          self._doc = doc
                          self._bd = doc.GetRenderBaseDraw()
                          self._camera = (self._bd.GetSceneCamera(doc) or
                                          self._bd.GetEditorCamera(doc))
                          # Set the timer of the dialog to 40 ms, i.e., 25 FPS. We are
                          # stretching here the limits of what is possible, because
                          # GeDialog.Timer is not designed for such short intervals and we
                          # will have to anticipate a very large error in the actual call
                          # intervals.
                          self.SetTimer(40)
                          self._time = None
                          return True
                  
                      @staticmethod
                      def PollKey(key):
                          """
                          """
                          res = c4d.BaseContainer()
                          if not c4d.gui.GetInputState(c4d.BFM_INPUT_KEYBOARD, ord(key), res):
                              return False
                          return res[c4d.BFM_INPUT_VALUE] == 1
                  
                  
                      def SetTraslationVelocity(self, mg, dt):
                          """
                          """
                          return mg.v3 * dt * self.TRL_VELOCITY
                  
                      def SetRotationVelocity(self, mg, dt):
                          """
                          """
                          return mg *= c4d.utils.MatrixRotY(dt * self.ROT_VELOCITY)
                  
                      def Timer(self, msg):
                          """
                          """
                          wKey, aKey, sKey, dKey = (self.PollKey("W"), self.PollKey("A"),
                                                    self.PollKey("S"), self.PollKey("D"))
                  
                          # When no keys are pressed exit and clean out the time.
                          if sum((wKey, aKey, sKey, dKey)) == False:
                              self._lastTime = None
                              return None
                  
                          # Initialize the time for the first frame a key is being pressed.
                          if self._lastTime is None:
                              self._lastTime = time.time()
                              return None
                  
                          # The delta between now and the last evaluation
                          dt = time.time() - self._lastTime
                          mg = self._camera.GetMg()
                  
                  
                          if aKey:
                              mg = self.SetRotationVelocity(mg, dt)
                          elif dKey:
                              mg = self.SetRotationVelocity(mg, -dt)
                  
                          if wKey:
                              mg.off += self.SetTraslationVelocity(mg, dt)
                          elif sKey:
                              mg.off += self.SetTraslationVelocity(mg, -dt)
                  
                          self._lastTime = time.time()
                          self._camera.SetMg(mg)
                          c4d.DrawViews(c4d.DRAWFLAGS_ONLY_ACTIVE_VIEW)
                  
                  
                  if __name__ == '__main__':
                      global dialog
                      dialog = CameraControlDialog(doc)
                      dialog.Open(c4d.DLG_TYPE_ASYNC)
                  

                  MAXON SDK Specialist
                  developers.maxon.net

                  A 1 Reply Last reply Reply Quote 0
                  • A
                    AiMiDi @ferdinand
                    last edited by

                    @ferdinand Wow,thank you so much ferdinand!

                    1 Reply Last reply Reply Quote 0
                    • i_mazlovI i_mazlov referenced this topic on
                    • First post
                      Last post