diff options
Diffstat (limited to 'apps/openmb/renderer/primitives.cpp')
| -rw-r--r-- | apps/openmb/renderer/primitives.cpp | 595 |
1 files changed, 595 insertions, 0 deletions
diff --git a/apps/openmb/renderer/primitives.cpp b/apps/openmb/renderer/primitives.cpp new file mode 100644 index 0000000..245f7e1 --- /dev/null +++ b/apps/openmb/renderer/primitives.cpp @@ -0,0 +1,595 @@ +#include "primitives.hpp" + +#include <vector> + +#include <glm/glm.hpp> + +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 |