How do I rotate a mesh around specified axis?



  • I have several obj mesh files that I am importing into a Scente3D view and I am trying to animate them. I need to move them into correct position relative to other objects and for example rotate them around its own center (not the 0,0,0 coordinate). For example here is my translate code:

                Transform {
                    id: centerFeedWheelTransform
                    property real userAngle: 0.0
                    matrix: {
                        var m = Qt.matrix4x4();
                        m.rotate(userAngle, Qt.vector3d(0, 0, 1))
                        m.translate(Qt.vector3d(8.66, 14.28, -18.04));
    
                        //m.rotateAround(Qt.vector3d(20,30,40),userAngle, Qt.vector3d(0, 0, 1));  // this did not work
                        return m;
                    }
                }
    

    The problem with the code above is that when object is translated it's origin is not carried with it, so it turns around the scene (0,0,0) coordinate.

    Any suggestions how I could move entities around in the scene and rotate them around their own independent origin? Ideally I like to set the origin for rotation to center of mass, but even if I can manually enter a vector, at least I can get by.


  • Qt Champions 2016

    Hi,
    Translate and scale matrices don't commute. To rotate around the object's own axis you need to switch to the object's local coordinate system. This ultimately means you need to do a translation, make the desired rotation and then reverse the translation. Suppose you have an object that is located at: Qt.vector3d(10, 10, 4), you'd do something like this:

    m.translate(Qt.vector3d(-10, -10, -4)); //< Move the object to the coordinate system's origin
    m.rotate(userAngle, Qt.vector3d(0, 0, 1)); //< Rotate around the z-axis with your angle.
    m.translate(Qt.vector3d(10, 10, 4)); //< Restore the object's original position
    

    Kind regards.



  • Thanks for your help!
    Is there a way to get the current location of my entitiy in code so I do not have to manually figure that out every time? That would make my life much easier since there are lots and lots of moving parts in my scene.

    As an example, here is how I load the mesh file and create and entity with it:

                Mesh {
                    id: centerFeedWheelMesh
                    source: "../../resources/CenterFeedWheel2.obj"
                } 
    
                        Entity {
                             id: centerFeedWheel
                             components: [centerFeedWheelMesh, centerFeedWheelTransform]
                         }
    

    I can not find any way to do this in the docs. Please tell me there is a way to get the current 3D location of entity. Yes?


  • Qt Champions 2016

    @Aras
    The current location of a 3D entity is simply it's applied transformation's translation. There's no special property for this, you can get it from the Transform object (if you've applied any).



  • @kshegunov that is not true! I can load multiple .obj files and they will appear at different locations on the scene without me applying any transformation to them. Their coordinate relative to the origin is taken into account when importing the objects. For example, depending on where your object was in the blender world, it will appear in different location when imported into the scene.

    That behavior is useful because you can arrange parts of a model in blender and then export them to obj. Now when you load them in your 3D scene they will be in correct position relative to each other. My problem now is that I need to know what their position vectors are so than I could use the trick you mentioned to rotate them around a custom rotation axis.


  • Qt Champions 2016

    @Aras
    I don't know, sorry. My early-dev experiment with Qt3D was almost half an year ago and I just bound the meshes to entities, which I could manipulate. I didn't load scenes.



  • @kshegunov no worries, you suggestion help me find a workaround for now. Here is how I did it, in case anyone else runs into the same problem:

    1. Inside blender I place the 3D cursor to where I want to rotate the item around and set that as the origin of my object

    2. Write down the (x,y,z) coordinates of my object in blender properties view

    3. Export selected object as .obj file

    4. Import mesh in qt

                        Mesh {
                            id: centerFeedMountMesh
                            source: "../../resources/CenterFeedMount.obj"
                        }
                        Mesh {
                            id: centerFeedWheelMesh
                            source: "../../resources/CenterFeedWheel.obj"
                        }
                        Entity {
                           id: centerFeedMount
                           components: [ centerFeedMountMesh, darkGreenMaterial]
                           Entity {
                               id: centerFeedWheel
                               components: [centerFeedWheelMesh, orangeMaterial, centerFeedWheelTransform]
                           }
                        }
    
    1. I rotate my object using the following code: (will of course be different for each object)

    Note: for some reason I had to swap Y and Z coordinates to get the correct vector. So if in blender X=10, Y=20, Z=30 then your translate vector will be Qt.vector3d(10, 30, 20)

                Transform {
                    id: centerFeedWheelTransform
                    property real userAngle: 0.0
                    matrix: {
                        var m = Qt.matrix4x4();
                        m.translate(Qt.vector3d(8.06, -18.04, 14.28));
                        m.rotate(userAngle, Qt.vector3d(0, 0, 1))
                        m.translate(Qt.vector3d(-8.06, 18.04, -14.28));
                        return m;
                    }
                }
    

    This works pretty well for me right now, so I will mark item as resolved. I still like to know if I can get the coordinate of entity in my Qt3D program. If you know how to do that, please comment!



  • @Aras Hi, i am facing the same problem ! can i get the complete source code of your work around here so , that i can resolve my issue. Please your help is required. Thank you !



  • @Naveen_D the transform was really the key to getting it working, I can not share my full code but I can tell you the 3D scene works after I fixed the rotation axis issue with this workaround.

    Can you share your code and tell me what issue is it that you are facing? Is it the same problem with objects rotating around wrong axis?



  • @Aras Thank you for the reply,

    Actually the problem is, I have a car model, Using blender software i have sliced the car obj for few diff parts like door, wheel, window, bonnet etc and i have rearranged the whole car by adding the car parts in the code.
    When i try to transform or rotate the door in a particular angle, it is not happening. The actual scenario i want is, to open and close the door as we do in a normal car.



  • @Naveen_D ok that sounds exactly like the problem I had. Please read my instructions above more carefully. The key is to figure out what is the coordinate of your door. You need to move (translate) the door to the origin in a way that the hinge ends up at (0,0,0) then you do your rotation and immediately after that use the opposite vector of you translate to move the door back to its correct location. This may seem counter intuitive but it works and does not cause any glitches in rendering. This is the line it is happening:

                        m.translate(Qt.vector3d(8.06, -18.04, 14.28));
                        m.rotate(userAngle, Qt.vector3d(0, 0, 1))
                        m.translate(Qt.vector3d(-8.06, 18.04, -14.28));
    


  • @Aras

    Inside blender I place the 3D cursor to where I want to rotate the item around and set that as the origin of my object

    Write down the (x,y,z) coordinates of my object in blender properties view

    Export selected object as .obj file

    Ya i got that.. even i tried with what instructions u have given above.. but i didn't get the output.,,,Can you please elaborate these instructions above. I was bit confused what exactly i need to do.
    And you are using the matrix there, and returning the value m, can you tell me where you are returning the value ?



  • @Aras

    You need to move (translate) the door to the origin in a way that the hinge ends up at (0,0,0)

    as said by you, i have tried with the following code. Where i took the x,y,z values of object's dimension instead of 3D cursor x,y,z values from the blender software and i am using the same method as you have shown above. but the problem here is when i give those dimension values for both front and back door, i am getting a gap between the door and the car.
    Can you tell me what i am doing is the correct way or what changes i need to do to make it work correctly.

    I have few questions,

    1. Is it possible to apply animations to that matrix ?
    2. Based on a button click i want to rotate the door, how to do that ?

    here is the code
    main.qml

    import Qt3D.Core 2.0
    import Qt3D.Render 2.0
    import Qt3D.Input 2.0
    import Qt3D.Extras 2.0
    import QtQuick 2.5
    import QtQuick.Controls 1.4
    
    Entity {
        id: sceneRoot
    
        Camera {
            id: camera
            projectionType: CameraLens.PerspectiveProjection
            fieldOfView: 25
            aspectRatio: _window.width / _window.height
            nearPlane : 0.1
            farPlane : 1000.0
            position: Qt.vector3d( 10, 0.0, 15.0 )
            viewCenter: carMainTransform.translation
        }
    
        OrbitCameraController {camera: camera}
    //    FirstPersonCameraController{ camera: camera}
        components: [
            RenderSettings {
                activeFrameGraph: ForwardRenderer {
                    clearColor: Qt.rgba(0, 0.5, 1, 1)
                    camera: camera
                }
            },
            InputSettings { }
        ]
    
        CarEntity {}
    
        Transform {
            id: carMainTransform
            rotation: fromAxisAndAngle(Qt.vector3d(0, 1, 0), 30)
            translation: Qt.vector3d(5.0,0.0,5.0)
        }
    
        Entity {
            id: carMainEntity
            components: [carMainTransform]
        }
    }
    
    

    CarEntity.qml

    import Qt3D.Core 2.0
    import Qt3D.Render 2.0
    import Qt3D.Input 2.0
    import Qt3D.Extras 2.0
    import QtQuick 2.5
    import QtQuick.Controls 1.4
    
    
    Entity {
        id: mainEntity
    
        PhongMaterial {
            id: carMaterial
        }
    
        Mesh {
            id: carMesh
            source: "qrc:/Meshes/CarBody.obj"
        }
    
        // Car door
        Mesh {
            id: carDoorMesh
            source: "qrc:/Meshes/CarFrontDoor.obj"
        }
    
        PhongMaterial{
            id: carDoorMaterial
        }
    
        Transform {
            id: carDoorTransform
            property real userAngle: -45.0
            matrix: {
                var m= Qt.matrix4x4();
                m.translate(Qt.vector3d(0.501096,1.5006,1.78036))
                m.rotate(userAngle, Qt.vector3d(0,1,0))
                m.translate(Qt.vector3d(-0.501096,-1.5006,-1.78036))
                return m
            }
    
        }
    
        Mesh {
            id: carBackDoorMesh
            source: "qrc:/Meshes/CarBackDoor.obj"
        }
    
        PhongMaterial{
            id: carBackDoorMaterial
        }
    
        Transform {
            id: carBackDoorTransform
            property real userAngle: -45.0
            matrix: {
                var m= Qt.matrix4x4();
                m.translate(Qt.vector3d(0.466782,1.48042,1.60597))
                m.rotate(userAngle, Qt.vector3d(0,1,0))
                m.translate(Qt.vector3d(-0.466782,-1.48042,-1.60597))
                return m
            }
        }
    
        Entity {
            id: firstEntity
            components: [ carMesh, carMaterial ]
    
            Entity {
                id: secondEntity
                components: [carDoorMesh, carDoorMaterial, carDoorTransform]
            }
    
            Entity {
                id: thirdEntity
                components: [carBackDoorMesh, carBackDoorMaterial, carBackDoorTransform]
            }
        }
    }
    
    

    Thank you.



  • @Aras Hi, any update on the above query?
    Thank you.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.