<commit_before>/*
    Copyright © 2010, 2011, 2012 <NAME> <<EMAIL>>

    This file is part of Magnum.

    Magnum is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License version 3
    only, as published by the Free Software Foundation.

    Magnum is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU Lesser General Public License version 3 for more details.
*/

#include "ObjectTest.h"

#include <sstream>

#include "Math/Constants.h"
#include "SceneGraph/MatrixTransformation3D.h"
#include "SceneGraph/Scene.h"

using namespace std;

CORRADE_TEST_MAIN(Magnum::SceneGraph::Test::ObjectTest)

namespace Magnum { namespace SceneGraph { namespace Test {

typedef SceneGraph::Object<SceneGraph::MatrixTransformation3D<GLfloat>> Object3D;
typedef SceneGraph::Scene<SceneGraph::MatrixTransformation3D<GLfloat>> Scene3D;

class CachingObject: public Object3D, AbstractFeature<3, GLfloat> {
    public:
        inline CachingObject(Object3D* parent = nullptr): Object3D(parent), AbstractFeature<3, GLfloat>(this) {
            setCachedTransformations(CachedTransformation::Absolute);
        }

        Matrix4 cleanedAbsoluteTransformation;

    protected:
        void clean(const Matrix4& absoluteTransformation) override {
            cleanedAbsoluteTransformation = absoluteTransformation;
        }
};

ObjectTest::ObjectTest() {
    addTests(&ObjectTest::parenting,
             &ObjectTest::scene,
             &ObjectTest::absoluteTransformation,
             &ObjectTest::transformations,
             &ObjectTest::setClean,
             &ObjectTest::bulkSetClean);
}

void ObjectTest::parenting() {
    Object3D root;

    Object3D* childOne = new Object3D(&root);
    Object3D* childTwo = new Object3D(&root);

    CORRADE_VERIFY(childOne->parent() == &root);
    CORRADE_VERIFY(childTwo->parent() == &root);
    CORRADE_VERIFY(root.firstChild() == childOne);
    CORRADE_VERIFY(root.lastChild() == childTwo);
    CORRADE_VERIFY(root.firstChild()->nextSibling() == root.lastChild());

    /* A object cannot be parent of itself */
    childOne->setParent(childOne);
    CORRADE_VERIFY(childOne->parent() == &root);

    /* In fact, cyclic dependencies are not allowed at all */
    root.setParent(childTwo);
    CORRADE_VERIFY(root.parent() == nullptr);

    /* Reparent to another */
    childTwo->setParent(childOne);
    CORRADE_VERIFY(root.firstChild() == childOne && root.firstChild()->nextSibling() == nullptr);
    CORRADE_VERIFY(childOne->firstChild() == childTwo && childOne->firstChild()->nextSibling() == nullptr);

    /* Delete child */
    delete childTwo;
    CORRADE_VERIFY(!childOne->hasChildren());
}

void ObjectTest::scene() {
    Scene3D scene;
    CORRADE_VERIFY(scene.scene() == &scene);

    Object3D* childOne = new Object3D(&scene);
    Object3D* childTwo = new Object3D(childOne);

    Object3D orphan;
    Object3D* childOfOrphan = new Object3D(&orphan);

    CORRADE_VERIFY(childTwo->scene() == &scene);
    CORRADE_VERIFY(childOfOrphan->scene() == nullptr);
}

void ObjectTest::absoluteTransformation() {
    Scene3D s;

    /* Proper transformation composition */
    Object3D o(&s);
    o.translate(Vector3::xAxis(2.0f));
    Object3D o2(&o);
    o2.rotateY(deg(90.0f));
    CORRADE_COMPARE(o2.absoluteTransformation(),
        Matrix4::translation(Vector3::xAxis(2.0f))*Matrix4::rotationY(deg(90.0f)));
    CORRADE_COMPARE(o2.absoluteTransformation(), o2.absoluteTransformationMatrix());

    /* Transformation of root object */
    Object3D o3;
    o3.translate({1.0f, 2.0f, 3.0f});
    CORRADE_COMPARE(o3.absoluteTransformation(), Matrix4::translation({1.0f, 2.0f, 3.0f}));
}

void ObjectTest::transformations() {
    Scene3D s;

    Matrix4 initial = Matrix4::rotationX(deg(90.0f)).inverted();

    /* Scene alone */
    CORRADE_COMPARE(s.transformations({&s}, initial), vector<Matrix4>{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), vector<Matrix4>{<commit_msg>SceneGraph: test Object::transformations() for empty list.<commit_after>/*
    Copyright © 2010, 2011, 2012 <NAME> <<EMAIL>>

    This file is part of Magnum.

    Magnum is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License version 3
    only, as published by the Free Software Foundation.

    Magnum is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU Lesser General Public License version 3 for more details.
*/

#include "ObjectTest.h"

#include <sstream>

#include "Math/Constants.h"
#include "SceneGraph/MatrixTransformation3D.h"
#include "SceneGraph/Scene.h"

using namespace std;

CORRADE_TEST_MAIN(Magnum::SceneGraph::Test::ObjectTest)

namespace Magnum { namespace SceneGraph { namespace Test {

typedef SceneGraph::Object<SceneGraph::MatrixTransformation3D<GLfloat>> Object3D;
typedef SceneGraph::Scene<SceneGraph::MatrixTransformation3D<GLfloat>> Scene3D;

class CachingObject: public Object3D, AbstractFeature<3, GLfloat> {
    public:
        inline CachingObject(Object3D* parent = nullptr): Object3D(parent), AbstractFeature<3, GLfloat>(this) {
            setCachedTransformations(CachedTransformation::Absolute);
        }

        Matrix4 cleanedAbsoluteTransformation;

    protected:
        void clean(const Matrix4& absoluteTransformation) override {
            cleanedAbsoluteTransformation = absoluteTransformation;
        }
};

ObjectTest::ObjectTest() {
    addTests(&ObjectTest::parenting,
             &ObjectTest::scene,
             &ObjectTest::absoluteTransformation,
             &ObjectTest::transformations,
             &ObjectTest::setClean,
             &ObjectTest::bulkSetClean);
}

void ObjectTest::parenting() {
    Object3D root;

    Object3D* childOne = new Object3D(&root);
    Object3D* childTwo = new Object3D(&root);

    CORRADE_VERIFY(childOne->parent() == &root);
    CORRADE_VERIFY(childTwo->parent() == &root);
    CORRADE_VERIFY(root.firstChild() == childOne);
    CORRADE_VERIFY(root.lastChild() == childTwo);
    CORRADE_VERIFY(root.firstChild()->nextSibling() == root.lastChild());

    /* A object cannot be parent of itself */
    childOne->setParent(childOne);
    CORRADE_VERIFY(childOne->parent() == &root);

    /* In fact, cyclic dependencies are not allowed at all */
    root.setParent(childTwo);
    CORRADE_VERIFY(root.parent() == nullptr);

    /* Reparent to another */
    childTwo->setParent(childOne);
    CORRADE_VERIFY(root.firstChild() == childOne && root.firstChild()->nextSibling() == nullptr);
    CORRADE_VERIFY(childOne->firstChild() == childTwo && childOne->firstChild()->nextSibling() == nullptr);

    /* Delete child */
    delete childTwo;
    CORRADE_VERIFY(!childOne->hasChildren());
}

void ObjectTest::scene() {
    Scene3D scene;
    CORRADE_VERIFY(scene.scene() == &scene);

    Object3D* childOne = new Object3D(&scene);
    Object3D* childTwo = new Object3D(childOne);

    Object3D orphan;
    Object3D* childOfOrphan = new Object3D(&orphan);

    CORRADE_VERIFY(childTwo->scene() == &scene);
    CORRADE_VERIFY(childOfOrphan->scene() == nullptr);
}

void ObjectTest::absoluteTransformation() {
    Scene3D s;

    /* Proper transformation composition */
    Object3D o(&s);
    o.translate(Vector3::xAxis(2.0f));
    Object3D o2(&o);
    o2.rotateY(deg(90.0f));
    CORRADE_COMPARE(o2.absoluteTransformation(),
        Matrix4::translation(Vector3::xAxis(2.0f))*Matrix4::rotationY(deg(90.0f)));
    CORRADE_COMPARE(o2.absoluteTransformation(), o2.absoluteTransformationMatrix());

    /* Transformation of root object */
    Object3D o3;
    o3.translate({1.0f, 2.0f, 3.0f});
    CORRADE_COMPARE(o3.absoluteTransformation(), Matrix4::translation({1.0f, 2.0f, 3.0f}));
}

void ObjectTest::transformations() {
    Scene3D s;

    Matrix4 initial = Matrix4::rotationX(deg(90.0f)).inverted();

    /* Empty list */
    CORRADE_COMPARE(s.transformations(vector<Object3D*>(), initial), vector<Matrix4>());

    /* Scene alone */
    CORRADE_COMPARE(s.transformations({&s}, initial), vector<Matrix4>{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), vector<Matrix4>{
{'fraction_non_alphanumeric': 0.12873907040957203, 'fraction_numerical': 0.021859180855959504, 'mean_word_length': 4.113529411764706, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 55, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5305755', 'n_tokens_mistral': 2804, 'n_tokens_neox': 2660, 'n_words': 573}