commit f7bab989ed3ccea09b13252b1ac75b80ce122491 parent 5e60b92fe7c2bd6d64fe0416386fea14c3482a6e Author: Michael Savage <mikejsavage@gmail.com> Date: Sat Sep 10 19:40:31 -0700 Add immediate_arrow Diffstat:
immediate.cc | | | 88 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
immediate.h | | | 3 | +++ |
diff --git a/immediate.cc b/immediate.cc @@ -126,6 +126,94 @@ void immediate_aabb( ImmediateContext * ctx, glm::vec3 mins, glm::vec3 maxs, glm immediate_triangle( ctx, v7, v6, v2, colour ); } +static glm::mat3 about_with_sin_cos( glm::vec3 axis, float s, float c ) { + return glm::mat3( + axis.x * axis.x + ( 1.0 - axis.x * axis.x ) * c, + axis.x * axis.y * ( 1.0 - c ) - axis.z * s, + axis.x * axis.z * ( 1.0 - c ) + axis.y * s, + axis.y * axis.x * ( 1.0 - c ) + axis.z * s, + axis.y * axis.y + ( 1.0 - axis.y * axis.y ) * c, + axis.y * axis.z * ( 1.0 - c ) - axis.x * s, + axis.z * axis.x * ( 1.0 - c ) - axis.y * s, + axis.z * axis.y * ( 1.0 - c ) + axis.x * s, + axis.z * axis.z + ( 1.0 - axis.z * axis.z ) * c + ); +} + +static glm::mat3 rotation_between( glm::vec3 from, glm::vec3 to ) { + if( from == to ) return glm::mat3(); + if( from == -to ) return -glm::mat3(); + + glm::vec3 axis = glm::normalize( glm::cross( from, to ) ); + float cos_theta = glm::dot( from, to ); + // TODO: why is this -????? + float sin_theta = -sqrtf( 1.0f - cos_theta * cos_theta ); + + return about_with_sin_cos( axis, sin_theta, cos_theta ); +} + +void immediate_arrow( ImmediateContext * ctx, glm::vec3 origin, glm::vec3 direction, float length, glm::vec4 colour ) { + glm::vec3 v[] = { + // base of stick + glm::vec3( -0.05, -0.05, 0 ), + glm::vec3( 0.05, -0.05, 0 ), + glm::vec3( -0.05, 0.05, 0 ), + glm::vec3( 0.05, 0.05, 0 ), + + // top of stick + glm::vec3( -0.05, -0.05, 0.6 ), + glm::vec3( 0.05, -0.05, 0.6 ), + glm::vec3( -0.05, 0.05, 0.6 ), + glm::vec3( 0.05, 0.05, 0.6 ), + + // point + glm::vec3( 0, 0, 1 ), + glm::vec3( 0, 0, 0.6 ), + }; + + const size_t CONE_SUBDIVISIONS = 8; + glm::vec3 cone[ CONE_SUBDIVISIONS ]; + + // TODO: do the fast sin/cos thing + // TODO: make a helper function to do it that fills in an array of floats + for( size_t i = 0; i < array_count( cone ); i++ ) { + float s = sinf( float( i ) / float( array_count( cone ) ) * 2.0f * M_PI ); + float c = cosf( float( i ) / float( array_count( cone ) ) * 2.0f * M_PI ); + + cone[ i ] = glm::vec3( 0.2f * c, 0.2f * s, 0.6 ); + } + + glm::mat3 rot = rotation_between( glm::vec3( 0, 0, 1 ), glm::normalize( direction ) ); + + for( size_t i = 0; i < array_count( v ); i++ ) { + v[ i ] = ( rot * v[ i ] ) * length + origin; + } + for( size_t i = 0; i < array_count( cone ); i++ ) { + cone[ i ] = ( rot * cone[ i ] ) * length + origin; + } + + immediate_triangle( ctx, v[ 0 ], v[ 1 ], v[ 2 ], colour ); // bottom + immediate_triangle( ctx, v[ 1 ], v[ 3 ], v[ 2 ], colour ); + immediate_triangle( ctx, v[ 4 ], v[ 6 ], v[ 5 ], colour ); // top + immediate_triangle( ctx, v[ 6 ], v[ 7 ], v[ 5 ], colour ); + immediate_triangle( ctx, v[ 2 ], v[ 6 ], v[ 0 ], colour ); // left + immediate_triangle( ctx, v[ 6 ], v[ 4 ], v[ 0 ], colour ); + immediate_triangle( ctx, v[ 1 ], v[ 5 ], v[ 3 ], colour ); // right + immediate_triangle( ctx, v[ 5 ], v[ 7 ], v[ 3 ], colour ); + immediate_triangle( ctx, v[ 0 ], v[ 4 ], v[ 1 ], colour ); // front + immediate_triangle( ctx, v[ 4 ], v[ 5 ], v[ 1 ], colour ); + immediate_triangle( ctx, v[ 3 ], v[ 7 ], v[ 2 ], colour ); // back + immediate_triangle( ctx, v[ 7 ], v[ 6 ], v[ 2 ], colour ); + + for( size_t i = 0; i < array_count( cone ); i++ ) { + immediate_triangle( ctx, v[ 8 ], cone[ ( i + 1 ) % array_count( cone ) ], cone[ i ], colour ); + } + + for( size_t i = 0; i < array_count( cone ); i++ ) { + immediate_triangle( ctx, v[ 9 ], cone[ i ], cone[ ( i + 1 ) % array_count( cone ) ], colour ); + } +} + void immediate_render( const ImmediateContext * ctx, GLint at_position, GLint at_colour, diff --git a/immediate.h b/immediate.h @@ -34,6 +34,9 @@ void immediate_sphere( ImmediateContext * ctx, void immediate_aabb( ImmediateContext * ctx, glm::vec3 mins, glm::vec3 maxs, glm::vec4 colour ); +void immediate_arrow( ImmediateContext * ctx, glm::vec3 origin, + glm::vec3 direction, float length, glm::vec4 colour ); + void immediate_render( const ImmediateContext * ctx, GLint at_position, GLint at_colour, bool textured = false, GLint at_uv = 0, GLint un_texture = 0 );