thinhare

08-14-2009, 04:35 AM

rotate about the mouse clicked point

Hi, all

I am making a 3d scene, with an area that contains many geometris, and centered on the screen, when rotating, it is for now always going about the center. What I want to do next is: I want it to rotate about the point mouse clicked, instead of the center of the screen, but my code seems odd:

1) I used UnProject to find the spot that I clicked, but the result seems not really accurate, if not entirely incorrect.

public void getClickedPositionCoordinate(GL aGL) {

double[] l_Coordinate = new double[4];

double[] l_ModelViewMatrix = new double[16];

double[] l_ProjectionMatrix = new double[16];

aGL.glGetDoublev(GL.GL_MODELVIEW_MATRIX, l_ModelViewMatrix, 0);

aGL.glGetDoublev(GL.GL_PROJECTION_MATRIX, l_ProjectionMatrix, 0);

int l_X = fPickPoint.x;

int l_Y = fViewport[3] - fPickPoint.y - 1;

FloatBuffer l_ZFloatBuffer = FloatBuffer.allocate(1);

aGL.glReadPixels(l_X, l_Y, 1, 1, GL.GL_DEPTH_COMPONENT, GL.GL_DOUBLE, l_ZFloatBuffer);

fGlu.gluUnProject((double) l_X, (double) l_Y, l_ZFloatBuffer.get(0),

l_ModelViewMatrix, 0, l_ProjectionMatrix, 0, fViewport, 0, l_Coordinate, 0);

double fClickedPositionX = l_Coordinate[0];

double fClickedPositionZ = l_Coordinate[2];

}

2) I tried to do the non-center rotating using all the maths I know, but it is always like rotating about some spot other that the place I clicked.

double l_XDisplacement = 0.0;

double l_ZDisplacement = 0.0;

double l_AzimuthInRadians = fAzimuth/180.0*Math.PI;

double l_OldX = 0.0;

double l_OldZ = 0.0;

double l_NewX = 0.0;

double l_NewZ = 0.0;

if (fClickedPositionX != 0 || fClickedPositionZ != 0) {

l_AzimuthInRadians = fAzimuth/180.0*Math.PI;

l_OldX = fClickedPositionX - fRotationCenterX;

l_OldZ = fClickedPositionZ - fRotationCenterZ;

l_NewX = l_OldX*Math.cos(l_AzimuthInRadians) - l_OldZ*Math.sin(l_AzimuthInRadians);

l_NewZ = l_OldX*Math.sin(l_AzimuthInRadians) + l_OldZ*Math.cos(l_AzimuthInRadians);

l_XDisplacement = l_NewX - l_OldX;

l_ZDisplacement = l_NewZ - l_OldZ;

}

A snipt of the code is included above, and any help are welcome.

Thx!!

Hi, all

I am making a 3d scene, with an area that contains many geometris, and centered on the screen, when rotating, it is for now always going about the center. What I want to do next is: I want it to rotate about the point mouse clicked, instead of the center of the screen, but my code seems odd:

1) I used UnProject to find the spot that I clicked, but the result seems not really accurate, if not entirely incorrect.

public void getClickedPositionCoordinate(GL aGL) {

double[] l_Coordinate = new double[4];

double[] l_ModelViewMatrix = new double[16];

double[] l_ProjectionMatrix = new double[16];

aGL.glGetDoublev(GL.GL_MODELVIEW_MATRIX, l_ModelViewMatrix, 0);

aGL.glGetDoublev(GL.GL_PROJECTION_MATRIX, l_ProjectionMatrix, 0);

int l_X = fPickPoint.x;

int l_Y = fViewport[3] - fPickPoint.y - 1;

FloatBuffer l_ZFloatBuffer = FloatBuffer.allocate(1);

aGL.glReadPixels(l_X, l_Y, 1, 1, GL.GL_DEPTH_COMPONENT, GL.GL_DOUBLE, l_ZFloatBuffer);

fGlu.gluUnProject((double) l_X, (double) l_Y, l_ZFloatBuffer.get(0),

l_ModelViewMatrix, 0, l_ProjectionMatrix, 0, fViewport, 0, l_Coordinate, 0);

double fClickedPositionX = l_Coordinate[0];

double fClickedPositionZ = l_Coordinate[2];

}

2) I tried to do the non-center rotating using all the maths I know, but it is always like rotating about some spot other that the place I clicked.

double l_XDisplacement = 0.0;

double l_ZDisplacement = 0.0;

double l_AzimuthInRadians = fAzimuth/180.0*Math.PI;

double l_OldX = 0.0;

double l_OldZ = 0.0;

double l_NewX = 0.0;

double l_NewZ = 0.0;

if (fClickedPositionX != 0 || fClickedPositionZ != 0) {

l_AzimuthInRadians = fAzimuth/180.0*Math.PI;

l_OldX = fClickedPositionX - fRotationCenterX;

l_OldZ = fClickedPositionZ - fRotationCenterZ;

l_NewX = l_OldX*Math.cos(l_AzimuthInRadians) - l_OldZ*Math.sin(l_AzimuthInRadians);

l_NewZ = l_OldX*Math.sin(l_AzimuthInRadians) + l_OldZ*Math.cos(l_AzimuthInRadians);

l_XDisplacement = l_NewX - l_OldX;

l_ZDisplacement = l_NewZ - l_OldZ;

}

A snipt of the code is included above, and any help are welcome.

Thx!!