#include "primitives.hpp" #include #include namespace renderer { namespace primitives { Mesh makeCube() { std::vector< float > verts = { -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f }; Mesh m; m.createFromPositions( verts, false ); return m; } Mesh makeTexturedCube() { std::vector< float > verts; verts.insert( verts.end(), { -0.5f, -0.5f, 0.5f, 0.0f, 0.0f } ); verts.insert( verts.end(), { 0.5f, -0.5f, 0.5f, 1.0f, 0.0f } ); verts.insert( verts.end(), { 0.5f, 0.5f, 0.5f, 1.0f, 1.0f } ); verts.insert( verts.end(), { 0.5f, 0.5f, 0.5f, 1.0f, 1.0f } ); verts.insert( verts.end(), { -0.5f, 0.5f, 0.5f, 0.0f, 1.0f } ); verts.insert( verts.end(), { -0.5f, -0.5f, 0.5f, 0.0f, 0.0f } ); verts.insert( verts.end(), { 0.5f, -0.5f, -0.5f, 0.0f, 0.0f } ); verts.insert( verts.end(), { -0.5f, -0.5f, -0.5f, 1.0f, 0.0f } ); verts.insert( verts.end(), { -0.5f, 0.5f, -0.5f, 1.0f, 1.0f } ); verts.insert( verts.end(), { -0.5f, 0.5f, -0.5f, 1.0f, 1.0f } ); verts.insert( verts.end(), { 0.5f, 0.5f, -0.5f, 0.0f, 1.0f } ); verts.insert( verts.end(), { 0.5f, -0.5f, -0.5f, 0.0f, 0.0f } ); verts.insert( verts.end(), { -0.5f, -0.5f, -0.5f, 0.0f, 0.0f } ); verts.insert( verts.end(), { -0.5f, -0.5f, 0.5f, 1.0f, 0.0f } ); verts.insert( verts.end(), { -0.5f, 0.5f, 0.5f, 1.0f, 1.0f } ); verts.insert( verts.end(), { -0.5f, 0.5f, 0.5f, 1.0f, 1.0f } ); verts.insert( verts.end(), { -0.5f, 0.5f, -0.5f, 0.0f, 1.0f } ); verts.insert( verts.end(), { -0.5f, -0.5f, -0.5f, 0.0f, 0.0f } ); verts.insert( verts.end(), { 0.5f, -0.5f, 0.5f, 0.0f, 0.0f } ); verts.insert( verts.end(), { 0.5f, -0.5f, -0.5f, 1.0f, 0.0f } ); verts.insert( verts.end(), { 0.5f, 0.5f, -0.5f, 1.0f, 1.0f } ); verts.insert( verts.end(), { 0.5f, 0.5f, -0.5f, 1.0f, 1.0f } ); verts.insert( verts.end(), { 0.5f, 0.5f, 0.5f, 0.0f, 1.0f } ); verts.insert( verts.end(), { 0.5f, -0.5f, 0.5f, 0.0f, 0.0f } ); verts.insert( verts.end(), { -0.5f, 0.5f, 0.5f, 0.0f, 0.0f } ); verts.insert( verts.end(), { 0.5f, 0.5f, 0.5f, 1.0f, 0.0f } ); verts.insert( verts.end(), { 0.5f, 0.5f, -0.5f, 1.0f, 1.0f } ); verts.insert( verts.end(), { 0.5f, 0.5f, -0.5f, 1.0f, 1.0f } ); verts.insert( verts.end(), { -0.5f, 0.5f, -0.5f, 0.0f, 1.0f } ); verts.insert( verts.end(), { -0.5f, 0.5f, 0.5f, 0.0f, 0.0f } ); verts.insert( verts.end(), { -0.5f, -0.5f, -0.5f, 0.0f, 0.0f } ); verts.insert( verts.end(), { 0.5f, -0.5f, -0.5f, 1.0f, 0.0f } ); verts.insert( verts.end(), { 0.5f, -0.5f, 0.5f, 1.0f, 1.0f } ); verts.insert( verts.end(), { 0.5f, -0.5f, 0.5f, 1.0f, 1.0f } ); verts.insert( verts.end(), { -0.5f, -0.5f, 0.5f, 0.0f, 1.0f } ); verts.insert( verts.end(), { -0.5f, -0.5f, -0.5f, 0.0f, 0.0f } ); Mesh m; m.createFromPosTex( verts ); return m; } Mesh makeGrid( int halfSize, float spacing ) { std::vector< float > verts; for ( int i = -halfSize; i <= halfSize; ++i ) { float x = i * spacing; verts.push_back( x ); verts.push_back( 0.0f ); verts.push_back( -halfSize * spacing ); verts.push_back( x ); verts.push_back( 0.0f ); verts.push_back( halfSize * spacing ); } for ( int j = -halfSize; j <= halfSize; ++j ) { float z = j * spacing; verts.push_back( -halfSize * spacing ); verts.push_back( 0.0f ); verts.push_back( z ); verts.push_back( halfSize * spacing ); verts.push_back( 0.0f ); verts.push_back( z ); } Mesh m; m.createFromPositions( verts, true ); return m; } Mesh makeTexturedGrid( int width, int depth, float tileSize ) { std::vector< float > verts; for ( int z = 0; z < depth; ++z ) { for ( int x = 0; x < width; ++x ) { float x0 = ( x - width * 0.5f ) * tileSize; float z0 = ( z - depth * 0.5f ) * tileSize; float x1 = x0 + tileSize; float z1 = z0 + tileSize; verts.push_back( x0 ); verts.push_back( 0.0f ); verts.push_back( z0 ); verts.push_back( 0.0f ); verts.push_back( 0.0f ); verts.push_back( x1 ); verts.push_back( 0.0f ); verts.push_back( z0 ); verts.push_back( 1.0f ); verts.push_back( 0.0f ); verts.push_back( x0 ); verts.push_back( 0.0f ); verts.push_back( z1 ); verts.push_back( 0.0f ); verts.push_back( 1.0f ); verts.push_back( x0 ); verts.push_back( 0.0f ); verts.push_back( z1 ); verts.push_back( 0.0f ); verts.push_back( 1.0f ); verts.push_back( x1 ); verts.push_back( 0.0f ); verts.push_back( z0 ); verts.push_back( 1.0f ); verts.push_back( 0.0f ); verts.push_back( x1 ); verts.push_back( 0.0f ); verts.push_back( z1 ); verts.push_back( 1.0f ); verts.push_back( 1.0f ); } } Mesh m; m.createFromPosTex( verts ); return m; } Mesh makeTexturedCubeGrid( int width, int depth, float tileSize ) { std::vector< float > verts; auto pushFace = [&]( const std::array< float, 18 > &pos, const std::array< float, 12 > &uv, float cx, float cy, float cz, float scale ) { for ( int i = 0; i < 6; ++i ) { int pi = i * 3; int ui = i * 2; verts.push_back( cx + pos[pi + 0] * scale ); verts.push_back( cy + pos[pi + 1] * scale ); verts.push_back( cz + pos[pi + 2] * scale ); verts.push_back( uv[ui + 0] ); verts.push_back( uv[ui + 1] ); } }; const std::array< float, 18 > topPos = { -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f }; const std::array< float, 12 > topUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f }; const std::array< float, 18 > bottomPos = { -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f }; const std::array< float, 12 > bottomUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f }; const std::array< float, 18 > frontPos = { -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f }; const std::array< float, 12 > frontUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f }; const std::array< float, 18 > backPos = { 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f }; const std::array< float, 12 > backUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f }; const std::array< float, 18 > leftPos = { -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f }; const std::array< float, 12 > leftUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f }; const std::array< float, 18 > rightPos = { 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, 0.5f }; const std::array< float, 12 > rightUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f }; for ( int z = 0; z < depth; ++z ) { for ( int x = 0; x < width; ++x ) { float cx = ( x - width * 0.5f ) * tileSize + tileSize * 0.5f; float cz = ( z - depth * 0.5f ) * tileSize + tileSize * 0.5f; float cy = -0.5f * tileSize; float scale = tileSize; pushFace( topPos, topUV, cx, cy, cz, scale ); pushFace( bottomPos, bottomUV, cx, cy, cz, scale ); pushFace( frontPos, frontUV, cx, cy, cz, scale ); pushFace( backPos, backUV, cx, cy, cz, scale ); pushFace( leftPos, leftUV, cx, cy, cz, scale ); pushFace( rightPos, rightUV, cx, cy, cz, scale ); } } Mesh m; m.createFromPosTex( verts ); return m; } Mesh makeTexturedWall( int length, int height, float tileSize, bool alongX, float fixedCoord ) { std::vector< float > verts; auto pushFace = [&]( const std::array< float, 18 > &pos, const std::array< float, 12 > &uv, float cx, float cy, float cz, float scale ) { for ( int i = 0; i < 6; ++i ) { int pi = i * 3; int ui = i * 2; verts.push_back( cx + pos[pi + 0] * scale ); verts.push_back( cy + pos[pi + 1] * scale ); verts.push_back( cz + pos[pi + 2] * scale ); verts.push_back( uv[ui + 0] ); verts.push_back( uv[ui + 1] ); } }; const std::array< float, 18 > topPos = { -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f }; const std::array< float, 12 > topUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f }; const std::array< float, 18 > bottomPos = { -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f }; const std::array< float, 12 > bottomUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f }; const std::array< float, 18 > frontPos = { -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f }; const std::array< float, 12 > frontUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f }; const std::array< float, 18 > backPos = { 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f }; const std::array< float, 12 > backUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f }; const std::array< float, 18 > leftPos = { -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f }; const std::array< float, 12 > leftUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f }; const std::array< float, 18 > rightPos = { 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, 0.5f }; const std::array< float, 12 > rightUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f }; if ( alongX ) { for ( int lx = 0; lx < length; ++lx ) { float cx = ( lx - length * 0.5f ) * tileSize + tileSize * 0.5f; float cz = fixedCoord; for ( int hy = 0; hy < height; ++hy ) { float cy = 0.02f * tileSize + hy * tileSize; float scale = tileSize; pushFace( topPos, topUV, cx, cy, cz, scale ); pushFace( bottomPos, bottomUV, cx, cy, cz, scale ); pushFace( frontPos, frontUV, cx, cy, cz, scale ); pushFace( backPos, backUV, cx, cy, cz, scale ); pushFace( leftPos, leftUV, cx, cy, cz, scale ); pushFace( rightPos, rightUV, cx, cy, cz, scale ); } } } else { for ( int lz = 0; lz < length; ++lz ) { float cz = ( lz - length * 0.5f ) * tileSize + tileSize * 0.5f; float cx = fixedCoord; for ( int hy = 0; hy < height; ++hy ) { float cy = 0.02f * tileSize + hy * tileSize; float scale = tileSize; pushFace( topPos, topUV, cx, cy, cz, scale ); pushFace( bottomPos, bottomUV, cx, cy, cz, scale ); pushFace( frontPos, frontUV, cx, cy, cz, scale ); pushFace( backPos, backUV, cx, cy, cz, scale ); pushFace( leftPos, leftUV, cx, cy, cz, scale ); pushFace( rightPos, rightUV, cx, cy, cz, scale ); } } } Mesh m; m.createFromPosTex( verts ); return m; } Mesh makeTexturedCubeWithNormals() { std::vector< float > verts; verts.insert( verts.end(), { -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f } ); verts.insert( verts.end(), { 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f } ); verts.insert( verts.end(), { 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f } ); verts.insert( verts.end(), { 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f } ); verts.insert( verts.end(), { -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f } ); verts.insert( verts.end(), { -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f } ); verts.insert( verts.end(), { 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f } ); verts.insert( verts.end(), { -0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, -1.0f } ); verts.insert( verts.end(), { -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.0f, 0.0f, -1.0f } ); verts.insert( verts.end(), { -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.0f, 0.0f, -1.0f } ); verts.insert( verts.end(), { 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f } ); verts.insert( verts.end(), { 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f } ); verts.insert( verts.end(), { -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f } ); verts.insert( verts.end(), { -0.5f, -0.5f, 0.5f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f } ); verts.insert( verts.end(), { -0.5f, 0.5f, 0.5f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f } ); verts.insert( verts.end(), { -0.5f, 0.5f, 0.5f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f } ); verts.insert( verts.end(), { -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f } ); verts.insert( verts.end(), { -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f } ); verts.insert( verts.end(), { 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f } ); verts.insert( verts.end(), { 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f } ); verts.insert( verts.end(), { 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f } ); verts.insert( verts.end(), { 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f } ); verts.insert( verts.end(), { 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f } ); verts.insert( verts.end(), { 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f } ); verts.insert( verts.end(), { -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f } ); verts.insert( verts.end(), { 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f } ); verts.insert( verts.end(), { 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f } ); verts.insert( verts.end(), { 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f } ); verts.insert( verts.end(), { -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f } ); verts.insert( verts.end(), { -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f } ); verts.insert( verts.end(), { -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f } ); verts.insert( verts.end(), { 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, -1.0f, 0.0f } ); verts.insert( verts.end(), { 0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 0.0f, -1.0f, 0.0f } ); verts.insert( verts.end(), { 0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 0.0f, -1.0f, 0.0f } ); verts.insert( verts.end(), { -0.5f, -0.5f, 0.5f, 0.0f, 1.0f, 0.0f, -1.0f, 0.0f } ); verts.insert( verts.end(), { -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f } ); Mesh m; m.createFromPosTexNormal( verts ); return m; } Mesh makeTexturedGridWithNormals( int width, int depth, float tileSize ) { std::vector< float > verts; for ( int z = 0; z < depth; ++z ) { for ( int x = 0; x < width; ++x ) { float x0 = ( x - width * 0.5f ) * tileSize; float z0 = ( z - depth * 0.5f ) * tileSize; float x1 = x0 + tileSize; float z1 = z0 + tileSize; verts.insert( verts.end(), { x0, 0.0f, z0, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f } ); verts.insert( verts.end(), { x1, 0.0f, z0, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f } ); verts.insert( verts.end(), { x0, 0.0f, z1, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f } ); verts.insert( verts.end(), { x0, 0.0f, z1, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f } ); verts.insert( verts.end(), { x1, 0.0f, z0, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f } ); verts.insert( verts.end(), { x1, 0.0f, z1, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f } ); } } Mesh m; m.createFromPosTexNormal( verts ); return m; } Mesh makeTexturedCubeGridWithNormals( int width, int depth, float tileSize ) { std::vector< float > verts; auto pushFaceWithNormal = [&]( const std::array< float, 18 > &pos, const std::array< float, 12 > &uv, const glm::vec3 &normal, float cx, float cy, float cz, float scale ) { for ( int i = 0; i < 6; ++i ) { int pi = i * 3; int ui = i * 2; verts.push_back( cx + pos[pi + 0] * scale ); verts.push_back( cy + pos[pi + 1] * scale ); verts.push_back( cz + pos[pi + 2] * scale ); verts.push_back( uv[ui + 0] ); verts.push_back( uv[ui + 1] ); verts.push_back( normal.x ); verts.push_back( normal.y ); verts.push_back( normal.z ); } }; const std::array< float, 18 > topPos = { -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f }; const std::array< float, 12 > topUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f }; const std::array< float, 18 > bottomPos = { -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f }; const std::array< float, 12 > bottomUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f }; const std::array< float, 18 > frontPos = { -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f }; const std::array< float, 12 > frontUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f }; const std::array< float, 18 > backPos = { 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f }; const std::array< float, 12 > backUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f }; const std::array< float, 18 > leftPos = { -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f }; const std::array< float, 12 > leftUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f }; const std::array< float, 18 > rightPos = { 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, 0.5f }; const std::array< float, 12 > rightUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f }; for ( int z = 0; z < depth; ++z ) { for ( int x = 0; x < width; ++x ) { float cx = ( x - width * 0.5f ) * tileSize + tileSize * 0.5f; float cz = ( z - depth * 0.5f ) * tileSize + tileSize * 0.5f; float cy = -0.5f * tileSize; float scale = tileSize; pushFaceWithNormal( topPos, topUV, glm::vec3( 0.0f, 1.0f, 0.0f ), cx, cy, cz, scale ); pushFaceWithNormal( bottomPos, bottomUV, glm::vec3( 0.0f, -1.0f, 0.0f ), cx, cy, cz, scale ); pushFaceWithNormal( frontPos, frontUV, glm::vec3( 0.0f, 0.0f, 1.0f ), cx, cy, cz, scale ); pushFaceWithNormal( backPos, backUV, glm::vec3( 0.0f, 0.0f, -1.0f ), cx, cy, cz, scale ); pushFaceWithNormal( leftPos, leftUV, glm::vec3( -1.0f, 0.0f, 0.0f ), cx, cy, cz, scale ); pushFaceWithNormal( rightPos, rightUV, glm::vec3( 1.0f, 0.0f, 0.0f ), cx, cy, cz, scale ); } } Mesh m; m.createFromPosTexNormal( verts ); return m; } Mesh makeTexturedWallWithNormals( int length, int height, float tileSize, bool alongX, float fixedCoord ) { std::vector< float > verts; auto pushFaceWithNormal = [&]( const std::array< float, 18 > &pos, const std::array< float, 12 > &uv, const glm::vec3 &normal, float cx, float cy, float cz, float scale ) { for ( int i = 0; i < 6; ++i ) { int pi = i * 3; int ui = i * 2; verts.push_back( cx + pos[pi + 0] * scale ); verts.push_back( cy + pos[pi + 1] * scale ); verts.push_back( cz + pos[pi + 2] * scale ); verts.push_back( uv[ui + 0] ); verts.push_back( uv[ui + 1] ); verts.push_back( normal.x ); verts.push_back( normal.y ); verts.push_back( normal.z ); } }; const std::array< float, 18 > topPos = { -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f }; const std::array< float, 12 > topUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f }; const std::array< float, 18 > bottomPos = { -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f }; const std::array< float, 12 > bottomUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f }; const std::array< float, 18 > frontPos = { -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f }; const std::array< float, 12 > frontUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f }; const std::array< float, 18 > backPos = { 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f }; const std::array< float, 12 > backUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f }; const std::array< float, 18 > leftPos = { -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f }; const std::array< float, 12 > leftUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f }; const std::array< float, 18 > rightPos = { 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, 0.5f }; const std::array< float, 12 > rightUV = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f }; if ( alongX ) { for ( int lx = 0; lx < length; ++lx ) { float cx = ( lx - length * 0.5f ) * tileSize + tileSize * 0.5f; float cz = fixedCoord; for ( int hy = 0; hy < height; ++hy ) { float cy = hy * tileSize + tileSize * 0.5f; float scale = tileSize; pushFaceWithNormal( topPos, topUV, glm::vec3( 0.0f, 1.0f, 0.0f ), cx, cy, cz, scale ); pushFaceWithNormal( bottomPos, bottomUV, glm::vec3( 0.0f, -1.0f, 0.0f ), cx, cy, cz, scale ); pushFaceWithNormal( frontPos, frontUV, glm::vec3( 0.0f, 0.0f, 1.0f ), cx, cy, cz, scale ); pushFaceWithNormal( backPos, backUV, glm::vec3( 0.0f, 0.0f, -1.0f ), cx, cy, cz, scale ); pushFaceWithNormal( leftPos, leftUV, glm::vec3( -1.0f, 0.0f, 0.0f ), cx, cy, cz, scale ); pushFaceWithNormal( rightPos, rightUV, glm::vec3( 1.0f, 0.0f, 0.0f ), cx, cy, cz, scale ); } } } else { for ( int lz = 0; lz < length; ++lz ) { float cz = ( lz - length * 0.5f ) * tileSize + tileSize * 0.5f; float cx = fixedCoord; for ( int hy = 0; hy < height; ++hy ) { float cy = hy * tileSize + tileSize * 0.5f; float scale = tileSize; pushFaceWithNormal( topPos, topUV, glm::vec3( 0.0f, 1.0f, 0.0f ), cx, cy, cz, scale ); pushFaceWithNormal( bottomPos, bottomUV, glm::vec3( 0.0f, -1.0f, 0.0f ), cx, cy, cz, scale ); pushFaceWithNormal( frontPos, frontUV, glm::vec3( 0.0f, 0.0f, 1.0f ), cx, cy, cz, scale ); pushFaceWithNormal( backPos, backUV, glm::vec3( 0.0f, 0.0f, -1.0f ), cx, cy, cz, scale ); pushFaceWithNormal( leftPos, leftUV, glm::vec3( -1.0f, 0.0f, 0.0f ), cx, cy, cz, scale ); pushFaceWithNormal( rightPos, rightUV, glm::vec3( 1.0f, 0.0f, 0.0f ), cx, cy, cz, scale ); } } } Mesh m; m.createFromPosTexNormal( verts ); return m; } } // namespace primitives } // namespace renderer