Walking around a sphere
Posted: Mon Oct 31, 2016 3:51 pm
Hello All. I am trying to place a character on a sphere and walk around it. I am pretty close, except I have two issues:
1. When I get to the pole, i rotate really fast when moving forward (Gimbal lock?)
2. When I move forward, I am following travel the sphere at the same latitude, as opposed to moving in the true forward direction. (Same with strafing)
Here is the code I have. Any help would be greatly appreciated!
1. When I get to the pole, i rotate really fast when moving forward (Gimbal lock?)
2. When I move forward, I am following travel the sphere at the same latitude, as opposed to moving in the true forward direction. (Same with strafing)
Here is the code I have. Any help would be greatly appreciated!
Code: Select all
core::vector3df masterUp = player->getPosition() - planet->getPosition();
core::vector3df dir(0, 1, 0);
core::vector3df masterDirection = dir.crossProduct(masterUp);
masterDirection.normalize();
masterUp.normalize();
core::vector3df realUp = masterDirection.crossProduct(masterUp).normalize();
realUp = realUp.crossProduct(masterDirection);
core::quaternion quatDirection;
quatDirection.rotationFromTo(core::vector3df(0, 0, 1), masterDirection);
core::vector3df worldUp(0, 1, 0);
core::matrix4 mat;
mat = quatDirection.getMatrix();
mat.rotateVect(worldUp);
core::quaternion quatUp;
quatUp.rotationFromTo(worldUp, realUp);
core::quaternion quat = quatDirection * quatUp;
core::vector3df eulers;
quat.toEuler(eulers);
eulers *= core::RADTODEG;
player->setRotation(eulers);
player->updateAbsolutePosition();
mat = player->getAbsoluteTransformation();
core::vector3df slaveDirection(0, 0, 1);
mat.rotateVect(slaveDirection);
core::vector3df slaveUp(0, 1, 0);
mat.rotateVect(slaveUp);
// move player relative to the direction they are aligned.
core::vector3df pmove(0, 0, 0);
if (receiver.IsKeyDown(irr::KEY_KEY_W))
pmove.Z += 1.f;
if (receiver.IsKeyDown(irr::KEY_KEY_S))
pmove.Z -= 1.f;
if (receiver.IsKeyDown(irr::KEY_KEY_A))
pmove.X += 1.f;
if (receiver.IsKeyDown(irr::KEY_KEY_D))
pmove.X -= 1.f;
// move the player
core::vector3df playerPosition( player->getPosition() );
// rotate the movement vector into parent coordinate system
player->getRelativeTransformation().rotateVect(pmove);
const core::vector3df velocity(10.f, 10.f, 10.f); // we can move faster forward than sideways
// apply movement over elapsed time at provided velocity
playerPosition += (pmove * (velocity * frameDeltaTime));
// update the final position
player->setPosition(playerPosition);