Advertisement

Normals Using Matrix Question

Started by June 21, 2005 01:39 PM
3 comments, last by newbird 19 years, 5 months ago
Hi everyone, I have a simple problem I was hoping someone could help me with. I have a simple OpenGL program where I need to recompute the normals every frame to point toward the camera. I'm using the well-known ArcBall algorithm for rotating the OpenGL object using mouse input. In my display function I translate the object away from the origin such that I can see the entire object. I then rotate the object according to the 4x4 ArcBall matrix via: float* matrix=Spaceball.GetMatrix(); glMultMatrixf(matrix); Now for every point in my scene, I need to assign the x,y,z values of the new normal for that point. I'm sure it's a simple set of equations, but it currently escapes me on how to do this. Can anyone figure out how to assign the normals to point toward the camera by essentially using this modelview matrix? --Newbird [Edited by - newbird on June 24, 2005 10:39:29 AM]
OK, if I understand you right: You want to compute object-space normals that point to camera?
-If so then you can just use something like normal = normalize( camera_position - vertex_position ).
-If not then I hope someone else will know...
You should never let your fears become the boundaries of your dreams.
Advertisement
It's a little more complicated than that. The reason is because I'm using splatting which makes each voxel stay at the same "location" and the ArcBall matrix performs the necessary rotation on the provided volume. I don't know the exact location of the each voxel in object space because it's changed/encoded in the ArcBall rotation matrix. Perhaps to make the question more clear, I draw what I like to call "hairy splats" by using the following code:

for(i=0;i<numVerts;i++) {
glBegin(GL_LINES);
pos = (unsigned short*)&voxels[i*10+4];
glVertex3f(pos[0],pos[1],pos[2]);
glVertex3f(pos[0]+5.f*(float)voxels[i*10+1]/255.f,pos[1]+5.f*(float)voxels[i*10+2]/255.f,pos[2]+5.f*(float)voxels[i*10+3]/255.f);
glEnd();
}

This essentially draws the direction of the normal at every location (a helpful visual tool if you ever need to see if your normals are behaving themselves). voxels[i*10+1] is an unsigned short of the normal in the X direction, 2 for Y, 3 for Z.

I'm essentially looking for something like the following where matrix is the typical OpenGL column-major order modelview matrix:
for(i=0;i<numVerts;i++) {
voxels[i*10+ 1] = (255.f*cos(matrix[2])); // x-component of normal
voxels[i*10+ 2] = (255.f*sin(matrix[1])); // y-component of normal
voxels[i*10+ 3] = (255.f*tan(matrix[0])); // z-component of normal
}//This is obviously wrong
--Newbird
Quote: Original post by newbird
I don't know the exact location of the each voxel in object space because it's changed/encoded in the ArcBall rotation matrix.

Then first calculate worldspace position and then use the formula posted above. Or use inverse transformation to get camera in object space.

You should never let your fears become the boundaries of your dreams.
I try that in the following manner. Can you tell if I am doing something wrong?

glGetFloatv (GL_MODELVIEW_MATRIX, SpaceballInv);
for(i=0;i<numVerts;i++) {
pos = (unsigned short*)&voxels[i*10+4];
MatMult4f(normalDir, SpaceballInv, (float)pos[0], (float)pos[1], (float)pos[2], 1.f);
for(j=0;j<3;j++) normalDir[j]=-1.f*((float)pos[j] - view.eye[j]);
Normalize3(&normalDir[0]);

voxels[i*10+ 1] = (unsigned char)(255.f*normalDir[0]); // x-component of normal
voxels[i*10+ 2] = (unsigned char)(255.f*normalDir[1]); // y-component of normal
voxels[i*10+ 3] = (unsigned char)(255.f*normalDir[2]); // z-component of normal
}

[Edited by - newbird on June 27, 2005 11:32:12 AM]

This topic is closed to new replies.

Advertisement