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