diff --git a/src/Magnum/SceneGraph/AbstractCamera.hpp b/src/Magnum/SceneGraph/AbstractCamera.hpp index 994729c60..b3128484a 100644 --- a/src/Magnum/SceneGraph/AbstractCamera.hpp +++ b/src/Magnum/SceneGraph/AbstractCamera.hpp @@ -93,9 +93,10 @@ template void AbstractCamera::dr AbstractFeature::object().setClean(); /* Compute transformations of all objects in the group relative to the camera */ - std::vector*> objects(group.size()); + std::vector>> objects; + objects.reserve(group.size()); for(std::size_t i = 0; i != group.size(); ++i) - objects[i] = &group[i].object(); + objects.push_back(group[i].object()); std::vector::MatrixType> transformations = scene->transformationMatrices(objects, _cameraMatrix); diff --git a/src/Magnum/SceneGraph/AbstractObject.h b/src/Magnum/SceneGraph/AbstractObject.h index cc204eb36..f02872d09 100644 --- a/src/Magnum/SceneGraph/AbstractObject.h +++ b/src/Magnum/SceneGraph/AbstractObject.h @@ -29,6 +29,7 @@ * @brief Class @ref Magnum::SceneGraph::AbstractObject, alias @ref Magnum::SceneGraph::AbstractBasicObject2D, @ref Magnum::SceneGraph::AbstractBasicObject3D, typedef @ref Magnum::SceneGraph::AbstractObject2D, @ref Magnum::SceneGraph::AbstractObject3D */ +#include #include #include @@ -154,10 +155,18 @@ template class AbstractObject * @ref Object type, use typesafe @ref Object::transformationMatrices() * when possible. */ - std::vector transformationMatrices(const std::vector*>& objects, const MatrixType& initialTransformationMatrix = MatrixType()) const { + std::vector transformationMatrices(const std::vector>>& objects, const MatrixType& initialTransformationMatrix = MatrixType()) const { return doTransformationMatrices(objects, initialTransformationMatrix); } + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @copybrief transformationMatrices(const std::vector>>&, const MatrixType&) + * @deprecated Use @ref Magnum::SceneGraph::AbstractObject::transformationMatrices(const std::vector>>&, const MatrixType&) "transformationMatrices(const std::vector>>&, const MatrixType&)" instead. + */ + CORRADE_DEPRECATED("use transformationMatrices(const std::vector>>&, const MatrixType&) instead") std::vector transformationMatrices(const std::vector*>& objects, const MatrixType& initialTransformationMatrix = MatrixType()) const; + #endif + /*@}*/ /** @@ -174,11 +183,19 @@ template class AbstractObject * @ref Object type, use typesafe @ref Object::setClean() when * possible. */ - static void setClean(const std::vector*>& objects) { + static void setClean(const std::vector>>& objects) { if(objects.empty()) return; - objects.front()->doSetClean(objects); + objects.front().get().doSetClean(objects); } + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @copybrief setClean(const std::vector>>&) + * @deprecated Use @ref Magnum::SceneGraph::AbstractObject::setClean(const std::vector>>&) "setClean(const std::vector>>&)" instead. + */ + static CORRADE_DEPRECATED("use setClean(const std::vector>>&) instead") void setClean(const std::vector*>& objects); + #endif + /** * @brief Whether absolute transformation is dirty * @@ -223,12 +240,12 @@ template class AbstractObject virtual MatrixType doTransformationMatrix() const = 0; virtual MatrixType doAbsoluteTransformationMatrix() const = 0; - virtual std::vector doTransformationMatrices(const std::vector*>& objects, const MatrixType& initialTransformationMatrix) const = 0; + virtual std::vector doTransformationMatrices(const std::vector>>& objects, const MatrixType& initialTransformationMatrix) const = 0; virtual bool doIsDirty() const = 0; virtual void doSetDirty() = 0; virtual void doSetClean() = 0; - virtual void doSetClean(const std::vector*>& objects) = 0; + virtual void doSetClean(const std::vector>>& objects) = 0; }; #ifndef CORRADE_GCC46_COMPATIBILITY diff --git a/src/Magnum/SceneGraph/Object.h b/src/Magnum/SceneGraph/Object.h index 634b50597..09911ae5c 100644 --- a/src/Magnum/SceneGraph/Object.h +++ b/src/Magnum/SceneGraph/Object.h @@ -247,7 +247,15 @@ template class Object: public AbstractObject transformationMatrices(const std::vector*>& objects, const MatrixType& initialTransformationMatrix = MatrixType()) const; + std::vector transformationMatrices(const std::vector>>& objects, const MatrixType& initialTransformationMatrix = MatrixType()) const; + + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @copybrief transformationMatrices(const std::vector>>&, const MatrixType&) + * @deprecated Use @ref Magnum::SceneGraph::Object::transformationMatrices(const std::vector>>&, const MatrixType&) "transformationMatrices(const std::vector>>&, const MatrixType&)" instead. + */ + CORRADE_DEPRECATED("use transformationMatrices(const std::vector>>&, const MatrixType&) instead") std::vector transformationMatrices(const std::vector*>& objects, const MatrixType& initialTransformationMatrix = MatrixType()) const; + #endif /** * @brief Transformations of given group of objects relative to this object @@ -258,7 +266,15 @@ template class Object: public AbstractObject transformations(std::vector*> objects, const typename Transformation::DataType& initialTransformation = typename Transformation::DataType()) const; + std::vector transformations(std::vector>> objects, const typename Transformation::DataType& initialTransformation = typename Transformation::DataType()) const; + + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @copybrief transformations(std::vector>>, const typename Transformation::DataType&) + * @deprecated Use @ref Magnum::SceneGraph::Object::transformations(std::vector>>, const typename Transformation::DataType&) "transformations(std::vector>>, const typename Transformation::DataType&)" instead. + */ + CORRADE_DEPRECATED("use transformations(std::vector>>, const typename Transformation::DataType&) instead") std::vector transformations(std::vector*> objects, const typename Transformation::DataType& initialTransformation = typename Transformation::DataType()) const; + #endif /*@}*/ @@ -275,7 +291,15 @@ template class Object: public AbstractObject*> objects); + static void setClean(std::vector>> objects); + + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @copybrief setClean(std::vector>>) + * @deprecated Use @ref Magnum::SceneGraph::Object::setClean(std::vector>> "setClean(std::vector>>" instead. + */ + CORRADE_DEPRECATED("use setClean(std::vector>>) instead") static void setClean(std::vector*> objects); + #endif /** @copydoc AbstractObject::isDirty() */ bool isDirty() const { return !!(flags & Flag::Dirty); } @@ -291,7 +315,7 @@ template class Object: public AbstractObject*>), + * See also @ref setClean(std::vector>>), * which cleans given set of objects more efficiently than when calling * @ref setClean() on each object individually. * @see @ref scenegraph-caching, @ref setDirty(), @ref isDirty() @@ -317,16 +341,16 @@ template class Object: public AbstractObject doTransformationMatrices(const std::vector*>& objects, const MatrixType& initialTransformationMatrix) const override final; + std::vector doTransformationMatrices(const std::vector>>& objects, const MatrixType& initialTransformationMatrix) const override final; - typename Transformation::DataType MAGNUM_SCENEGRAPH_LOCAL computeJointTransformation(const std::vector*>& jointObjects, std::vector& jointTransformations, const std::size_t joint, const typename Transformation::DataType& initialTransformation) const; + typename Transformation::DataType MAGNUM_SCENEGRAPH_LOCAL computeJointTransformation(const std::vector>>& jointObjects, std::vector& jointTransformations, const std::size_t joint, const typename Transformation::DataType& initialTransformation) const; bool MAGNUM_SCENEGRAPH_LOCAL doIsDirty() const override final { return isDirty(); } void MAGNUM_SCENEGRAPH_LOCAL doSetDirty() override final { setDirty(); } void MAGNUM_SCENEGRAPH_LOCAL doSetClean() override final { setClean(); } - void doSetClean(const std::vector*>& objects) override final; + void doSetClean(const std::vector>>& objects) override final; - void MAGNUM_SCENEGRAPH_LOCAL setClean(const typename Transformation::DataType& absoluteTransformation); + void MAGNUM_SCENEGRAPH_LOCAL setCleanInternal(const typename Transformation::DataType& absoluteTransformation); typedef Implementation::ObjectFlag Flag; typedef Implementation::ObjectFlags Flags; diff --git a/src/Magnum/SceneGraph/Object.hpp b/src/Magnum/SceneGraph/Object.hpp index d0dafa267..2f6cbcd55 100644 --- a/src/Magnum/SceneGraph/Object.hpp +++ b/src/Magnum/SceneGraph/Object.hpp @@ -38,9 +38,35 @@ namespace Magnum { namespace SceneGraph { +#ifdef MAGNUM_BUILD_DEPRECATED +template void AbstractObject::setClean(const std::vector*>& objects) { + std::vector>> references; + references.reserve(objects.size()); + for(auto o: objects) { + CORRADE_INTERNAL_ASSERT(o != nullptr); + references.push_back(*o); + } + + setClean(references); +} +#endif + template AbstractObject::AbstractObject() {} template AbstractObject::~AbstractObject() {} +#ifdef MAGNUM_BUILD_DEPRECATED +template auto AbstractObject::transformationMatrices(const std::vector*>& objects, const MatrixType& initialTransformationMatrix) const -> std::vector { + std::vector>> references; + references.reserve(objects.size()); + for(auto o: objects) { + CORRADE_INTERNAL_ASSERT(o != nullptr); + references.push_back(*o); + } + + return transformationMatrices(references, initialTransformationMatrix); +} +#endif + template AbstractTransformation::AbstractTransformation() {} template Object::Object(Object* parent): counter(0xFFFFu), flags(Flag::Dirty) { @@ -159,22 +185,21 @@ template void Object::setClean() { /* Compose transformation and clean object */ absoluteTransformation = Implementation::Transformation::compose(absoluteTransformation, o->transformation()); CORRADE_INTERNAL_ASSERT(o->isDirty()); - o->setClean(absoluteTransformation); + o->setCleanInternal(absoluteTransformation); CORRADE_ASSERT(!o->isDirty(), "SceneGraph::Object::setClean(): original implementation was not called", ); } } -template auto Object::doTransformationMatrices(const std::vector*>& objects, const MatrixType& initialTransformationMatrix) const -> std::vector { - std::vector*> castObjects(objects.size()); - for(std::size_t i = 0; i != objects.size(); ++i) - /* Non-null is checked in transformations() */ - /** @todo Ensure this doesn't crash, somehow */ - castObjects[i] = static_cast*>(objects[i]); +template auto Object::doTransformationMatrices(const std::vector>>& objects, const MatrixType& initialTransformationMatrix) const -> std::vector { + std::vector>> castObjects; + castObjects.reserve(objects.size()); + /** @todo Ensure this doesn't crash, somehow */ + for(auto o: objects) castObjects.push_back(static_cast&>(o.get())); return transformationMatrices(std::move(castObjects), initialTransformationMatrix); } -template auto Object::transformationMatrices(const std::vector*>& objects, const MatrixType& initialTransformationMatrix) const -> std::vector { +template auto Object::transformationMatrices(const std::vector>>& objects, const MatrixType& initialTransformationMatrix) const -> std::vector { std::vector transformations = this->transformations(std::move(objects), Implementation::Transformation::fromMatrix(initialTransformationMatrix)); std::vector transformationMatrices(transformations.size()); for(std::size_t i = 0; i != objects.size(); ++i) @@ -183,6 +208,19 @@ template auto Object::transformationMatric return transformationMatrices; } +#ifdef MAGNUM_BUILD_DEPRECATED +template auto Object::transformationMatrices(const std::vector*>& objects, const MatrixType& initialTransformationMatrix) const -> std::vector { + std::vector>> references; + references.reserve(objects.size()); + for(auto o: objects) { + CORRADE_INTERNAL_ASSERT(o != nullptr); + references.push_back(*o); + } + + return transformationMatrices(references, initialTransformationMatrix); +} +#endif + /* Computing absolute transformations for given list of objects @@ -197,7 +235,7 @@ Then for all joints their transformation (relative to parent joint) is computed and recursively concatenated together. Resulting transformations for joints which were originally in `object` list is then returned. */ -template std::vector Object::transformations(std::vector*> objects, const typename Transformation::DataType& initialTransformation) const { +template std::vector Object::transformations(std::vector>> objects, const typename Transformation::DataType& initialTransformation) const { CORRADE_ASSERT(objects.size() < 0xFFFFu, "SceneGraph::Object::transformations(): too large scene", std::vector{}); /* Remember object count for later */ @@ -206,16 +244,14 @@ template std::vector Ob /* Mark all original objects as joints and create initial list of joints from them */ for(std::size_t i = 0; i != objects.size(); ++i) { - CORRADE_INTERNAL_ASSERT(objects[i]); - /* Multiple occurences of one object in the array, don't overwrite it with different counter */ - if(objects[i]->counter != 0xFFFFu) continue; + if(objects[i].get().counter != 0xFFFFu) continue; - objects[i]->counter = UnsignedShort(i); - objects[i]->flags |= Flag::Joint; + objects[i].get().counter = UnsignedShort(i); + objects[i].get().flags |= Flag::Joint; } - std::vector*> jointObjects(objects); + std::vector>> jointObjects(objects); /* Scene object */ const Scene* scene = this->scene(); @@ -227,19 +263,19 @@ template std::vector Ob auto it = objects.begin(); while(!objects.empty()) { /* Already visited, remove and continue to next (duplicate occurence) */ - if((*it)->flags & Flag::Visited) { + if(it->get().flags & Flag::Visited) { it = objects.erase(it); continue; } /* Mark the object as visited */ - (*it)->flags |= Flag::Visited; + it->get().flags |= Flag::Visited; - Object* parent = (*it)->parent(); + Object* parent = it->get().parent(); /* If this is root object, remove from list */ if(!parent) { - CORRADE_ASSERT(*it == scene, "SceneGraph::Object::transformations(): the objects are not part of the same tree", std::vector{}); + CORRADE_ASSERT(&it->get() == scene, "SceneGraph::Object::transformations(): the objects are not part of the same tree", std::vector{}); it = objects.erase(it); /* Parent is an joint or already visited - remove current from list */ @@ -254,11 +290,11 @@ template std::vector Ob CORRADE_INTERNAL_ASSERT(parent->counter == 0xFFFFu); parent->counter = UnsignedShort(jointObjects.size()); parent->flags |= Flag::Joint; - jointObjects.push_back(parent); + jointObjects.push_back(*parent); } /* Else go up the hierarchy */ - } else *it = parent; + } else *it = *parent; /* Cycle if reached end */ if(it == objects.end()) it = objects.begin(); @@ -274,17 +310,17 @@ template std::vector Ob /* Copy transformation for second or next occurences from first occurence of duplicate object */ for(std::size_t i = 0; i != objectCount; ++i) { - if(jointObjects[i]->counter != i) - jointTransformations[i] = jointTransformations[jointObjects[i]->counter]; + if(jointObjects[i].get().counter != i) + jointTransformations[i] = jointTransformations[jointObjects[i].get().counter]; } /* All visited marks are now cleaned, clean joint marks and counters */ for(auto i: jointObjects) { /* All not-already cleaned objects (...duplicate occurences) should have joint mark */ - CORRADE_INTERNAL_ASSERT(i->counter == 0xFFFFu || i->flags & Flag::Joint); - i->flags &= ~Flag::Joint; - i->counter = 0xFFFFu; + CORRADE_INTERNAL_ASSERT(i.get().counter == 0xFFFFu || i.get().flags & Flag::Joint); + i.get().flags &= ~Flag::Joint; + i.get().counter = 0xFFFFu; } /* Shrink the array to contain only transformations of requested objects and return */ @@ -292,27 +328,40 @@ template std::vector Ob return jointTransformations; } -template typename Transformation::DataType Object::computeJointTransformation(const std::vector*>& jointObjects, std::vector& jointTransformations, const std::size_t joint, const typename Transformation::DataType& initialTransformation) const { - Object* o = jointObjects[joint]; +#ifdef MAGNUM_BUILD_DEPRECATED +template std::vector Object::transformations(std::vector*> objects, const typename Transformation::DataType& initialTransformation) const { + std::vector>> references; + references.reserve(objects.size()); + for(auto o: objects) { + CORRADE_INTERNAL_ASSERT(o != nullptr); + references.push_back(*o); + } + + return transformations(references, initialTransformation); +} +#endif + +template typename Transformation::DataType Object::computeJointTransformation(const std::vector>>& jointObjects, std::vector& jointTransformations, const std::size_t joint, const typename Transformation::DataType& initialTransformation) const { + std::reference_wrapper> o = jointObjects[joint]; /* Transformation already computed ("unvisited" by this function before either due to recursion or duplicate object occurences), done */ - if(!(o->flags & Flag::Visited)) return jointTransformations[joint]; + if(!(o.get().flags & Flag::Visited)) return jointTransformations[joint]; /* Initialize transformation */ - jointTransformations[joint] = o->transformation(); + jointTransformations[joint] = o.get().transformation(); /* Go up until next joint or root */ for(;;) { /* Clean visited mark */ - CORRADE_INTERNAL_ASSERT(o->flags & Flag::Visited); - o->flags &= ~Flag::Visited; + CORRADE_INTERNAL_ASSERT(o.get().flags & Flag::Visited); + o.get().flags &= ~Flag::Visited; - Object* parent = o->parent(); + Object* parent = o.get().parent(); /* Root object, compose transformation with initial, done */ if(!parent) { - CORRADE_INTERNAL_ASSERT(o->isScene()); + CORRADE_INTERNAL_ASSERT(o.get().isScene()); return (jointTransformations[joint] = Implementation::Transformation::compose(initialTransformation, jointTransformations[joint])); @@ -324,23 +373,23 @@ template typename Transformation::DataType Object::compose(parent->transformation(), jointTransformations[joint]); - o = parent; + o = *parent; } } } -template void Object::doSetClean(const std::vector*>& objects) { - std::vector*> castObjects(objects.size()); - for(std::size_t i = 0; i != objects.size(); ++i) - /** @todo Ensure this doesn't crash, somehow */ - castObjects[i] = static_cast*>(objects[i]); +template void Object::doSetClean(const std::vector>>& objects) { + std::vector>> castObjects; + castObjects.reserve(objects.size()); + /** @todo Ensure this doesn't crash, somehow */ + for(auto o: objects) castObjects.push_back(static_cast&>(o.get())); setClean(std::move(castObjects)); } -template void Object::setClean(std::vector*> objects) { +template void Object::setClean(std::vector>> objects) { /* Remove all clean objects from the list */ - auto firstClean = std::remove_if(objects.begin(), objects.end(), [](Object* o) { return !o->isDirty(); }); + auto firstClean = std::remove_if(objects.begin(), objects.end(), [](Object& o) { return !o.isDirty(); }); objects.erase(firstClean, objects.end()); /* No dirty objects left, done */ @@ -349,35 +398,48 @@ template void Object::setClean(std::vector /* Add non-clean parents to the list. Mark each added object as visited, so they aren't added more than once */ for(std::size_t end = objects.size(), i = 0; i != end; ++i) { - Object* o = objects[i]; - o->flags |= Flag::Visited; + Object& o = objects[i]; + o.flags |= Flag::Visited; - Object* parent = o->parent(); + Object* parent = o.parent(); while(parent && !(parent->flags & Flag::Visited) && parent->isDirty()) { - objects.push_back(parent); + objects.push_back(*parent); parent = parent->parent(); } } /* Cleanup all marks */ - for(auto o: objects) o->flags &= ~Flag::Visited; + for(auto o: objects) o.get().flags &= ~Flag::Visited; /* Compute absolute transformations */ - Scene* scene = objects[0]->scene(); + Scene* scene = objects[0].get().scene(); CORRADE_ASSERT(scene, "Object::setClean(): objects must be part of some scene", ); std::vector transformations(scene->transformations(objects)); /* Go through all objects and clean them */ for(std::size_t i = 0; i != objects.size(); ++i) { /* The object might be duplicated in the list, don't clean it more than once */ - if(!objects[i]->isDirty()) continue; + if(!objects[i].get().isDirty()) continue; + + objects[i].get().setCleanInternal(transformations[i]); + CORRADE_ASSERT(!objects[i].get().isDirty(), "SceneGraph::Object::setClean(): original implementation was not called", ); + } +} - objects[i]->setClean(transformations[i]); - CORRADE_ASSERT(!objects[i]->isDirty(), "SceneGraph::Object::setClean(): original implementation was not called", ); +#ifdef MAGNUM_BUILD_DEPRECATED +template void Object::setClean(std::vector*> objects) { + std::vector>> references; + references.reserve(objects.size()); + for(auto o: objects) { + CORRADE_INTERNAL_ASSERT(o != nullptr); + references.push_back(*o); } + + return setClean(objects); } +#endif -template void Object::setClean(const typename Transformation::DataType& absoluteTransformation) { +template void Object::setCleanInternal(const typename Transformation::DataType& absoluteTransformation) { /* "Lazy storage" for transformation matrix and inverted transformation matrix */ CachedTransformations cached; MatrixType matrix, invertedMatrix; diff --git a/src/Magnum/SceneGraph/Test/ObjectTest.cpp b/src/Magnum/SceneGraph/Test/ObjectTest.cpp index 401f9accb..c031b3d02 100644 --- a/src/Magnum/SceneGraph/Test/ObjectTest.cpp +++ b/src/Magnum/SceneGraph/Test/ObjectTest.cpp @@ -174,22 +174,22 @@ void ObjectTest::transformations() { Matrix4 initial = Matrix4::rotationX(Deg(90.0f)).inverted(); /* Empty list */ - CORRADE_COMPARE(s.transformations(std::vector(), initial), std::vector()); + CORRADE_COMPARE(s.transformations({}, initial), std::vector()); /* Scene alone */ - CORRADE_COMPARE(s.transformations({&s}, initial), std::vector{initial}); + CORRADE_COMPARE(s.transformations({s}, initial), std::vector{initial}); /* One object */ Object3D first(&s); first.rotateZ(Deg(30.0f)); Object3D second(&first); second.scale(Vector3(0.5f)); - CORRADE_COMPARE(s.transformations({&second}, initial), std::vector{ + CORRADE_COMPARE(s.transformations({second}, initial), std::vector{ initial*Matrix4::rotationZ(Deg(30.0f))*Matrix4::scaling(Vector3(0.5f)) }); /* One object and scene */ - CORRADE_COMPARE(s.transformations({&second, &s}, initial), (std::vector{ + CORRADE_COMPARE(s.transformations({second, s}, initial), (std::vector{ initial*Matrix4::rotationZ(Deg(30.0f))*Matrix4::scaling(Vector3(0.5f)), initial })); @@ -197,13 +197,13 @@ void ObjectTest::transformations() { /* Two objects with foreign joint */ Object3D third(&first); third.translate(Vector3::xAxis(5.0f)); - CORRADE_COMPARE(s.transformations({&second, &third}, initial), (std::vector{ + CORRADE_COMPARE(s.transformations({second, third}, initial), (std::vector{ initial*Matrix4::rotationZ(Deg(30.0f))*Matrix4::scaling(Vector3(0.5f)), initial*Matrix4::rotationZ(Deg(30.0f))*Matrix4::translation(Vector3::xAxis(5.0f)), })); /* Three objects with joint as one of them */ - CORRADE_COMPARE(s.transformations({&second, &third, &first}, initial), (std::vector{ + CORRADE_COMPARE(s.transformations({second, third, first}, initial), (std::vector{ initial*Matrix4::rotationZ(Deg(30.0f))*Matrix4::scaling(Vector3(0.5f)), initial*Matrix4::rotationZ(Deg(30.0f))*Matrix4::translation(Vector3::xAxis(5.0f)), initial*Matrix4::rotationZ(Deg(30.0f)), @@ -222,7 +222,7 @@ void ObjectTest::transformationsRelative() { third.translate(Vector3::xAxis(5.0f)); /* Transformation relative to another object */ - CORRADE_COMPARE(second.transformations({&third}), std::vector{ + CORRADE_COMPARE(second.transformations({third}), std::vector{ Matrix4::scaling(Vector3(0.5f)).inverted()*Matrix4::translation(Vector3::xAxis(5.0f)) }); @@ -234,7 +234,7 @@ void ObjectTest::transformationsRelative() { orphan1.scale(Vector3::xScale(3.0f)); Object3D orphan2(&orphanParent); orphan2.translate(Vector3::zAxis(5.0f)); - CORRADE_COMPARE(orphan1.transformations({&orphan2}), std::vector{ + CORRADE_COMPARE(orphan1.transformations({orphan2}), std::vector{ Matrix4::scaling(Vector3::xScale(3.0f)).inverted()*Matrix4::translation(Vector3::zAxis(5.0f)) }); } @@ -246,7 +246,7 @@ void ObjectTest::transformationsOrphan() { /* Transformation of objects not part of the same scene */ Scene3D s; Object3D orphan; - CORRADE_COMPARE(s.transformations({&orphan}), std::vector()); + CORRADE_COMPARE(s.transformations({orphan}), std::vector()); CORRADE_COMPARE(o.str(), "SceneGraph::Object::transformations(): the objects are not part of the same tree\n"); } @@ -262,7 +262,7 @@ void ObjectTest::transformationsDuplicate() { Matrix4 firstExpected = Matrix4::rotationZ(Deg(30.0f)); Matrix4 secondExpected = Matrix4::rotationZ(Deg(30.0f))*Matrix4::scaling(Vector3(0.5f)); Matrix4 thirdExpected = Matrix4::rotationZ(Deg(30.0f))*Matrix4::translation(Vector3::xAxis(5.0f)); - CORRADE_COMPARE(s.transformations({&second, &third, &second, &first, &third}), (std::vector{ + CORRADE_COMPARE(s.transformations({second, third, second, first, third}), (std::vector{ secondExpected, thirdExpected, secondExpected, firstExpected, thirdExpected })); } @@ -392,7 +392,7 @@ void ObjectTest::setCleanListHierarchy() { childThree->rotate(Deg(90.0f), Vector3::yAxis()); /* Clean the object and all its dirty parents (but not children) */ - Scene3D::setClean(std::vector{childTwo}); + Scene3D::setClean({*childTwo}); CORRADE_VERIFY(!scene.isDirty()); CORRADE_VERIFY(!childOne->isDirty()); CORRADE_VERIFY(!childTwo->isDirty()); @@ -406,19 +406,19 @@ void ObjectTest::setCleanListHierarchy() { /* If the object itself is already clean, it shouldn't clean it again */ childOne->cleanedAbsoluteTransformation = Matrix4(Matrix4::Zero); CORRADE_VERIFY(!childOne->isDirty()); - Scene3D::setClean(std::vector{childOne}); + Scene3D::setClean({*childOne}); CORRADE_COMPARE(childOne->cleanedAbsoluteTransformation, Matrix4(Matrix4::Zero)); /* If any object in the hierarchy is already clean, it shouldn't clean it again */ CORRADE_VERIFY(!childOne->isDirty()); childTwo->setDirty(); - Scene3D::setClean(std::vector{childTwo}); + Scene3D::setClean({*childTwo}); CORRADE_COMPARE(childOne->cleanedAbsoluteTransformation, Matrix4(Matrix4::Zero)); } void ObjectTest::setCleanListBulk() { /* Verify it doesn't crash when passed empty list */ - Object3D::setClean(std::vector()); + Object3D::setClean({}); Scene3D scene; Object3D a(&scene); @@ -429,7 +429,6 @@ void ObjectTest::setCleanListBulk() { CachingObject d(&c); d.scale(Vector3(-2.0f)); Object3D e(&scene); - std::vector cleanAll{&a, &b, &c, &d, &e}; /* All objects should be cleaned */ CORRADE_VERIFY(a.isDirty()); @@ -437,7 +436,7 @@ void ObjectTest::setCleanListBulk() { CORRADE_VERIFY(c.isDirty()); CORRADE_VERIFY(d.isDirty()); CORRADE_VERIFY(e.isDirty()); - Object3D::setClean(cleanAll); + Object3D::setClean({a, b, c, d, e}); CORRADE_VERIFY(!a.isDirty()); CORRADE_VERIFY(!b.isDirty()); CORRADE_VERIFY(!c.isDirty()); diff --git a/src/Magnum/Shapes/ShapeGroup.cpp b/src/Magnum/Shapes/ShapeGroup.cpp index 64648f9db..aebee420d 100644 --- a/src/Magnum/Shapes/ShapeGroup.cpp +++ b/src/Magnum/Shapes/ShapeGroup.cpp @@ -32,9 +32,10 @@ namespace Magnum { namespace Shapes { template void ShapeGroup::setClean() { /* Clean all objects */ if(!this->isEmpty()) { - std::vector*> objects(this->size()); + std::vector>> objects; + objects.reserve(this->size()); for(std::size_t i = 0; i != this->size(); ++i) - objects[i] = &(*this)[i].object(); + objects.push_back((*this)[i].object()); SceneGraph::AbstractObject::setClean(objects); }