Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-09 07:49:39

0001 #pragma once
0002 /**
0003 SGLM_Arcball.h
0004 ================
0005 
0006 * https://research.cs.wisc.edu/graphics/Courses/559-f2001/Examples/Gl3D/arcball-gems.pdf
0007 * ~/opticks_refs/ken_shoemake_arcball_rotation_control_gem.pdf 
0008 
0009 * http://www.talisman.org/~erlkonig/misc/shoemake92-arcball.pdf
0010 * ~/opticks_refs/shoemake92-arcball.pdf
0011 
0012 * :google:`ken shoemake arcball rotation control gem`
0013 
0014 **/
0015 
0016 #include <glm/glm.hpp>
0017 #include <glm/gtx/quaternion.hpp>
0018 
0019 
0020 struct SGLM_Arcball
0021 {
0022     static glm::quat Identity() ; 
0023     static glm::quat A2B_Arcball( const glm::vec3& a, const glm::vec3& b ) ; 
0024     static glm::quat A2B_Screen( const glm::vec2& a, const glm::vec2& b ) ; 
0025     static float ZProject(const glm::vec2& p ); 
0026 }; 
0027 
0028 
0029 inline glm::quat SGLM_Arcball::Identity()
0030 {
0031     return glm::identity<glm::quat>(); 
0032 }
0033 
0034 
0035 /**
0036 SGLM_Arcball::A2B_Arcball
0037 -------------------------
0038 
0039 * formula to form quat from two vecs direct from Ken Shoemake
0040   using properties of pure quaternions (which are points 
0041   on the equator of the hypersphere)
0042 
0043 **/
0044 
0045 inline glm::quat SGLM_Arcball::A2B_Arcball( const glm::vec3& a, const glm::vec3& b )
0046 {
0047     glm::vec3 A = glm::normalize(a); 
0048     glm::vec3 B = glm::normalize(b); 
0049     return glm::quat( -glm::dot(A,B), glm::cross(A,B) ); 
0050 }
0051 
0052 inline glm::quat SGLM_Arcball::A2B_Screen( const glm::vec2& a, const glm::vec2& b )
0053 {
0054     glm::vec3 A(a.x, a.y, ZProject(a) ); 
0055     glm::vec3 B(b.x, b.y, ZProject(b) ); 
0056     return A2B_Arcball(A, B) ; 
0057 } 
0058 
0059 /**
0060 SGLM_Arcball::ZProject cf Trackball::project
0061 -------------------------------------------------
0062 
0063 What to do when outside unit circle is kinda arbitrary 
0064 are seeing flips when do so, 
0065 
0066 **/
0067 inline float SGLM_Arcball::ZProject( const glm::vec2& p )
0068 {
0069     float ll = glm::dot(p,p); 
0070     float z = ll <= 1.f ? std::sqrt(1.f - ll) : 0.f  ; 
0071     return z ; 
0072 }
0073