Browse Source

SceneGraph: added Object::setParentKeepTransformation().

pull/278/head
Vladimír Vondruš 13 years ago
parent
commit
3b861f6f64
  1. 11
      src/SceneGraph/Object.h
  2. 11
      src/SceneGraph/Object.hpp
  3. 27
      src/SceneGraph/Test/ObjectTest.cpp

11
src/SceneGraph/Object.h

@ -205,9 +205,20 @@ template<class Transformation> class MAGNUM_SCENEGRAPH_EXPORT Object: public Abs
/**
* @brief Set parent object
* @return Pointer to self (for method chaining)
*
* @see setParentKeepTransformation()
*/
Object<Transformation>* setParent(Object<Transformation>* parent);
/**
* @brief Set parent object and keep absolute transformation
* @return Pointer to self (for method chaining)
*
* While setParent() preserves only relative transformation of the
* object, this funcition preserves absolute transformation.
*/
Object<Transformation>* setParentKeepTransformation(Object<Transformation>* parent);
/*@}*/
/** @{ @name Object transformation */

11
src/SceneGraph/Object.hpp

@ -87,6 +87,17 @@ template<class Transformation> Object<Transformation>* Object<Transformation>::s
return this;
}
template<class Transformation> Object<Transformation>* Object<Transformation>::setParentKeepTransformation(Object<Transformation>* parent) {
CORRADE_ASSERT(scene() == parent->scene(), "SceneGraph::Object::setParentKeepTransformation(): both parents must be in the same scene", this);
const auto transformation = Transformation::compose(
Transformation::inverted(parent->absoluteTransformation()), absoluteTransformation());
setParent(parent);
this->setTransformation(transformation);
return this;
}
template<class Transformation> typename Transformation::DataType Object<Transformation>::absoluteTransformation() const {
if(!parent()) return Transformation::transformation();
return Transformation::compose(parent()->absoluteTransformation(), Transformation::transformation());

27
src/SceneGraph/Test/ObjectTest.cpp

@ -36,6 +36,7 @@ class ObjectTest: public Corrade::TestSuite::Tester {
void parenting();
void scene();
void setParentKeepTransformation();
void absoluteTransformation();
void transformations();
void transformationsRelative();
@ -66,6 +67,7 @@ class CachingObject: public Object3D, AbstractFeature<3> {
ObjectTest::ObjectTest() {
addTests({&ObjectTest::parenting,
&ObjectTest::scene,
&ObjectTest::setParentKeepTransformation,
&ObjectTest::absoluteTransformation,
&ObjectTest::transformations,
&ObjectTest::transformationsRelative,
@ -120,6 +122,31 @@ void ObjectTest::scene() {
CORRADE_VERIFY(childOfOrphan->scene() == nullptr);
}
void ObjectTest::setParentKeepTransformation() {
Object3D root;
root.rotateZ(Deg(35.0f));
Object3D* childOne = new Object3D(&root);
Object3D* childTwo = new Object3D(&root);
childOne->translate(Vector3::xAxis(2.0f));
childTwo->rotateY(Deg(90.0f));
/* Old parent and new parent must share the same scene */
std::ostringstream o;
Error::setOutput(&o);
Scene3D scene;
childOne->setParentKeepTransformation(&scene);
CORRADE_COMPARE(o.str(), "SceneGraph::Object::setParentKeepTransformation(): both parents must be in the same scene\n");
CORRADE_COMPARE(childOne->parent(), &root);
/* Reparent to another and keep absolute transformation */
auto transformation = childOne->absoluteTransformation();
childOne->setParentKeepTransformation(childTwo);
CORRADE_VERIFY(childOne->parent() == childTwo);
CORRADE_COMPARE(childOne->absoluteTransformation(), transformation);
}
void ObjectTest::absoluteTransformation() {
Scene3D s;

Loading…
Cancel
Save