mds91
mds91

Reputation: 217

Transform cube on to surface of sphere in openGL

I'm currently working on a game which renders a textured sphere (representing Earth) and cubes representing player models (which will be implemented later).

When a user clicks a point on the sphere, the cube is translated from the origin (0,0,0) (which is also the center of the sphere) to the point on the surface of the sphere.

The problem is that I want the cube to rotate so as to sit with it's base flat on the sphere's surface (as opposed to just translating the cube).

What the best way is to calculate the rotation matrices about each axis in order to achieve this effect?

Upvotes: 1

Views: 1437

Answers (1)

JasonD
JasonD

Reputation: 16612

This is the same calculation as you'd perform to make a "lookat" matrix.

In this form, you would use the normalised point on the sphere as one axis (often used as the 'Z' axis), and then make the other two as perpendicular vectors to that. Typically to do that you choose some arbitrary 'up' axis, which needs to not be parallel to your first axis, and then use two cross-products. First you cross 'Z' and 'Up' to make an 'X' axis, and then you cross the 'X' and 'Z' axes to make a 'Y' axis.

The X, Y, and Z axes (normalised) form a rotation matrix which will orient the cube to the surface normal of the sphere. Then just translate it to the surface point.

The basic idea in GL is this:

float x_axis[3];
float y_axis[3];
float z_axis[3]; // This is the point on sphere, normalised

x_axis = cross(z_axis, up);
normalise(x_axis);
y_axis = cross(z_axis, x_axis);

DrawSphere();

float mat[16] = {
    x_axis[0],x_axis[1],x_axis[2],0,
    y_axis[0],y_axis[1],y_axis[2],0,
    z_axis[0],z_axis[1],z_axis[2],0,
    (sphereRad + cubeSize) * z_axis[0], (sphereRad + cubeSize) * z_axis[1], (sphereRad + cubeSize) * z_axis[2], 1 };

glMultMatrixf(mat);

DrawCube();

Where z_axis[] is the normalised point on the sphere, x_axis[] is the normalised cross-product of that vector with the arbitrary 'up' vector, and y_axis[] is the normalised cross-product of the other two axes. sphereRad and cubeSize are the sizes of the sphere and cube - I'm assuming both shapes are centred on their local coordinate origin.

Upvotes: 2

Related Questions