#include "EditorHelpers.hpp" #include #include #include namespace renderer { namespace editor { Mesh makeWireCube ( float size ) { float h = size * 0.5f; std::vector verts = { -h, -h, -h, h, -h, -h, h, -h, -h, h, -h, h, h, -h, h, -h, -h, h, -h, -h, h, -h, -h, -h, -h, h, -h, h, h, -h, h, h, -h, h, h, h, h, h, h, -h, h, h, -h, h, h, -h, h, -h, -h, -h, -h, -h, h, -h, h, -h, -h, h, h, -h, h, -h, h, h, h, h, -h, -h, h, -h, h, h }; Mesh m; m.createFromPositions( verts, true ); return m; } Mesh makeCircleWire ( float radius, int segments ) { if( segments < 3 ) segments = 3; std::vector verts; verts.reserve( segments * 3 ); const float twoPi = 6.28318530717958647692f; for( int i = 0; i < segments; ++i ) { int ni = ( i + 1 ) % segments; float ti = (float)i / (float)segments; float angi = ti * twoPi; float xi = cosf( angi ) * radius; float zi = sinf( angi ) * radius; float tni = (float)ni / (float)segments; float angni = tni * twoPi; float xni = cosf( angni ) * radius; float zni = sinf( angni ) * radius; verts.push_back( xi ); verts.push_back( 0.0f ); verts.push_back( zi ); verts.push_back( xni ); verts.push_back( 0.0f ); verts.push_back( zni ); } Mesh m; m.createFromPositions( verts, true ); return m; } Mesh makeCircleFilled ( float radius, int segments ) { if( segments < 3 ) segments = 3; std::vector data; data.reserve( ( segments + 2 ) * 5 ); const float twoPi = 6.28318530717958647692f; float cx = 0.0f, cz = 0.0f; float cu = 0.5f, cv = 0.5f; for( int i = 0; i < segments; ++i ) { int i1 = i; int i2 = ( i + 1 ) % segments; float t1 = (float)i1 / (float)segments; float ang1 = t1 * twoPi; float x1 = cosf( ang1 ) * radius; float z1 = sinf( ang1 ) * radius; float u1 = ( x1 / ( radius * 2.0f ) ) + 0.5f; float v1 = ( z1 / ( radius * 2.0f ) ) + 0.5f; float t2 = (float)i2 / (float)segments; float ang2 = t2 * twoPi; float x2 = cosf( ang2 ) * radius; float z2 = sinf( ang2 ) * radius; float u2 = ( x2 / ( radius * 2.0f ) ) + 0.5f; float v2 = ( z2 / ( radius * 2.0f ) ) + 0.5f; data.push_back( cx ); data.push_back( 0.0f ); data.push_back( cz ); data.push_back( cu ); data.push_back( cv ); data.push_back( x1 ); data.push_back( 0.0f ); data.push_back( z1 ); data.push_back( u1 ); data.push_back( v1 ); data.push_back( x2 ); data.push_back( 0.0f ); data.push_back( z2 ); data.push_back( u2 ); data.push_back( v2 ); } Mesh m; m.createFromPosTex( data ); return m; } bool makeRayFromMouse ( const glm::vec2& mousePx, int fbw, int fbh, const glm::mat4& view, const glm::mat4& proj, const glm::vec3& camPos, glm::vec3& outOrigin, glm::vec3& outDir ) { if( fbw <= 0 || fbh <= 0 ) return false; float ndcX = ( mousePx.x / (float)fbw ) * 2.0f - 1.0f; float ndcY = 1.0f - ( mousePx.y / (float)fbh ) * 2.0f; glm::vec4 nearPointNDC( ndcX, ndcY, -1.0f, 1.0f ); glm::vec4 farPointNDC( ndcX, ndcY, 1.0f, 1.0f ); glm::mat4 invPV = glm::inverse( proj * view ); glm::vec4 nearWorld = invPV * nearPointNDC; glm::vec4 farWorld = invPV * farPointNDC; if( nearWorld.w == 0.0f || farWorld.w == 0.0f ) return false; nearWorld /= nearWorld.w; farWorld /= farWorld.w; glm::vec3 nearPos = glm::vec3( nearWorld ); glm::vec3 farPos = glm::vec3( farWorld ); outOrigin = nearPos; outDir = glm::normalize( farPos - nearPos ); if( !isfinite( outDir.x ) || !isfinite( outDir.y ) || !isfinite( outDir.z ) ) { outOrigin = camPos; outDir = glm::normalize( glm::vec3( 0.0f, 0.0f, -1.0f ) ); } return true; } } // namespace editor } // namespace renderer