When implementing this:
http://lwjgl.org/wiki/index.php?title=Using_Shaders_to_Calculate_Model%27s_PositionI noticed a problem. The rotation seems to rotate about the origin rather than the position the objects have been translated to.
Short of doing the matrix math all by myself, can anyone offer some help as to how to properly calculate, in the shader, the rotation about the new position rather than the origin?
Obviously, I use the mouse and keyboard for movement; currently I'm doing three glRotate calls: one to set yaw (heading) directly, and the other two translate the mouse pitch (y movement) into a combination of roll and pitch depending on the yaw (heading). The basic formula is roll = cameraPitch*sin(yaw*PI) and pitch = cameraPitch*cos(yaw*PI). That just means you roll the scene if the player is facing parallel to the GL X axis, and you pitch it if they are facing parallel to the GL Z axis. The percent by which you pitch or roll at intermediate positions is determined by the circle functions.
This works, but I'm uncertain as to where GLRotate is done; I'd prefer to do the work in the shader if possible since rotating a fair number of vertexes can be computationally intensive.
Looking at the shader code, (I've successfully linked this up, so there doesn't seem to be a problem getting the floats into the uniform.)
uniform vec3 pos;
uniform vec3 rot;
varying vec4 vertColor;
void main(){
mat4x4 position=mat4x4(1.0);
position[3].x=pos.x;
position[3].y=pos.y;
position[3].z=pos.z;
mat4x4 heading=mat4x4(1.0);
heading[0][0]=cos(rot.y);
heading[0][2]=-(sin(rot.y));
heading[2][0]=sin(rot.y);
heading[2][2]=cos(rot.y);
mat4x4 pitch=mat4x4(1.0);
pitch[1][1]=cos(rot.x);
pitch[1][2]=sin(rot.x);
pitch[2][1]=-(sin(rot.x));
pitch[2][2]=cos(rot.x);
mat4x4 roll=mat4x4(1.0);
roll[0][0]=cos(rot.z);
roll[0][1]=sin(rot.z);
roll[1][0]=-(sin(rot.z));
roll[1][1]=cos(rot.z);
gl_Position= gl_ModelViewProjectionMatrix*position*heading*pitch*roll*gl_Vertex;
vertColor = vec4(0.6,0.5,0.3,1.0f);
}
I don't use his vertColor nonsense (I pass through gl_Color to gl_frontColor) but I have noticed that if position is different, heading, pitch and roll seem to rotate the scene around the origin rather than the position. Obviously this isn't evident if you haven't moved.
To reiterate my question, what changes do I need to make to this matrix math to factor in the current position into the rotations? With his math a particular yaw value (for instance, .5 radians) still rotates the vertices to the same position no matter what the camera position is. Thus you get the weird effect of rotating objects 'into' you when you approach them to one side and try to look around.
My thought was something like:
uniform vec3 pos;
uniform vec3 rot;
varying vec4 vertColor;
void main(){
mat4x4 position=mat4x4(1.0);
position[3].x=pos.x;
position[3].y=pos.y;
position[3].z=pos.z;
mat4x4 heading=mat4x4(1.0);
heading[0][0]=cos(rot.y);
heading[0][2]=-(sin(rot.y));
heading[2][0]=sin(rot.y);
heading[2][2]=cos(rot.y);
heading[3][0]=pos.x;
heading[3][1]=pos.y;
heading[3][2]=pos.z;
mat4x4 pitch=mat4x4(1.0);
pitch[1][1]=cos(rot.x);
pitch[1][2]=sin(rot.x);
pitch[2][1]=-(sin(rot.x));
pitch[2][2]=cos(rot.x);
pitch[3][0]=pos.x;
pitch[3][1]=pos.y;
pitch[3][2]=pos.z;
mat4x4 roll=mat4x4(1.0);
roll[0][0]=cos(rot.z);
roll[0][1]=sin(rot.z);
roll[1][0]=-(sin(rot.z));
roll[1][1]=cos(rot.z);
roll[3][0]=pos.x;
roll[3][1]=pos.y;
roll[3][2]=pos.z;
gl_Position= gl_ModelViewProjectionMatrix*position*heading*pitch*roll*gl_Vertex;
vertColor = vec4(0.6,0.5,0.3,1.0f);
}
Also ultimately I'm trying to make the math as efficient as possible, but first I'd just like it to work the way it 'feels' it should vis a vis moving around in a 3d scene.