mirror of https://github.com/mosra/magnum.git
6 changed files with 285 additions and 0 deletions
@ -0,0 +1,46 @@ |
|||||||
|
/*
|
||||||
|
Copyright © 2010 Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
|
||||||
|
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 "AbstractObject.h" |
||||||
|
|
||||||
|
using namespace std; |
||||||
|
|
||||||
|
namespace Magnum { |
||||||
|
|
||||||
|
void AbstractObject::setParent(AbstractObject* parent) { |
||||||
|
if(_parent == parent) return; |
||||||
|
|
||||||
|
/* Remove the object from old parent children list */ |
||||||
|
if(_parent != 0) |
||||||
|
_parent->_children.erase(this); |
||||||
|
|
||||||
|
/* Set new parent and add the object to new parent children list */ |
||||||
|
if(parent != 0) { |
||||||
|
parent->_children.insert(this); |
||||||
|
} |
||||||
|
|
||||||
|
_parent = parent; |
||||||
|
} |
||||||
|
|
||||||
|
AbstractObject::~AbstractObject() { |
||||||
|
/* Remove the object from parent's children */ |
||||||
|
setParent(0); |
||||||
|
|
||||||
|
/* Delete all children */ |
||||||
|
for(set<AbstractObject*>::const_iterator it = _children.begin(); it != _children.end(); ++it) |
||||||
|
delete *it; |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,143 @@ |
|||||||
|
#ifndef Magnum_AbstractObject_h |
||||||
|
#define Magnum_AbstractObject_h |
||||||
|
/*
|
||||||
|
Copyright © 2010 Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
|
||||||
|
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. |
||||||
|
*/ |
||||||
|
|
||||||
|
/** @file
|
||||||
|
* @brief Class Magnum::AbstractObject |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <set> |
||||||
|
|
||||||
|
#include "Magnum.h" |
||||||
|
|
||||||
|
namespace Magnum { |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Base for all positioned objects |
||||||
|
* |
||||||
|
* @todo Transform transformation when changing parent, so the object stays in |
||||||
|
* place. |
||||||
|
*/ |
||||||
|
class AbstractObject { |
||||||
|
DISABLE_COPY(AbstractObject) |
||||||
|
|
||||||
|
public: |
||||||
|
/**
|
||||||
|
* @brief Constructor |
||||||
|
* @param parent Parent object |
||||||
|
* |
||||||
|
* Sets all transformations to their default values. |
||||||
|
*/ |
||||||
|
inline AbstractObject(AbstractObject* parent = 0): _parent(0) { |
||||||
|
setParent(parent); |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Destructor |
||||||
|
* |
||||||
|
* Removes itself from parent's children list and destroys all own |
||||||
|
* children. |
||||||
|
*/ |
||||||
|
virtual ~AbstractObject(); |
||||||
|
|
||||||
|
/** @brief Parent object */ |
||||||
|
inline AbstractObject* parent() const { return _parent; } |
||||||
|
|
||||||
|
/** @brief Child objects */ |
||||||
|
const std::set<AbstractObject*>& children() const { return _children; } |
||||||
|
|
||||||
|
/** @brief Set parent object */ |
||||||
|
void setParent(AbstractObject* parent); |
||||||
|
|
||||||
|
/** @brief Transformation matrix */ |
||||||
|
inline Matrix4 transformation() const { return _transformation; } |
||||||
|
|
||||||
|
/** @brief Set transformation matrix */ |
||||||
|
inline void setTransformation(const Matrix4& transformation) { _transformation = transformation; } |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Multiply transformation matrix |
||||||
|
* |
||||||
|
* Multiplies current transformation matrix <strong>from the |
||||||
|
* left</strong> by new matrix. |
||||||
|
*/ |
||||||
|
inline void multiplyTransformation(const Matrix4& transformation) { _transformation = transformation*_transformation; } |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set transformation and parent from another object |
||||||
|
* |
||||||
|
* Sets parent and transformation from another object, so they will |
||||||
|
* appear in the same place. |
||||||
|
*/ |
||||||
|
inline void setTransformationFrom(const AbstractObject& another) { |
||||||
|
setParent(another.parent()); |
||||||
|
setTransformation(another.transformation()); |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Translate object |
||||||
|
* |
||||||
|
* Same as calling multiplyTransformation() with Matrix4::translation(). |
||||||
|
*/ |
||||||
|
inline void translate(Vector3 vec) { |
||||||
|
multiplyTransformation(Matrix4::translation(vec)); |
||||||
|
} |
||||||
|
|
||||||
|
/** @copydoc translate(Vector3) */ |
||||||
|
inline void translate(GLfloat x, GLfloat y, GLfloat z) { |
||||||
|
translate(Vector3(x, y, z)); |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Scale object |
||||||
|
* |
||||||
|
* Same as calling multiplyTransformation() with Matrix4::scaling(). |
||||||
|
*/ |
||||||
|
inline void scale(Vector3 vec) { |
||||||
|
multiplyTransformation(Matrix4::scaling(vec)); |
||||||
|
} |
||||||
|
|
||||||
|
/** @copydoc scale(Vector3) */ |
||||||
|
inline void scale(GLfloat x, GLfloat y, GLfloat z) { |
||||||
|
scale(Vector3(x, y, z)); |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Rotate object |
||||||
|
* |
||||||
|
* Same as calling multiplyTransformation() with Matrix4::rotation(). |
||||||
|
*/ |
||||||
|
inline void rotate(GLfloat angle, Vector3 vec) { |
||||||
|
multiplyTransformation(Matrix4::rotation(angle, vec)); |
||||||
|
} |
||||||
|
|
||||||
|
/** @copydoc rotate(GLfloat, Vector3) */ |
||||||
|
inline void rotate(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) { |
||||||
|
rotate(angle, Vector3(x, y, z)); |
||||||
|
} |
||||||
|
|
||||||
|
/** @brief Draw object */ |
||||||
|
virtual void draw(const Matrix4& transformationMatrix, const Matrix4& projectionMatrix) = 0; |
||||||
|
|
||||||
|
private: |
||||||
|
AbstractObject* _parent; |
||||||
|
std::set<AbstractObject*> _children; |
||||||
|
Matrix4 _transformation; |
||||||
|
}; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
#endif |
||||||
@ -1,7 +1,18 @@ |
|||||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}) |
include_directories(${CMAKE_CURRENT_SOURCE_DIR}) |
||||||
|
|
||||||
|
find_package(OpenGL REQUIRED) |
||||||
|
find_package(GLEW REQUIRED) |
||||||
|
|
||||||
add_subdirectory(Math) |
add_subdirectory(Math) |
||||||
|
|
||||||
|
set(Magnum_SRCS |
||||||
|
AbstractObject.cpp |
||||||
|
) |
||||||
|
|
||||||
|
add_library(Magnum SHARED ${Magnum_SRCS}) |
||||||
|
target_link_libraries(Magnum ${OPENGL_gl_LIBRARY} ${GLEW_LIBRARY}) |
||||||
|
|
||||||
if(BUILD_TESTS) |
if(BUILD_TESTS) |
||||||
enable_testing() |
enable_testing() |
||||||
|
add_subdirectory(Test) |
||||||
endif() |
endif() |
||||||
|
|||||||
@ -0,0 +1,43 @@ |
|||||||
|
/*
|
||||||
|
Copyright © 2010 Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
|
||||||
|
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 "AbstractObjectTest.h" |
||||||
|
|
||||||
|
#include <QtTest/QTest> |
||||||
|
|
||||||
|
QTEST_APPLESS_MAIN(Magnum::Test::AbstractObjectTest) |
||||||
|
|
||||||
|
namespace Magnum { namespace Test { |
||||||
|
|
||||||
|
void AbstractObjectTest::parenting() { |
||||||
|
Object root; |
||||||
|
|
||||||
|
Object* childOne = new Object(&root); |
||||||
|
Object* childTwo = new Object(&root); |
||||||
|
|
||||||
|
QVERIFY(childOne->parent() == &root); |
||||||
|
QVERIFY(root.children().size() == 2); |
||||||
|
|
||||||
|
/* Reparent to another */ |
||||||
|
childTwo->setParent(childOne); |
||||||
|
QVERIFY(root.children().size() == 1 && *root.children().begin() == childOne); |
||||||
|
QVERIFY(childOne->children().size() == 1 && *childOne->children().begin() == childTwo); |
||||||
|
|
||||||
|
/* Delete child */ |
||||||
|
delete childTwo; |
||||||
|
QVERIFY(childOne->children().size() == 0); |
||||||
|
} |
||||||
|
|
||||||
|
}} |
||||||
@ -0,0 +1,41 @@ |
|||||||
|
#ifndef Magnum_Test_AbstractObjectTest_h |
||||||
|
#define Magnum_Test_AbstractObjectTest_h |
||||||
|
/*
|
||||||
|
Copyright © 2010 Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
|
||||||
|
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 <QtCore/QObject> |
||||||
|
|
||||||
|
#include "AbstractObject.h" |
||||||
|
|
||||||
|
namespace Magnum { namespace Test { |
||||||
|
|
||||||
|
class Object: public AbstractObject { |
||||||
|
public: |
||||||
|
inline Object(AbstractObject* parent = 0): AbstractObject(parent) {} |
||||||
|
inline virtual void draw(const Magnum::Matrix4& transformationMatrix, const Magnum::Matrix4& projectionMatrix) {} |
||||||
|
|
||||||
|
inline const std::set<AbstractObject*>& children() { return AbstractObject::children(); } |
||||||
|
}; |
||||||
|
|
||||||
|
class AbstractObjectTest: public QObject { |
||||||
|
Q_OBJECT |
||||||
|
|
||||||
|
private slots: |
||||||
|
void parenting(); |
||||||
|
}; |
||||||
|
|
||||||
|
}} |
||||||
|
|
||||||
|
#endif |
||||||
Loading…
Reference in new issue