Browse Source

Trade: animation import interface in AbstractImporter.

pull/191/head
Vladimír Vondruš 8 years ago
parent
commit
0b3e1e3068
  1. 2
      doc/changelog.dox
  2. 33
      src/Magnum/Trade/AbstractImporter.cpp
  3. 68
      src/Magnum/Trade/AbstractImporter.h
  4. 201
      src/Magnum/Trade/Test/AbstractImporterTest.cpp

2
doc/changelog.dox

@ -93,6 +93,8 @@ See also:
@subsubsection changelog-latest-new-trade Trade library @subsubsection changelog-latest-new-trade Trade library
- @ref Trade::AnimationData class and animation import interface in
@ref Trade::AbstractImporter::animation() and related functions
- @ref Trade::ObjectData2D and @ref Trade::ObjectData3D now support also - @ref Trade::ObjectData2D and @ref Trade::ObjectData3D now support also
separate translation / rotation / scaling specification instead of a separate translation / rotation / scaling specification instead of a
combined transformation matrix. See @ref Trade::ObjectData2D::transformation() combined transformation matrix. See @ref Trade::ObjectData2D::transformation()

33
src/Magnum/Trade/AbstractImporter.cpp

@ -32,6 +32,7 @@
#include <Corrade/Utility/Directory.h> #include <Corrade/Utility/Directory.h>
#include "Magnum/Trade/AbstractMaterialData.h" #include "Magnum/Trade/AbstractMaterialData.h"
#include "Magnum/Trade/AnimationData.h"
#include "Magnum/Trade/CameraData.h" #include "Magnum/Trade/CameraData.h"
#include "Magnum/Trade/ImageData.h" #include "Magnum/Trade/ImageData.h"
#include "Magnum/Trade/LightData.h" #include "Magnum/Trade/LightData.h"
@ -186,6 +187,38 @@ Containers::Optional<SceneData> AbstractImporter::doScene(UnsignedInt) {
CORRADE_ASSERT(false, "Trade::AbstractImporter::scene(): not implemented", {}); CORRADE_ASSERT(false, "Trade::AbstractImporter::scene(): not implemented", {});
} }
UnsignedInt AbstractImporter::animationCount() const {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::animationCount(): no file opened", {});
return doAnimationCount();
}
UnsignedInt AbstractImporter::doAnimationCount() const { return 0; }
Int AbstractImporter::animationForName(const std::string& name) {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::animationForName(): no file opened", {});
return doAnimationForName(name);
}
Int AbstractImporter::doAnimationForName(const std::string&) { return -1; }
std::string AbstractImporter::animationName(const UnsignedInt id) {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::animationName(): no file opened", {});
CORRADE_ASSERT(id < doAnimationCount(), "Trade::AbstractImporter::animationName(): index out of range", {});
return doAnimationName(id);
}
std::string AbstractImporter::doAnimationName(UnsignedInt) { return {}; }
Containers::Optional<AnimationData> AbstractImporter::animation(const UnsignedInt id) {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::animation(): no file opened", {});
CORRADE_ASSERT(id < doAnimationCount(), "Trade::AbstractImporter::animation(): index out of range", {});
return doAnimation(id);
}
Containers::Optional<AnimationData> AbstractImporter::doAnimation(UnsignedInt) {
CORRADE_ASSERT(false, "Trade::AbstractImporter::animation(): not implemented", {});
}
UnsignedInt AbstractImporter::lightCount() const { UnsignedInt AbstractImporter::lightCount() const {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::lightCount(): no file opened", {}); CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::lightCount(): no file opened", {});
return doLightCount(); return doLightCount();

68
src/Magnum/Trade/AbstractImporter.h

@ -139,6 +139,8 @@ expose internal state through various accessors:
state for currently opened file state for currently opened file
- @ref AbstractMaterialData::importerState() can expose importer state for - @ref AbstractMaterialData::importerState() can expose importer state for
given material imported by @ref material() given material imported by @ref material()
- @ref AnimationData::importerState() can expose importer state for given
animation imported by @ref animation()
- @ref CameraData::importerState() can expose importer state for a camera - @ref CameraData::importerState() can expose importer state for a camera
importer by @ref camera() importer by @ref camera()
- @ref ImageData::importerState() can expose importer state for an image - @ref ImageData::importerState() can expose importer state for an image
@ -204,10 +206,19 @@ checked by the implementation:
- All `do*()` implementations taking data ID as parameter are called only if - All `do*()` implementations taking data ID as parameter are called only if
the ID is from valid range. the ID is from valid range.
@attention @ref Corrade::Containers::Array instances returned from the plugin @attention
@ref Corrade::Containers::Array instances returned from the plugin
should *not* use anything else than the default deleter, otherwise this can should *not* use anything else than the default deleter, otherwise this can
cause dangling function pointer call on array destruction if the plugin cause dangling function pointer call on array destruction if the plugin
gets unloaded before the array is destroyed. gets unloaded before the array is destroyed.
@attention
Similarly for interpolator functions passed through
@ref Animation::TrackView instances to @ref AnimationData --- to avoid
dangling pointers, be sure to always include an interpolator returned from
@ref animationInterpolatorFor(), which guarantees the function is *not*
instantiated in the plugin binary. Avoid using
@ref Animation::interpolatorFor() (or indirectly it by specifying
just @ref Animation::Interpolation), as it doesn't have such guarantee.
*/ */
class MAGNUM_TRADE_EXPORT AbstractImporter: public PluginManager::AbstractManagingPlugin<AbstractImporter> { class MAGNUM_TRADE_EXPORT AbstractImporter: public PluginManager::AbstractManagingPlugin<AbstractImporter> {
public: public:
@ -446,6 +457,34 @@ class MAGNUM_TRADE_EXPORT AbstractImporter: public PluginManager::AbstractManagi
*/ */
Containers::Optional<SceneData> scene(UnsignedInt id); Containers::Optional<SceneData> scene(UnsignedInt id);
/** @brief Animation count */
UnsignedInt animationCount() const;
/**
* @brief Animation ID for given name
*
* If no animation for given name exists, returns @cpp -1 @ce.
* @see @ref animationName()
*/
Int animationForName(const std::string& name);
/**
* @brief Animation name
* @param id Animation ID, from range [0, @ref animationCount()).
*
* @see @ref animationForName()
*/
std::string animationName(UnsignedInt id);
/**
* @brief Animation
* @param id Animation ID, from range [0, @ref animationCount()).
*
* Returns given animation or @ref Containers::NullOpt if importing
* failed.
*/
Containers::Optional<AnimationData> animation(UnsignedInt id);
/** @brief Light count */ /** @brief Light count */
UnsignedInt lightCount() const; UnsignedInt lightCount() const;
@ -753,7 +792,8 @@ class MAGNUM_TRADE_EXPORT AbstractImporter: public PluginManager::AbstractManagi
* documentation of a particular plugin for more information about * documentation of a particular plugin for more information about
* returned type and contents. Returns `nullptr` by default. * returned type and contents. Returns `nullptr` by default.
* @see @ref AbstractMaterialData::importerState(), * @see @ref AbstractMaterialData::importerState(),
* @ref CameraData::importerState(), @ref ImageData::importerState(), * @ref AnimationData::importerState(), @ref CameraData::importerState(),
* @ref ImageData::importerState(), @ref LightData::importerState(),
* @ref MeshData2D::importerState(), @ref MeshData3D::importerState(), * @ref MeshData2D::importerState(), @ref MeshData3D::importerState(),
* @ref ObjectData2D::importerState(), @ref ObjectData3D::importerState(), * @ref ObjectData2D::importerState(), @ref ObjectData3D::importerState(),
* @ref SceneData::importerState(), @ref TextureData::importerState() * @ref SceneData::importerState(), @ref TextureData::importerState()
@ -834,6 +874,30 @@ class MAGNUM_TRADE_EXPORT AbstractImporter: public PluginManager::AbstractManagi
/** @brief Implementation for @ref scene() */ /** @brief Implementation for @ref scene() */
virtual Containers::Optional<SceneData> doScene(UnsignedInt id); virtual Containers::Optional<SceneData> doScene(UnsignedInt id);
/**
* @brief Implementation for @ref animationCount()
*
* Default implementation returns @cpp 0 @ce.
*/
virtual UnsignedInt doAnimationCount() const;
/**
* @brief Implementation for @ref animationForName()
*
* Default implementation returns @cpp -1 @ce.
*/
virtual Int doAnimationForName(const std::string& name);
/**
* @brief Implementation for @ref animationName()
*
* Default implementation returns empty string.
*/
virtual std::string doAnimationName(UnsignedInt id);
/** @brief Implementation for @ref animation() */
virtual Containers::Optional<AnimationData> doAnimation(UnsignedInt id);
/** /**
* @brief Implementation for @ref lightCount() * @brief Implementation for @ref lightCount()
* *

201
src/Magnum/Trade/Test/AbstractImporterTest.cpp

@ -29,6 +29,7 @@
#include <Corrade/Utility/Directory.h> #include <Corrade/Utility/Directory.h>
#include "Magnum/Trade/AbstractImporter.h" #include "Magnum/Trade/AbstractImporter.h"
#include "Magnum/Trade/AnimationData.h"
#include "Magnum/Trade/CameraData.h" #include "Magnum/Trade/CameraData.h"
#include "Magnum/Trade/ImageData.h" #include "Magnum/Trade/ImageData.h"
#include "Magnum/Trade/LightData.h" #include "Magnum/Trade/LightData.h"
@ -85,6 +86,18 @@ class AbstractImporterTest: public TestSuite::Tester {
void sceneNoFile(); void sceneNoFile();
void sceneOutOfRange(); void sceneOutOfRange();
void animation();
void animationCountNotImplemented();
void animationCountNoFile();
void animationForNameNotImplemented();
void animationForNameNoFile();
void animationNameNotImplemented();
void animationNameNoFile();
void animationNameOutOfRange();
void animationNotImplemented();
void animationNoFile();
void animationOutOfRange();
void light(); void light();
void lightCountNotImplemented(); void lightCountNotImplemented();
void lightCountNoFile(); void lightCountNoFile();
@ -264,6 +277,18 @@ AbstractImporterTest::AbstractImporterTest() {
&AbstractImporterTest::sceneNoFile, &AbstractImporterTest::sceneNoFile,
&AbstractImporterTest::sceneOutOfRange, &AbstractImporterTest::sceneOutOfRange,
&AbstractImporterTest::animation,
&AbstractImporterTest::animationCountNotImplemented,
&AbstractImporterTest::animationCountNoFile,
&AbstractImporterTest::animationForNameNotImplemented,
&AbstractImporterTest::animationForNameNoFile,
&AbstractImporterTest::animationNameNotImplemented,
&AbstractImporterTest::animationNameNoFile,
&AbstractImporterTest::animationNameOutOfRange,
&AbstractImporterTest::animationNotImplemented,
&AbstractImporterTest::animationNoFile,
&AbstractImporterTest::animationOutOfRange,
&AbstractImporterTest::light, &AbstractImporterTest::light,
&AbstractImporterTest::lightCountNotImplemented, &AbstractImporterTest::lightCountNotImplemented,
&AbstractImporterTest::lightCountNoFile, &AbstractImporterTest::lightCountNoFile,
@ -963,6 +988,182 @@ void AbstractImporterTest::sceneOutOfRange() {
CORRADE_COMPARE(out.str(), "Trade::AbstractImporter::scene(): index out of range\n"); CORRADE_COMPARE(out.str(), "Trade::AbstractImporter::scene(): index out of range\n");
} }
void AbstractImporterTest::animation() {
class Importer: public Trade::AbstractImporter {
Features doFeatures() const override { return {}; }
bool doIsOpened() const override { return true; }
void doClose() override {}
UnsignedInt doAnimationCount() const override { return 8; }
Int doAnimationForName(const std::string& name) override {
if(name == "eighth") return 7;
else return -1;
}
std::string doAnimationName(UnsignedInt id) override {
if(id == 7) return "eighth";
else return {};
}
Containers::Optional<AnimationData> doAnimation(UnsignedInt id) override {
if(id == 7) return AnimationData{{}, {}, &state};
else return AnimationData{{}, {}};
}
};
std::ostringstream out;
Error redirectError{&out};
Importer importer;
CORRADE_COMPARE(importer.animationCount(), 8);
CORRADE_COMPARE(importer.animationForName("eighth"), 7);
CORRADE_COMPARE(importer.animationName(7), "eighth");
auto data = importer.animation(7);
CORRADE_VERIFY(data);
CORRADE_COMPARE(data->importerState(), &state);
}
void AbstractImporterTest::animationCountNotImplemented() {
class Importer: public Trade::AbstractImporter {
Features doFeatures() const override { return {}; }
bool doIsOpened() const override { return true; }
void doClose() override {}
};
Importer importer;
CORRADE_COMPARE(importer.animationCount(), 0);
}
void AbstractImporterTest::animationCountNoFile() {
class Importer: public Trade::AbstractImporter {
Features doFeatures() const override { return {}; }
bool doIsOpened() const override { return false; }
void doClose() override {}
};
std::ostringstream out;
Error redirectError{&out};
Importer importer;
importer.animationCount();
CORRADE_COMPARE(out.str(), "Trade::AbstractImporter::animationCount(): no file opened\n");
}
void AbstractImporterTest::animationForNameNotImplemented() {
class Importer: public Trade::AbstractImporter {
Features doFeatures() const override { return {}; }
bool doIsOpened() const override { return true; }
void doClose() override {}
};
Importer importer;
CORRADE_COMPARE(importer.animationForName(""), -1);
}
void AbstractImporterTest::animationForNameNoFile() {
class Importer: public Trade::AbstractImporter {
Features doFeatures() const override { return {}; }
bool doIsOpened() const override { return false; }
void doClose() override {}
};
std::ostringstream out;
Error redirectError{&out};
Importer importer;
importer.animationForName("");
CORRADE_COMPARE(out.str(), "Trade::AbstractImporter::animationForName(): no file opened\n");
}
void AbstractImporterTest::animationNameNotImplemented() {
class Importer: public Trade::AbstractImporter {
Features doFeatures() const override { return {}; }
bool doIsOpened() const override { return true; }
void doClose() override {}
UnsignedInt doAnimationCount() const override { return 8; }
};
Importer importer;
CORRADE_COMPARE(importer.animationName(7), "");
}
void AbstractImporterTest::animationNameNoFile() {
class Importer: public Trade::AbstractImporter {
Features doFeatures() const override { return {}; }
bool doIsOpened() const override { return false; }
void doClose() override {}
};
std::ostringstream out;
Error redirectError{&out};
Importer importer;
importer.animationName(42);
CORRADE_COMPARE(out.str(), "Trade::AbstractImporter::animationName(): no file opened\n");
}
void AbstractImporterTest::animationNameOutOfRange() {
class Importer: public Trade::AbstractImporter {
Features doFeatures() const override { return {}; }
bool doIsOpened() const override { return true; }
void doClose() override {}
};
std::ostringstream out;
Error redirectError{&out};
Importer importer;
importer.animationName(0);
CORRADE_COMPARE(out.str(), "Trade::AbstractImporter::animationName(): index out of range\n");
}
void AbstractImporterTest::animationNotImplemented() {
class Importer: public Trade::AbstractImporter {
Features doFeatures() const override { return {}; }
bool doIsOpened() const override { return true; }
void doClose() override {}
UnsignedInt doAnimationCount() const override { return 8; }
};
std::ostringstream out;
Error redirectError{&out};
Importer importer;
importer.animation(7);
CORRADE_COMPARE(out.str(), "Trade::AbstractImporter::animation(): not implemented\n");
}
void AbstractImporterTest::animationNoFile() {
class Importer: public Trade::AbstractImporter {
Features doFeatures() const override { return {}; }
bool doIsOpened() const override { return false; }
void doClose() override {}
};
std::ostringstream out;
Error redirectError{&out};
Importer importer;
importer.animation(42);
CORRADE_COMPARE(out.str(), "Trade::AbstractImporter::animation(): no file opened\n");
}
void AbstractImporterTest::animationOutOfRange() {
class Importer: public Trade::AbstractImporter {
Features doFeatures() const override { return {}; }
bool doIsOpened() const override { return true; }
void doClose() override {}
};
std::ostringstream out;
Error redirectError{&out};
Importer importer;
importer.animation(0);
CORRADE_COMPARE(out.str(), "Trade::AbstractImporter::animation(): index out of range\n");
}
void AbstractImporterTest::light() { void AbstractImporterTest::light() {
class Importer: public Trade::AbstractImporter { class Importer: public Trade::AbstractImporter {
Features doFeatures() const override { return {}; } Features doFeatures() const override { return {}; }

Loading…
Cancel
Save