+TextureCubeFace TextureCube::enumerate_faces(unsigned i)
+{
+ switch(i)
+ {
+ case 0: return POSITIVE_X;
+ case 1: return NEGATIVE_X;
+ case 2: return POSITIVE_Y;
+ case 3: return NEGATIVE_Y;
+ case 4: return POSITIVE_Z;
+ case 5: return NEGATIVE_Z;
+ default: throw out_of_range("TextureCube::enumerate_faces");
+ }
+}
+
+const Vector3 &TextureCube::get_face_direction(TextureCubeFace face)
+{
+ switch(face)
+ {
+ case POSITIVE_X: return directions[0];
+ case NEGATIVE_X: return directions[1];
+ case POSITIVE_Y: return directions[2];
+ case NEGATIVE_Y: return directions[3];
+ case POSITIVE_Z: return directions[4];
+ case NEGATIVE_Z: return directions[5];
+ default: throw invalid_argument("TextureCube::get_face_direction");
+ }
+}
+
+const Vector3 &TextureCube::get_s_direction(TextureCubeFace face)
+{
+ switch(face)
+ {
+ case POSITIVE_X: return directions[5];
+ case NEGATIVE_X: return directions[4];
+ case POSITIVE_Y: return directions[0];
+ case NEGATIVE_Y: return directions[0];
+ case POSITIVE_Z: return directions[0];
+ case NEGATIVE_Z: return directions[1];
+ default: throw invalid_argument("TextureCube::get_s_direction");
+ }
+}
+
+const Vector3 &TextureCube::get_t_direction(TextureCubeFace face)
+{
+ switch(face)
+ {
+ case POSITIVE_X: return directions[3];
+ case NEGATIVE_X: return directions[3];
+ case POSITIVE_Y: return directions[4];
+ case NEGATIVE_Y: return directions[5];
+ case POSITIVE_Z: return directions[3];
+ case NEGATIVE_Z: return directions[3];
+ default: throw invalid_argument("TextureCube::get_t_direction");
+ }
+}
+
+Vector3 TextureCube::get_texel_direction(TextureCubeFace face, unsigned u, unsigned v)
+{
+ float s = (u+0.5f)*2.0f/size-1.0f;
+ float t = (v+0.5f)*2.0f/size-1.0f;
+ const Vector3 &fv = get_face_direction(face);
+ const Vector3 &sv = get_s_direction(face);
+ const Vector3 &tv = get_t_direction(face);
+ return Vector3(fv.x+s*sv.x, fv.y+t*tv.y, fv.z+s*sv.z+t*tv.z);
+}
+