PDA

View Full Version : How can I inverse the pitch if only have the viewMatrix



kitman20022002
05-15-2016, 09:25 PM
I trying to do a reflection for my ocean, and how can I inverse the pitch if I only have the viewmatrix in OpenGL becasue my camera is control by Utility::freeMovement( m_cameraMatrix, a_deltaTime, static_cast<float>(m_cameraSpeed));
and this video describe what I'm doing
https://www.youtube.com/watch?v=0NH9k4zTAqk&index=3&list=PLRIWtICgwaX23jiqVByUs0bqhnalNTNZh
from 11:19 to 12:19 thanks.

I have try so many method but does not work, giving me crazy results


First method:


tempCam = m_cameraMatrix;

tempCam[1].y *= -1;

glm::mat4 tempView = inverse(tempCam);
drawScene(m_projection , inverse(tempCam));



Second method:


tempCam = m_cameraMatrix;

tempCam[2] = glm::reflect(tempView[2] , glm::vec4(1,0,0,1));
tempCam[2].w = 0.0f;

glm::mat4 tempView = inverse(tempCam);
drawScene(m_projection , inverse(tempCam));


Third method:


tempCam = m_cameraMatrix;

tempCam [0].y *= -1;
tempCam [1].y *= -1;
tempCam [2].y *= -1;

glm::mat4 tempView = inverse(tempCam);
drawScene(m_projection , inverse(tempCam));


Forth method:


tempCam = m_cameraMatrix;

tempCam[2] = glm::reflect(tempCam[2] , glm::vec4(1,0,0,1));
tempCam[2].w = 0.0f;
tempCam[1].y *= -1;

glm::mat4 tempView = inverse(tempCam);
drawScene(m_projection , inverse(tempCam));


Fifth method:


tempCam = m_cameraMatrix;

tempCam[2] = glm::reflect(tempCam[2] , glm::vec4(1,0,0,1));
tempCam[2].w = 0.0f;
tempCam[1]= glm::reflect(tempCam[1] , glm::vec4(0,1,0,1));
tempCam[1].w = 0.0f;

glm::mat4 tempView = inverse(tempCam);
drawScene(m_projection , inverse(tempCam));

BBeck1
05-16-2016, 05:50 AM
Edit: If this seems like incoherent rambling, it's because I'm thinking through the problem rather than answering it. I eventually decide glm::scale() is the answer and just negative scale on the axis that points out of the reflection plane. I'd actually have to try it to know if it works, but it sounds right to me anyway.

I have to think about this one a bit. I did some water code in XNA years ago, but I've forgotten half of what I knew back then.

If you roll the camera 180 degrees around the local axis - so that it is upside down, that should get you half way there. The problem, obviously is that if you are dealing with a matrix instead of pitch, yaw, and roll values (which in most other cases would be a bad idea) you have to do a pitch rotation around the local axis so that it pitches in the opposite direction.

First things first, whether you rotate around the local or global axis is a matter of what order you multiply the matrices in. If you do MyMatrix = RotationMatrix * MyMatrix, you will get one result and doing MyMatrix = MyMatrix * RotationMatrix you will get the other and in languages like C++ where you can do MyMatrix *= RotationMatrix that can be something you don't think about.

I'm wondering if you can't just invert the view matrix using glm::inverse(). I would think the inverse matrix would be exactly what you're looking for since it's the complete opposite (reflection) of the original matrix.

Anyway, in the video he seems to get away with merely multiplying pitch by -1 because he's storing pitch as a scalar. I prefer to keep everything in the matrix when possible. And then you don't conveniently have the pitch value. But MyMatrix = glm::inverse(MyMatrix); should, I would think give you the opposite. Thus if it is right side up, it will be upside down. And if it's pitched down 43 degrees, it will be pitched up 43 degrees.

The problem might be that it is also reflected around the yaw rotation, which would not be the results you want. That one axis should be the same.

There's some reflection code here (http://www.mbroecker.com/project_mirrors.html). Not sure if that helps.

Maybe the way to go is to build a "reflection" matrix (http://www.euclideanspace.com/maths/geometry/affine/reflection/matrix/) and multiply it by the view matrix.

This would presumably be a reflection on the xz plane if y points up. So, possibly the matrix

1, 0, 0
0,-1, 0
0, 0, 1

would do the trick?

That's a 3x3 matrix. I've rarely messed with working different sized matrices against each other. Applying that globally should scale along the y axis opposite. There you go. That should be it. That not only turns it upside down but reverses the pitch too.

GLM has the built in scale function (http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices/).

Try MyMatrix = MyMatrix * glm::scale(1.0f, -1.0f, 1.0f);

or maybe it's

MyMatrix = glm::scale(1.0f, -1.0f, 1.0f) * MyMatrix;

where MyMatrix is your view matrix. This should turn everything upside down like you want assuming that's the correct axis. Scale should care about the order of multiplication, so not sure which comes first. Probably the scale matrix.

john_connor
05-17-2016, 08:56 AM
1. mirror the camera position at the ocean surface
2. reflect the forward direction
3. invert up direction



// step 1
glm::vec3 newposition = camera.position - (oceannormal) * (distance_ocean_camera);

// step 2
glm::vec3 newforward = glm::reflect(camera.forward, ocean.normal);

// step 3
glm::vec3 newup = camera.up * -1.0f;

glm::mat4 view = glm::lookAt(newposition, newforward, newup);


learnopengl.com --> Getting-started --> Camera


----------------------------------------------------------

edit: sorry, wrong idea, after you reflect the camera.forward direction, the camera.up direction has obviously changed also !! but i thing the forward / up directions dont have to be perpendicular (as long as they dont lie at each other)