How do I rotate a mesh around specified axis?
-
I have several
obj
mesh files that I am importing into aScente3D
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.
-
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?
-
@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. -
@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:
-
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 -
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] } }
- 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!
-
-
@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));
-
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 ? -
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,
- Is it possible to apply animations to that matrix ?
- Based on a button click i want to rotate the door, how to do that ?
here is the code
main.qmlimport 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.