Browse Source

SceneGraph: public setTransformation() and transform() for RigidMT*D.

Now it is nearly similar to MatrixTransformation*D except for scaling.
Public functions setTransformation() and transform() assert that the
matrix represents rigid transformation.
pull/278/head
Vladimír Vondruš 13 years ago
parent
commit
0d5f234f64
  1. 56
      src/SceneGraph/RigidMatrixTransformation2D.h
  2. 66
      src/SceneGraph/RigidMatrixTransformation3D.h
  3. 54
      src/SceneGraph/Test/RigidMatrixTransformation2DTest.cpp
  4. 55
      src/SceneGraph/Test/RigidMatrixTransformation3DTest.cpp

56
src/SceneGraph/RigidMatrixTransformation2D.h

@ -85,20 +85,53 @@ class RigidMatrixTransformation2D: public AbstractTranslationRotation2D<T> {
* to prevent rounding errors when rotating the object subsequently.
*/
RigidMatrixTransformation2D<T>* normalizeRotation() {
setTransformation(Math::Matrix3<T>::from(
setTransformationInternal(Math::Matrix3<T>::from(
Math::Algorithms::gramSchmidtOrthonormalize(_transformation.rotationScaling()),
_transformation.translation()));
return this;
}
/**
* @brief Set transformation
* @return Pointer to self (for method chaining)
*
* Expects that the matrix represents rigid transformation.
* @see Matrix3::isRigidTransformation()
*/
RigidMatrixTransformation2D<T>* setTransformation(const Math::Matrix3<T>& transformation) {
CORRADE_ASSERT(transformation.isRigidTransformation(),
"SceneGraph::RigidMatrixTransformation2D::setTransformation(): the matrix doesn't represent rigid transformation", this);
setTransformationInternal(transformation);
return this;
}
inline RigidMatrixTransformation2D<T>* resetTransformation() override {
setTransformation({});
setTransformationInternal({});
return this;
}
/**
* @brief Transform object
* @param transformation Transformation
* @param type Transformation type
* @return Pointer to self (for method chaining)
*
* Expects that the matrix represents rigid transformation.
* @see Matrix3::isRigidTransformation()
*/
inline RigidMatrixTransformation2D<T>* transform(const Math::Matrix3<T>& transformation, TransformationType type = TransformationType::Global) {
CORRADE_ASSERT(transformation.isRigidTransformation(),
"SceneGraph::RigidMatrixTransformation2D::transform(): the matrix doesn't represent rigid transformation", this);
transformInternal(transformation, type);
return this;
}
/** @copydoc AbstractTranslationRotation2D::translate() */
/**
* @copydoc AbstractTranslationRotationScaling2D::translate()
* Same as calling transform() with Matrix3::translation().
*/
inline RigidMatrixTransformation2D<T>* translate(const Math::Vector2<T>& vector, TransformationType type = TransformationType::Global) override {
transform(Math::Matrix3<T>::translation(vector), type);
transformInternal(Math::Matrix3<T>::translation(vector), type);
return this;
}
@ -108,10 +141,11 @@ class RigidMatrixTransformation2D: public AbstractTranslationRotation2D<T> {
* @param type Transformation type
* @return Pointer to self (for method chaining)
*
* @see normalizeRotation(), Matrix3::rotation()
* Same as calling transform() with Matrix3::rotation().
* @see normalizeRotation()
*/
inline RigidMatrixTransformation2D<T>* rotate(Math::Rad<T> angle, TransformationType type = TransformationType::Global) override {
transform(Math::Matrix3<T>::rotation(angle), type);
transformInternal(Math::Matrix3<T>::rotation(angle), type);
return this;
}
@ -122,10 +156,10 @@ class RigidMatrixTransformation2D: public AbstractTranslationRotation2D<T> {
* @param type Transformation type
* @return Pointer to self (for method chaining)
*
* @see Matrix3::reflection()
* Same as calling transform() with Matrix3::reflection().
*/
inline RigidMatrixTransformation2D<T>* reflect(const Math::Vector2<T>& normal, TransformationType type = TransformationType::Global) {
transform(Math::Matrix3<T>::reflection(normal), type);
transformInternal(Math::Matrix3<T>::reflection(normal), type);
return this;
}
@ -145,7 +179,8 @@ class RigidMatrixTransformation2D: public AbstractTranslationRotation2D<T> {
inline explicit RigidMatrixTransformation2D() = default;
private:
inline void setTransformation(const Math::Matrix3<T>& transformation) {
/* No assertions fired, for internal use */
inline void setTransformationInternal(const Math::Matrix3<T>& transformation) {
/* Setting transformation is forbidden for the scene */
/** @todo Assert for this? */
/** @todo Do this in some common code so we don't need to include Object? */
@ -155,7 +190,8 @@ class RigidMatrixTransformation2D: public AbstractTranslationRotation2D<T> {
}
}
inline void transform(const Math::Matrix3<T>& transformation, TransformationType type) {
/* No assertions fired, for internal use */
inline void transformInternal(const Math::Matrix3<T>& transformation, TransformationType type) {
setTransformation(type == TransformationType::Global ?
transformation*_transformation : _transformation*transformation);
}

66
src/SceneGraph/RigidMatrixTransformation3D.h

@ -91,22 +91,47 @@ class RigidMatrixTransformation3D: public AbstractTranslationRotation3D<T> {
return this;
}
/**
* @brief Set transformation
* @return Pointer to self (for method chaining)
*
* Expects that the matrix represents rigid transformation.
* @see Matrix4::isRigidTransformation()
*/
RigidMatrixTransformation3D<T>* setTransformation(const Math::Matrix4<T>& transformation) {
CORRADE_ASSERT(transformation.isRigidTransformation(),
"SceneGraph::RigidMatrixTransformation3D::setTransformation(): the matrix doesn't represent rigid transformation", this);
setTransformationInternal(transformation);
return this;
}
inline RigidMatrixTransformation3D<T>* resetTransformation() override {
setTransformation({});
return this;
}
/**
* @brief Translate object
* @param vector Translation vector
* @brief Multiply transformation
* @param transformation Transformation
* @param type Transformation type
* @return Pointer to self (for method chaining)
*
* @see Vector3::xAxis(), Vector3::yAxis(), Vector3::zAxis(),
* Matrix4::translation()
* Expects that the matrix represents rigid transformation.
* @see Matrix4::isRigidTransformation()
*/
inline RigidMatrixTransformation3D<T>* transform(const Math::Matrix4<T>& transformation, TransformationType type = TransformationType::Global) {
CORRADE_ASSERT(transformation.isRigidTransformation(),
"SceneGraph::RigidMatrixTransformation3D::transform(): the matrix doesn't represent rigid transformation", this);
transformInternal(transformation, type);
return this;
}
/**
* @copydoc AbstractTranslationRotationScaling3D::translate()
* Same as calling transform() with Matrix4::translation().
*/
inline RigidMatrixTransformation3D<T>* translate(const Math::Vector3<T>& vector, TransformationType type = TransformationType::Global) override {
transform(Math::Matrix4<T>::translation(vector), type);
transformInternal(Math::Matrix4<T>::translation(vector), type);
return this;
}
@ -117,12 +142,12 @@ class RigidMatrixTransformation3D: public AbstractTranslationRotation3D<T> {
* @param type Transformation type
* @return Pointer to self (for method chaining)
*
* Same as calling transform() with Matrix4::rotation().
* @see rotateX(), rotateY(), rotateZ(), Vector3::xAxis(),
* Vector3::yAxis(), Vector3::zAxis(), normalizeRotation(),
* Matrix4::rotation()
* Vector3::yAxis(), Vector3::zAxis(), normalizeRotation()
*/
inline RigidMatrixTransformation3D<T>* rotate(Math::Rad<T> angle, const Math::Vector3<T>& normalizedAxis, TransformationType type = TransformationType::Global) override {
transform(Math::Matrix4<T>::rotation(angle, normalizedAxis), type);
transformInternal(Math::Matrix4<T>::rotation(angle, normalizedAxis), type);
return this;
}
@ -132,10 +157,11 @@ class RigidMatrixTransformation3D: public AbstractTranslationRotation3D<T> {
* @param type Transformation type
* @return Pointer to self (for method chaining)
*
* @see normalizeRotation(), Matrix4::rotationX()
* Same as calling transform() with Matrix4::rotationX().
* @see normalizeRotation()
*/
inline RigidMatrixTransformation3D<T>* rotateX(Math::Rad<T> angle, TransformationType type = TransformationType::Global) override {
transform(Math::Matrix4<T>::rotationX(angle), type);
transformInternal(Math::Matrix4<T>::rotationX(angle), type);
return this;
}
@ -145,10 +171,11 @@ class RigidMatrixTransformation3D: public AbstractTranslationRotation3D<T> {
* @param type Transformation type
* @return Pointer to self (for method chaining)
*
* @see normalizeRotation(), Matrix4::rotationY()
* Same as calling transform() with Matrix4::rotationY().
* @see normalizeRotation()
*/
inline RigidMatrixTransformation3D<T>* rotateY(Math::Rad<T> angle, TransformationType type = TransformationType::Global) override {
transform(Math::Matrix4<T>::rotationY(angle), type);
transformInternal(Math::Matrix4<T>::rotationY(angle), type);
return this;
}
@ -158,10 +185,11 @@ class RigidMatrixTransformation3D: public AbstractTranslationRotation3D<T> {
* @param type Transformation type
* @return Pointer to self (for method chaining)
*
* @see normalizeRotation(), Matrix4::rotationZ()
* Same as calling transform() with Matrix4::rotationZ().
* @see normalizeRotation()
*/
inline RigidMatrixTransformation3D<T>* rotateZ(Math::Rad<T> angle, TransformationType type = TransformationType::Global) override {
transform(Math::Matrix4<T>::rotationZ(angle), type);
transformInternal(Math::Matrix4<T>::rotationZ(angle), type);
return this;
}
@ -172,10 +200,10 @@ class RigidMatrixTransformation3D: public AbstractTranslationRotation3D<T> {
* @param type Transformation type
* @return Pointer to self (for method chaining)
*
* @see Matrix4::reflection()
* Same as calling transform() with Matrix4::reflection().
*/
inline RigidMatrixTransformation3D<T>* reflect(const Math::Vector3<T>& normal, TransformationType type = TransformationType::Global) {
transform(Math::Matrix4<T>::reflection(normal), type);
transformInternal(Math::Matrix4<T>::reflection(normal), type);
return this;
}
@ -184,7 +212,8 @@ class RigidMatrixTransformation3D: public AbstractTranslationRotation3D<T> {
inline explicit RigidMatrixTransformation3D() = default;
private:
inline void setTransformation(const Math::Matrix4<T>& transformation) {
/* No assertions fired, for internal use */
inline void setTransformationInternal(const Math::Matrix4<T>& transformation) {
/* Setting transformation is forbidden for the scene */
/** @todo Assert for this? */
/** @todo Do this in some common code so we don't need to include Object? */
@ -194,7 +223,8 @@ class RigidMatrixTransformation3D: public AbstractTranslationRotation3D<T> {
}
}
inline void transform(const Math::Matrix4<T>& transformation, TransformationType type) {
/* No assertions fired, for internal use */
inline void transformInternal(const Math::Matrix4<T>& transformation, TransformationType type) {
setTransformation(type == TransformationType::Global ?
transformation*_transformation : _transformation*transformation);
}

54
src/SceneGraph/Test/RigidMatrixTransformation2DTest.cpp

@ -44,6 +44,7 @@ class RigidMatrixTransformation2DTest: public Corrade::TestSuite::Tester {
void setTransformation();
void resetTransformation();
void transform();
void translate();
void rotate();
void reflect();
@ -58,6 +59,7 @@ RigidMatrixTransformation2DTest::RigidMatrixTransformation2DTest() {
&RigidMatrixTransformation2DTest::setTransformation,
&RigidMatrixTransformation2DTest::resetTransformation,
&RigidMatrixTransformation2DTest::transform,
&RigidMatrixTransformation2DTest::translate,
&RigidMatrixTransformation2DTest::rotate,
&RigidMatrixTransformation2DTest::reflect,
@ -91,37 +93,67 @@ void RigidMatrixTransformation2DTest::inverted() {
}
void RigidMatrixTransformation2DTest::setTransformation() {
/* Dirty after setting transformation */
Object2D o;
/* Can't transform with non-rigid transformation */
std::ostringstream out;
Error::setOutput(&out);
o.setTransformation(Matrix3::scaling(Vector2(3.0f)));
CORRADE_COMPARE(out.str(), "SceneGraph::RigidMatrixTransformation2D::setTransformation(): the matrix doesn't represent rigid transformation\n");
/* Dirty after setting transformation */
o.setClean();
o.rotate(Deg(17.0f));
CORRADE_VERIFY(!o.isDirty());
o.setTransformation(Matrix3::rotation(Deg(17.0f)));
CORRADE_VERIFY(o.isDirty());
CORRADE_COMPARE(o.transformationMatrix(), Matrix3::rotation(Deg(17.0f)));
/* Scene cannot be transformed */
Scene2D s;
s.setClean();
s.rotate(Deg(17.0f));
s.setTransformation(Matrix3::rotation(Deg(17.0f)));
CORRADE_VERIFY(!s.isDirty());
CORRADE_COMPARE(s.transformationMatrix(), Matrix3());
}
void RigidMatrixTransformation2DTest::resetTransformation() {
Object2D o;
o.rotate(Deg(17.0f));
o.setTransformation(Matrix3::rotation(Deg(17.0f)));
CORRADE_VERIFY(o.transformationMatrix() != Matrix3());
o.resetTransformation();
CORRADE_COMPARE(o.transformationMatrix(), Matrix3());
}
void RigidMatrixTransformation2DTest::transform() {
{
/* Can't transform with non-rigid transformation */
Object2D o;
std::ostringstream out;
Error::setOutput(&out);
o.transform(Matrix3::scaling(Vector2(3.0f)));
CORRADE_COMPARE(out.str(), "SceneGraph::RigidMatrixTransformation2D::transform(): the matrix doesn't represent rigid transformation\n");
} {
Object2D o;
o.setTransformation(Matrix3::rotation(Deg(17.0f)));
o.transform(Matrix3::translation({1.0f, -0.3f}));
CORRADE_COMPARE(o.transformationMatrix(), Matrix3::translation({1.0f, -0.3f})*Matrix3::rotation(Deg(17.0f)));
} {
Object2D o;
o.setTransformation(Matrix3::rotation(Deg(17.0f)));
o.transform(Matrix3::translation({1.0f, -0.3f}), TransformationType::Local);
CORRADE_COMPARE(o.transformationMatrix(), Matrix3::rotation(Deg(17.0f))*Matrix3::translation({1.0f, -0.3f}));
}
}
void RigidMatrixTransformation2DTest::translate() {
{
Object2D o;
o.rotate(Deg(17.0f));
o.setTransformation(Matrix3::rotation(Deg(17.0f)));
o.translate({1.0f, -0.3f});
CORRADE_COMPARE(o.transformationMatrix(), Matrix3::translation({1.0f, -0.3f})*Matrix3::rotation(Deg(17.0f)));
} {
Object2D o;
o.rotate(Deg(17.0f));
o.setTransformation(Matrix3::rotation(Deg(17.0f)));
o.translate({1.0f, -0.3f}, TransformationType::Local);
CORRADE_COMPARE(o.transformationMatrix(), Matrix3::rotation(Deg(17.0f))*Matrix3::translation({1.0f, -0.3f}));
}
@ -130,12 +162,12 @@ void RigidMatrixTransformation2DTest::translate() {
void RigidMatrixTransformation2DTest::rotate() {
{
Object2D o;
o.translate({1.0f, -0.3f});
o.setTransformation(Matrix3::translation({1.0f, -0.3f}));
o.rotate(Deg(17.0f));
CORRADE_COMPARE(o.transformationMatrix(), Matrix3::rotation(Deg(17.0f))*Matrix3::translation({1.0f, -0.3f}));
} {
Object2D o;
o.translate({1.0f, -0.3f});
o.setTransformation(Matrix3::translation({1.0f, -0.3f}));
o.rotate(Deg(17.0f), TransformationType::Local);
CORRADE_COMPARE(o.transformationMatrix(), Matrix3::translation({1.0f, -0.3f})*Matrix3::rotation(Deg(17.0f)));
}
@ -144,12 +176,12 @@ void RigidMatrixTransformation2DTest::rotate() {
void RigidMatrixTransformation2DTest::reflect() {
{
Object2D o;
o.rotate(Deg(17.0f));
o.setTransformation(Matrix3::rotation(Deg(17.0f)));
o.reflect(Vector2(-1.0f/Constants::sqrt2()));
CORRADE_COMPARE(o.transformationMatrix(), Matrix3::reflection(Vector2(-1.0f/Constants::sqrt2()))*Matrix3::rotation(Deg(17.0f)));
} {
Object2D o;
o.rotate(Deg(17.0f));
o.setTransformation(Matrix3::rotation(Deg(17.0f)));
o.reflect(Vector2(-1.0f/Constants::sqrt2()), TransformationType::Local);
CORRADE_COMPARE(o.transformationMatrix(), Matrix3::rotation(Deg(17.0f))*Matrix3::reflection(Vector2(-1.0f/Constants::sqrt2())));
}
@ -157,7 +189,7 @@ void RigidMatrixTransformation2DTest::reflect() {
void RigidMatrixTransformation2DTest::normalizeRotation() {
Object2D o;
o.rotate(Deg(17.0f));
o.setTransformation(Matrix3::rotation(Deg(17.0f)));
o.normalizeRotation();
CORRADE_COMPARE(o.transformationMatrix(), Matrix3::rotation(Deg(17.0f)));
}

55
src/SceneGraph/Test/RigidMatrixTransformation3DTest.cpp

@ -44,6 +44,7 @@ class RigidMatrixTransformation3DTest: public Corrade::TestSuite::Tester {
void setTransformation();
void resetTransformation();
void transform();
void translate();
void rotate();
void reflect();
@ -58,6 +59,7 @@ RigidMatrixTransformation3DTest::RigidMatrixTransformation3DTest() {
&RigidMatrixTransformation3DTest::setTransformation,
&RigidMatrixTransformation3DTest::resetTransformation,
&RigidMatrixTransformation3DTest::transform,
&RigidMatrixTransformation3DTest::translate,
&RigidMatrixTransformation3DTest::rotate,
&RigidMatrixTransformation3DTest::reflect,
@ -91,37 +93,68 @@ void RigidMatrixTransformation3DTest::inverted() {
}
void RigidMatrixTransformation3DTest::setTransformation() {
/* Dirty after setting transformation */
Object3D o;
/* Can't transform with non-rigid transformation */
std::ostringstream out;
Error::setOutput(&out);
o.setTransformation(Matrix4::scaling(Vector3(3.0f)));
CORRADE_COMPARE(out.str(), "SceneGraph::RigidMatrixTransformation3D::setTransformation(): the matrix doesn't represent rigid transformation\n");
/* Dirty after setting transformation */
o.setClean();
o.rotateX(Deg(17.0f));
CORRADE_VERIFY(!o.isDirty());
o.setTransformation(Matrix4::rotationX(Deg(17.0f)));
CORRADE_VERIFY(o.isDirty());
CORRADE_COMPARE(o.transformationMatrix(), Matrix4::rotationX(Deg(17.0f)));
/* Scene cannot be transformed */
Scene3D s;
s.setClean();
s.rotateX(Deg(17.0f));
CORRADE_VERIFY(!s.isDirty());
s.setTransformation(Matrix4::rotationX(Deg(17.0f)));
CORRADE_VERIFY(!s.isDirty());
CORRADE_COMPARE(s.transformationMatrix(), Matrix4());
}
void RigidMatrixTransformation3DTest::resetTransformation() {
Object3D o;
o.rotateX(Deg(17.0f));
o.setTransformation(Matrix4::rotationX(Deg(17.0f)));
CORRADE_VERIFY(o.transformationMatrix() != Matrix4());
o.resetTransformation();
CORRADE_COMPARE(o.transformationMatrix(), Matrix4());
}
void RigidMatrixTransformation3DTest::transform() {
{
/* Can't transform with non-rigid transformation */
Object3D o;
std::ostringstream out;
Error::setOutput(&out);
o.transform(Matrix4::scaling(Vector3(3.0f)));
CORRADE_COMPARE(out.str(), "SceneGraph::RigidMatrixTransformation3D::transform(): the matrix doesn't represent rigid transformation\n");
} {
Object3D o;
o.setTransformation(Matrix4::rotationX(Deg(17.0f)));
o.transform(Matrix4::translation({1.0f, -0.3f, 2.3f}));
CORRADE_COMPARE(o.transformationMatrix(), Matrix4::translation({1.0f, -0.3f, 2.3f})*Matrix4::rotationX(Deg(17.0f)));
} {
Object3D o;
o.setTransformation(Matrix4::rotationX(Deg(17.0f)));
o.transform(Matrix4::translation({1.0f, -0.3f, 2.3f}), TransformationType::Local);
CORRADE_COMPARE(o.transformationMatrix(), Matrix4::rotationX(Deg(17.0f))*Matrix4::translation({1.0f, -0.3f, 2.3f}));
}
}
void RigidMatrixTransformation3DTest::translate() {
{
Object3D o;
o.rotateX(Deg(17.0f));
o.setTransformation(Matrix4::rotationX(Deg(17.0f)));
o.translate({1.0f, -0.3f, 2.3f});
CORRADE_COMPARE(o.transformationMatrix(), Matrix4::translation({1.0f, -0.3f, 2.3f})*Matrix4::rotationX(Deg(17.0f)));
} {
Object3D o;
o.rotateX(Deg(17.0f));
o.setTransformation(Matrix4::rotationX(Deg(17.0f)));
o.translate({1.0f, -0.3f, 2.3f}, TransformationType::Local);
CORRADE_COMPARE(o.transformationMatrix(), Matrix4::rotationX(Deg(17.0f))*Matrix4::translation({1.0f, -0.3f, 2.3f}));
}
@ -130,7 +163,7 @@ void RigidMatrixTransformation3DTest::translate() {
void RigidMatrixTransformation3DTest::rotate() {
{
Object3D o;
o.translate({1.0f, -0.3f, 2.3f});
o.setTransformation(Matrix4::translation({1.0f, -0.3f, 2.3f}));
o.rotateX(Deg(17.0f))
->rotateY(Deg(25.0f))
->rotateZ(Deg(-23.0f))
@ -143,7 +176,7 @@ void RigidMatrixTransformation3DTest::rotate() {
Matrix4::translation({1.0f, -0.3f, 2.3f}));
} {
Object3D o;
o.translate({1.0f, -0.3f, 2.3f});
o.setTransformation(Matrix4::translation({1.0f, -0.3f, 2.3f}));
o.rotateX(Deg(17.0f), TransformationType::Local)
->rotateY(Deg(25.0f), TransformationType::Local)
->rotateZ(Deg(-23.0f), TransformationType::Local)
@ -160,12 +193,12 @@ void RigidMatrixTransformation3DTest::rotate() {
void RigidMatrixTransformation3DTest::reflect() {
{
Object3D o;
o.rotateX(Deg(17.0f));
o.setTransformation(Matrix4::rotationX(Deg(17.0f)));
o.reflect(Vector3(-1.0f/Constants::sqrt3()));
CORRADE_COMPARE(o.transformationMatrix(), Matrix4::reflection(Vector3(-1.0f/Constants::sqrt3()))*Matrix4::rotationX(Deg(17.0f)));
} {
Object3D o;
o.rotateX(Deg(17.0f));
o.setTransformation(Matrix4::rotationX(Deg(17.0f)));
o.reflect(Vector3(-1.0f/Constants::sqrt3()), TransformationType::Local);
CORRADE_COMPARE(o.transformationMatrix(), Matrix4::rotationX(Deg(17.0f))*Matrix4::reflection(Vector3(-1.0f/Constants::sqrt3())));
}
@ -173,7 +206,7 @@ void RigidMatrixTransformation3DTest::reflect() {
void RigidMatrixTransformation3DTest::normalizeRotation() {
Object3D o;
o.rotateX(Deg(17.0f));
o.setTransformation(Matrix4::rotationX(Deg(17.0f)));
o.normalizeRotation();
CORRADE_COMPARE(o.transformationMatrix(), Matrix4::rotationX(Deg(17.0f)));
}

Loading…
Cancel
Save