Skip to content

Commit

Permalink
Trade: support separate translation/rotation/scaling in ObjectData.
Browse files Browse the repository at this point in the history
Doesn't make any backwards-incompatible change -- plugins can still
export the transformation as matrix and users can still access the
combined one even if separate transformations are used. Yay!
  • Loading branch information
mosra committed Jul 16, 2018
1 parent 7cad71c commit 10b4c06
Show file tree
Hide file tree
Showing 14 changed files with 663 additions and 23 deletions.
7 changes: 7 additions & 0 deletions doc/changelog.dox
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,13 @@ See also:
@ref Platform::AndroidApplication. This also makes the default framebuffer
parameters consistent across the implementations.

@subsubsection changelog-latest-new-trade Trade library

- @ref Trade::ObjectData2D and @ref Trade::ObjectData3D now support also
separate translation / rotation / scaling specification instead of a
combined transformation matrix. See @ref Trade::ObjectData2D::transformation()
and @ref Trade::ObjectData3D::transformation() for more information.

@subsection changelog-latest-changes Changes and improvements

@subsubsection changelog-latest-changes-audio Audio library
Expand Down
24 changes: 24 additions & 0 deletions doc/snippets/MagnumTrade.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
#include "Magnum/PixelFormat.h"
#include "Magnum/Trade/AbstractImporter.h"
#include "Magnum/Trade/ImageData.h"
#include "Magnum/Trade/ObjectData2D.h"
#include "Magnum/Trade/ObjectData3D.h"
#ifdef MAGNUM_TARGET_GL
#include "Magnum/GL/Texture.h"
#endif
Expand Down Expand Up @@ -67,4 +69,26 @@ else
}
#endif

{
Trade::ObjectData2D& foo();
Trade::ObjectData2D& data = foo();
/* [ObjectData2D-transformation] */
Matrix3 transformation =
Matrix3::from(data.rotation().toMatrix(), data.translation())*
Matrix3::scaling(data.scaling());
/* [ObjectData2D-transformation] */
static_cast<void>(transformation);
}

{
Trade::ObjectData3D& bar();
Trade::ObjectData3D& data = bar();
/* [ObjectData3D-transformation] */
Matrix4 transformation =
Matrix4::from(data.rotation().toMatrix(), data.translation())*
Matrix4::scaling(data.scaling());
/* [ObjectData3D-transformation] */
static_cast<void>(transformation);
}

}
6 changes: 3 additions & 3 deletions src/Magnum/Trade/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,14 @@ set(MagnumTrade_SRCS
MeshData3D.cpp
MeshObjectData2D.cpp
MeshObjectData3D.cpp
ObjectData2D.cpp
ObjectData3D.cpp
PhongMaterialData.cpp
SceneData.cpp
TextureData.cpp)

set(MagnumTrade_GracefulAssert_SRCS
ImageData.cpp)
ImageData.cpp
ObjectData2D.cpp
ObjectData3D.cpp)

