Qt quick interaction and opengl scene
-
Hello forum,
I have integrated qt quick and opengl where I am rendering the opengl scene as an underlay and I am going through some issues regarding the mouse interaction from qt quick and the corresponding behavior of the underlying opengl scene.
I am trying to rotate the opengl scene while the user is holding down the left mouse button and the mouse is moving. Right now I am doing it as follows with unexpected behavior:
@ RippleSceneItem
{
id: ripple
}MouseArea
{
anchors.fill: root
//enable the mouse area
enabled: true
acceptedButtons: Qt.LeftButtononPressed: { ripple.oldMouseX = mouse.x ripple.oldMouseY = mouse.y ripple.mousePressed = true ripple.mouseMoved = false } onReleased: { ripple.mousePressed = false ripple.mouseMoved = false } onPositionChanged: { ripple.currentMouseX = mouse.x ripple.currentMouseY = mouse.y ripple.mouseMoved = true ripple.mousePressed = true } }@
The Problem of the above snippet is that the scene keeps rotating even if the mouse has stopped moving while the left button is pressed. How to capture the signal when the mouse is not moving ?
Any suggestion to address the issue efficiently ?
Thanks
-
Hi,
My question is: Why does it move even if you are not moving the mouse ? According to the code if you press and move mouse, onPositionChanged handler would be triggered. But if you don't, it wouldn't and thus ripple.currentMouseX and Y wouldn't be updated and hence ripple shouldn't move. May be I'm missing something. Trying to understand.
-
It is moving because, the following flag is not getting false in the case of mouse stopped moving:
@ripple.mouseMoved = false@
As you can see that I am flagging it to true when the mouse is moving as follows:
@onPositionChanged:
{
.............
ripple.mouseMoved = true
.............
}@I have to flag it to false when the mouse is not moving . Is there any signal like onPositionNotChanged ?
I am not aware of any signal handler within which I can flag it to false.
Do you know of any ?
-
bq. I have to flag it to false when the mouse is not moving . Is there any signal like onPositionNotChanged ?
If there would have been a signal like that then it would have freezed the system as it would been fired like countless times.
IMO, you need to change some logic in your code. Why do you require ripple.mouseMoved flag at all ? If you require something similar, you can just add some code in RippleSceneItem itself to detect the change.
-
I need it because I need to rotate the scene with the mouse move event and this flag is sent to the opengl scene through the quickitem object to let it aware if the mouse is moving or not.
Is there any better option ? Let me explain the issue again that I want to achieve.
A simple opengl scene rotation with mouse move event while left mouse button is pressed. I am using the qtquick integration here because I want to add some more UI stuff later in the project and I want to keep the camera movement and orientation with the mouse and key events.
Any reference/hint that achieve something related to what I am seeking here ?
I am still stuck at the very initial stage of the project.
-
bq. A simple opengl scene rotation with mouse move event while left mouse button is pressed.
As seen in the first post, you are updating the ripple.currentMouseX and ripple.currentMouseY, so does an update to these properties rotate the RippleSceneItem ? If yes, then when you stop moving the mouse they wont be updated and hence RippleSceneItem shouldn't rotate actually. If no, then I think you will need to monitor the position change parameters using a Timer, if those dont change for a limited amount of time then mouse movement has probably stopped.
-
Here goes the snippet within the render function :
@
void RippleScene::render()
{
static const GLfloat color[] = {0.0f,0.0f,0.0f,1.0f};
static const GLfloat depth = 1.0f;glClearBufferfv(GL_COLOR,0,color); glClearBufferfv(GL_DEPTH,0,&depth); //updated mouse parameters are here if(mMousePressed && mMouseMoved) { mRx += (mCurrentMouseX - mOldMouseX)/50.0f; mRy += (mCurrentMouseY - mOldMouseY)/50.0f; }
.......................
.......................
}glm::mat4 T = glm::translate(glm::mat4(1.0f),glm::vec3(0.0f,0.0f,mDist)); glm::mat4 Rx = glm::rotate(T, glm::radians(mRx),glm::vec3(1.0f,0.0f,0.0f)); glm::mat4 MV = glm::rotate(Rx,glm::radians(mRy),glm::vec3(0.0f,1.0f,0.0f)); //calculate the model-view matrix mModelViewMatrix = mProjectionMatrix * MV;
@
As you can see that the rotation values are updated only when mouse is pressed and moved. I need some way to set the mouse move flag to false from the .qml file so that the scene does not keep rotating even when the mouse is pressed and stopped moving.
-
@
if(mMousePressed && mMouseMoved)
{
mRx += (mCurrentMouseX - mOldMouseX)/50.0f;
mRy += (mCurrentMouseY - mOldMouseY)/50.0f;
}
@So even if the condition is true the values mCurrentMouseX (assuming ripple.currentMouseX coincides with mCurrentMouseX in Ripple class) and mCurrentMouseY would be the same as previous (as onPositionChanged handler is not triggered) which in turn would not update mRx and mRy and thus should not rotate the item.
Still if you want mMouseMoved to be made false then as said earlier, updating it through Timer would be possible solution according to me. -
Sorry for such a late response. Will it really be as you mentioned above ?
Please Note that the mOldMouseX is only initialized once - when the mouse is pressed. The mOldMouseX variable has to be updated if it has to behave as you mentioned.
I think that I am over-complicating this issue. It should not be that complex. It is quite possible that people would like to rotate the opengl scene while it is designed as an underlay.
How would you address this if you were to develop something similar to what I am trying to get.
Here goes the link to the whole source of the project for you review.
"Source":https://sajis997@bitbucket.org/sajis997/ripplemaker.git
Thanks