Object rotation



  • On 12/12/2017 at 07:01, xxxxxxxx wrote:

    User Information:
    Cinema 4D Version:   R18 
    Platform:      
    Language(s) :     C++  ;

    ---------
    How can I rotate the object visible from the camera's position in the same direction as the camera's axis?

      
    BaseDraw * rbd = doc-> GetRenderBaseDraw ();   
    BaseObject * camera = rbd -> GetSceneCamera (doc);   
    Matrix mCamera = camera -> GetMg ();   
    Vector vCameraHPB = MatrixToHPB (mCamera, ROTATIONORDER_HPB);   
    Matrix mCameraProjection = HPBToMatrix (vCameraHPB, ROTATIONORDER_HPB);   
      
    BaseObject * obj = doc-> GetActiveObject ();   
    Matrix mObj = obj -> GetMg ();   
    Vector vXaxis = Vector (1, 0, 0);   
    vXaxis = mCameraProjection * vXaxis;   
    Matrix mRotateObj = RotAxisToMatrix (vXaxis, Rad (0.1));   
    mObj = mObj * mRotateObj;   
    obj -> SetMg (mObj);   
      
    EventAdd ();   
    

    Wherever the position of the camera is, the object will rotate vertically.
    This code is successful.
    However, after moving the camera, the axis of rotation is shifted for some reason.
    When examined by debugging, vXaxis correctly creates the X axis from the position of the camera, but the actual result is rotated by using the X axis of the camera position which existed at the time of first creating the object I will excuse you. Why is this?



  • On 14/12/2017 at 09:52, xxxxxxxx wrote:

    Hi deepSpec, thanks for writing us.

    With reference to your request, creating a look-at matrix by following some basic linear algebra rules is way easier than converting to/from HPB and applying rotation.
    Given the eye point (in your case the object position), the target point (the camera position) and the  "up" vector (the camera up-vector), the look-at matrix to be applied to the object to "look-at" the camera can be easily obtained using:

      
      static Matrix BuildLookAt(const Vector eye, const Vector target, const Vector up)  
      {  
          Matrix res;  
      
          // calculate the vector between target and eye  
          res.v2 = (target - eye).GetNormalized();  
          // calculate the direction perpendicular to the camera up-vector and the target-eye dir  
          res.v1 = Cross(-up, res.v2).GetNormalized();  
          // calculate the direction perpendicular to the camera up-vector and the previously calculated dir  
          res.v3 = Cross(-res.v2, res.v1).GetNormalized();  
          // set the position of the transformation where the object currently resides  
          res.off = eye;  
      
          return res;  
      }  
    

    Last but not least, it might be worthy looking at the C++ SDK LookAtCamera Tag example found in our SDK Example set.

    Best, Riccardo



  • On 16/12/2017 at 08:27, xxxxxxxx wrote:

    thank you for your answer.
    What I understand now is that when using "RotAxisToMatrix", it is one thing "Calculates matrix from rotation axis and angle."
    The other is to rotate the vector by multiplying the vector by the rotation matrix.
    I only have these two knowledge.

    And I do not know how to rotate using "BuildLookAt" and "LookAtCamera Tag".
    Now I started studying 3D mathematics. However, it will take a few months to understand.
    I am not an engineer, so I can only use the SDK.
    You can move it. That alone is OK.

    What I want to make is to project emotional expressions in animation. One 3D mouse is used to move the camera. Another 3DMouse is used for expressing wings to freely flap. The third 3D Mouse is used to express how to fly. Etc.
    In order to record the movement of the world of the theater beyond the movement of the real world, it is necessary to input all these operations at the same time.

    Question 1
    The coordinates of the camera are treated statically. Until the camera moves.
    EventAdd ();
    is not.
    obj-> ObjectUpdata ();
    Do I need such a description?

    Question 2
    Initializing the modeling axis will rotate correctly.
    I do not know how to write.

      
    · · ·   
    obj -> SetMg (mObj);   
      
    Matrix mModelingAxis = obj -> GetModelingAxis (doc);   
    mModelingAxis.v1 = Vector (1.0, 0.0, 0.0);   
    mModelingAxis.v2 = Vector (0.0, 1.0, 0.0);   
    mModelingAxis.v3 = Vector (0.0, 0.0, 1.0);   
    obj-> SetModelingAxis (mModelingAxis);   
    EventAdd ();   
    

    Why does the modeling axis not move with this code?

    Please watch this video.
    https://drive.google.com/file/d/1sbOQjISvKzRhfNeyTdsNbkLemHaRnBX0/view?usp=sharing



  • On 17/12/2017 at 04:40, xxxxxxxx wrote:

    Is it possible that you misunderstand what a modeling axis is?

    A modeling axis is used for a tool (like the Rotate tool) to determine the axis system in which the operation is performed. It is not the origin system of the object. Also, the modeling axis will only be used if the mode is set to Free.

    So you really want to control several 3D mice with whatever you are writing? I have written a plugin for the SpaceNavigator to control the camera, which is already a big effort. You will need to connect your plugin to the driver of the 3D mice too, beyond the work needed to perform the actual operations.

    My recommendation would be that you create some simple scripts to learn the basics of vector mathematics first, and explore the extent of the SDK. An SDK will only allow you to access internal functionalities, it's not going to do any problem solving for you, so there is a lot of programming ahead.



  • On 18/12/2017 at 01:23, xxxxxxxx wrote:

    thank you for the advice.
    I could not move modeling axis even using SetModelingAxis for object data plugin.
    C4D standard 3D mouse mode "Move" also rotates the object without rotating the modeling axis.
    I tried to try it with a script, but I could access the modeling axis from R19.
    You can get the axis with GetModelingAxis.
    However, the axis does not move at all even when set in edit mode.



  • On 19/12/2017 at 08:33, xxxxxxxx wrote:

    I just tried it with Python (since it's faster to test) and it works fine:

      
    import c4d   
    from c4d import gui   
      
    def main() :   
        obj = doc.GetActiveObject()   
        mModelingAxis = obj.GetModelingAxis (doc);   
        print mModelingAxis   
        mModelingAxis.off = c4d.Vector(mModelingAxis.off.x, mModelingAxis.off.y + 10.0, mModelingAxis.off.z)   
        obj.SetModelingAxis (mModelingAxis);   
        print mModelingAxis   
        c4d.EventAdd ();   
      
    if __name__=='__main__':   
        main()   
    

    This script moves the modeling axis up 10 units when triggered.

    Of course, to even SEE the modeling axis, you need to be in point, edge, or polygon mode, and select something, and have one of the translate/rotate/scale modes active, and set the Axis to Free in the Tool settings. Otherwise, you will not see the modeling axis but something else.



  • On 19/12/2017 at 21:56, xxxxxxxx wrote:

    That code did not work on R18.
    I ran that script on R19 DEMO.
    I could understand that we can not use the modeling axis to rotate the object.
    Then I succeeded in resetting and rotating the modeling axis in the virtual space.

      
    BaseDraw * rbd = doc-> GetRenderBaseDraw ();   
    BaseObject * camera = rbd -> GetSceneCamera (doc);   
    Matrix mCamera = camera -> GetMg ();   
    Vector vCameraHPB = MatrixToHPB (mCamera, ROTATIONORDER_HPB);   
    Matrix mCameraProjection = HPBToMatrix (vCameraHPB, ROTATIONORDER_HPB);   
      
    BaseObject * obj = doc-> GetActiveObject ();   
    Matrix mObj = obj -> GetMg ();   
      
    Matrix mModelingAxis = obj -> GetModelingAxis (doc);   
    Vector vModelingAxisHPB = MatrixToHPB (mModelingAxis, ROTATIONORDER_HPB);   
    Matrix mMAR = HPBToMatrix (vModelingAxisHPB, ROTATIONORDER_HPB);   
    Matrix mModelingAxisRotateReverse =   
    Matrix (   
    Vector (mMAR.off.x, mMAR.off.y, mMAR.off.z),   
    Vector (mMAR.v1.x, mMAR.v2.x, mMAR.v3.x),   
    Vector (mMAR.v1.y, mMAR.v2.y, mMAR.v3.y),   
    Vector (mMAR.v1.z, mMAR.v2.z, mMAR.v3.z)   
    );   
      
    Vector vXaxis = Vector (1, 0, 0);   
    vXaxis = mCameraProjection * vXaxis;   
    vXaxis = mModelingAxisRotateReverse * vXaxis;   
      
    Matrix mRotateObj = RotAxisToMatrix (vXaxis, Rad (0.1));   
    mObj = mObj * mRotateObj;   
    obj -> SetMg (mObj);   
      
    EventAdd ();   
    

    It is now possible to rotate objects freely with the inverse rotation matrix and axis rotation system.
    I thank you for going out with my selfishness.



  • On 20/12/2017 at 10:00, xxxxxxxx wrote:

    Hi deepSpec, sorry for getting here lately but I'm a bit confused on the direction the thread has taken and it's unclear to me if your initial support request has been addressed or not.

    Concerning the code I posted, it's is indeed pretty straightforward to use: just set the point from where the camera is supposed to be placed, the point where the target is support to be located and the so called up vector, which represents the direction from the camera to above.

    Getting back to your points:

    The coordinates of the camera are treated statically. Until the camera moves.
    EventAdd ();
    is not.
    obj-> ObjectUpdata ();
    Do I need such a description?

    Although not 100% clear the camera coordinates are not treated statically at all. They look static in the context of a command which is fired by the user, but if are managed in the different context (e.g. a SceneHookData plugin) you would be provided with constant updates.

    Question 2
    Initializing the modeling axis will rotate correctly.
    I do not know how to write.

    Here, seconding the Cairyn post, to better understand the design intent of the modeling axis, I suggest to give a look at:

    Looking forward hearing from you, I hope these notes can be of any help.

    Best, Riccardo



  • On 20/12/2017 at 14:39, xxxxxxxx wrote:

    All my problems have been solved.
    The Python problem got a response in a Python thread.
    I think that I will read and use the whole of this powerful SDK manual carefully.
    Thank you very much.


Log in to reply