set(MagnumTrade_HEADERS
AbstractImporter.h
Expand Down
2 changes: 2 additions & 0 deletions src/Magnum/Trade/MeshObjectData2D.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,6 @@ namespace Magnum { namespace Trade {

MeshObjectData2D::MeshObjectData2D(std::vector<UnsignedInt> children, const Matrix3& transformation, const UnsignedInt instance, const Int material, const void* const importerState): ObjectData2D{std::move(children), transformation, ObjectInstanceType2D::Mesh, instance, importerState}, _material{material} {}

MeshObjectData2D::MeshObjectData2D(std::vector<UnsignedInt> children, const Vector2& translation, const Complex& rotation, const Vector2& scaling, const UnsignedInt instance, const Int material, const void* const importerState): ObjectData2D{std::move(children), translation, rotation, scaling, ObjectInstanceType2D::Mesh, instance, importerState}, _material{material} {}

}}
16 changes: 15 additions & 1 deletion src/Magnum/Trade/MeshObjectData2D.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ Provides access to material information for given mesh instance.
class MAGNUM_TRADE_EXPORT MeshObjectData2D: public ObjectData2D {
public:
/**
* @brief Constructor
* @brief Construct with combined transformation
* @param children Child objects
* @param transformation Transformation (relative to parent)
* @param instance Instance ID
Expand All @@ -53,6 +53,20 @@ class MAGNUM_TRADE_EXPORT MeshObjectData2D: public ObjectData2D {
*/
explicit MeshObjectData2D(std::vector<UnsignedInt> children, const Matrix3& transformation, UnsignedInt instance, Int material, const void* importerState = nullptr);

/**
* @brief Construct with separate transformations
* @param children Child objects
* @param translation Translation (relative to parent)
* @param rotation Rotation (relative to parent)
* @param scaling Scaling (relative to parent)
* @param instance Instance ID
* @param material Material ID or `-1`
* @param importerState Importer-specific state
*
* Creates object with mesh instance type.
*/
explicit MeshObjectData2D(std::vector<UnsignedInt> children, const Vector2& translation, const Complex& rotation, const Vector2& scaling, UnsignedInt instance, Int material, const void* importerState = nullptr);

/** @brief Copying is not allowed */
MeshObjectData2D(const MeshObjectData2D&) = delete;

Expand Down
2 changes: 2 additions & 0 deletions src/Magnum/Trade/MeshObjectData3D.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,6 @@ namespace Magnum { namespace Trade {

MeshObjectData3D::MeshObjectData3D(std::vector<UnsignedInt> children, const Matrix4& transformation, const UnsignedInt instance, const Int material, const void* const importerState): ObjectData3D{std::move(children), transformation, ObjectInstanceType3D::Mesh, instance, importerState}, _material{material} {}

MeshObjectData3D::MeshObjectData3D(std::vector<UnsignedInt> children, const Vector3& translation, const Quaternion& rotation, const Vector3& scaling, const UnsignedInt instance, const Int material, const void* const importerState): ObjectData3D{std::move(children), translation, rotation, scaling, ObjectInstanceType3D::Mesh, instance, importerState}, _material{material} {}

}}
16 changes: 15 additions & 1 deletion src/Magnum/Trade/MeshObjectData3D.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ Provides access to material information for given mesh instance.
class MAGNUM_TRADE_EXPORT MeshObjectData3D: public ObjectData3D {
public:
/**
* @brief Constructor
* @brief Construct with combined transformation
* @param children Child objects
* @param transformation Transformation (relative to parent)
* @param instance Instance ID
Expand All @@ -53,6 +53,20 @@ class MAGNUM_TRADE_EXPORT MeshObjectData3D: public ObjectData3D {
*/
explicit MeshObjectData3D(std::vector<UnsignedInt> children, const Matrix4& transformation, UnsignedInt instance, Int material, const void* importerState = nullptr);

/**
* @brief Construct with separate transformations
* @param children Child objects
* @param translation Translation (relative to parent)
* @param rotation Rotation (relative to parent)
* @param scaling Scaling (relative to parent)
* @param instance Instance ID
* @param material Material ID or `-1`
* @param importerState Importer-specific state
*
* Creates object with mesh instance type.
*/
explicit MeshObjectData3D(std::vector<UnsignedInt> children, const Vector3& translation, const Quaternion& rotation, const Vector3& scaling, UnsignedInt instance, Int material, const void* importerState = nullptr);

/** @brief Copying is not allowed */
MeshObjectData3D(const MeshObjectData3D&) = delete;

Expand Down
53 changes: 51 additions & 2 deletions src/Magnum/Trade/ObjectData2D.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,17 @@

#include "ObjectData2D.h"

#include <Corrade/Containers/EnumSet.hpp>

namespace Magnum { namespace Trade {

ObjectData2D::ObjectData2D(std::vector<UnsignedInt> children, const Matrix3& transformation, const ObjectInstanceType2D instanceType, const UnsignedInt instance, const void* const importerState): _children{std::move(children)}, _transformation{transformation}, _instanceType{instanceType}, _instance{Int(instance)}, _importerState{importerState} {}
ObjectData2D::ObjectData2D(std::vector<UnsignedInt> children, const Matrix3& transformation, const ObjectInstanceType2D instanceType, const UnsignedInt instance, const void* const importerState): _children{std::move(children)}, _transformation{transformation}, _instanceType{instanceType}, _flags{}, _instance{Int(instance)}, _importerState{importerState} {}

ObjectData2D::ObjectData2D(std::vector<UnsignedInt> children, const Vector2& translation, const Complex& rotation, const Vector2& scaling, const ObjectInstanceType2D instanceType, const UnsignedInt instance, const void* const importerState): _children{std::move(children)}, _transformation{translation, rotation, scaling}, _instanceType{instanceType}, _flags{ObjectFlag2D::HasTransformationRotationScaling}, _instance{Int(instance)}, _importerState{importerState} {}

ObjectData2D::ObjectData2D(std::vector<UnsignedInt> children, const Matrix3& transformation, const void* const importerState): _children{std::move(children)}, _transformation{transformation}, _instanceType{ObjectInstanceType2D::Empty}, _flags{}, _instance{-1}, _importerState{importerState} {}

ObjectData2D::ObjectData2D(std::vector<UnsignedInt> children, const Matrix3& transformation, const void* const importerState): _children{std::move(children)}, _transformation{transformation}, _instanceType{ObjectInstanceType2D::Empty}, _instance{-1}, _importerState{importerState} {}
ObjectData2D::ObjectData2D(std::vector<UnsignedInt> children, const Vector2& translation, const Complex& rotation, const Vector2& scaling, const void* const importerState): _children{std::move(children)}, _transformation{translation, rotation, scaling}, _instanceType{ObjectInstanceType2D::Empty}, _flags{ObjectFlag2D::HasTransformationRotationScaling}, _instance{-1}, _importerState{importerState} {}

ObjectData2D::ObjectData2D(ObjectData2D&&)
#if !defined(__GNUC__) || __GNUC__*100 + __GNUC_MINOR__ != 409
Expand All @@ -45,6 +51,32 @@ ObjectData2D& ObjectData2D::operator=(ObjectData2D&&)
#endif
= default;

Vector2 ObjectData2D::translation() const {
CORRADE_ASSERT(_flags & ObjectFlag2D::HasTransformationRotationScaling,
"Trade::ObjectData2D::translation(): object has only a combined transformation", {});
return _transformation.trs.translation;
}

Complex ObjectData2D::rotation() const {
CORRADE_ASSERT(_flags & ObjectFlag2D::HasTransformationRotationScaling,
"Trade::ObjectData2D::rotation(): object has only a combined transformation", {});
return _transformation.trs.rotation;
}

Vector2 ObjectData2D::scaling() const {
CORRADE_ASSERT(_flags & ObjectFlag2D::HasTransformationRotationScaling,
"Trade::ObjectData2D::scaling(): object has only a combined transformation", {});
return _transformation.trs.scaling;
}

Matrix3 ObjectData2D::transformation() const {
if(_flags & ObjectFlag2D::HasTransformationRotationScaling)
return Matrix3::from(_transformation.trs.rotation.toMatrix(),
_transformation.trs.translation)*
Matrix3::scaling(_transformation.trs.scaling);
return _transformation.matrix;
}

#ifndef DOXYGEN_GENERATING_OUTPUT
Debug& operator<<(Debug& debug, ObjectInstanceType2D value) {
switch(value) {
Expand All @@ -59,6 +91,23 @@ Debug& operator<<(Debug& debug, ObjectInstanceType2D value) {

return debug << "Trade::ObjectInstanceType2D(" << Debug::nospace << reinterpret_cast<void*>(UnsignedByte(value)) << Debug::nospace << ")";
}

Debug& operator<<(Debug& debug, ObjectFlag2D value) {
switch(value) {
/* LCOV_EXCL_START */
#define _c(value) case ObjectFlag2D::value: return debug << "Trade::ObjectFlag2D::" #value;
_c(HasTransformationRotationScaling)
#undef _c
/* LCOV_EXCL_STOP */
}

return debug << "Trade::ObjectFlag2D(" << Debug::nospace << reinterpret_cast<void*>(UnsignedByte(value)) << Debug::nospace << ")";
}

Debug& operator<<(Debug& debug, ObjectFlags2D value) {
return enumSetDebugOutput(debug, value, "Trade::ObjectFlags2D{}", {
ObjectFlag2D::HasTransformationRotationScaling});
}
#endif

}}
Loading

0 comments on commit 10b4c06

Please sign in to comment.