Thanks for the advice. I finally worked the rotation out using the following code and after rereading the rotation around a point guide. Now I have a new problem. First I'll post the working rotation code in case it helps someone else. Next I'll post the new bug: the black hole effect at the poles.

` // the node stays in the translation on the globe (but the model does not!)`

Vector3f playerLocation = player.getLocalTranslation();

float playerDistanceFromCOTW = playerLocation.distance(centerOfTheWorld);

player.getLocalTranslation().multLocal(1 + ((GLOBE_RADIUS + 1) - playerDistanceFromCOTW) / (GLOBE_RADIUS+1));

// the player is rotated around the axis of where they are (must tilt the model to make it look right)

Quaternion q = player.getLocalRotation();

float angle = player.angle * FastMath.PI / 180;

q.fromAngleAxis(angle, playerLocation);

player.model.updateGeometricState(0, true);

// rotate the model to face th correct angle

quatA.loadIdentity();

quatB.loadIdentity();

// calculate the angles from the vector

xAngle = FastMath.asin(playerLocation.x/playerDistanceFromCOTW);

yAngle = FastMath.asin(playerLocation.y/playerDistanceFromCOTW);

zAngle = FastMath.asin(playerLocation.z/playerDistanceFromCOTW);

// change the model's rotation to point away from the globe

Quaternion qp = player.model.getLocalRotation();

// special cases for if z > 0 or z < 0

if (playerLocation.z >=0) {

quatA.fromAngleNormalAxis(FastMath.PI/2 - yAngle, Vector3f.UNIT_X);

quatB.fromAngleNormalAxis(xAngle, new Vector3f(0,0,-1));

} else {

quatA.fromAngleNormalAxis(FastMath.PI/2 - yAngle, new Vector3f(-1, 0, 0));

quatB.fromAngleNormalAxis(xAngle, new Vector3f(0,0,-1));

}

// now multiply

qp.loadIdentity();

qp.multLocal(quatA);

qp.multLocal(quatB);

I'm sure that the above code isn't optimal, but it seems to work pretty well. Now I have a different problem. As the player gets closer to the north or south poles they are more or less sucked in. I can not get the player to be able to run around the globe near either pole without the pole automatically sucking them in. If I run the player around elsewhere it is fine, but I think my movement math is a little off. Can anyone help? I think it has to do with using the y-axis as my reference point when calculating what direction is forward based on the player's current rotation.

Here is the player movement code. As before,

*angle* is an angle between 0 and 360 that gets updated as the left and right turn keys are pressed. Velocity is the same as in the flag rush tutorial, just a scalar that is either positive or negative based on if the forward or backward keys have been pressed.

` // always going to move a unit of 0.25`

float moveDistance = player.getVelocity() * tpf;

// move the player appropriately

Vector3f moveVector = player.getLocalTranslation();

// calculate the angle to y

Vector3f yIsUp = moveVector.mult(Vector3f.UNIT_Y);

// rotate about the axis -- seems to work well

rotationQuat.fromAngleAxis(player.angle*FastMath.DEG_TO_RAD, moveVector);

// calc the distance to the center of the world

float d = yIsUp.distance(Vector3f.ZERO);

yIsUp.normalizeLocal();

yIsUp.multLocal(MultiThreadGameState.GLOBE_RADIUS);

d = yIsUp.distance(Vector3f.ZERO);

// this vector is what I use as the 'forward' axis to move the player

Vector3f diff = moveVector.subtract(yIsUp);

diff.normalizeLocal().multLocal(moveDistance);

// rotate the vector around our axis

diff = rotationQuat.mult(diff);

// when crossing the y-axis flip rotation by 180 degrees to keep orientation.

if (moveVector.y > 0 && moveVector.y + diff.y < 0 || moveVector.y < 0 && moveVector.y + diff.y > 0) {

player.angle += 180;

}

// move the player the appropriate distance in the right direction

moveVector.addLocal(diff);

player.getLocalTranslation().set(moveVector);

My best guess is that I need to use more than just the y-axis when calculating the movement vector. I've played around with using the x-axis as well and adding 90 degrees to the rotation. It seems to work; however, the black hole effect still exists. Does anyone know how to modify the above code to avoid the black hole effect that I described?