aboutsummaryrefslogtreecommitdiff
path: root/apps/openmb/renderer/EditorHelpers.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'apps/openmb/renderer/EditorHelpers.cpp')
-rw-r--r--apps/openmb/renderer/EditorHelpers.cpp148
1 files changed, 148 insertions, 0 deletions
diff --git a/apps/openmb/renderer/EditorHelpers.cpp b/apps/openmb/renderer/EditorHelpers.cpp
new file mode 100644
index 0000000..9531fb0
--- /dev/null
+++ b/apps/openmb/renderer/EditorHelpers.cpp
@@ -0,0 +1,148 @@
+#include "EditorHelpers.hpp"
+#include <cmath>
+
+#include <glm/gtc/matrix_inverse.hpp>
+#include <vector>
+
+namespace renderer {
+namespace editor {
+Mesh makeWireCube ( float size ) {
+ float h = size * 0.5f;
+ std::vector<float> 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<float> 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<float> 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