assuming you use the simple transfrom from cube surface to sphere surface: vec3 sphereS = cubeS.Unit(),
going from sphere to cube is very easy - i'll show two methods:
1. intersection ray - plane
vec3 ray = (playerPos - planitCenter).Unit();
Find the largest dimension of (fabs(ray.x), fabs(ray.y), fabs(ray.z)) and it's sign to classify which cubeface to select.
Build a plane for that face, e.g. planeNormal = vec3(1,0,0) of positive x has been chosen.
Assuming the cube has a side length of 2, we can use the normal also for the plane position.
vec3 intersectionPoint = IntersectRayPlane (qVec3 (0,0,0), ray, planeNormal, planeNormal);
Get the coords for the quadtree from y&z, still assuming normal is x:
float u = (intersectionPoint.y + 1.0f) / 2.0f;
float v = (intersectionPoint.z + 1.0f) / 2.0f;
inline float IntersectRayPlane (qVec3 &rO, qVec3 &rD, qVec3 &pO, qVec3 &pN)
{
// rD does not need to be unit length
float d = pN.Dot(rD);
float n = pN.Dot(pO - rO);
if (fabs(d) < FP_EPSILON) // ray parallel to plane
{
if (fabs(n) < FP_EPSILON) return 0; // ray lies in plane
else return FLT_MAX; // no intersection
}
float t = n / d;
return t;
}
... you can optimize and remove the branches because those case will not happen.
2. interstion ray - box
struct AABox
{
vec minmax[2]; // would be [(-1,-1,-1), (1,1,1)] for the same cube as above
void DistanceRayFrontAndBackface (float &ffd, float& bfd, const vec& rayOrigin, const vec& rayInvDirection)
{
vec t0 = vec(minmax[0] - rayOrigin).MulPerElem (rayInvDirection);
vec t1 = vec(minmax[1] - rayOrigin).MulPerElem (rayInvDirection);
vec tMin = t0.MinPerElem (t1);
vec tMax = t0.MaxPerElem (t1);
ffd = tMin.MaxElem(); // front face distance (behind origin if inside box)
bfd = tMax.MinElem(); // back face distance
}
bool IntersectRay (float& t, const vec& rayOrigin, const vec& rayInvDirection, float rayLength)
{
float ffd, bfd;
DistanceRayFrontAndBackface (ffd, bfd, rayOrigin, rayInvDirection);
t = (ffd > 0) ? ffd : bfd; // always the first intersection with a face
return (ffd <= bfd) & (bfd >= 0.0f) & (ffd <= rayLength);
}
}
That's an optimization utilizing the fact our planes always match the coordinate system directions.
So no dot products, but the division is still there:
vec rayInvDirection = vec (1.0 / ray.x, 1.0 / ray.y, 1.0 / ray.z);
The math here is pretty basic so i wonder you ask.
Be sure to understand how it works if you can use it.
Should become second nature and you should also end with a simpler way than what i've shown here ;)
A more interesting question would be:
How can i do that sphere <-> cube mapping in a way, that all cube texels have similar area.
Currently there is more detail near the cube corners, and you don't want this.
I plan to work on this soon, in case i can't find a solution somewhere...