12 #ifndef MESHFACTORY_H_6014714286 13 #define MESHFACTORY_H_6014714286 22 #include <unordered_set> 55 template<
typename VertexType >
59 template<
typename VectorType >
60 static VertexType vertex(
const VectorType& position,
const VectorType& normal = VectorType(),
const VectorType& color = VectorType() );
104 template<
typename VertexType >
105 template<
typename VectorType >
109 vertex.x = position.x();
110 vertex.y = position.y();
111 vertex.z = position.z();
112 vertex.setNormal( normal );
113 vertex.setColor ( color );
118 template<
typename VertexType >
121 return createBox( size.x(), size.y(), size.z() );
125 template<
typename VertexType >
140 const std::size_t verticesCount = 6 * 4;
141 const std::size_t indicesCount = 6 * 2 * 3;
144 typedef typename MeshInstance::Vertex Vertex;
145 typedef typename MeshInstance:: Index Index;
146 Vertex vertices[ verticesCount ];
147 Index indices[ indicesCount ];
154 for(
unsigned int faceIndex = 0; faceIndex < 6; ++faceIndex )
156 const auto positionTransform = baseTransform * transforms[ faceIndex ];
157 const auto normalTransform = positionTransform.inverse().transpose();
158 const auto normalVector = ( normalTransform *
math::Vector4f( 0, 0, 1, 0 ) ).normalized();
160 vertices[ ++lastVertex ] = vertex< math::Vector4f >( positionTransform *
math::Vector4f( -1, -1, 1, 1 ), normalVector );
161 vertices[ ++lastVertex ] = vertex< math::Vector4f >( positionTransform *
math::Vector4f( +1, -1, 1, 1 ), normalVector );
162 vertices[ ++lastVertex ] = vertex< math::Vector4f >( positionTransform *
math::Vector4f( +1, +1, 1, 1 ), normalVector );
163 vertices[ ++lastVertex ] = vertex< math::Vector4f >( positionTransform *
math::Vector4f( -1, +1, 1, 1 ), normalVector );
165 indices[ ++lastIndex ] = lastVertex - 3;
166 indices[ ++lastIndex ] = lastVertex - 2;
167 indices[ ++lastIndex ] = lastVertex;
169 indices[ ++lastIndex ] = lastVertex;
170 indices[ ++lastIndex ] = lastVertex - 2;
171 indices[ ++lastIndex ] = lastVertex - 1;
174 return MeshInstance::create
176 , vertices, verticesCount
177 , indices, indicesCount );
181 template<
typename VertexType >
185 const unsigned int verticesPerEdge = 2 + degree;
186 const unsigned int verticesPerSide = verticesPerEdge * verticesPerEdge;
187 const unsigned int facesPerSide = ( verticesPerEdge - 1 ) * ( verticesPerEdge - 1 );
188 const unsigned int indicesPerSide = 6 * facesPerSide;
200 const std::size_t verticesCount = 6 * verticesPerSide;
201 const std::size_t indicesCount = 6 * indicesPerSide;
205 typedef typename MeshInstance::Vertex Vertex;
206 typedef typename MeshInstance:: Index Index;
207 Vertex vertices[ verticesCount ];
208 Index indices[ indicesCount ];
215 for(
unsigned int sideIndex = 0; sideIndex < 6; ++sideIndex )
217 const auto positionTransform = baseTransform * transforms[ sideIndex ];
218 const auto normalTransform = positionTransform.inverse().transpose();
220 for(
unsigned int y = 0; y < verticesPerEdge; ++y )
221 for(
unsigned int x = 0; x < verticesPerEdge; ++x )
223 const float fx = 2 * x / float( verticesPerEdge - 1 );
224 const float fy = 2 * y / float( verticesPerEdge - 1 );
225 const auto position =
math::Vector3f( -1 + fx, -1 + fy, 1 ).normalized();
226 vertices[ ++lastVertex ] = vertex< math::Vector4f >
227 ( positionTransform *
math::Vector4f( position.x(), position.y(), position.z(), 1 )
228 , normalTransform *
math::Vector4f( position.x(), position.y(), position.z(), 0 )
232 for(
unsigned int y = 0; y < verticesPerEdge - 1; ++y )
233 for(
unsigned int x = 0; x < verticesPerEdge - 1; ++x )
235 const uint16_t ul = x + y * verticesPerEdge;
236 const uint16_t ur = x + 1 + y * verticesPerEdge;
237 const uint16_t ll = x + ( y + 1 ) * verticesPerEdge;
238 const uint16_t lr = x + 1 + ( y + 1 ) * verticesPerEdge;
240 indices[ ++lastIndex ] = verticesPerSide * sideIndex + ul;
241 indices[ ++lastIndex ] = verticesPerSide * sideIndex + lr;
242 indices[ ++lastIndex ] = verticesPerSide * sideIndex + ll;
244 indices[ ++lastIndex ] = verticesPerSide * sideIndex + ul;
245 indices[ ++lastIndex ] = verticesPerSide * sideIndex + ur;
246 indices[ ++lastIndex ] = verticesPerSide * sideIndex + lr;
250 return MeshInstance::create
252 , vertices, verticesCount
253 , indices, indicesCount );
257 template<
typename VertexType >
261 typedef typename MeshInstance::Vertex Vertex;
262 typedef typename MeshInstance:: Index Index;
270 template<
typename VertexType >
273 return createFromSTL( std::fstream(path, std::ios::in | std::ios::binary) );
276 template<
typename VertexType >
279 auto origExceptMask = stlStream.exceptions();
280 stlStream.exceptions(std::istream::failbit | std::istream::badbit | std::istream::eofbit);
282 uint32_t amountTriangles;
285 stlStream.seekg(stlStream.beg + 80);
288 stlStream.read(reinterpret_cast<char*>(&amountTriangles), 4);
291 typedef typename MeshInstance::Vertex Vertex;
292 typedef typename MeshInstance::Index Index;
293 typedef typename std::pair< Vertex, std::size_t > VertexIndexPair;
295 std::size_t indicesCount = amountTriangles * 3;
296 std::unique_ptr<Index[]> indices (
new Index [indicesCount]);
297 std::unique_ptr<Vertex[]> vertices(
new Vertex [indicesCount]);
299 std::function<std::size_t(const VertexIndexPair&)> vertexHash =
300 [](
const VertexIndexPair& vertAndIndex) -> std::size_t
304 std::size_t hashVal = std::hash<decltype(vertAndIndex.first.x)>()(vertAndIndex.first.x);
305 hashVal ^= std::hash<decltype(vertAndIndex.first.y)>()(vertAndIndex.first.y) + 0x9e3779b9 + (hashVal << 6) + (hashVal >> 2);
306 hashVal ^= std::hash<decltype(vertAndIndex.first.z)> ()(vertAndIndex.first.z) + 0x9e3779b9 + (hashVal << 6) + (hashVal >> 2);
310 std::function<std::size_t(const VertexIndexPair&, const VertexIndexPair&)> vertexComp =
311 [](
const VertexIndexPair& vertAndIndex1,
const VertexIndexPair& vertAndIndex2) ->
bool 314 return ((vertAndIndex1.first.x) == (vertAndIndex2.first.x)) && ((vertAndIndex1.first.y) == (vertAndIndex2.first.y)) && ((vertAndIndex1.first.z) == (vertAndIndex2.first.z));
317 std::unordered_set< VertexIndexPair, decltype(vertexHash), decltype(vertexComp) > vertsWithArrIndices(amountTriangles * 3, vertexHash, vertexComp);
319 std::size_t indicesItCount = 0;
320 std::size_t verticesItCount = 0;
323 for (
unsigned int i = 0; i < amountTriangles; i++)
326 stlStream.seekg(12, std::ios_base::cur);
329 for (
unsigned int j = 0; j < 3; j++)
334 stlStream.read(reinterpret_cast<char*>(&x), 4);
335 stlStream.read(reinterpret_cast<char*>(&y), 4);
336 stlStream.read(reinterpret_cast<char*>(&z), 4);
343 auto emplRes = vertsWithArrIndices.emplace(std::piecewise_construct, std::forward_as_tuple(std::move(vert)), std::forward_as_tuple(verticesItCount));
347 vertices[verticesItCount++] = (emplRes.first)->first;
350 indices[indicesItCount++] = (emplRes.first)->second;
354 stlStream.seekg(2, std::ios_base::cur);
357 stlStream.exceptions(origExceptMask);
359 return MeshInstance::create
361 , vertices.get(), verticesItCount
362 , indices.get(), indicesCount);
371 #endif // MESHFACTORY_H_6014714286 Defines Carna::base::math namespace and CARNA_FOR_VECTOR3UI.
Matrix4f scaling4f(float x, float y, float z)
Creates scaling matrix for homogeneous coordinates.
static const unsigned int PRIMITIVE_TYPE_POINTS
Draws points. Indicates that each index makes up a single point.
static ManagedMesh< VertexType, uint8_t > & createBox(float width, float height, float depth)
Creates box with width, height and depth. The box is centered in .
Eigen::Matrix< float, 4, 1 > Vector4f
Defines vector.
Defines Carna::base::VertexAttributes.
static const unsigned int PRIMITIVE_TYPE_TRIANGLES
Draws triangles. Indicates that the indices make up the th triangle with .
Matrix4f basis4f(const Vector4f &x, const Vector4f &y, const Vector4f &z, const Vector4f &t=Vector4f(0, 0, 0, 0))
Creates basis embedded into a homogenous coordinates matrix.
Eigen::Matrix< float, 3, 1 > Vector3f
Defines vector.
Defines Carna::base::IndexBuffer.
Creates simple predefined ManagedMesh instances.
Defines Carna::base::ManagedMesh.
Eigen::Matrix< float, 4, 4, Eigen::ColMajor > Matrix4f
Defines matrix.
Defines Carna::base::PVertex, Carna::base::PNVertex, Carna::base::VertexPosition, Carna::base::Vertex...
Implements MeshBase class for particular VertexType and IndexType.
static ManagedMesh< VertexType, uint8_t > & createPoint()
Creates mesh that consists of a single point.
static ManagedMesh< VertexType, uint16_t > & createBall(float radius, unsigned int degree=3)
Creates sphere with radius and a vertices number determined by degree. The ball is centered in ...
#define CARNA_ASSERT(expression)
If the given expression is false, a break point is raised in debug mode and an AssertionFailure throw...
Defines Carna::base::VertexBuffer.
static ManagedMesh< VertexType, uint32_t > & createFromSTL(const std::string &path)
Creates mesh from an STL file.