+TextureCubeFace TextureCube::enumerate_faces(unsigned i)
+{
+ if(i>=6)
+ throw out_of_range("TextureCube::enumerate_faces");
+ return face_order[i];
+}
+
+unsigned TextureCube::get_face_index(TextureCubeFace face)
+{
+ switch(face)
+ {
+ case POSITIVE_X: return 0;
+ case NEGATIVE_X: return 1;
+ case POSITIVE_Y: return 2;
+ case NEGATIVE_Y: return 3;
+ case POSITIVE_Z: return 4;
+ case NEGATIVE_Z: return 5;
+ default: throw invalid_argument("TextureCube::get_face_index");
+ }
+}
+
+const Vector3 &TextureCube::get_face_direction(TextureCubeFace face)
+{
+ return directions[get_face_index(face)];
+}
+
+const Vector3 &TextureCube::get_s_direction(TextureCubeFace face)
+{
+ return directions[orientations[get_face_index(face)*2]];
+}
+
+const Vector3 &TextureCube::get_t_direction(TextureCubeFace face)
+{
+ return directions[orientations[get_face_index(face)*2+1]];
+}
+
+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 fv+s*sv+t*tv;
+}
+
+UInt64 TextureCube::get_data_size() const
+{
+ return id ? size*size*6*get_pixel_size(ifmt) : 0;
+}
+
+
+TextureCube::Loader::Loader(TextureCube &t):
+ DataFile::DerivedObjectLoader<TextureCube, Texture::Loader>(t)
+{
+ init();
+}
+
+TextureCube::Loader::Loader(TextureCube &t, Collection &c):
+ DataFile::DerivedObjectLoader<TextureCube, Texture::Loader>(t, c)
+{
+ init();
+}
+
+void TextureCube::Loader::init()
+{
+ add("external_image", &Loader::external_image);
+ add("image_data", &Loader::image_data);
+ add("raw_data", &Loader::raw_data);
+ add("storage", &Loader::storage);
+}
+
+void TextureCube::Loader::external_image(TextureCubeFace face, const string &fn)
+{
+ Graphics::Image img;
+ RefPtr<IO::Seekable> io = get_collection().open_raw(fn);
+ img.load_io(*io);
+
+ obj.image(face, img, srgb);
+}
+
+void TextureCube::Loader::image_data(TextureCubeFace face, const string &data)
+{
+ Graphics::Image img;
+ IO::Memory mem(data.data(), data.size());
+ img.load_io(mem);
+
+ obj.image(face, img, srgb);
+}
+
+void TextureCube::Loader::raw_data(TextureCubeFace face, const string &data)
+{
+ obj.image(face, 0, get_base_pixelformat(obj.ifmt), UNSIGNED_BYTE, data.data());
+}
+
+void TextureCube::Loader::storage(PixelFormat fmt, unsigned s)
+{
+ obj.storage(fmt, s);
+}
+
+
+void operator>>(const LexicalConverter &conv, TextureCubeFace &face)
+{
+ const string &str = conv.get();
+ if(str=="POSITIVE_X")
+ face = POSITIVE_X;
+ else if(str=="NEGATIVE_X")
+ face = NEGATIVE_X;
+ else if(str=="POSITIVE_Y")
+ face = POSITIVE_Y;
+ else if(str=="NEGATIVE_Y")
+ face = NEGATIVE_Y;
+ else if(str=="POSITIVE_Z")
+ face = POSITIVE_Z;
+ else if(str=="NEGATIVE_Z")
+ face = NEGATIVE_Z;
+ else
+ throw lexical_error(format("conversion of '%s' to TextureCubeFace", str));
+}
+