mirror of https://github.com/mosra/magnum.git
6 changed files with 208 additions and 0 deletions
@ -0,0 +1,52 @@ |
|||||||
|
/*
|
||||||
|
Copyright © 2010, 2011, 2012 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 "GenerateFlatNormals.h" |
||||||
|
|
||||||
|
#include "MeshTools/Clean.h" |
||||||
|
|
||||||
|
using namespace std; |
||||||
|
using namespace Corrade::Utility; |
||||||
|
|
||||||
|
namespace Magnum { namespace MeshTools { |
||||||
|
|
||||||
|
tuple<vector<unsigned int>, vector<Vector3>> generateFlatNormals(const std::vector< unsigned int >& indices, const vector< Vector4 >& vertices) { |
||||||
|
if(indices.size()%3 != 0) { |
||||||
|
Error() << "MeshTools::generateFlatNormals(): index count is not divisible by 3!"; |
||||||
|
return tuple<vector<unsigned int>, vector<Vector3>>(); |
||||||
|
} |
||||||
|
|
||||||
|
/* Create normal for every triangle (assuming counterclockwise winding) */ |
||||||
|
vector<unsigned int> normalIndices; |
||||||
|
normalIndices.reserve(indices.size()); |
||||||
|
vector<Vector3> normals; |
||||||
|
normals.reserve(indices.size()/3); |
||||||
|
for(size_t i = 0; i != indices.size(); i += 3) { |
||||||
|
Vector3 normal = Vector3::cross(vertices[indices[i+2]].xyz()-vertices[indices[i+1]].xyz(), |
||||||
|
vertices[indices[i]].xyz()-vertices[indices[i+1]].xyz()).normalized(); |
||||||
|
|
||||||
|
/* Use the same normal for all three vertices of the face */ |
||||||
|
normalIndices.push_back(normals.size()); |
||||||
|
normalIndices.push_back(normals.size()); |
||||||
|
normalIndices.push_back(normals.size()); |
||||||
|
normals.push_back(normal); |
||||||
|
} |
||||||
|
|
||||||
|
/* Clean duplicate normals and return */ |
||||||
|
clean(normalIndices, normals); |
||||||
|
return make_tuple(normalIndices, normals); |
||||||
|
} |
||||||
|
|
||||||
|
}} |
||||||
@ -0,0 +1,54 @@ |
|||||||
|
#ifndef Magnum_MeshTools_GenerateFlatNormals_h |
||||||
|
#define Magnum_MeshTools_GenerateFlatNormals_h |
||||||
|
/*
|
||||||
|
Copyright © 2010, 2011, 2012 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 Function Magnum::MeshTools::generateFlatNormals() |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <tuple> |
||||||
|
|
||||||
|
#include "Magnum.h" |
||||||
|
|
||||||
|
namespace Magnum { namespace MeshTools { |
||||||
|
|
||||||
|
/**
|
||||||
|
@brief Generate flat normals |
||||||
|
@param indices Array of triangle face indexes |
||||||
|
@param vertices Vertex array |
||||||
|
@return Normal indices and vectors |
||||||
|
|
||||||
|
For each face generates one normal vector, removes duplicates before |
||||||
|
returning. Example usage: |
||||||
|
@code |
||||||
|
std::vector<unsigned int> vertexIndices; |
||||||
|
std::vector<Vector4> vertices; |
||||||
|
|
||||||
|
std::vector<unsigned int> normalIndices; |
||||||
|
std::vector<Vector3> normals; |
||||||
|
std::tie(normalIndices, normals) = MeshTools::generateFlatNormals(vertexIndices, vertices); |
||||||
|
@endcode |
||||||
|
You can then use combineIndexedArrays() to combine normal and vertex array to |
||||||
|
use the same indices. |
||||||
|
|
||||||
|
@attention Index count must be divisible by 3, otherwise zero length result |
||||||
|
is generated. |
||||||
|
*/ |
||||||
|
std::tuple<std::vector<unsigned int>, std::vector<Vector3>> generateFlatNormals(const std::vector<unsigned int>& indices, const std::vector<Vector4>& vertices); |
||||||
|
|
||||||
|
}} |
||||||
|
|
||||||
|
#endif |
||||||
@ -0,0 +1,68 @@ |
|||||||
|
/*
|
||||||
|
Copyright © 2010, 2011, 2012 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 "GenerateFlatNormalsTest.h" |
||||||
|
|
||||||
|
#include <sstream> |
||||||
|
#include <QtTest/QTest> |
||||||
|
#include "MeshTools/GenerateFlatNormals.h" |
||||||
|
|
||||||
|
QTEST_APPLESS_MAIN(Magnum::MeshTools::Test::GenerateFlatNormalsTest) |
||||||
|
|
||||||
|
using namespace std; |
||||||
|
using namespace Corrade::Utility; |
||||||
|
|
||||||
|
namespace Magnum { namespace MeshTools { namespace Test { |
||||||
|
|
||||||
|
void GenerateFlatNormalsTest::wrongIndexCount() { |
||||||
|
stringstream ss; |
||||||
|
Error::setOutput(&ss); |
||||||
|
vector<unsigned int> indices; |
||||||
|
vector<Vector3> normals; |
||||||
|
tie(indices, normals) = MeshTools::generateFlatNormals({ |
||||||
|
0, 1 |
||||||
|
}, {}); |
||||||
|
|
||||||
|
QVERIFY(indices.size() == 0); |
||||||
|
QVERIFY(normals.size() == 0); |
||||||
|
QVERIFY(ss.str() == "MeshTools::generateFlatNormals(): index count is not divisible by 3!\n"); |
||||||
|
} |
||||||
|
|
||||||
|
void GenerateFlatNormalsTest::generate() { |
||||||
|
/* Two vertices connected by one edge, each winded in another direction */ |
||||||
|
vector<unsigned int> indices; |
||||||
|
vector<Vector3> normals; |
||||||
|
tie(indices, normals) = MeshTools::generateFlatNormals({ |
||||||
|
0, 1, 2, |
||||||
|
1, 2, 3 |
||||||
|
}, { |
||||||
|
{-1.0f, 0.0f, 0.0f}, |
||||||
|
{0.0f, -1.0f, 0.0f}, |
||||||
|
{0.0f, 1.0f, 0.0f}, |
||||||
|
{1.0f, 0.0f, 0.0f} |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
QVERIFY((indices == vector<unsigned int>{ |
||||||
|
0, 0, 0, |
||||||
|
1, 1, 1 |
||||||
|
})); |
||||||
|
QVERIFY((normals == vector<Vector3>{ |
||||||
|
Vector3::zAxis(), |
||||||
|
-Vector3::zAxis() |
||||||
|
})); |
||||||
|
} |
||||||
|
|
||||||
|
}}} |
||||||
@ -0,0 +1,32 @@ |
|||||||
|
#ifndef Magnum_MeshTools_Test_GenerateFlatNormalsTest_h |
||||||
|
#define Magnum_MeshTools_Test_GenerateFlatNormalsTest_h |
||||||
|
/*
|
||||||
|
Copyright © 2010, 2011, 2012 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> |
||||||
|
|
||||||
|
namespace Magnum { namespace MeshTools { namespace Test { |
||||||
|
|
||||||
|
class GenerateFlatNormalsTest: public QObject { |
||||||
|
Q_OBJECT |
||||||
|
|
||||||
|
private slots: |
||||||
|
void wrongIndexCount(); |
||||||
|
void generate(); |
||||||
|
}; |
||||||
|
|
||||||
|
}}} |
||||||
|
|
||||||
|
#endif |
||||||
Loading…
Reference in new issue