├── .gitignore ├── LICENSE ├── preview.png ├── readme.md ├── tiny-gizmo-example ├── CMakeLists.txt ├── example-main.cpp ├── gl-api.hpp ├── linalg.h ├── teapot.h ├── tiny-gizmo-example.sln ├── tiny-gizmo-example.vcxproj ├── tiny-gizmo-example.vcxproj.filters └── util.hpp ├── tiny-gizmo.cpp └── tiny-gizmo.hpp /.gitignore: -------------------------------------------------------------------------------- 1 | # User-specific files 2 | *.suo 3 | *.user 4 | 5 | # Build results 6 | [Dd]ebug/ 7 | [Rr]elease/ 8 | [Oo]bj/ 9 | 10 | *.ilk 11 | *.obj 12 | *.pch 13 | *.pdb 14 | *.log 15 | 16 | # Visual C++ cache files 17 | ipch/ 18 | *.opensdf 19 | *.sdf 20 | *.VC.* 21 | 22 | # Visual Studio profiler 23 | *.psess 24 | *.vsp 25 | *.vspx 26 | 27 | intermediate/ 28 | build/ 29 | assets/ 30 | *.mesh 31 | 32 | .DS_Store 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/meshula/tinygizmo/3dd4d382924e3d90060b8214a50fe57aa0aa58e8/preview.png -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # tinygizmo 2 | 3 |

4 | 5 |

6 | 7 | This project is a lightweight, self-contained library for gizmo editing commonly found in many game engines. It includes mechanisms for manipulating 3d position, rotation, and scale. Implemented in C++11, the library does not perform rendering directly and instead provides a per-frame buffer of world-space triangles. 8 | 9 | An included example is built on top of GLFW (with an OpenGL 3.3 context). Known limitations include hardcoded assumptions about a right-handed, Y-up coordinate system. While the gizmos are provided with vertex normals, the example does not perform any fancy shading. Furthermore, mouse-drag input with certain gizmos at extreme interaction grazing angles is known to produce anomalous output. 10 | 11 | # Motivation 12 | 13 | This project was born out of mild frustration with other immediate-mode gizmo libraries. Instead of 4x4 matrices and euler angles, the library exposes a `rigid_transform` consisting of a 3d position, rotation quaternion, and scale. The library is implemented in around 1200 lines of code, which also includes a complete 3d math library in ~400 LoC - [linalg.h](https://github.com/sgorsten/linalg). Alternatives include [ImGuizmo](https://github.com/CedricGuillemet/ImGuizmo) and [Im3D](https://github.com/john-chapman/im3d). Tinygizmo fits in-between these projects by being fully self-contained (no dependency on Dear ImGui), and by being provided in the public domain. 14 | 15 | # Features 16 | * Both axis-aligned global and object-local transform modes for translational and rotational gizmos 17 | * Optional ability draw the gizmos with a constant screen-space scale 18 | * Snap-to-unit (both linear and angular) 19 | * Set any of the `snap_` values in the `gizmo_application_state` struct. 20 | * VR ready (the user must call `update(...)` and `draw()` for each eye) 21 | * Hotkeys for transitioning between translation, rotation, and scaling: 22 | * `ctrl-t` to activate the translation gizmo 23 | * `ctrl-r` to activate the rotation gizmo 24 | * `ctrl-s` to activate the scale gizmo 25 | * `ctrl-l` to toggle between global and local transform modes 26 | 27 | # Attribution 28 | 29 | This project would not have been possible without reference implementations in the public-domain [workbench](https://github.com/sgorsten/workbench) project. 30 | 31 | # License 32 | 33 | This is free and unencumbered software released into the public domain. For more information, please refer to -------------------------------------------------------------------------------- /tiny-gizmo-example/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | cmake_minimum_required(VERSION 3.12) 3 | project(tinygizmo_example VERSION 0.1.0 LANGUAGES C CXX) 4 | set_property(GLOBAL PROPERTY USE_FOLDERS ON) 5 | 6 | set(CMAKE_CXX_STANDARD 14) 7 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 8 | set(CMAKE_CXX_EXTENSIONS OFF) 9 | 10 | if (WIN32) 11 | set (PLATFORM_DEFS 12 | WIN32_LEAN_AND_MEAN 13 | NOMINMAX 14 | _CRT_SECURE_NO_WARNINGS 15 | ) 16 | endif() 17 | 18 | # Because rpaths have to be as fiendishly difficult as possible on Mac: 19 | if (APPLE) 20 | 21 | # use, i.e. don't skip the full RPATH for the build tree 22 | set(CMAKE_SKIP_BUILD_RPATH FALSE) 23 | 24 | # when building, don't use the install RPATH already 25 | # (but later on when installing) 26 | set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) 27 | 28 | set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") 29 | 30 | # add the automatically determined parts of the RPATH 31 | # which point to directories outside the build tree to the install RPATH 32 | set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) 33 | 34 | # the RPATH to be used when installing, but only if it's not a system directory 35 | list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/lib" isSystemDir) 36 | if("${isSystemDir}" STREQUAL "-1") 37 | set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") 38 | endif("${isSystemDir}" STREQUAL "-1") 39 | 40 | endif() 41 | 42 | 43 | set(TINYGIZMO_EXAMPLE_SRC 44 | example-main.cpp 45 | gl-api.hpp 46 | teapot.h 47 | util.hpp 48 | ) 49 | 50 | if(APPLE) 51 | set(TINYGIZMO_DEFS 52 | ) 53 | else() 54 | set(TINYGIZMO_DEFS 55 | ) 56 | endif() 57 | 58 | find_package(glfw3 REQUIRED) 59 | find_package(glew REQUIRED) 60 | 61 | #------------------------------------------------------------------------------- 62 | # tinygizmo 63 | #------------------------------------------------------------------------------- 64 | 65 | if (WIN32) 66 | endif() 67 | 68 | set(TINYGIZMO_SRC 69 | ../tiny-gizmo.cpp 70 | ../tiny-gizmo.hpp 71 | ) 72 | 73 | add_library(tinygizmo STATIC ${TINYGIZMO_SRC}) 74 | target_include_directories(tinygizmo SYSTEM 75 | PUBLIC ..) 76 | target_compile_definitions(tinygizmo PRIVATE 77 | ${PLATFORM_DEFS} 78 | ) 79 | 80 | #------------------------------------------------------------------------------- 81 | # tinygizmo_example 82 | #------------------------------------------------------------------------------- 83 | 84 | add_executable(tinygizmo_example 85 | ${TINYGIZMO_EXAMPLE_SRC} 86 | ) 87 | 88 | set_target_properties(tinygizmo_example PROPERTIES 89 | RUNTIME_OUTPUT_DIRECTORY bin) 90 | 91 | target_compile_definitions(tinygizmo_example PRIVATE 92 | ${PLATFORM_DEFS} 93 | ) 94 | 95 | target_include_directories(tinygizmo_example 96 | PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src 97 | PRIVATE ${GLEW_INCLUDE_DIR} 98 | ) 99 | 100 | if (WIN32) 101 | set(PLATFORM_LIBS ws2_32 Iphlpapi.lib opengl32.lib) 102 | elseif (APPLE) 103 | # if(CMAKE_OSX_SYSROOT MATCHES ".*iphoneos.*") 104 | # set(DARWIN_LIBS 105 | # "-framework AudioToolbox" 106 | # "-framework Accelerate" 107 | # "-framework CoreAudio") 108 | # else() 109 | set(PLATFORM_LIBS 110 | "-framework AudioToolbox" 111 | "-framework AudioUnit" 112 | "-framework Accelerate" 113 | "-framework Cocoa" 114 | "-framework CoreAudio" 115 | "-framework Metal" 116 | "-framework MetalKit" 117 | "-framework QuartzCore" 118 | "-framework OpenGL" 119 | ) 120 | # endif() 121 | endif() 122 | 123 | target_link_libraries(tinygizmo_example 124 | ${PLATFORM_LIBS} ${GLEW_SHARED_LIBRARY_RELEASE} glfw tinygizmo 125 | ) 126 | 127 | #------------------------------------------------------------------------------- 128 | # Installer 129 | #------------------------------------------------------------------------------- 130 | 131 | install( 132 | TARGETS tinygizmo_example 133 | BUNDLE DESTINATION bin 134 | ARCHIVE DESTINATION lib 135 | LIBRARY DESTINATION lib 136 | RUNTIME DESTINATION bin) 137 | 138 | -------------------------------------------------------------------------------- /tiny-gizmo-example/example-main.cpp: -------------------------------------------------------------------------------- 1 | // This is free and unencumbered software released into the public domain. 2 | // For more information, please refer to 3 | 4 | #include 5 | #include 6 | 7 | #include "../tiny-gizmo.hpp" 8 | #include "util.hpp" 9 | #include "gl-api.hpp" 10 | #include "teapot.h" 11 | 12 | using namespace tinygizmo; 13 | 14 | static inline uint64_t get_local_time_ns() 15 | { 16 | return std::chrono::duration_cast(std::chrono::high_resolution_clock::now().time_since_epoch()).count(); 17 | } 18 | 19 | const linalg::aliases::float4x4 identity4x4 = { { 1, 0, 0, 0 },{ 0, 1, 0, 0 },{ 0, 0, 1, 0 },{ 0, 0, 0, 1 } }; 20 | 21 | constexpr const char gizmo_vert[] = R"(#version 330 22 | layout(location = 0) in vec3 vertex; 23 | layout(location = 1) in vec3 normal; 24 | layout(location = 2) in vec4 color; 25 | out vec4 v_color; 26 | out vec3 v_world, v_normal; 27 | uniform mat4 u_mvp; 28 | void main() 29 | { 30 | gl_Position = u_mvp * vec4(vertex.xyz, 1); 31 | v_color = color; 32 | v_world = vertex; 33 | v_normal = normal; 34 | } 35 | )"; 36 | 37 | constexpr const char gizmo_frag[] = R"(#version 330 38 | in vec4 v_color; 39 | in vec3 v_world, v_normal; 40 | out vec4 f_color; 41 | uniform vec3 u_eye; 42 | void main() 43 | { 44 | vec3 light = vec3(1) * max(dot(v_normal, normalize(u_eye - v_world)), 0.50) + 0.25; 45 | f_color = v_color * vec4(light, 1); 46 | } 47 | )"; 48 | 49 | constexpr const char lit_vert[] = R"(#version 330 50 | uniform mat4 u_modelMatrix; 51 | uniform mat4 u_viewProj; 52 | 53 | layout(location = 0) in vec3 inPosition; 54 | layout(location = 1) in vec3 inNormal; 55 | 56 | out vec3 v_position, v_normal; 57 | 58 | void main() 59 | { 60 | vec4 worldPos = u_modelMatrix * vec4(inPosition, 1); 61 | v_position = worldPos.xyz; 62 | v_normal = normalize((u_modelMatrix * vec4(inNormal,0)).xyz); 63 | gl_Position = u_viewProj * worldPos; 64 | } 65 | )"; 66 | 67 | constexpr const char lit_frag[] = R"(#version 330 68 | uniform vec3 u_diffuse = vec3(1, 1, 1); 69 | uniform vec3 u_eye; 70 | 71 | in vec3 v_position; 72 | in vec3 v_normal; 73 | 74 | out vec4 f_color; 75 | 76 | vec3 compute_lighting(vec3 eyeDir, vec3 position, vec3 color) 77 | { 78 | vec3 light = vec3(0, 0, 0); 79 | vec3 lightDir = normalize(position - v_position); 80 | light += color * u_diffuse * max(dot(v_normal, lightDir), 0); 81 | vec3 halfDir = normalize(lightDir + eyeDir); 82 | light += color * u_diffuse * pow(max(dot(v_normal, halfDir), 0), 128); 83 | return light; 84 | } 85 | 86 | void main() 87 | { 88 | vec3 eyeDir = vec3(0, 1, -2); 89 | vec3 light = vec3(0, 0, 0); 90 | light += compute_lighting(eyeDir, vec3(+3, 1, 0), vec3(235.0/255.0, 43.0/255.0, 211.0/255.0)); 91 | light += compute_lighting(eyeDir, vec3(-3, 1, 0), vec3(43.0/255.0, 236.0/255.0, 234.0/255.0)); 92 | f_color = vec4(light + vec3(0.5, 0.5, 0.5), 1.0); 93 | } 94 | )"; 95 | 96 | ////////////////////////// 97 | // Main Application // 98 | ////////////////////////// 99 | 100 | struct geometry_vertex { v3f position, normal; v4f color; }; 101 | struct geometry_mesh { std::vector vertices; std::vector triangles; }; 102 | 103 | geometry_mesh make_teapot() 104 | { 105 | geometry_mesh mesh; 106 | for (int i = 0; i < 4974; i+=6) 107 | { 108 | geometry_vertex v; 109 | v.position = v3f{ teapot_vertices[i + 0], teapot_vertices[i + 1], teapot_vertices[i + 2] }; 110 | v.normal = v3f{ teapot_vertices[i + 3], teapot_vertices[i + 4], teapot_vertices[i + 5] }; 111 | mesh.vertices.push_back(v); 112 | } 113 | for (int i = 0; i < 4680; i += 3) mesh.triangles.push_back(uint3{ teapot_triangles[i + 0], teapot_triangles[i + 1], teapot_triangles[i + 2] }); 114 | return mesh; 115 | } 116 | 117 | void draw_mesh(GlShader & shader, GlMesh & mesh, const linalg::aliases::float3 eye, const linalg::aliases::float4x4 & viewProj, const linalg::aliases::float4x4 & model) 118 | { 119 | linalg::aliases::float4x4 modelViewProjectionMatrix = mul(viewProj, model); 120 | shader.bind(); 121 | shader.uniform("u_mvp", modelViewProjectionMatrix); 122 | shader.uniform("u_eye", eye); 123 | mesh.draw_elements(); 124 | shader.unbind(); 125 | } 126 | 127 | void draw_lit_mesh(GlShader & shader, GlMesh & mesh, const linalg::aliases::float3 eye, const linalg::aliases::float4x4 & viewProj, const linalg::aliases::float4x4 & model) 128 | { 129 | shader.bind(); 130 | shader.uniform("u_viewProj", viewProj); 131 | shader.uniform("u_modelMatrix", model); 132 | shader.uniform("u_eye", eye); 133 | mesh.draw_elements(); 134 | shader.unbind(); 135 | } 136 | 137 | void upload_mesh(const geometry_mesh & cpu, GlMesh & gpu) 138 | { 139 | gpu.set_vertex_data(cpu.vertices.size() * sizeof(cpu.vertices[0]), cpu.vertices.data(), GL_DYNAMIC_DRAW); 140 | gpu.set_attribute(0, 3, GL_FLOAT, GL_FALSE, sizeof(geometry_vertex), (GLvoid*) offsetof(geometry_vertex, position)); 141 | gpu.set_attribute(1, 3, GL_FLOAT, GL_FALSE, sizeof(geometry_vertex), (GLvoid*) offsetof(geometry_vertex, normal)); 142 | gpu.set_attribute(2, 4, GL_FLOAT, GL_FALSE, sizeof(geometry_vertex), (GLvoid*) offsetof(geometry_vertex, color)); 143 | gpu.set_elements(static_cast(cpu.triangles.size()), reinterpret_cast(cpu.triangles.data()), GL_DYNAMIC_DRAW); 144 | } 145 | 146 | std::unique_ptr win; 147 | 148 | int main(int argc, char * argv[]) 149 | { 150 | bool ml = 0, mr = 0, bf = 0, bl = 0, bb = 0, br = 0; 151 | 152 | camera cam = {}; 153 | cam.yfov = 1.0f; 154 | cam.near_clip = 0.01f; 155 | cam.far_clip = 32.0f; 156 | cam.position = { 0,1.5f,4 }; 157 | 158 | gizmo_application_state gizmo_state; 159 | gizmo_context gizmo_ctx; 160 | 161 | try 162 | { 163 | win.reset(new Window(1280, 800, "tiny-gizmo-example-app")); 164 | glfwSwapInterval(1); 165 | } 166 | catch (const std::exception & e) 167 | { 168 | std::cout << "Caught GLFW window exception: " << e.what() << std::endl; 169 | } 170 | 171 | auto windowSize = win->get_window_size(); 172 | 173 | GlShader wireframeShader, litShader; 174 | GlMesh gizmoEditorMesh, teapotMesh; 175 | 176 | wireframeShader = GlShader(gizmo_vert, gizmo_frag); 177 | litShader = GlShader(lit_vert, lit_frag); 178 | 179 | geometry_mesh teapot = make_teapot(); 180 | upload_mesh(teapot, teapotMesh); 181 | 182 | win->on_key = [&](int key, int action, int mods) 183 | { 184 | if (key == GLFW_KEY_LEFT_CONTROL) gizmo_state.hotkey_ctrl = (action != GLFW_RELEASE); 185 | if (key == GLFW_KEY_L) gizmo_state.hotkey_local = (action != GLFW_RELEASE); 186 | if (key == GLFW_KEY_T) gizmo_state.hotkey_translate = (action != GLFW_RELEASE); 187 | if (key == GLFW_KEY_R) gizmo_state.hotkey_rotate = (action != GLFW_RELEASE); 188 | if (key == GLFW_KEY_S) gizmo_state.hotkey_scale = (action != GLFW_RELEASE); 189 | if (key == GLFW_KEY_W) bf = (action != GLFW_RELEASE); 190 | if (key == GLFW_KEY_A) bl = (action != GLFW_RELEASE); 191 | if (key == GLFW_KEY_S) bb = (action != GLFW_RELEASE); 192 | if (key == GLFW_KEY_D) br = (action != GLFW_RELEASE); 193 | if (key == GLFW_KEY_ESCAPE) win->close(); 194 | }; 195 | 196 | win->on_mouse_button = [&](int button, int action, int mods) 197 | { 198 | if (button == GLFW_MOUSE_BUTTON_LEFT) gizmo_state.mouse_left = (action != GLFW_RELEASE); 199 | if (button == GLFW_MOUSE_BUTTON_LEFT) ml = (action != GLFW_RELEASE); 200 | if (button == GLFW_MOUSE_BUTTON_RIGHT) mr = (action != GLFW_RELEASE); 201 | }; 202 | 203 | linalg::aliases::float2 lastCursor; 204 | win->on_cursor_pos = [&](linalg::aliases::float2 position) 205 | { 206 | auto deltaCursorMotion = linalg::aliases::float2(position.x, position.y) - lastCursor; 207 | if (mr) 208 | { 209 | cam.yaw -= deltaCursorMotion.x * 0.01f; 210 | cam.pitch -= deltaCursorMotion.y * 0.01f; 211 | } 212 | lastCursor = linalg::aliases::float2(position.x, position.y); 213 | }; 214 | 215 | rigid_transform xform_a; 216 | xform_a.position = { -2, 0, 0 }; 217 | 218 | rigid_transform xform_a_last; 219 | 220 | rigid_transform xform_b; 221 | xform_b.position = { +2, 0, 0 }; 222 | 223 | auto t0 = std::chrono::high_resolution_clock::now(); 224 | while (!win->should_close()) 225 | { 226 | glfwPollEvents(); 227 | 228 | auto t1 = std::chrono::high_resolution_clock::now(); 229 | float timestep = std::chrono::duration(t1 - t0).count(); 230 | t0 = t1; 231 | 232 | if (mr) 233 | { 234 | const linalg::aliases::float4 orientation = cam.get_orientation(); 235 | linalg::aliases::float3 move; 236 | if (bf) move -= qzdir(orientation); 237 | if (bl) move -= qxdir(orientation); 238 | if (bb) move += qzdir(orientation); 239 | if (br) move += qxdir(orientation); 240 | if (length2(move) > 0) cam.position += normalize(move) * (timestep * 10); 241 | } 242 | 243 | glViewport(0, 0, windowSize.x, windowSize.y); 244 | 245 | glEnable(GL_DEPTH_TEST); 246 | glEnable(GL_BLEND); 247 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 248 | glClearColor(0.725f, 0.725f, 0.725f, 1.0f); 249 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 250 | 251 | auto cameraOrientation = cam.get_orientation(); 252 | 253 | const auto rayDir = get_ray_from_pixel({ lastCursor.x, lastCursor.y }, { 0, 0, windowSize.x, windowSize.y }, cam).direction; 254 | 255 | // Gizmo input interaction state populated via win->on_input(...) callback above. Update app parameters: 256 | gizmo_state.viewport_size = v2f{ float(windowSize.x), float(windowSize.y) }; 257 | gizmo_state.cam.near_clip = cam.near_clip; 258 | gizmo_state.cam.far_clip = cam.far_clip; 259 | gizmo_state.cam.yfov = cam.yfov; 260 | gizmo_state.cam.position = v3f{ cam.position.x, cam.position.y, cam.position.z }; 261 | gizmo_state.cam.orientation = v4f{ cameraOrientation.x, cameraOrientation.y, cameraOrientation.z, cameraOrientation.w }; 262 | gizmo_state.ray_origin= v3f{ cam.position.x, cam.position.y, cam.position.z }; 263 | gizmo_state.ray_direction = v3f{ rayDir.x, rayDir.y, rayDir.z }; 264 | //gizmo_state.screenspace_scale = 80.f; // optional flag to draw the gizmos at a constant screen-space scale 265 | 266 | glDisable(GL_CULL_FACE); 267 | auto teapotModelMatrix_a_tmp = xform_a.matrix(); 268 | auto teapotModelMatrix_a = reinterpret_cast(teapotModelMatrix_a_tmp); 269 | draw_lit_mesh(litShader, teapotMesh, cam.position, cam.get_viewproj_matrix((float)windowSize.x / (float)windowSize.y), teapotModelMatrix_a); 270 | 271 | auto teapotModelMatrix_b_tmp = xform_b.matrix(); 272 | auto teapotModelMatrix_b = reinterpret_cast(teapotModelMatrix_b_tmp); 273 | draw_lit_mesh(litShader, teapotMesh, cam.position, cam.get_viewproj_matrix((float)windowSize.x / (float)windowSize.y), teapotModelMatrix_b); 274 | 275 | //glClear(GL_DEPTH_BUFFER_BIT); 276 | 277 | gizmo_ctx.begin(gizmo_state); 278 | 279 | if (gizmo_ctx.transform_gizmo("first-example-gizmo", xform_a)) 280 | { 281 | //std::cout << get_local_time_ns() << " - " << "First Gizmo Hovered..." << std::endl; 282 | //if (xform_a != xform_a_last) std::cout << get_local_time_ns() << " - " << "First Gizmo Changed..." << std::endl; 283 | xform_a_last = xform_a; 284 | } 285 | 286 | gizmo_ctx.transform_gizmo("second-example-gizmo", xform_b); 287 | 288 | static geometry_mesh r; // Combine all gizmo sub-meshes into one super-mesh 289 | 290 | // update index buffer 291 | size_t triangle_count = gizmo_ctx.triangles(reinterpret_cast(r.triangles.data()), r.triangles.size()); 292 | if (triangle_count > r.triangles.size()) 293 | { 294 | r.triangles.resize(triangle_count); 295 | triangle_count = gizmo_ctx.triangles(reinterpret_cast(r.triangles.data()), r.triangles.size()); 296 | } 297 | else if (triangle_count < r.triangles.size()) 298 | { 299 | r.triangles.resize(triangle_count); 300 | } 301 | 302 | // update vertex buffer 303 | size_t vertex_count = gizmo_ctx.vertices(reinterpret_cast(r.vertices.data()), sizeof(r.vertices[0]), 304 | sizeof(float) * 3, sizeof(float) * 6, r.vertices.size()); 305 | if (vertex_count > r.vertices.size()) 306 | { 307 | r.vertices.resize(vertex_count); 308 | size_t vertex_count = gizmo_ctx.vertices(reinterpret_cast(r.vertices.data()), sizeof(r.vertices[0]), 309 | sizeof(float) * 3, sizeof(float) * 6, r.vertices.size()); 310 | } 311 | else if (vertex_count < r.vertices.size()) 312 | { 313 | r.vertices.resize(vertex_count); 314 | } 315 | 316 | upload_mesh(r, gizmoEditorMesh); 317 | draw_mesh(wireframeShader, gizmoEditorMesh, cam.position, cam.get_viewproj_matrix((float)windowSize.x / (float)windowSize.y), identity4x4); 318 | 319 | //gizmo_ctx.draw(); 320 | gizmo_ctx.end(gizmo_state); 321 | 322 | gl_check_error(__FILE__, __LINE__); 323 | 324 | win->swap_buffers(); 325 | } 326 | return EXIT_SUCCESS; 327 | } 328 | -------------------------------------------------------------------------------- /tiny-gizmo-example/gl-api.hpp: -------------------------------------------------------------------------------- 1 | // This is free and unencumbered software released into the public domain. 2 | // For more information, please refer to 3 | 4 | #pragma once 5 | 6 | #ifndef gl_api_hpp 7 | #define gl_api_hpp 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include "linalg.h" 14 | 15 | namespace 16 | { 17 | static bool gEnableGLDebugOutputErrorBreakpoints = false; 18 | 19 | inline void compile_shader(GLuint program, GLenum type, const char * source) 20 | { 21 | GLuint shader = glCreateShader(type); 22 | glShaderSource(shader, 1, &source, nullptr); 23 | glCompileShader(shader); 24 | 25 | GLint status, length; 26 | glGetShaderiv(shader, GL_COMPILE_STATUS, &status); 27 | 28 | if (status == GL_FALSE) 29 | { 30 | glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length); 31 | std::vector buffer(length); 32 | glGetShaderInfoLog(shader, (GLsizei)buffer.size(), nullptr, buffer.data()); 33 | glDeleteShader(shader); 34 | std::cerr << "GL Compile Error: " << buffer.data() << std::endl; 35 | std::cerr << "Source: " << source << std::endl; 36 | throw std::runtime_error("GLSL Compile Failure"); 37 | } 38 | 39 | glAttachShader(program, shader); 40 | glDeleteShader(shader); 41 | } 42 | 43 | std::string gl_src_to_str(GLenum source) 44 | { 45 | switch (source) 46 | { 47 | case GL_DEBUG_SOURCE_WINDOW_SYSTEM: return "WINDOW_SYSTEM"; 48 | case GL_DEBUG_SOURCE_SHADER_COMPILER: return "SHADER_COMPILER"; 49 | case GL_DEBUG_SOURCE_THIRD_PARTY: return "THIRD_PARTY"; 50 | case GL_DEBUG_SOURCE_APPLICATION: return "APPLICATION"; 51 | case GL_DEBUG_SOURCE_OTHER: return "OTHER"; 52 | case GL_DEBUG_SOURCE_API: return "API"; 53 | default: return "UNKNOWN"; 54 | } 55 | } 56 | 57 | std::string gl_enum_to_str(GLenum type) 58 | { 59 | switch (type) 60 | { 61 | case GL_DEBUG_TYPE_ERROR: return "ERROR"; 62 | case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: return "DEPRECATION"; 63 | case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: return "UNDEFINED_BEHAVIOR"; 64 | case GL_DEBUG_TYPE_PORTABILITY: return "PORTABILITY"; 65 | case GL_DEBUG_TYPE_PERFORMANCE: return "PERFORMANCE"; 66 | case GL_DEBUG_TYPE_OTHER: return "OTHER"; 67 | default: return "UNKNOWN"; 68 | } 69 | } 70 | 71 | std::string gl_severity_to_str(GLenum severity) 72 | { 73 | switch (severity) 74 | { 75 | case GL_DEBUG_SEVERITY_LOW: return "LOW"; 76 | case GL_DEBUG_SEVERITY_MEDIUM: return "MEDIUM"; 77 | case GL_DEBUG_SEVERITY_HIGH: return "HIGH"; 78 | default: return "UNKNOWN"; 79 | } 80 | } 81 | 82 | static void APIENTRY gl_debug_callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar * message, GLvoid * userParam) 83 | { 84 | if (type != GL_DEBUG_TYPE_ERROR) return; 85 | auto sourceStr = gl_src_to_str(source); 86 | auto typeStr = gl_enum_to_str(type); 87 | auto severityStr = gl_severity_to_str(severity); 88 | std::cout << "gl_debug_callback: " << sourceStr << ", " << severityStr << ", " << typeStr << " , " << id << ", " << message << std::endl; 89 | #ifdef __WIN32 90 | if ((type == GL_DEBUG_TYPE_ERROR) && (gEnableGLDebugOutputErrorBreakpoints)) __debugbreak(); 91 | #endif 92 | } 93 | 94 | inline void gl_check_error(const char * file, int32_t line) 95 | { 96 | #if defined(_DEBUG) || defined(DEBUG) 97 | GLint error = glGetError(); 98 | if (error) 99 | { 100 | const char * errorStr = 0; 101 | switch (error) 102 | { 103 | case GL_INVALID_ENUM: errorStr = "GL_INVALID_ENUM"; break; 104 | case GL_INVALID_VALUE: errorStr = "GL_INVALID_VALUE"; break; 105 | case GL_INVALID_OPERATION: errorStr = "GL_INVALID_OPERATION"; break; 106 | case GL_OUT_OF_MEMORY: errorStr = "GL_OUT_OF_MEMORY"; break; 107 | default: errorStr = "unknown error"; break; 108 | } 109 | printf("GL error : %s, line %d : %s\n", file, line, errorStr); 110 | error = 0; 111 | } 112 | #endif 113 | } 114 | 115 | inline size_t gl_size_bytes(GLenum type) 116 | { 117 | switch (type) 118 | { 119 | case GL_UNSIGNED_BYTE: return sizeof(uint8_t); 120 | case GL_UNSIGNED_SHORT: return sizeof(uint16_t); 121 | case GL_UNSIGNED_INT: return sizeof(uint32_t); 122 | default: throw std::logic_error("unknown element type"); break; 123 | } 124 | } 125 | } 126 | 127 | template 128 | class GlObject 129 | { 130 | mutable GLuint handle = 0; 131 | std::string n; 132 | public: 133 | GlObject() {} 134 | GlObject(GLuint h) : handle(h) {} 135 | ~GlObject() { if (handle) factory_t::destroy(handle); } 136 | GlObject(const GlObject & r) = delete; 137 | GlObject & operator = (GlObject && r) { std::swap(handle, r.handle); std::swap(n, r.n); return *this; } 138 | GlObject(GlObject && r) { *this = std::move(r); } 139 | operator GLuint () const { if (!handle) factory_t::create(handle); return handle; } 140 | GlObject & operator = (GLuint & other) { handle = other; return *this; } 141 | void set_name(const std::string & newName) { n = newName; } 142 | std::string name() const { return n; } 143 | GLuint id() const { return handle; }; 144 | }; 145 | 146 | struct GlBufferFactory { static void create(GLuint & x) { glGenBuffers(1, &x); }; static void destroy(GLuint x) { glDeleteBuffers(1, &x); }; }; 147 | struct GlTextureFactory { static void create(GLuint & x) { glGenTextures(1, &x); }; static void destroy(GLuint x) { glDeleteTextures(1, &x); }; }; 148 | struct GlVertexArrayFactory { static void create(GLuint & x) { glGenVertexArrays(1, &x); }; static void destroy(GLuint x) { glDeleteVertexArrays(1, &x); }; }; 149 | struct GlRenderbufferFactory { static void create(GLuint & x) { glGenRenderbuffers(1, &x); }; static void destroy(GLuint x) { glDeleteRenderbuffers(1, &x); }; }; 150 | struct GlFramebufferFactory { static void create(GLuint & x) { glGenFramebuffers(1, &x); }; static void destroy(GLuint x) { glDeleteFramebuffers(1, &x); }; }; 151 | struct GlQueryFactory { static void create(GLuint & x) { glGenQueries(1, &x); }; static void destroy(GLuint x) { glDeleteQueries(1, &x); }; }; 152 | struct GlSamplerFactory { static void create(GLuint & x) { glGenSamplers(1, &x); }; static void destroy(GLuint x) { glDeleteSamplers(1, &x); }; }; 153 | struct GlTransformFeedbacksFactory { static void create(GLuint & x) { glGenTransformFeedbacks(1, &x); }; static void destroy(GLuint x) { glDeleteTransformFeedbacks(1, &x); }; }; 154 | 155 | typedef GlObject GlBufferObject; 156 | typedef GlObject GlTextureObject; 157 | typedef GlObject GlVertexArrayObject; 158 | typedef GlObject GlRenderbufferObject; 159 | typedef GlObject GlFramebufferObject; 160 | typedef GlObject GlQueryObject; 161 | typedef GlObject GlSamplerObject; 162 | typedef GlObject GlTransformFeedbacksObject; 163 | 164 | ////////////////// 165 | // GlBuffer // 166 | ////////////////// 167 | 168 | struct GlBuffer : public GlBufferObject 169 | { 170 | GLsizeiptr size; 171 | GlBuffer() {} 172 | void set_buffer_data(const GLsizeiptr s, const GLvoid * data, const GLenum usage) { this->size = s; glNamedBufferData(*this, size, data, usage); } 173 | void set_buffer_data(const std::vector & bytes, const GLenum usage) { set_buffer_data(bytes.size(), bytes.data(), usage); } 174 | void set_buffer_sub_data(const GLsizeiptr s, const GLintptr offset, const GLvoid * data) { glNamedBufferSubData(*this, offset, s, data); } 175 | void set_buffer_sub_data(const std::vector & bytes, const GLintptr offset, const GLenum usage) { set_buffer_sub_data(bytes.size(), offset, bytes.data()); } 176 | }; 177 | 178 | //////////////////////// 179 | // GlRenderbuffer // 180 | //////////////////////// 181 | 182 | struct GlRenderbuffer : public GlRenderbufferObject 183 | { 184 | float width{ 0 }, height{ 0 }; 185 | GlRenderbuffer() {} 186 | GlRenderbuffer(float width, float height) : width(width), height(height) {} 187 | }; 188 | 189 | /////////////////////// 190 | // GlFramebuffer // 191 | /////////////////////// 192 | 193 | struct GlFramebuffer : public GlFramebufferObject 194 | { 195 | float width{ 0 }, height{ 0 }, depth{ 0 }; 196 | GlFramebuffer() {} 197 | GlFramebuffer(float width, float height) : width(width), height(height) {} 198 | GlFramebuffer(float width, float height, float depth) : width(width), height(height), depth(depth) {} 199 | void check_complete() { if (glCheckNamedFramebufferStatusEXT(*this, GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) throw std::runtime_error("fbo incomplete"); } 200 | }; 201 | 202 | /////////////////// 203 | // GlTexture // 204 | /////////////////// 205 | 206 | struct GlTexture2D : public GlTextureObject 207 | { 208 | float width{ 0 }, height{ 0 }; 209 | GlTexture2D() {} 210 | GlTexture2D(float width, float height) : width(width), height(height) {} 211 | 212 | void setup(GLsizei width, GLsizei height, GLenum internal_fmt, GLenum format, GLenum type, const GLvoid * pixels, bool createMipmap = false) 213 | { 214 | glTextureImage2DEXT(*this, GL_TEXTURE_2D, 0, internal_fmt, width, height, 0, format, type, pixels); 215 | if (createMipmap) glGenerateTextureMipmapEXT(*this, GL_TEXTURE_2D); 216 | glTextureParameteriEXT(*this, GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 217 | glTextureParameteriEXT(*this, GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, createMipmap ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR); 218 | glTextureParameteriEXT(*this, GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 219 | glTextureParameteriEXT(*this, GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 220 | this->width = static_cast(width); 221 | this->height = static_cast(height); 222 | } 223 | }; 224 | 225 | ///////////////////// 226 | // GlTexture3D // 227 | ///////////////////// 228 | 229 | // As either a 3D texture or 2D array 230 | struct GlTexture3D : public GlTextureObject 231 | { 232 | float width{ 0 }, height{ 0 }, depth{ 0 }; 233 | GlTexture3D() {} 234 | GlTexture3D(float width, float height, float depth) : width(width), height(height), depth(depth) {} 235 | 236 | void setup(GLenum target, GLsizei width, GLsizei height, GLsizei depth, GLenum internal_fmt, GLenum format, GLenum type, const GLvoid * pixels) 237 | { 238 | glTextureImage3DEXT(*this, target, 0, internal_fmt, width, height, depth, 0, format, type, pixels); 239 | glTextureParameteriEXT(*this, target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 240 | glTextureParameteriEXT(*this, target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 241 | glTextureParameteriEXT(*this, target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); 242 | glTextureParameteriEXT(*this, target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); 243 | glTextureParameteriEXT(*this, target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_BORDER); 244 | this->width = static_cast(width); 245 | this->height = static_cast(height); 246 | this->depth = static_cast(depth); 247 | } 248 | }; 249 | 250 | ////////////////// 251 | // GlShader // 252 | ////////////////// 253 | 254 | class GlShader 255 | { 256 | GLuint program; 257 | bool enabled = false; 258 | 259 | protected: 260 | GlShader(const GlShader & r) = delete; 261 | GlShader & operator = (const GlShader & r) = delete; 262 | public: 263 | 264 | GlShader() : program() {} 265 | 266 | GlShader(const GLuint type, const std::string & src) 267 | { 268 | program = glCreateProgram(); 269 | 270 | ::compile_shader(program, type, src.c_str()); 271 | glProgramParameteri(program, GL_PROGRAM_SEPARABLE, GL_TRUE); 272 | 273 | glLinkProgram(program); 274 | 275 | GLint status, length; 276 | glGetProgramiv(program, GL_LINK_STATUS, &status); 277 | 278 | if (status == GL_FALSE) 279 | { 280 | glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length); 281 | std::vector buffer(length); 282 | glGetProgramInfoLog(program, (GLsizei)buffer.size(), nullptr, buffer.data()); 283 | std::cerr << "GL Link Error: " << buffer.data() << std::endl; 284 | throw std::runtime_error("GLSL Link Failure"); 285 | } 286 | } 287 | 288 | GlShader(const std::string & vert, const std::string & frag, const std::string & geom = "") 289 | { 290 | program = glCreateProgram(); 291 | 292 | glProgramParameteri(program, GL_PROGRAM_SEPARABLE, GL_FALSE); 293 | 294 | ::compile_shader(program, GL_VERTEX_SHADER, vert.c_str()); 295 | ::compile_shader(program, GL_FRAGMENT_SHADER, frag.c_str()); 296 | 297 | if (geom.length() != 0) ::compile_shader(program, GL_GEOMETRY_SHADER, geom.c_str()); 298 | 299 | glLinkProgram(program); 300 | 301 | GLint status, length; 302 | glGetProgramiv(program, GL_LINK_STATUS, &status); 303 | 304 | if (status == GL_FALSE) 305 | { 306 | glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length); 307 | std::vector buffer(length); 308 | glGetProgramInfoLog(program, (GLsizei)buffer.size(), nullptr, buffer.data()); 309 | std::cerr << "GL Link Error: " << buffer.data() << std::endl; 310 | throw std::runtime_error("GLSL Link Failure"); 311 | } 312 | } 313 | 314 | ~GlShader() { if (program) glDeleteProgram(program); } 315 | 316 | GlShader(GlShader && r) : GlShader() { *this = std::move(r); } 317 | 318 | GLuint handle() const { return program; } 319 | GLint get_uniform_location(const std::string & name) const { return glGetUniformLocation(program, name.c_str()); } 320 | 321 | GlShader & operator = (GlShader && r) { std::swap(program, r.program); return *this; } 322 | 323 | std::map reflect() 324 | { 325 | std::map locations; 326 | GLint count; 327 | glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &count); 328 | for (GLuint i = 0; i < static_cast(count); ++i) 329 | { 330 | char buffer[1024]; GLenum type; GLsizei length; GLint size, block_index; 331 | glGetActiveUniform(program, i, sizeof(buffer), &length, &size, &type, buffer); 332 | glGetActiveUniformsiv(program, 1, &i, GL_UNIFORM_BLOCK_INDEX, &block_index); 333 | if (block_index != -1) continue; 334 | GLint loc = glGetUniformLocation(program, buffer); 335 | locations[loc] = std::string(buffer); 336 | } 337 | return locations; 338 | } 339 | 340 | void uniform(const std::string & name, int scalar) const { glProgramUniform1i(program, get_uniform_location(name), scalar); } 341 | void uniform(const std::string & name, float scalar) const { glProgramUniform1f(program, get_uniform_location(name), scalar); } 342 | void uniform(const std::string & name, const linalg::aliases::float2 & vec) const { glProgramUniform2fv(program, get_uniform_location(name), 1, &vec.x); } 343 | void uniform(const std::string & name, const linalg::aliases::float3 & vec) const { glProgramUniform3fv(program, get_uniform_location(name), 1, &vec.x); } 344 | void uniform(const std::string & name, const linalg::aliases::float4 & vec) const { glProgramUniform4fv(program, get_uniform_location(name), 1, &vec.x); } 345 | void uniform(const std::string & name, const linalg::aliases::float3x3 & mat) const { glProgramUniformMatrix3fv(program, get_uniform_location(name), 1, GL_FALSE, &mat.x.x); } 346 | void uniform(const std::string & name, const linalg::aliases::float4x4 & mat) const { glProgramUniformMatrix4fv(program, get_uniform_location(name), 1, GL_FALSE, &mat.x.x); } 347 | 348 | void uniform(const std::string & name, const int elements, const std::vector & scalar) const { glProgramUniform1iv(program, get_uniform_location(name), elements, scalar.data()); } 349 | void uniform(const std::string & name, const int elements, const std::vector & scalar) const { glProgramUniform1fv(program, get_uniform_location(name), elements, scalar.data()); } 350 | void uniform(const std::string & name, const int elements, const std::vector & vec) const { glProgramUniform2fv(program, get_uniform_location(name), elements, &vec[0].x); } 351 | void uniform(const std::string & name, const int elements, const std::vector & vec) const { glProgramUniform3fv(program, get_uniform_location(name), elements, &vec[0].x); } 352 | void uniform(const std::string & name, const int elements, const std::vector & mat) const { glProgramUniformMatrix3fv(program, get_uniform_location(name), elements, GL_FALSE, &mat[0].x.x); } 353 | void uniform(const std::string & name, const int elements, const std::vector & mat) const { glProgramUniformMatrix4fv(program, get_uniform_location(name), elements, GL_FALSE, &mat[0].x.x); } 354 | 355 | void texture(GLint loc, GLenum target, int unit, GLuint tex) const 356 | { 357 | glBindMultiTextureEXT(GL_TEXTURE0 + unit, target, tex); 358 | glProgramUniform1i(program, loc, unit); 359 | } 360 | 361 | void texture(const char * name, int unit, GLuint tex, GLenum target) const { texture(get_uniform_location(name), target, unit, tex); } 362 | 363 | void bind() { if (program > 0) enabled = true; glUseProgram(program); } 364 | void unbind() { enabled = false; glUseProgram(0); } 365 | }; 366 | 367 | //////////////// 368 | // GlMesh // 369 | //////////////// 370 | 371 | class GlMesh 372 | { 373 | GlVertexArrayObject vao; 374 | GlBuffer vertexBuffer, instanceBuffer, indexBuffer; 375 | 376 | GLenum drawMode = GL_TRIANGLES; 377 | GLenum indexType = 0; 378 | GLsizei vertexStride = 0, instanceStride = 0, indexCount = 0; 379 | 380 | public: 381 | 382 | GlMesh() {} 383 | GlMesh(GlMesh && r) { *this = std::move(r); } 384 | GlMesh(const GlMesh & r) = delete; 385 | GlMesh & operator = (GlMesh && r) 386 | { 387 | char buffer[sizeof(GlMesh)]; 388 | memcpy(buffer, this, sizeof(buffer)); 389 | memcpy(this, &r, sizeof(buffer)); 390 | memcpy(&r, buffer, sizeof(buffer)); 391 | return *this; 392 | } 393 | GlMesh & operator = (const GlMesh & r) = delete; 394 | ~GlMesh() {}; 395 | 396 | void set_non_indexed(GLenum newMode) 397 | { 398 | drawMode = newMode; 399 | indexBuffer = {}; 400 | indexType = 0; 401 | indexCount = 0; 402 | } 403 | 404 | void draw_elements(int instances = 0) const 405 | { 406 | if (vertexBuffer.size) 407 | { 408 | glBindVertexArray(vao); 409 | if (indexCount) 410 | { 411 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer); 412 | if (instances) glDrawElementsInstanced(drawMode, indexCount, indexType, 0, instances); 413 | else glDrawElements(drawMode, indexCount, indexType, nullptr); 414 | } 415 | else 416 | { 417 | if (instances) glDrawArraysInstanced(drawMode, 0, static_cast(vertexBuffer.size / vertexStride), instances); 418 | else glDrawArrays(drawMode, 0, static_cast(vertexBuffer.size / vertexStride)); 419 | } 420 | glBindVertexArray(0); 421 | } 422 | } 423 | 424 | void set_vertex_data(GLsizeiptr size, const GLvoid * data, GLenum usage) { vertexBuffer.set_buffer_data(size, data, usage); } 425 | GlBuffer & get_vertex_data_buffer() { return vertexBuffer; }; 426 | 427 | void set_instance_data(GLsizeiptr size, const GLvoid * data, GLenum usage) { instanceBuffer.set_buffer_data(size, data, usage); } 428 | 429 | void set_index_data(GLenum mode, GLenum type, GLsizei count, const GLvoid * data, GLenum usage) 430 | { 431 | size_t size = gl_size_bytes(type); 432 | indexBuffer.set_buffer_data(size * count, data, usage); 433 | drawMode = mode; 434 | indexType = type; 435 | indexCount = count; 436 | } 437 | GlBuffer & get_index_data_buffer() { return indexBuffer; }; 438 | 439 | void set_attribute(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid * offset) 440 | { 441 | glEnableVertexArrayAttribEXT(vao, index); 442 | glVertexArrayVertexAttribOffsetEXT(vao, vertexBuffer, index, size, type, normalized, stride, (GLintptr)offset); 443 | vertexStride = stride; 444 | } 445 | 446 | void set_instance_attribute(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid * offset) 447 | { 448 | glEnableVertexArrayAttribEXT(vao, index); 449 | glVertexArrayVertexAttribOffsetEXT(vao, instanceBuffer, index, size, type, normalized, stride, (GLintptr)offset); 450 | glVertexArrayVertexAttribDivisorEXT(vao, index, 1); 451 | instanceStride = stride; 452 | } 453 | 454 | void set_indices(GLenum mode, GLsizei count, const uint8_t * indices, GLenum usage) { set_index_data(mode, GL_UNSIGNED_BYTE, count, indices, usage); } 455 | void set_indices(GLenum mode, GLsizei count, const uint16_t * indices, GLenum usage) { set_index_data(mode, GL_UNSIGNED_SHORT, count, indices, usage); } 456 | void set_indices(GLenum mode, GLsizei count, const uint32_t * indices, GLenum usage) { set_index_data(mode, GL_UNSIGNED_INT, count, indices, usage); } 457 | 458 | template void set_vertices(size_t count, const T * vertices, GLenum usage) { set_vertex_data(count * sizeof(T), vertices, usage); } 459 | template void set_vertices(const std::vector & vertices, GLenum usage) { set_vertices(vertices.size(), vertices.data(), usage); } 460 | template void set_vertices(const T(&vertices)[N], GLenum usage) { set_vertices(N, vertices, usage); } 461 | 462 | template void set_attribute(GLuint index, float V::*field) { set_attribute(index, 1, GL_FLOAT, GL_FALSE, sizeof(V), &(((V*)0)->*field)); } 463 | template void set_attribute(GLuint index, linalg::vec V::*field) { set_attribute(index, N, GL_FLOAT, GL_FALSE, sizeof(V), &(((V*)0)->*field)); } 464 | 465 | template void set_elements(GLsizei count, const linalg::vec * elements, GLenum usage) { set_indices(GL_LINES, count * 2, &elements->x, usage); } 466 | template void set_elements(GLsizei count, const linalg::vec * elements, GLenum usage) { set_indices(GL_TRIANGLES, count * 3, &elements->x, usage); } 467 | template void set_elements(GLsizei count, const linalg::vec * elements, GLenum usage) { set_indices(GL_QUADS, count * 4, &elements->x, usage); } 468 | 469 | template void set_elements(const std::vector & elements, GLenum usage) { set_elements((GLsizei)elements.size(), elements.data(), usage); } 470 | 471 | template void set_elements(const T(&elements)[N], GLenum usage) { set_elements(N, elements, usage); } 472 | }; 473 | 474 | #endif // end gl_api_hpp 475 | -------------------------------------------------------------------------------- /tiny-gizmo-example/linalg.h: -------------------------------------------------------------------------------- 1 | // linalg.h - v2.0 - Single-header public domain linear algebra library 2 | // 3 | // The intent of this library is to provide the bulk of the functionality 4 | // you need to write programs that frequently use small, fixed-size vectors 5 | // and matrices, in domains such as computational geometry or computer 6 | // graphics. It strives for terse, readable source code. 7 | // 8 | // The original author of this software is Sterling Orsten, and its permanent 9 | // home is . If you find this software 10 | // useful, an acknowledgement in your source text and/or product documentation 11 | // is appreciated, but not required. 12 | // 13 | // The author acknowledges significant insights and contributions by: 14 | // Stan Melax 15 | // Dimitri Diakopoulos 16 | 17 | 18 | 19 | // This is free and unencumbered software released into the public domain. 20 | // 21 | // Anyone is free to copy, modify, publish, use, compile, sell, or 22 | // distribute this software, either in source code form or as a compiled 23 | // binary, for any purpose, commercial or non-commercial, and by any 24 | // means. 25 | // 26 | // In jurisdictions that recognize copyright laws, the author or authors 27 | // of this software dedicate any and all copyright interest in the 28 | // software to the public domain. We make this dedication for the benefit 29 | // of the public at large and to the detriment of our heirs and 30 | // successors. We intend this dedication to be an overt act of 31 | // relinquishment in perpetuity of all present and future rights to this 32 | // software under copyright law. 33 | // 34 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 35 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 36 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 37 | // IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 38 | // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 39 | // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 40 | // OTHER DEALINGS IN THE SOFTWARE. 41 | // 42 | // For more information, please refer to 43 | 44 | 45 | 46 | #pragma once 47 | #ifndef LINALG_H 48 | #define LINALG_H 49 | 50 | #include // For various unary math functions, such as std::sqrt 51 | #include // To resolve std::abs ambiguity on clang 52 | #include // For implementing namespace linalg::aliases 53 | #include // For std::array, used in the relational operator overloads 54 | #include // For std::numeric_limits/epsilon 55 | 56 | // Visual Studio versions prior to 2015 lack constexpr support 57 | #if defined(_MSC_VER) && _MSC_VER < 1900 && !defined(constexpr) 58 | #define constexpr 59 | #endif 60 | 61 | namespace linalg 62 | { 63 | // Small, fixed-length vector type, consisting of exactly M elements of type T, and presumed to be a column-vector unless otherwise noted 64 | template struct vec; 65 | template struct vec 66 | { 67 | T x,y; 68 | constexpr vec() : x(), y() {} 69 | constexpr vec(T x, T y) : x(x), y(y) {} 70 | constexpr explicit vec(T s) : x(s), y(s) {} 71 | constexpr explicit vec(const T * p) : vec(p[0], p[1]) {} 72 | template 73 | constexpr explicit vec(const vec & v) : vec(static_cast(v.x), static_cast(v.y)) {} 74 | constexpr const T & operator[] (int i) const { return (&x)[i]; } 75 | T & operator[] (int i) { return (&x)[i]; } 76 | }; 77 | template struct vec 78 | { 79 | T x,y,z; 80 | constexpr vec() : x(), y(), z() {} 81 | constexpr vec(T x, T y, T z) : x(x), y(y), z(z) {} 82 | constexpr explicit vec(T s) : x(s), y(s), z(s) {} 83 | constexpr explicit vec(const T * p) : vec(p[0], p[1], p[2]) {} 84 | template 85 | constexpr explicit vec(const vec & v) : vec(static_cast(v.x), static_cast(v.y), static_cast(v.z)) {} 86 | constexpr vec(const vec & xy, T z) : vec(xy.x, xy.y, z) {} 87 | constexpr const T & operator[] (int i) const { return (&x)[i]; } 88 | T & operator[] (int i) { return (&x)[i]; } 89 | constexpr const vec & xy() const { return *reinterpret_cast *>(this); } 90 | vec & xy() { return *reinterpret_cast *>(this); } 91 | }; 92 | template struct vec 93 | { 94 | T x,y,z,w; 95 | constexpr vec() : x(), y(), z(), w() {} 96 | constexpr vec(T x, T y, T z, T w) : x(x), y(y), z(z), w(w) {} 97 | constexpr explicit vec(T s) : x(s), y(s), z(s), w(s) {} 98 | constexpr explicit vec(const T * p) : vec(p[0], p[1], p[2], p[3]) {} 99 | template 100 | constexpr explicit vec(const vec & v) : vec(static_cast(v.x), static_cast(v.y), static_cast(v.z), static_cast(v.w)) {} 101 | constexpr vec(const vec & xyz, T w) : vec(xyz.x, xyz.y, xyz.z, w) {} 102 | constexpr const T & operator[] (int i) const { return (&x)[i]; } 103 | T & operator[] (int i) { return (&x)[i]; } 104 | constexpr const vec & xyz() const { return *reinterpret_cast *>(this); } 105 | vec & xyz() { return *reinterpret_cast *>(this); } 106 | }; 107 | 108 | // Small, fixed-size matrix type, consisting of exactly M rows and N columns of type T, stored in column-major order. 109 | template struct mat; 110 | template struct mat 111 | { 112 | typedef vec V; 113 | V x,y; 114 | constexpr mat() : x(), y() {} 115 | constexpr mat(V x, V y) : x(x), y(y) {} 116 | constexpr explicit mat(T s) : x(s), y(s) {} 117 | constexpr explicit mat(const T * p) : x(p+M*0), y(p+M*1) {} 118 | template 119 | constexpr explicit mat(const mat & m) : mat(V(m.x), V(m.y)) {} 120 | constexpr vec row(int i) const { return {x[i], y[i]}; } 121 | constexpr const V & operator[] (int j) const { return (&x)[j]; } 122 | V & operator[] (int j) { return (&x)[j]; } 123 | }; 124 | template struct mat 125 | { 126 | typedef vec V; 127 | V x,y,z; 128 | constexpr mat() : x(), y(), z() {} 129 | constexpr mat(V x, V y, V z) : x(x), y(y), z(z) {} 130 | constexpr explicit mat(T s) : x(s), y(s), z(s) {} 131 | constexpr explicit mat(const T * p) : x(p+M*0), y(p+M*1), z(p+M*2) {} 132 | template 133 | constexpr explicit mat(const mat & m) : mat(V(m.x), V(m.y), V(m.z)) {} 134 | constexpr vec row(int i) const { return {x[i], y[i], z[i]}; } 135 | constexpr const V & operator[] (int j) const { return (&x)[j]; } 136 | V & operator[] (int j) { return (&x)[j]; } 137 | }; 138 | template struct mat 139 | { 140 | typedef vec V; 141 | V x,y,z,w; 142 | constexpr mat() : x(), y(), z(), w() {} 143 | constexpr mat(V x, V y, V z, V w) : x(x), y(y), z(z), w(w) {} 144 | constexpr explicit mat(T s) : x(s), y(s), z(s), w(s) {} 145 | constexpr explicit mat(const T * p) : x(p+M*0), y(p+M*1), z(p+M*2), w(p+M*3) {} 146 | template 147 | constexpr explicit mat(const mat & m) : mat(V(m.x), V(m.y), V(m.z), V(m.w)) {} 148 | constexpr vec row(int i) const { return {x[i], y[i], z[i], w[i]}; } 149 | constexpr const V & operator[] (int j) const { return (&x)[j]; } 150 | V & operator[] (int j) { return (&x)[j]; } 151 | }; 152 | 153 | // Type traits for a binary operation involving linear algebra types, used for SFINAE on templated functions and operator overloads 154 | template struct traits {}; 155 | template struct traits, vec> { typedef T scalar; typedef vec result; typedef vec bool_result; typedef vec arith_result; typedef std::array compare_as; }; 156 | template struct traits, T > { typedef T scalar; typedef vec result; typedef vec bool_result; typedef vec arith_result; }; 157 | template struct traits> { typedef T scalar; typedef vec result; typedef vec bool_result; typedef vec arith_result; }; 158 | template struct traits, mat> { typedef T scalar; typedef mat result; typedef mat bool_result; typedef mat arith_result; typedef std::array compare_as; }; 159 | template struct traits, T > { typedef T scalar; typedef mat result; typedef mat bool_result; typedef mat arith_result; }; 160 | template struct traits> { typedef T scalar; typedef mat result; typedef mat bool_result; typedef mat arith_result; }; 161 | template using scalar_t = typename traits::scalar; // Underlying scalar type when performing elementwise operations 162 | template using result_t = typename traits::result; // Result of calling a function on linear algebra types 163 | template using bool_result_t = typename traits::bool_result; // Result of a comparison or unary not operation on linear algebra types 164 | template using arith_result_t = typename traits::arith_result; // Result of an arithmetic operation on linear algebra types (accounts for integer promotion) 165 | 166 | // Produce a scalar by applying f(T,T) -> T to adjacent pairs of elements from vector a in left-to-right order (matching the associativity of arithmetic and logical operators) 167 | template constexpr T fold(const vec & a, F f) { return f(a.x,a.y); } 168 | template constexpr T fold(const vec & a, F f) { return f(f(a.x,a.y),a.z); } 169 | template constexpr T fold(const vec & a, F f) { return f(f(f(a.x,a.y),a.z),a.w); } 170 | 171 | // Produce a vector/matrix by applying f(T,T) to corresponding pairs of elements from vectors/matrix a and b 172 | template constexpr auto zip(const vec & a, const vec & b, F f) -> vec { return {f(a.x,b.x), f(a.y,b.y)}; } 173 | template constexpr auto zip(const vec & a, const vec & b, F f) -> vec { return {f(a.x,b.x), f(a.y,b.y), f(a.z,b.z)}; } 174 | template constexpr auto zip(const vec & a, const vec & b, F f) -> vec { return {f(a.x,b.x), f(a.y,b.y), f(a.z,b.z), f(a.w,b.w)}; } 175 | template constexpr auto zip(const vec & a, T b, F f) -> vec { return zip(a, vec(b), f); } 176 | template constexpr auto zip( T a, const vec & b, F f) -> vec { return zip(vec(a), b, f); } 177 | template constexpr auto zip(const mat & a, const mat & b, F f) -> mat { return {zip(a.x,b.x,f), zip(a.y,b.y,f)}; } 178 | template constexpr auto zip(const mat & a, const mat & b, F f) -> mat { return {zip(a.x,b.x,f), zip(a.y,b.y,f), zip(a.z,b.z,f)}; } 179 | template constexpr auto zip(const mat & a, const mat & b, F f) -> mat { return {zip(a.x,b.x,f), zip(a.y,b.y,f), zip(a.z,b.z,f), zip(a.w,b.w,f)}; } 180 | template constexpr auto zip(const mat & a, T b, F f) -> mat { return zip(a, mat(b), f); } 181 | template constexpr auto zip( T a, const mat & b, F f) -> mat { return zip(mat(a), b, f); } 182 | 183 | // Produce a vector/matrix by applying f(T) to elements from vector/matrix a 184 | template constexpr auto map(const vec & a, F f) -> vec { return zip(a, a, [f](T l, T) { return f(l); }); } 185 | template constexpr auto map(const mat & a, F f) -> mat { return zip(a, a, [f](T l, T) { return f(l); }); } 186 | 187 | // Relational operators are defined to compare the elements of two vectors or matrices lexicographically, in column-major order 188 | template::compare_as> constexpr bool operator == (const A & a, const A & b) { return reinterpret_cast(a) == reinterpret_cast(b); } 189 | template::compare_as> constexpr bool operator != (const A & a, const A & b) { return reinterpret_cast(a) != reinterpret_cast(b); } 190 | template::compare_as> constexpr bool operator < (const A & a, const A & b) { return reinterpret_cast(a) < reinterpret_cast(b); } 191 | template::compare_as> constexpr bool operator > (const A & a, const A & b) { return reinterpret_cast(a) > reinterpret_cast(b); } 192 | template::compare_as> constexpr bool operator <= (const A & a, const A & b) { return reinterpret_cast(a) <= reinterpret_cast(b); } 193 | template::compare_as> constexpr bool operator >= (const A & a, const A & b) { return reinterpret_cast(a) >= reinterpret_cast(b); } 194 | 195 | // Lambdas are not permitted inside constexpr functions, so we provide explicit function objects instead 196 | namespace op 197 | { 198 | template struct pos { constexpr auto operator() (T r) const -> decltype(+r) { return +r; } }; 199 | template struct neg { constexpr auto operator() (T r) const -> decltype(-r) { return -r; } }; 200 | template struct add { constexpr auto operator() (T l, T r) const -> decltype(l + r) { return l + r; } }; 201 | template struct sub { constexpr auto operator() (T l, T r) const -> decltype(l - r) { return l - r; } }; 202 | template struct mul { constexpr auto operator() (T l, T r) const -> decltype(l * r) { return l * r; } }; 203 | template struct div { constexpr auto operator() (T l, T r) const -> decltype(l / r) { return l / r; } }; 204 | template struct mod { constexpr auto operator() (T l, T r) const -> decltype(l % r) { return l % r; } }; 205 | template struct lshift { constexpr auto operator() (T l, T r) const -> decltype(l << r) { return l << r; } }; 206 | template struct rshift { constexpr auto operator() (T l, T r) const -> decltype(l >> r) { return l >> r; } }; 207 | 208 | template struct binary_not { constexpr auto operator() (T r) const -> decltype(+r) { return ~r; } }; 209 | template struct binary_or { constexpr auto operator() (T l, T r) const -> decltype(l | r) { return l | r; } }; 210 | template struct binary_xor { constexpr auto operator() (T l, T r) const -> decltype(l ^ r) { return l ^ r; } }; 211 | template struct binary_and { constexpr auto operator() (T l, T r) const -> decltype(l & r) { return l & r; } }; 212 | 213 | template struct logical_not { constexpr bool operator() (T r) const { return !r; } }; 214 | template struct logical_or { constexpr bool operator() (T l, T r) const { return l || r; } }; 215 | template struct logical_and { constexpr bool operator() (T l, T r) const { return l && r; } }; 216 | 217 | template struct equal { constexpr bool operator() (T l, T r) const { return l == r; } }; 218 | template struct nequal { constexpr bool operator() (T l, T r) const { return l != r; } }; 219 | template struct less { constexpr bool operator() (T l, T r) const { return l < r; } }; 220 | template struct greater { constexpr bool operator() (T l, T r) const { return l > r; } }; 221 | template struct lequal { constexpr bool operator() (T l, T r) const { return l <= r; } }; 222 | template struct gequal { constexpr bool operator() (T l, T r) const { return l >= r; } }; 223 | 224 | template struct min { constexpr T operator() (T l, T r) const { return l < r ? l : r; } }; 225 | template struct max { constexpr T operator() (T l, T r) const { return l > r ? l : r; } }; 226 | } 227 | 228 | // Functions for coalescing scalar values 229 | template constexpr bool any(const vec & a) { return fold(a, op::logical_or{}); } 230 | template constexpr bool all(const vec & a) { return fold(a, op::logical_and{}); } 231 | template constexpr T sum (const vec & a) { return fold(a, op::add{}); } 232 | template constexpr T product(const vec & a) { return fold(a, op::mul{}); } 233 | template int argmin(const vec & a) { int j=0; for(int i=1; i int argmax(const vec & a) { int j=0; for(int i=1; i a[j]) j = i; return j; } 235 | template T minelem(const vec & a) { return a[argmin(a)]; } 236 | template T maxelem(const vec & a) { return a[argmax(a)]; } 237 | 238 | // Overloads for unary operators on vectors are implemented in terms of elementwise application of the operator 239 | template constexpr arith_result_t operator + (const A & a) { return map(a, op::pos>{}); } 240 | template constexpr arith_result_t operator - (const A & a) { return map(a, op::neg>{}); } 241 | template constexpr arith_result_t operator ~ (const A & a) { return map(a, op::binary_not>{}); } 242 | template constexpr bool_result_t operator ! (const A & a) { return map(a, op::logical_not>{}); } 243 | 244 | // Mirror the set of unary scalar math functions to apply elementwise to vectors 245 | template result_t abs (const A & a) { return map(a, [](scalar_t l) { return std::abs (l); }); } 246 | template result_t floor(const A & a) { return map(a, [](scalar_t l) { return std::floor(l); }); } 247 | template result_t ceil (const A & a) { return map(a, [](scalar_t l) { return std::ceil (l); }); } 248 | template result_t exp (const A & a) { return map(a, [](scalar_t l) { return std::exp (l); }); } 249 | template result_t log (const A & a) { return map(a, [](scalar_t l) { return std::log (l); }); } 250 | template result_t log10(const A & a) { return map(a, [](scalar_t l) { return std::log10(l); }); } 251 | template result_t sqrt (const A & a) { return map(a, [](scalar_t l) { return std::sqrt (l); }); } 252 | template result_t sin (const A & a) { return map(a, [](scalar_t l) { return std::sin (l); }); } 253 | template result_t cos (const A & a) { return map(a, [](scalar_t l) { return std::cos (l); }); } 254 | template result_t tan (const A & a) { return map(a, [](scalar_t l) { return std::tan (l); }); } 255 | template result_t asin (const A & a) { return map(a, [](scalar_t l) { return std::asin (l); }); } 256 | template result_t acos (const A & a) { return map(a, [](scalar_t l) { return std::acos (l); }); } 257 | template result_t atan (const A & a) { return map(a, [](scalar_t l) { return std::atan (l); }); } 258 | template result_t sinh (const A & a) { return map(a, [](scalar_t l) { return std::sinh (l); }); } 259 | template result_t cosh (const A & a) { return map(a, [](scalar_t l) { return std::cosh (l); }); } 260 | template result_t tanh (const A & a) { return map(a, [](scalar_t l) { return std::tanh (l); }); } 261 | template result_t round(const A & a) { return map(a, [](scalar_t l) { return std::round(l); }); } 262 | template result_t fract(const A & a) { return map(a, [](scalar_t l) { return l - std::floor(l); }); } 263 | 264 | // Overloads for vector op vector are implemented in terms of elementwise application of the operator, followed by casting back to the original type (integer promotion is suppressed) 265 | template constexpr arith_result_t operator + (const A & a, const B & b) { return zip(a, b, op::add>{}); } 266 | template constexpr arith_result_t operator - (const A & a, const B & b) { return zip(a, b, op::sub>{}); } 267 | template constexpr arith_result_t operator * (const A & a, const B & b) { return zip(a, b, op::mul>{}); } 268 | template constexpr arith_result_t operator / (const A & a, const B & b) { return zip(a, b, op::div>{}); } 269 | template constexpr arith_result_t operator % (const A & a, const B & b) { return zip(a, b, op::mod>{}); } 270 | template constexpr arith_result_t operator | (const A & a, const B & b) { return zip(a, b, op::binary_or>{}); } 271 | template constexpr arith_result_t operator ^ (const A & a, const B & b) { return zip(a, b, op::binary_xor>{}); } 272 | template constexpr arith_result_t operator & (const A & a, const B & b) { return zip(a, b, op::binary_and>{}); } 273 | template constexpr arith_result_t operator << (const A & a, const B & b) { return zip(a, b, op::lshift>{}); } 274 | template constexpr arith_result_t operator >> (const A & a, const B & b) { return zip(a, b, op::rshift>{}); } 275 | 276 | // Overloads for assignment operators are implemented trivially 277 | template result_t & operator += (A & a, const B & b) { return a = a + b; } 278 | template result_t & operator -= (A & a, const B & b) { return a = a - b; } 279 | template result_t & operator *= (A & a, const B & b) { return a = a * b; } 280 | template result_t & operator /= (A & a, const B & b) { return a = a / b; } 281 | template result_t & operator %= (A & a, const B & b) { return a = a % b; } 282 | template result_t & operator |= (A & a, const B & b) { return a = a | b; } 283 | template result_t & operator ^= (A & a, const B & b) { return a = a ^ b; } 284 | template result_t & operator &= (A & a, const B & b) { return a = a & b; } 285 | template result_t & operator <<= (A & a, const B & b) { return a = a << b; } 286 | template result_t & operator >>= (A & a, const B & b) { return a = a >> b; } 287 | 288 | // Mirror the set of binary scalar math functions to apply elementwise to vectors 289 | template constexpr result_t min (const A & a, const B & b) { return zip(a, b, op::min>{}); } 290 | template constexpr result_t max (const A & a, const B & b) { return zip(a, b, op::max>{}); } 291 | template constexpr result_t clamp(const A & a, const B & b, const B & c) { return min(max(a,b),c); } // TODO: Revisit 292 | template result_t fmod (const A & a, const B & b) { return zip(a, b, [](scalar_t l, scalar_t r) { return std::fmod (l, r); }); } 293 | template result_t pow (const A & a, const B & b) { return zip(a, b, [](scalar_t l, scalar_t r) { return std::pow (l, r); }); } 294 | template result_t atan2 (const A & a, const B & b) { return zip(a, b, [](scalar_t l, scalar_t r) { return std::atan2 (l, r); }); } 295 | template result_t copysign(const A & a, const B & b) { return zip(a, b, [](scalar_t l, scalar_t r) { return std::copysign(l, r); }); } 296 | 297 | // Functions for componentwise application of equivalence and relational operators 298 | template bool_result_t equal (const A & a, const B & b) { return zip(a, b, op::equal >{}); } 299 | template bool_result_t nequal (const A & a, const B & b) { return zip(a, b, op::nequal >{}); } 300 | template bool_result_t less (const A & a, const B & b) { return zip(a, b, op::less >{}); } 301 | template bool_result_t greater(const A & a, const B & b) { return zip(a, b, op::greater>{}); } 302 | template bool_result_t lequal (const A & a, const B & b) { return zip(a, b, op::lequal >{}); } 303 | template bool_result_t gequal (const A & a, const B & b) { return zip(a, b, op::gequal >{}); } 304 | 305 | // Support for vector algebra 306 | template constexpr T cross (const vec & a, const vec & b) { return a.x*b.y-a.y*b.x; } 307 | template constexpr vec cross (const vec & a, const vec & b) { return {a.y*b.z-a.z*b.y, a.z*b.x-a.x*b.z, a.x*b.y-a.y*b.x}; } 308 | template constexpr T dot (const vec & a, const vec & b) { return sum(a*b); } 309 | template constexpr T length2 (const vec & a) { return dot(a,a); } 310 | template T length (const vec & a) { return std::sqrt(length2(a)); } 311 | template vec normalize(const vec & a) { return a / length(a); } 312 | template constexpr T distance2(const vec & a, const vec & b) { return length2(b-a); } 313 | template T distance (const vec & a, const vec & b) { return length(b-a); } 314 | template T uangle (const vec & a, const vec & b) { T d=dot(a,b); return d > 1 ? 0 : std::acos(d < -1 ? -1 : d); } 315 | template T angle (const vec & a, const vec & b) { return uangle(normalize(a), normalize(b)); } 316 | template constexpr vec lerp (const vec & a, const vec & b, T t) { return a*(1-t) + b*t; } 317 | template vec nlerp (const vec & a, const vec & b, T t) { return normalize(lerp(a,b,t)); } 318 | template vec slerp (const vec & a, const vec & b, T t) { T th=uangle(a,b); return th == 0 ? a : a*(std::sin(th*(1-t))/std::sin(th)) + b*(std::sin(th*t)/std::sin(th)); } 319 | template constexpr mat outerprod(const vec & a, const vec & b) { return {a*b.x, a*b.y}; } 320 | template constexpr mat outerprod(const vec & a, const vec & b) { return {a*b.x, a*b.y, a*b.z}; } 321 | template constexpr mat outerprod(const vec & a, const vec & b) { return {a*b.x, a*b.y, a*b.z, a*b.w}; } 322 | 323 | // Support for quaternion algebra using 4D vectors, representing xi + yj + zk + w 324 | template constexpr vec qconj(const vec & q) { return {-q.x,-q.y,-q.z,q.w}; } 325 | template vec qinv (const vec & q) { return qconj(q)/length2(q); } 326 | template vec qexp (const vec & q) { const auto v = q.xyz(); const auto vv = length(v); return std::exp(q.w) * vec{v * (vv > 0 ? std::sin(vv)/vv : 0), std::cos(vv)}; } 327 | template vec qlog (const vec & q) { const auto v = q.xyz(); const auto vv = length(v), qq = length(q); return {v * (vv > 0 ? std::acos(q.w/qq)/vv : 0), std::log(qq)}; } 328 | template vec qpow (const vec & q, const T & p) { const auto v = q.xyz(); const auto vv = length(v), qq = length(q), th = std::acos(q.w/qq); return std::pow(qq,p)*vec{v * (vv > 0 ? std::sin(p*th)/vv : 0), std::cos(p*th)}; } 329 | template constexpr vec qmul (const vec & a, const vec & b) { return {a.x*b.w+a.w*b.x+a.y*b.z-a.z*b.y, a.y*b.w+a.w*b.y+a.z*b.x-a.x*b.z, a.z*b.w+a.w*b.z+a.x*b.y-a.y*b.x, a.w*b.w-a.x*b.x-a.y*b.y-a.z*b.z}; } 330 | template constexpr vec qmul(const vec & a, R... r) { return qmul(a, qmul(r...)); } 331 | 332 | // Support for 3D spatial rotations using quaternions, via qmul(qmul(q, v), qconj(q)) 333 | template constexpr vec qxdir (const vec & q) { return {q.w*q.w+q.x*q.x-q.y*q.y-q.z*q.z, (q.x*q.y+q.z*q.w)*2, (q.z*q.x-q.y*q.w)*2}; } 334 | template constexpr vec qydir (const vec & q) { return {(q.x*q.y-q.z*q.w)*2, q.w*q.w-q.x*q.x+q.y*q.y-q.z*q.z, (q.y*q.z+q.x*q.w)*2}; } 335 | template constexpr vec qzdir (const vec & q) { return {(q.z*q.x+q.y*q.w)*2, (q.y*q.z-q.x*q.w)*2, q.w*q.w-q.x*q.x-q.y*q.y+q.z*q.z}; } 336 | template constexpr mat qmat (const vec & q) { return {qxdir(q), qydir(q), qzdir(q)}; } 337 | template constexpr vec qrot (const vec & q, const vec & v) { return qxdir(q)*v.x + qydir(q)*v.y + qzdir(q)*v.z; } 338 | template T qangle(const vec & q) { return std::acos(q.w)*2; } 339 | template vec qaxis (const vec & q) { return normalize(q.xyz()); } 340 | template vec qnlerp(const vec & a, const vec & b, T t) { return nlerp(a, dot(a,b) < 0 ? -b : b, t); } 341 | template vec qslerp(const vec & a, const vec & b, T t) { return slerp(a, dot(a,b) < 0 ? -b : b, t); } 342 | 343 | // Support for matrix algebra 344 | template constexpr vec mul(const mat & a, const vec & b) { return a.x*b.x + a.y*b.y; } 345 | template constexpr vec mul(const mat & a, const vec & b) { return a.x*b.x + a.y*b.y + a.z*b.z; } 346 | template constexpr vec mul(const mat & a, const vec & b) { return a.x*b.x + a.y*b.y + a.z*b.z + a.w*b.w; } 347 | template constexpr mat mul(const mat & a, const mat & b) { return {mul(a,b.x), mul(a,b.y)}; } 348 | template constexpr mat mul(const mat & a, const mat & b) { return {mul(a,b.x), mul(a,b.y), mul(a,b.z)}; } 349 | template constexpr mat mul(const mat & a, const mat & b) { return {mul(a,b.x), mul(a,b.y), mul(a,b.z), mul(a,b.w)}; } 350 | #if _MSC_VER >= 1910 351 | template constexpr auto mul(const mat & a, R... r) { return mul(a, mul(r...)); } 352 | #else 353 | template constexpr auto mul(const mat & a, R... r) -> decltype(mul(a, mul(r...))) { return mul(a, mul(r...)); } 354 | #endif 355 | template constexpr vec diagonal(const mat & a) { return {a.x.x, a.y.y}; } 356 | template constexpr vec diagonal(const mat & a) { return {a.x.x, a.y.y, a.z.z}; } 357 | template constexpr vec diagonal(const mat & a) { return {a.x.x, a.y.y, a.z.z, a.w.w}; } 358 | template constexpr mat transpose(const mat & m) { return {m.row(0), m.row(1)}; } 359 | template constexpr mat transpose(const mat & m) { return {m.row(0), m.row(1), m.row(2)}; } 360 | template constexpr mat transpose(const mat & m) { return {m.row(0), m.row(1), m.row(2), m.row(3)}; } 361 | template constexpr mat adjugate(const mat & a) { return {{a.y.y, -a.x.y}, {-a.y.x, a.x.x}}; } 362 | template constexpr mat adjugate(const mat & a) { return { 363 | {a.y.y*a.z.z - a.z.y*a.y.z, a.z.y*a.x.z - a.x.y*a.z.z, a.x.y*a.y.z - a.y.y*a.x.z}, 364 | {a.y.z*a.z.x - a.z.z*a.y.x, a.z.z*a.x.x - a.x.z*a.z.x, a.x.z*a.y.x - a.y.z*a.x.x}, 365 | {a.y.x*a.z.y - a.z.x*a.y.y, a.z.x*a.x.y - a.x.x*a.z.y, a.x.x*a.y.y - a.y.x*a.x.y}}; } 366 | template constexpr mat adjugate(const mat & a) { return { 367 | {a.y.y*a.z.z*a.w.w + a.w.y*a.y.z*a.z.w + a.z.y*a.w.z*a.y.w - a.y.y*a.w.z*a.z.w - a.z.y*a.y.z*a.w.w - a.w.y*a.z.z*a.y.w, 368 | a.x.y*a.w.z*a.z.w + a.z.y*a.x.z*a.w.w + a.w.y*a.z.z*a.x.w - a.w.y*a.x.z*a.z.w - a.z.y*a.w.z*a.x.w - a.x.y*a.z.z*a.w.w, 369 | a.x.y*a.y.z*a.w.w + a.w.y*a.x.z*a.y.w + a.y.y*a.w.z*a.x.w - a.x.y*a.w.z*a.y.w - a.y.y*a.x.z*a.w.w - a.w.y*a.y.z*a.x.w, 370 | a.x.y*a.z.z*a.y.w + a.y.y*a.x.z*a.z.w + a.z.y*a.y.z*a.x.w - a.x.y*a.y.z*a.z.w - a.z.y*a.x.z*a.y.w - a.y.y*a.z.z*a.x.w}, 371 | {a.y.z*a.w.w*a.z.x + a.z.z*a.y.w*a.w.x + a.w.z*a.z.w*a.y.x - a.y.z*a.z.w*a.w.x - a.w.z*a.y.w*a.z.x - a.z.z*a.w.w*a.y.x, 372 | a.x.z*a.z.w*a.w.x + a.w.z*a.x.w*a.z.x + a.z.z*a.w.w*a.x.x - a.x.z*a.w.w*a.z.x - a.z.z*a.x.w*a.w.x - a.w.z*a.z.w*a.x.x, 373 | a.x.z*a.w.w*a.y.x + a.y.z*a.x.w*a.w.x + a.w.z*a.y.w*a.x.x - a.x.z*a.y.w*a.w.x - a.w.z*a.x.w*a.y.x - a.y.z*a.w.w*a.x.x, 374 | a.x.z*a.y.w*a.z.x + a.z.z*a.x.w*a.y.x + a.y.z*a.z.w*a.x.x - a.x.z*a.z.w*a.y.x - a.y.z*a.x.w*a.z.x - a.z.z*a.y.w*a.x.x}, 375 | {a.y.w*a.z.x*a.w.y + a.w.w*a.y.x*a.z.y + a.z.w*a.w.x*a.y.y - a.y.w*a.w.x*a.z.y - a.z.w*a.y.x*a.w.y - a.w.w*a.z.x*a.y.y, 376 | a.x.w*a.w.x*a.z.y + a.z.w*a.x.x*a.w.y + a.w.w*a.z.x*a.x.y - a.x.w*a.z.x*a.w.y - a.w.w*a.x.x*a.z.y - a.z.w*a.w.x*a.x.y, 377 | a.x.w*a.y.x*a.w.y + a.w.w*a.x.x*a.y.y + a.y.w*a.w.x*a.x.y - a.x.w*a.w.x*a.y.y - a.y.w*a.x.x*a.w.y - a.w.w*a.y.x*a.x.y, 378 | a.x.w*a.z.x*a.y.y + a.y.w*a.x.x*a.z.y + a.z.w*a.y.x*a.x.y - a.x.w*a.y.x*a.z.y - a.z.w*a.x.x*a.y.y - a.y.w*a.z.x*a.x.y}, 379 | {a.y.x*a.w.y*a.z.z + a.z.x*a.y.y*a.w.z + a.w.x*a.z.y*a.y.z - a.y.x*a.z.y*a.w.z - a.w.x*a.y.y*a.z.z - a.z.x*a.w.y*a.y.z, 380 | a.x.x*a.z.y*a.w.z + a.w.x*a.x.y*a.z.z + a.z.x*a.w.y*a.x.z - a.x.x*a.w.y*a.z.z - a.z.x*a.x.y*a.w.z - a.w.x*a.z.y*a.x.z, 381 | a.x.x*a.w.y*a.y.z + a.y.x*a.x.y*a.w.z + a.w.x*a.y.y*a.x.z - a.x.x*a.y.y*a.w.z - a.w.x*a.x.y*a.y.z - a.y.x*a.w.y*a.x.z, 382 | a.x.x*a.y.y*a.z.z + a.z.x*a.x.y*a.y.z + a.y.x*a.z.y*a.x.z - a.x.x*a.z.y*a.y.z - a.y.x*a.x.y*a.z.z - a.z.x*a.y.y*a.x.z}}; } 383 | template constexpr T determinant(const mat & a) { return a.x.x*a.y.y - a.x.y*a.y.x; } 384 | template constexpr T determinant(const mat & a) { return a.x.x*(a.y.y*a.z.z - a.z.y*a.y.z) + a.x.y*(a.y.z*a.z.x - a.z.z*a.y.x) + a.x.z*(a.y.x*a.z.y - a.z.x*a.y.y); } 385 | template constexpr T determinant(const mat & a) { return a.x.x*(a.y.y*a.z.z*a.w.w + a.w.y*a.y.z*a.z.w + a.z.y*a.w.z*a.y.w - a.y.y*a.w.z*a.z.w - a.z.y*a.y.z*a.w.w - a.w.y*a.z.z*a.y.w) 386 | + a.x.y*(a.y.z*a.w.w*a.z.x + a.z.z*a.y.w*a.w.x + a.w.z*a.z.w*a.y.x - a.y.z*a.z.w*a.w.x - a.w.z*a.y.w*a.z.x - a.z.z*a.w.w*a.y.x) 387 | + a.x.z*(a.y.w*a.z.x*a.w.y + a.w.w*a.y.x*a.z.y + a.z.w*a.w.x*a.y.y - a.y.w*a.w.x*a.z.y - a.z.w*a.y.x*a.w.y - a.w.w*a.z.x*a.y.y) 388 | + a.x.w*(a.y.x*a.w.y*a.z.z + a.z.x*a.y.y*a.w.z + a.w.x*a.z.y*a.y.z - a.y.x*a.z.y*a.w.z - a.w.x*a.y.y*a.z.z - a.z.x*a.w.y*a.y.z); } 389 | template constexpr mat inverse(const mat & a) { return adjugate(a)/determinant(a); } 390 | 391 | // Vectors and matrices can be used as ranges 392 | template T * begin( vec & a) { return &a[0]; } 393 | template const T * begin(const vec & a) { return &a[0]; } 394 | template T * end ( vec & a) { return begin(a) + M; } 395 | template const T * end (const vec & a) { return begin(a) + M; } 396 | template vec * begin( mat & a) { return &a[0]; } 397 | template const vec * begin(const mat & a) { return &a[0]; } 398 | template vec * end ( mat & a) { return begin(a) + N; } 399 | template const vec * end (const mat & a) { return begin(a) + N; } 400 | 401 | // Factory functions for 3D spatial transformations (will possibly be removed or changed in a future version) 402 | enum fwd_axis { neg_z, pos_z }; // Should projection matrices be generated assuming forward is {0,0,-1} or {0,0,1} 403 | enum z_range { neg_one_to_one, zero_to_one }; // Should projection matrices map z into the range of [-1,1] or [0,1]? 404 | template vec rotation_quat (const vec & axis, T angle) { return {axis*std::sin(angle/2), std::cos(angle/2)}; } 405 | template vec rotation_quat (const mat & m) { return copysign(sqrt(max(T(0), T(1) + vec(m.x.x-m.y.y-m.z.z, m.y.y-m.x.x-m.z.z, m.z.z-m.x.x-m.y.y, m.x.x+m.y.y+m.z.z))) / T(2), vec(m.y.z-m.z.y, m.z.x-m.x.z, m.x.y-m.y.x, 1)); } 406 | template mat translation_matrix(const vec & translation) { return {{1,0,0,0},{0,1,0,0},{0,0,1,0},{translation,1}}; } 407 | template mat rotation_matrix (const vec & rotation) { return {{qxdir(rotation),0}, {qydir(rotation),0}, {qzdir(rotation),0}, {0,0,0,1}}; } 408 | template mat scaling_matrix (const vec & scaling) { return {{scaling.x,0,0,0}, {0,scaling.y,0,0}, {0,0,scaling.z,0}, {0,0,0,1}}; } 409 | template mat pose_matrix (const vec & q, const vec & p) { return {{qxdir(q),0}, {qydir(q),0}, {qzdir(q),0}, {p,1}}; } 410 | template mat frustum_matrix (T x0, T x1, T y0, T y1, T n, T f, fwd_axis a = neg_z, z_range z = neg_one_to_one) { const T s = a == pos_z ? T(1) : T(-1); return z == zero_to_one ? mat{{2*n/(x1-x0),0,0,0}, {0,2*n/(y1-y0),0,0}, {(x0+x1)/(x1-x0),(y0+y1)/(y1-y0),s*(f+0)/(f-n),s}, {0,0,-1*n*f/(f-n),0}} : mat{{2*n/(x1-x0),0,0,0}, {0,2*n/(y1-y0),0,0}, {(x0+x1)/(x1-x0),(y0+y1)/(y1-y0),s*(f+n)/(f-n),s}, {0,0,-2*n*f/(f-n),0}}; } 411 | template mat perspective_matrix(T fovy, T aspect, T n, T f, fwd_axis a = neg_z, z_range z = neg_one_to_one) { T y = n*std::tan(fovy / 2), x = y*aspect; return frustum_matrix(-x, x, -y, y, n, f, a, z); } 412 | 413 | // Provide typedefs for common element types and vector/matrix sizes 414 | namespace aliases 415 | { 416 | typedef vec bool2; typedef vec byte2; typedef vec short2; typedef vec ushort2; 417 | typedef vec bool3; typedef vec byte3; typedef vec short3; typedef vec ushort3; 418 | typedef vec bool4; typedef vec byte4; typedef vec short4; typedef vec ushort4; 419 | typedef vec int2; typedef vec uint2; typedef vec float2; typedef vec double2; 420 | typedef vec int3; typedef vec uint3; typedef vec float3; typedef vec double3; 421 | typedef vec int4; typedef vec uint4; typedef vec float4; typedef vec double4; 422 | typedef mat bool2x2; typedef mat int2x2; typedef mat float2x2; typedef mat double2x2; 423 | typedef mat bool2x3; typedef mat int2x3; typedef mat float2x3; typedef mat double2x3; 424 | typedef mat bool2x4; typedef mat int2x4; typedef mat float2x4; typedef mat double2x4; 425 | typedef mat bool3x2; typedef mat int3x2; typedef mat float3x2; typedef mat double3x2; 426 | typedef mat bool3x3; typedef mat int3x3; typedef mat float3x3; typedef mat double3x3; 427 | typedef mat bool3x4; typedef mat int3x4; typedef mat float3x4; typedef mat double3x4; 428 | typedef mat bool4x2; typedef mat int4x2; typedef mat float4x2; typedef mat double4x2; 429 | typedef mat bool4x3; typedef mat int4x3; typedef mat float4x3; typedef mat double4x3; 430 | typedef mat bool4x4; typedef mat int4x4; typedef mat float4x4; typedef mat double4x4; 431 | } 432 | } 433 | 434 | // Provide specializations for std::hash<...> with linalg types 435 | namespace std 436 | { 437 | template struct hash> { std::size_t operator()(const linalg::vec & v) const { std::hash h; return h(v.x) ^ (h(v.y) << 1); } }; 438 | template struct hash> { std::size_t operator()(const linalg::vec & v) const { std::hash h; return h(v.x) ^ (h(v.y) << 1) ^ (h(v.z) << 2); } }; 439 | template struct hash> { std::size_t operator()(const linalg::vec & v) const { std::hash h; return h(v.x) ^ (h(v.y) << 1) ^ (h(v.z) << 2) ^ (h(v.w) << 3); } }; 440 | template struct hash> { std::size_t operator()(const linalg::mat & v) const { std::hash> h; return h(v.x) ^ (h(v.y) << M); } }; 441 | template struct hash> { std::size_t operator()(const linalg::mat & v) const { std::hash> h; return h(v.x) ^ (h(v.y) << M) ^ (h(v.z) << (M*2)); } }; 442 | template struct hash> { std::size_t operator()(const linalg::mat & v) const { std::hash> h; return h(v.x) ^ (h(v.y) << M) ^ (h(v.z) << (M*2)) ^ (h(v.w) << (M*3)); } }; 443 | } 444 | 445 | #endif 446 | -------------------------------------------------------------------------------- /tiny-gizmo-example/teapot.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | static float teapot_vertices[] = 6 | { 7 | 0.0479f,0.1900f,0.1425f,0.2677f,0.4803f,0.8268f,0.0466f,0.1963f,0.1386f,0.2283f,0.6614f,0.7087f,0.0000f,0.1963f,0.1460f,0.0000f,0.6614f,0.7480f,0.0000f,0.1900f,0.1500f,0.0000f,0.4803f,0.8740f,0.0453f,0.1995f,0.1348f,0.1024f,0.9291f,0.3386f,0.0000f,0.1995f,0.1420f,0.0000f,0.9291f,0.3543f,0.0444f,0.1995f,0.1320f,-0.1641f,0.8268f,-0.5234f,0.0000f,0.1995f,0.1390f,0.0000f,0.8268f,-0.5469f,0.0440f,0.1963f,0.1311f,-0.3047f,0.0000f,-0.9453f,0.0000f,0.1963f,0.1380f,0.0000f,0.0000f,-1.0000f,0.0447f,0.1900f,0.1330f,-0.2891f,-0.2969f,-0.9063f,0.0000f,0.1900f,0.1400f,0.0000f,-0.2969f,-0.9531f,0.0891f,0.1900f,0.1214f,0.5118f,0.4803f,0.7008f,0.0867f,0.1963f,0.1181f,0.4331f,0.6614f,0.5984f,0.0843f,0.1995f,0.1149f,0.2047f,0.9291f,0.2835f,0.0826f,0.1995f,0.1125f,-0.3203f,0.8268f,-0.4453f,0.0820f,0.1963f,0.1117f,-0.5859f,0.0000f,-0.8047f,0.0831f,0.1900f,0.1133f,-0.5547f,-0.2969f,-0.7656f,0.1214f,0.1900f,0.0891f,0.7008f,0.4803f,0.5118f,0.1181f,0.1963f,0.0867f,0.5984f,0.6614f,0.4331f,0.1149f,0.1995f,0.0843f,0.2835f,0.9291f,0.2047f,0.1125f,0.1995f,0.0826f,-0.4453f,0.8268f,-0.3203f,0.1117f,0.1963f,0.0820f,-0.8047f,0.0000f,-0.5859f,0.1133f,0.1900f,0.0831f,-0.7656f,-0.2969f,-0.5547f,0.1425f,0.1900f,0.0479f,0.8268f,0.4803f,0.2677f,0.1386f,0.1963f,0.0466f,0.7087f,0.6614f,0.2283f,0.1348f,0.1995f,0.0453f,0.3386f,0.9291f,0.1024f,0.1320f,0.1995f,0.0444f,-0.5234f,0.8268f,-0.1641f,0.1311f,0.1963f,0.0440f,-0.9453f,0.0000f,-0.3047f,0.1330f,0.1900f,0.0447f,-0.9063f,-0.2969f,-0.2891f,0.1500f,0.1900f,0.0000f,0.8740f,0.4803f,0.0000f,0.1460f,0.1963f,0.0000f,0.7480f,0.6614f,0.0000f,0.1420f,0.1995f,0.0000f,0.3543f,0.9291f,0.0000f,0.1390f,0.1995f,0.0000f,-0.5469f,0.8268f,0.0000f,0.1380f,0.1963f,0.0000f,-1.0000f,0.0000f,0.0000f,0.1400f,0.1900f,0.0000f,-0.9531f,-0.2969f,0.0000f,-0.1425f,0.1900f,0.0479f,-0.8281f,0.4803f,0.2677f,-0.1386f,0.1963f,0.0466f,-0.7109f,0.6614f,0.2283f,-0.1460f,0.1963f,0.0000f,-0.7422f,0.6614f,0.0000f,-0.1500f,0.1900f,0.0000f,-0.8750f,0.4803f,0.0000f,-0.1348f,0.1995f,0.0453f,-0.3359f,0.9291f,0.1024f,-0.1420f,0.1995f,0.0000f,-0.3516f,0.9291f,0.0000f,-0.1320f,0.1995f,0.0444f,0.5197f,0.8268f,-0.1641f,-0.1390f,0.1995f,0.0000f,0.5512f,0.8268f,0.0000f,-0.1311f,0.1963f,0.0440f,0.9449f,0.0000f,-0.3047f,-0.1380f,0.1963f,0.0000f,1.0000f,0.0000f,0.0000f,-0.1330f,0.1900f,0.0447f,0.9055f,-0.2969f,-0.2891f,-0.1400f,0.1900f,0.0000f,0.9528f,-0.2969f,0.0000f,-0.1214f,0.1900f,0.0891f,-0.7031f,0.4803f,0.5118f,-0.1181f,0.1963f,0.0867f,-0.6016f,0.6614f,0.4331f,-0.1149f,0.1995f,0.0843f,-0.2813f,0.9291f,0.2047f,-0.1125f,0.1995f,0.0826f,0.4409f,0.8268f,-0.3203f,-0.1117f,0.1963f,0.0820f,0.8031f,0.0000f,-0.5859f,-0.1133f,0.1900f,0.0831f,0.7717f,-0.2969f,-0.5547f,-0.0891f,0.1900f,0.1214f,-0.5078f,0.4803f,0.7008f,-0.0867f,0.1963f,0.1181f,-0.4375f,0.6614f,0.5984f,-0.0843f,0.1995f,0.1149f,-0.2031f,0.9291f,0.2835f,-0.0826f,0.1995f,0.1125f,0.3228f,0.8268f,-0.4453f,-0.0820f,0.1963f,0.1117f,0.5827f,0.0000f,-0.8047f,-0.0831f,0.1900f,0.1133f,0.5591f,-0.2969f,-0.7656f,-0.0479f,0.1900f,0.1425f,-0.2656f,0.4803f,0.8268f,-0.0466f,0.1963f,0.1386f,-0.2266f,0.6614f,0.7087f,-0.0453f,0.1995f,0.1348f,-0.1094f,0.9291f,0.3386f,-0.0444f,0.1995f,0.1320f,0.1654f,0.8268f,-0.5234f,-0.0440f,0.1963f,0.1311f,0.3071f,0.0000f,-0.9453f,-0.0447f,0.1900f,0.1330f,0.2913f,-0.2969f,-0.9063f,-0.0479f,0.1900f,-0.1425f,-0.2656f,0.4803f,-0.8281f,-0.0466f,0.1963f,-0.1386f,-0.2266f,0.6614f,-0.7109f,0.0000f,0.1963f,-0.1460f,0.0000f,0.6614f,-0.7422f,0.0000f,0.1900f,-0.1500f,0.0000f,0.4803f,-0.8750f,-0.0453f,0.1995f,-0.1348f,-0.1094f,0.9291f,-0.3359f,0.0000f,0.1995f,-0.1420f,0.0000f,0.9291f,-0.3516f,-0.0444f,0.1995f,-0.1320f,0.1654f,0.8268f,0.5197f,0.0000f,0.1995f,-0.1390f,0.0000f,0.8268f,0.5512f,-0.0440f,0.1963f,-0.1311f,0.3071f,0.0000f,0.9449f,0.0000f,0.1963f,-0.1380f,0.0000f,0.0000f,1.0000f,-0.0447f,0.1900f,-0.1330f,0.2913f,-0.2969f,0.9055f,0.0000f,0.1900f,-0.1400f,0.0000f,-0.2969f,0.9528f,-0.0891f,0.1900f,-0.1214f,-0.5078f,0.4803f,-0.7031f,-0.0867f,0.1963f,-0.1181f,-0.4375f,0.6614f,-0.6016f,-0.0843f,0.1995f,-0.1149f,-0.2031f,0.9291f,-0.2813f,-0.0826f,0.1995f,-0.1125f,0.3228f,0.8268f,0.4409f,-0.0820f,0.1963f,-0.1117f,0.5827f,0.0000f,0.8031f,-0.0831f,0.1900f,-0.1133f,0.5591f,-0.2969f,0.7717f,-0.1214f,0.1900f,-0.0891f,-0.7031f,0.4803f,-0.5078f,-0.1181f,0.1963f,-0.0867f,-0.6016f,0.6614f,-0.4375f,-0.1149f,0.1995f,-0.0843f,-0.2813f,0.9291f,-0.2031f,-0.1125f,0.1995f,-0.0826f,0.4409f,0.8268f,0.3228f,-0.1117f,0.1963f,-0.0820f,0.8031f,0.0000f,0.5827f,-0.1133f,0.1900f,-0.0831f,0.7717f,-0.2969f,0.5591f,-0.1425f,0.1900f,-0.0479f,-0.8281f,0.4803f,-0.2656f,-0.1386f,0.1963f,-0.0466f,-0.7109f,0.6614f,-0.2266f,-0.1348f,0.1995f,-0.0453f,-0.3359f,0.9291f,-0.1094f,-0.1320f,0.1995f,-0.0444f,0.5197f,0.8268f,0.1654f,-0.1311f,0.1963f,-0.0440f,0.9449f,0.0000f,0.3071f,-0.1330f,0.1900f,-0.0447f,0.9055f,-0.2969f,0.2913f,0.1425f,0.1900f,-0.0479f,0.8268f,0.4803f,-0.2656f,0.1386f,0.1963f,-0.0466f,0.7087f,0.6614f,-0.2266f,0.1348f,0.1995f,-0.0453f,0.3386f,0.9291f,-0.1094f,0.1320f,0.1995f,-0.0444f,-0.5234f,0.8268f,0.1654f,0.1311f,0.1963f,-0.0440f,-0.9453f,0.0000f,0.3071f,0.1330f,0.1900f,-0.0447f,-0.9063f,-0.2969f,0.2913f,0.1214f,0.1900f,-0.0891f,0.7008f,0.4803f,-0.5078f,0.1181f,0.1963f,-0.0867f,0.5984f,0.6614f,-0.4375f,0.1149f,0.1995f,-0.0843f,0.2835f,0.9291f,-0.2031f,0.1125f,0.1995f,-0.0826f,-0.4453f,0.8268f,0.3228f,0.1117f,0.1963f,-0.0820f,-0.8047f,0.0000f,0.5827f,0.1133f,0.1900f,-0.0831f,-0.7656f,-0.2969f,0.5591f,0.0891f,0.1900f,-0.1214f,0.5118f,0.4803f,-0.7031f,0.0867f,0.1963f,-0.1181f,0.4331f,0.6614f,-0.6016f,0.0843f,0.1995f,-0.1149f,0.2047f,0.9291f,-0.2813f,0.0826f,0.1995f,-0.1125f,-0.3203f,0.8268f,0.4409f,0.0820f,0.1963f,-0.1117f,-0.5859f,0.0000f,0.8031f,0.0831f,0.1900f,-0.1133f,-0.5547f,-0.2969f,0.7717f,0.0479f,0.1900f,-0.1425f,0.2677f,0.4803f,-0.8281f,0.0466f,0.1963f,-0.1386f,0.2283f,0.6614f,-0.7109f,0.0453f,0.1995f,-0.1348f,0.1024f,0.9291f,-0.3359f,0.0444f,0.1995f,-0.1320f,-0.1641f,0.8268f,0.5197f,0.0440f,0.1963f,-0.1311f,-0.3047f,0.0000f,0.9449f,0.0447f,0.1900f,-0.1330f,-0.2891f,-0.2969f,0.9055f,0.0638f,0.0400f,0.1900f,0.3071f,-0.0469f,0.9449f,0.0629f,0.0678f,0.1873f,0.2992f,0.1732f,0.9291f,0.0000f,0.0678f,0.1972f,0.0000f,0.1732f,0.9843f,0.0000f,0.0400f,0.2000f,0.0000f,-0.0469f,0.9921f,0.0605f,0.0971f,0.1801f,0.2913f,0.2913f,0.9055f,0.0000f,0.0971f,0.1896f,0.0000f,0.2913f,0.9528f,0.0569f,0.1275f,0.1694f,0.2835f,0.3701f,0.8819f,0.0000f,0.1275f,0.1784f,0.0000f,0.3701f,0.9213f,0.0526f,0.1586f,0.1565f,0.2756f,0.4094f,0.8583f,0.0000f,0.1586f,0.1648f,0.0000f,0.4094f,0.9055f,0.1188f,0.0400f,0.1619f,0.5827f,-0.0469f,0.8031f,0.1171f,0.0678f,0.1596f,0.5748f,0.1732f,0.7953f,0.1126f,0.0971f,0.1534f,0.5591f,0.2913f,0.7717f,0.1060f,0.1275f,0.1444f,0.5433f,0.3701f,0.7480f,0.0979f,0.1586f,0.1334f,0.5276f,0.4094f,0.7323f,0.1619f,0.0400f,0.1188f,0.8031f,-0.0469f,0.5827f,0.1596f,0.0678f,0.1171f,0.7953f,0.1732f,0.5748f,0.1534f,0.0971f,0.1126f,0.7717f,0.2913f,0.5591f,0.1444f,0.1275f,0.1060f,0.7480f,0.3701f,0.5433f,0.1334f,0.1586f,0.0979f,0.7323f,0.4094f,0.5276f,0.1900f,0.0400f,0.0638f,0.9449f,-0.0469f,0.3071f,0.1873f,0.0678f,0.0629f,0.9291f,0.1732f,0.2992f,0.1801f,0.0971f,0.0605f,0.9055f,0.2913f,0.2913f,0.1694f,0.1275f,0.0569f,0.8819f,0.3701f,0.2835f,0.1565f,0.1586f,0.0526f,0.8583f,0.4094f,0.2756f,0.2000f,0.0400f,0.0000f,0.9921f,-0.0469f,0.0000f,0.1972f,0.0678f,0.0000f,0.9843f,0.1732f,0.0000f,0.1896f,0.0971f,0.0000f,0.9528f,0.2913f,0.0000f,0.1784f,0.1275f,0.0000f,0.9213f,0.3701f,0.0000f,0.1648f,0.1586f,0.0000f,0.9055f,0.4094f,0.0000f,-0.1900f,0.0400f,0.0638f,-0.9453f,-0.0469f,0.3071f,-0.1873f,0.0678f,0.0629f,-0.9297f,0.1732f,0.2992f,-0.1972f,0.0678f,0.0000f,-0.9844f,0.1732f,0.0000f,-0.2000f,0.0400f,0.0000f,-0.8516f,0.5197f,0.0000f,-0.1801f,0.0971f,0.0605f,-0.9063f,0.2913f,0.2913f,-0.1896f,0.0971f,0.0000f,-0.9531f,0.2913f,0.0000f,-0.1694f,0.1275f,0.0569f,-0.8750f,0.3701f,0.2835f,-0.1784f,0.1275f,0.0000f,-0.9219f,0.3701f,0.0000f,-0.1565f,0.1586f,0.0526f,-0.8594f,0.4094f,0.2756f,-0.1648f,0.1586f,0.0000f,-0.9063f,0.4094f,0.0000f,-0.1619f,0.0400f,0.1188f,-0.8047f,-0.0469f,0.5827f,-0.1596f,0.0678f,0.1171f,-0.7891f,0.1732f,0.5748f,-0.1534f,0.0971f,0.1126f,-0.7656f,0.2913f,0.5591f,-0.1444f,0.1275f,0.1060f,-0.7500f,0.3701f,0.5433f,-0.1334f,0.1586f,0.0979f,-0.7344f,0.4094f,0.5276f,-0.1188f,0.0400f,0.1619f,-0.5859f,-0.0469f,0.8031f,-0.1171f,0.0678f,0.1596f,-0.5781f,0.1732f,0.7953f,-0.1126f,0.0971f,0.1534f,-0.5547f,0.2913f,0.7717f,-0.1060f,0.1275f,0.1444f,-0.5391f,0.3701f,0.7480f,-0.0979f,0.1586f,0.1334f,-0.5313f,0.4094f,0.7323f,-0.0638f,0.0400f,0.1900f,-0.3047f,-0.0469f,0.9449f,-0.0629f,0.0678f,0.1873f,-0.2969f,0.1732f,0.9291f,-0.0605f,0.0971f,0.1801f,-0.2891f,0.2913f,0.9055f,-0.0569f,0.1275f,0.1694f,-0.2813f,0.3701f,0.8819f,-0.0526f,0.1586f,0.1565f,-0.2813f,0.4094f,0.8583f,-0.0638f,0.0400f,-0.1900f,-0.3047f,-0.0469f,-0.9453f,-0.0629f,0.0678f,-0.1873f,-0.2969f,0.1732f,-0.9297f,0.0000f,0.0678f,-0.1972f,0.0000f,0.1732f,-0.9844f,0.0000f,0.0400f,-0.2000f,0.0000f,-0.0469f,-0.9922f,-0.0605f,0.0971f,-0.1801f,-0.2891f,0.2913f,-0.9063f,0.0000f,0.0971f,-0.1896f,0.0000f,0.2913f,-0.9531f,-0.0569f,0.1275f,-0.1694f,-0.2813f,0.3701f,-0.8750f,0.0000f,0.1275f,-0.1784f,0.0000f,0.3701f,-0.9219f,-0.0526f,0.1586f,-0.1565f,-0.2813f,0.4094f,-0.8594f,0.0000f,0.1586f,-0.1648f,0.0000f,0.4094f,-0.9063f,-0.1188f,0.0400f,-0.1619f,-0.5859f,-0.0469f,-0.8047f,-0.1171f,0.0678f,-0.1596f,-0.5781f,0.1732f,-0.7891f,-0.1126f,0.0971f,-0.1534f,-0.5547f,0.2913f,-0.7656f,-0.1060f,0.1275f,-0.1444f,-0.5391f,0.3701f,-0.7500f,-0.0979f,0.1586f,-0.1334f,-0.5313f,0.4094f,-0.7344f,-0.1619f,0.0400f,-0.1188f,-0.8047f,-0.0469f,-0.5859f,-0.1596f,0.0678f,-0.1171f,-0.7891f,0.1732f,-0.5781f,-0.1534f,0.0971f,-0.1126f,-0.7656f,0.2913f,-0.5547f,-0.1444f,0.1275f,-0.1060f,-0.7500f,0.3701f,-0.5391f,-0.1334f,0.1586f,-0.0979f,-0.7344f,0.4094f,-0.5313f,-0.1900f,0.0400f,-0.0638f,-0.9453f,-0.0469f,-0.3047f,-0.1873f,0.0678f,-0.0629f,-0.9297f,0.1732f,-0.2969f,-0.1801f,0.0971f,-0.0605f,-0.9063f,0.2913f,-0.2891f,-0.1694f,0.1275f,-0.0569f,-0.8750f,0.3701f,-0.2813f,-0.1565f,0.1586f,-0.0526f,-0.8594f,0.4094f,-0.2813f,0.1900f,0.0400f,-0.0638f,0.9449f,-0.0469f,-0.3047f,0.1873f,0.0678f,-0.0629f,0.9291f,0.1732f,-0.2969f,0.1801f,0.0971f,-0.0605f,0.9055f,0.2913f,-0.2891f,0.1694f,0.1275f,-0.0569f,0.8819f,0.3701f,-0.2813f,0.1565f,0.1586f,-0.0526f,0.8583f,0.4094f,-0.2813f,0.1619f,0.0400f,-0.1188f,0.8031f,-0.0469f,-0.5859f,0.1596f,0.0678f,-0.1171f,0.7953f,0.1732f,-0.5781f,0.1534f,0.0971f,-0.1126f,0.7717f,0.2913f,-0.5547f,0.1444f,0.1275f,-0.1060f,0.7480f,0.3701f,-0.5391f,0.1334f,0.1586f,-0.0979f,0.7323f,0.4094f,-0.5313f,0.1188f,0.0400f,-0.1619f,0.5827f,-0.0469f,-0.8047f,0.1171f,0.0678f,-0.1596f,0.5748f,0.1732f,-0.7891f,0.1126f,0.0971f,-0.1534f,0.5591f,0.2913f,-0.7656f,0.1060f,0.1275f,-0.1444f,0.5433f,0.3701f,-0.7500f,0.0979f,0.1586f,-0.1334f,0.5276f,0.4094f,-0.7344f,0.0638f,0.0400f,-0.1900f,0.3071f,-0.0469f,-0.9453f,0.0629f,0.0678f,-0.1873f,0.2992f,0.1732f,-0.9297f,0.0605f,0.0971f,-0.1801f,0.2913f,0.2913f,-0.9063f,0.0569f,0.1275f,-0.1694f,0.2835f,0.3701f,-0.8750f,0.0526f,0.1586f,-0.1565f,0.2756f,0.4094f,-0.8594f,0.0479f,-0.0350f,0.1425f,0.2362f,-0.6328f,0.7323f,0.0495f,-0.0286f,0.1474f,0.2126f,-0.7031f,0.6693f,0.0000f,-0.0286f,0.1552f,0.0000f,-0.7031f,0.7008f,0.0000f,-0.0350f,0.1500f,0.0000f,-0.5234f,0.8504f,0.0535f,-0.0183f,0.1592f,0.2047f,-0.7344f,0.6378f,0.0000f,-0.0183f,0.1676f,0.0000f,-0.7344f,0.6693f,0.0582f,-0.0037f,0.1732f,0.2362f,-0.6172f,0.7402f,0.0000f,-0.0037f,0.1824f,0.0000f,-0.6172f,0.7795f,0.0621f,0.0156f,0.1850f,0.2835f,-0.3750f,0.8740f,0.0000f,0.0156f,0.1948f,0.0000f,-0.3672f,0.9213f,0.0891f,-0.0350f,0.1214f,0.4961f,-0.5234f,0.6850f,0.0922f,-0.0286f,0.1256f,0.4094f,-0.7031f,0.5669f,0.0995f,-0.0183f,0.1356f,0.3937f,-0.7344f,0.5433f,0.1083f,-0.0037f,0.1476f,0.4567f,-0.6250f,0.6299f,0.1157f,0.0156f,0.1576f,0.5433f,-0.3750f,0.7480f,0.1214f,-0.0350f,0.0891f,0.6850f,-0.5234f,0.4961f,0.1256f,-0.0286f,0.0922f,0.5669f,-0.7031f,0.4094f,0.1356f,-0.0183f,0.0995f,0.5433f,-0.7344f,0.3937f,0.1476f,-0.0037f,0.1083f,0.6299f,-0.6250f,0.4567f,0.1576f,0.0156f,0.1157f,0.7480f,-0.3750f,0.5433f,0.1425f,-0.0350f,0.0479f,0.7323f,-0.6328f,0.2362f,0.1474f,-0.0286f,0.0495f,0.6693f,-0.7031f,0.2126f,0.1592f,-0.0183f,0.0535f,0.6378f,-0.7344f,0.2047f,0.1732f,-0.0037f,0.0582f,0.7402f,-0.6172f,0.2362f,0.1850f,0.0156f,0.0621f,0.8740f,-0.3750f,0.2835f,0.1500f,-0.0350f,0.0000f,0.8504f,-0.5234f,0.0000f,0.1552f,-0.0286f,0.0000f,0.7008f,-0.7031f,0.0000f,0.1676f,-0.0183f,0.0000f,0.6693f,-0.7344f,0.0000f,0.1824f,-0.0037f,0.0000f,0.7795f,-0.6172f,0.0000f,0.1948f,0.0156f,0.0000f,0.9213f,-0.3672f,0.0000f,-0.1425f,-0.0350f,0.0479f,-0.7344f,-0.6328f,0.2362f,-0.1474f,-0.0286f,0.0495f,-0.6641f,-0.7031f,0.2126f,-0.1552f,-0.0286f,0.0000f,-0.7031f,-0.7031f,0.0000f,-0.1500f,-0.0350f,0.0000f,-0.8438f,-0.5234f,0.0000f,-0.1592f,-0.0183f,0.0535f,-0.6406f,-0.7344f,0.2047f,-0.1676f,-0.0183f,0.0000f,-0.6719f,-0.7344f,0.0000f,-0.1732f,-0.0037f,0.0582f,-0.7422f,-0.6172f,0.2362f,-0.1824f,-0.0037f,0.0000f,-0.7813f,-0.6172f,0.0000f,-0.1850f,0.0156f,0.0621f,-0.8750f,-0.3750f,0.2835f,-0.1948f,0.0156f,0.0000f,-0.9219f,-0.3672f,0.0000f,-0.1214f,-0.0350f,0.0891f,-0.6797f,-0.5234f,0.4961f,-0.1256f,-0.0286f,0.0922f,-0.5625f,-0.7031f,0.4094f,-0.1356f,-0.0183f,0.0995f,-0.5391f,-0.7344f,0.3937f,-0.1476f,-0.0037f,0.1083f,-0.6250f,-0.6250f,0.4567f,-0.1576f,0.0156f,0.1157f,-0.7422f,-0.3750f,0.5433f,-0.0891f,-0.0350f,0.1214f,-0.4922f,-0.5234f,0.6850f,-0.0922f,-0.0286f,0.1256f,-0.4141f,-0.7031f,0.5669f,-0.0995f,-0.0183f,0.1356f,-0.3906f,-0.7344f,0.5433f,-0.1083f,-0.0037f,0.1476f,-0.4531f,-0.6250f,0.6299f,-0.1157f,0.0156f,0.1576f,-0.5391f,-0.3750f,0.7480f,-0.0479f,-0.0350f,0.1425f,-0.2344f,-0.6328f,0.7323f,-0.0495f,-0.0286f,0.1474f,-0.2109f,-0.7031f,0.6693f,-0.0535f,-0.0183f,0.1592f,-0.2031f,-0.7344f,0.6378f,-0.0582f,-0.0037f,0.1732f,-0.2344f,-0.6172f,0.7402f,-0.0621f,0.0156f,0.1850f,-0.2813f,-0.3750f,0.8740f,-0.0479f,-0.0350f,-0.1425f,-0.2344f,-0.6328f,-0.7344f,-0.0495f,-0.0286f,-0.1474f,-0.2109f,-0.7031f,-0.6641f,0.0000f,-0.0286f,-0.1552f,0.0000f,-0.7031f,-0.7031f,0.0000f,-0.0350f,-0.1500f,0.0000f,-0.5234f,-0.8438f,-0.0535f,-0.0183f,-0.1592f,-0.2031f,-0.7344f,-0.6406f,0.0000f,-0.0183f,-0.1676f,0.0000f,-0.7344f,-0.6719f,-0.0582f,-0.0037f,-0.1732f,-0.2344f,-0.6172f,-0.7422f,0.0000f,-0.0037f,-0.1824f,0.0000f,-0.6172f,-0.7813f,-0.0621f,0.0156f,-0.1850f,-0.2813f,-0.3750f,-0.8750f,0.0000f,0.0156f,-0.1948f,0.0000f,-0.3672f,-0.9219f,-0.0891f,-0.0350f,-0.1214f,-0.4922f,-0.5234f,-0.6797f,-0.0922f,-0.0286f,-0.1256f,-0.4141f,-0.7031f,-0.5625f,-0.0995f,-0.0183f,-0.1356f,-0.3906f,-0.7344f,-0.5391f,-0.1083f,-0.0037f,-0.1476f,-0.4531f,-0.6250f,-0.6250f,-0.1157f,0.0156f,-0.1576f,-0.5391f,-0.3750f,-0.7422f,-0.1214f,-0.0350f,-0.0891f,-0.6797f,-0.5234f,-0.4922f,-0.1256f,-0.0286f,-0.0922f,-0.5625f,-0.7031f,-0.4141f,-0.1356f,-0.0183f,-0.0995f,-0.5391f,-0.7344f,-0.3906f,-0.1476f,-0.0037f,-0.1083f,-0.6250f,-0.6250f,-0.4531f,-0.1576f,0.0156f,-0.1157f,-0.7422f,-0.3750f,-0.5391f,-0.1425f,-0.0350f,-0.0479f,-0.7344f,-0.6328f,-0.2344f,-0.1474f,-0.0286f,-0.0495f,-0.6641f,-0.7031f,-0.2109f,-0.1592f,-0.0183f,-0.0535f,-0.6406f,-0.7344f,-0.2031f,-0.1732f,-0.0037f,-0.0582f,-0.7422f,-0.6172f,-0.2344f,-0.1850f,0.0156f,-0.0621f,-0.8750f,-0.3750f,-0.2813f,0.1425f,-0.0350f,-0.0479f,0.7323f,-0.6328f,-0.2344f,0.1474f,-0.0286f,-0.0495f,0.6693f,-0.7031f,-0.2109f,0.1592f,-0.0183f,-0.0535f,0.6378f,-0.7344f,-0.2031f,0.1732f,-0.0037f,-0.0582f,0.7402f,-0.6172f,-0.2344f,0.1850f,0.0156f,-0.0621f,0.8740f,-0.3750f,-0.2813f,0.1214f,-0.0350f,-0.0891f,0.6850f,-0.5234f,-0.4922f,0.1256f,-0.0286f,-0.0922f,0.5669f,-0.7031f,-0.4141f,0.1356f,-0.0183f,-0.0995f,0.5433f,-0.7344f,-0.3906f,0.1476f,-0.0037f,-0.1083f,0.6299f,-0.6250f,-0.4531f,0.1576f,0.0156f,-0.1157f,0.7480f,-0.3750f,-0.5391f,0.0891f,-0.0350f,-0.1214f,0.4961f,-0.5234f,-0.6797f,0.0922f,-0.0286f,-0.1256f,0.4094f,-0.7031f,-0.5625f,0.0995f,-0.0183f,-0.1356f,0.3937f,-0.7344f,-0.5391f,0.1083f,-0.0037f,-0.1476f,0.4567f,-0.6250f,-0.6250f,0.1157f,0.0156f,-0.1576f,0.5433f,-0.3750f,-0.7422f,0.0479f,-0.0350f,-0.1425f,0.2362f,-0.6328f,-0.7344f,0.0495f,-0.0286f,-0.1474f,0.2126f,-0.7031f,-0.6641f,0.0535f,-0.0183f,-0.1592f,0.2047f,-0.7344f,-0.6406f,0.0582f,-0.0037f,-0.1732f,0.2362f,-0.6172f,-0.7422f,0.0621f,0.0156f,-0.1850f,0.2835f,-0.3750f,-0.8750f,0.0479f,-0.0350f,-0.1425f,0.2835f,-0.3906f,-0.8672f,0.0472f,-0.0394f,-0.1406f,0.2205f,-0.6875f,-0.6797f,0.0000f,-0.0394f,-0.1481f,0.0000f,-0.6875f,-0.7188f,0.0441f,-0.0435f,-0.1313f,0.0787f,-0.9609f,-0.2578f,0.0000f,-0.0435f,-0.1382f,0.0000f,-0.9609f,-0.2734f,0.0365f,-0.0469f,-0.1086f,0.0236f,-0.9922f,-0.0938f,0.0000f,-0.0469f,-0.1144f,0.0000f,-0.9922f,-0.0938f,0.0224f,-0.0492f,-0.0668f,0.0079f,-0.9922f,-0.0313f,0.0000f,-0.0492f,-0.0703f,0.0000f,-0.9922f,-0.0313f,0.0000f,-0.0500f,0.0000f,0.0000f,-1.0000f,0.0000f,0.0879f,-0.0394f,-0.1198f,0.4173f,-0.6875f,-0.5781f,0.0821f,-0.0435f,-0.1119f,0.1575f,-0.9609f,-0.2188f,0.0679f,-0.0469f,-0.0925f,0.0551f,-0.9922f,-0.0781f,0.0418f,-0.0492f,-0.0569f,0.0157f,-0.9922f,-0.0234f,0.1198f,-0.0394f,-0.0879f,0.5748f,-0.6875f,-0.4219f,0.1119f,-0.0435f,-0.0821f,0.2205f,-0.9609f,-0.1563f,0.0925f,-0.0469f,-0.0679f,0.0787f,-0.9922f,-0.0547f,0.0569f,-0.0492f,-0.0418f,0.0236f,-0.9922f,-0.0156f,0.1425f,-0.0350f,-0.0479f,0.8661f,-0.3906f,-0.2813f,0.1406f,-0.0394f,-0.0472f,0.6772f,-0.6875f,-0.2188f,0.1313f,-0.0435f,-0.0441f,0.2598f,-0.9609f,-0.0781f,0.1086f,-0.0469f,-0.0365f,0.0945f,-0.9922f,-0.0234f,0.0668f,-0.0492f,-0.0224f,0.0315f,-0.9922f,-0.0078f,0.1481f,-0.0394f,0.0000f,0.7165f,-0.6875f,0.0000f,0.1382f,-0.0435f,0.0000f,0.2677f,-0.9609f,0.0000f,0.1144f,-0.0469f,0.0000f,0.0945f,-0.9922f,0.0000f,0.0703f,-0.0492f,0.0000f,0.0315f,-0.9922f,0.0000f,-0.1425f,-0.0350f,-0.0479f,-0.8672f,-0.3906f,-0.2813f,-0.1406f,-0.0394f,-0.0472f,-0.6797f,-0.6875f,-0.2188f,-0.1481f,-0.0394f,0.0000f,-0.7188f,-0.6875f,0.0000f,-0.1313f,-0.0435f,-0.0441f,-0.2578f,-0.9609f,-0.0781f,-0.1382f,-0.0435f,0.0000f,-0.2734f,-0.9609f,0.0000f,-0.1086f,-0.0469f,-0.0365f,-0.0938f,-0.9922f,-0.0234f,-0.1144f,-0.0469f,0.0000f,-0.0938f,-0.9922f,0.0000f,-0.0668f,-0.0492f,-0.0224f,-0.0313f,-0.9922f,-0.0078f,-0.0703f,-0.0492f,0.0000f,-0.0313f,-0.9922f,0.0000f,-0.1198f,-0.0394f,-0.0879f,-0.5781f,-0.6875f,-0.4219f,-0.1119f,-0.0435f,-0.0821f,-0.2188f,-0.9609f,-0.1563f,-0.0925f,-0.0469f,-0.0679f,-0.0781f,-0.9922f,-0.0547f,-0.0569f,-0.0492f,-0.0418f,-0.0234f,-0.9922f,-0.0156f,-0.0879f,-0.0394f,-0.1198f,-0.4219f,-0.6875f,-0.5781f,-0.0821f,-0.0435f,-0.1119f,-0.1563f,-0.9609f,-0.2188f,-0.0679f,-0.0469f,-0.0925f,-0.0547f,-0.9922f,-0.0781f,-0.0418f,-0.0492f,-0.0569f,-0.0156f,-0.9922f,-0.0234f,-0.0479f,-0.0350f,-0.1425f,-0.2813f,-0.3906f,-0.8672f,-0.0472f,-0.0394f,-0.1406f,-0.2188f,-0.6875f,-0.6797f,-0.0441f,-0.0435f,-0.1313f,-0.0781f,-0.9609f,-0.2578f,-0.0365f,-0.0469f,-0.1086f,-0.0234f,-0.9922f,-0.0938f,-0.0224f,-0.0492f,-0.0668f,-0.0078f,-0.9922f,-0.0313f,-0.0479f,-0.0350f,0.1425f,-0.2813f,-0.3906f,0.8661f,-0.0472f,-0.0394f,0.1406f,-0.2188f,-0.6875f,0.6772f,0.0000f,-0.0394f,0.1481f,0.0000f,-0.6875f,0.7165f,-0.0441f,-0.0435f,0.1313f,-0.0781f,-0.9609f,0.2598f,0.0000f,-0.0435f,0.1382f,0.0000f,-0.9609f,0.2677f,-0.0365f,-0.0469f,0.1086f,-0.0234f,-0.9922f,0.0945f,0.0000f,-0.0469f,0.1144f,0.0000f,-0.9922f,0.0945f,-0.0224f,-0.0492f,0.0668f,-0.0078f,-0.9922f,0.0315f,0.0000f,-0.0492f,0.0703f,0.0000f,-0.9922f,0.0315f,-0.0879f,-0.0394f,0.1198f,-0.4219f,-0.6875f,0.5748f,-0.0821f,-0.0435f,0.1119f,-0.1563f,-0.9609f,0.2205f,-0.0679f,-0.0469f,0.0925f,-0.0547f,-0.9922f,0.0787f,-0.0418f,-0.0492f,0.0569f,-0.0156f,-0.9922f,0.0236f,-0.1198f,-0.0394f,0.0879f,-0.5781f,-0.6875f,0.4173f,-0.1119f,-0.0435f,0.0821f,-0.2188f,-0.9609f,0.1575f,-0.0925f,-0.0469f,0.0679f,-0.0781f,-0.9922f,0.0551f,-0.0569f,-0.0492f,0.0418f,-0.0234f,-0.9922f,0.0157f,-0.1425f,-0.0350f,0.0479f,-0.8672f,-0.3906f,0.2835f,-0.1406f,-0.0394f,0.0472f,-0.6797f,-0.6875f,0.2205f,-0.1313f,-0.0435f,0.0441f,-0.2578f,-0.9609f,0.0787f,-0.1086f,-0.0469f,0.0365f,-0.0938f,-0.9922f,0.0236f,-0.0668f,-0.0492f,0.0224f,-0.0313f,-0.9922f,0.0079f,0.1425f,-0.0350f,0.0479f,0.8661f,-0.3906f,0.2835f,0.1406f,-0.0394f,0.0472f,0.6772f,-0.6875f,0.2205f,0.1313f,-0.0435f,0.0441f,0.2598f,-0.9609f,0.0787f,0.1086f,-0.0469f,0.0365f,0.0945f,-0.9922f,0.0236f,0.0668f,-0.0492f,0.0224f,0.0315f,-0.9922f,0.0079f,0.1198f,-0.0394f,0.0879f,0.5748f,-0.6875f,0.4173f,0.1119f,-0.0435f,0.0821f,0.2205f,-0.9609f,0.1575f,0.0925f,-0.0469f,0.0679f,0.0787f,-0.9922f,0.0551f,0.0569f,-0.0492f,0.0418f,0.0236f,-0.9922f,0.0157f,0.0879f,-0.0394f,0.1198f,0.4173f,-0.6875f,0.5748f,0.0821f,-0.0435f,0.1119f,0.1575f,-0.9609f,0.2205f,0.0679f,-0.0469f,0.0925f,0.0551f,-0.9922f,0.0787f,0.0418f,-0.0492f,0.0569f,0.0157f,-0.9922f,0.0236f,0.0479f,-0.0350f,0.1425f,0.2835f,-0.3906f,0.8661f,0.0472f,-0.0394f,0.1406f,0.2205f,-0.6875f,0.6772f,0.0441f,-0.0435f,0.1313f,0.0787f,-0.9609f,0.2598f,0.0365f,-0.0469f,0.1086f,0.0236f,-0.9922f,0.0945f,0.0224f,-0.0492f,0.0668f,0.0079f,-0.9922f,0.0315f,-0.2969f,0.1300f,0.0144f,-0.8750f,0.0472f,0.4724f,-0.2910f,0.1508f,0.0144f,-0.7266f,0.5039f,0.4567f,-0.2940f,0.1520f,0.0000f,-0.8203f,0.5591f,0.0000f,-0.3000f,0.1300f,0.0000f,-0.9922f,0.0472f,0.0000f,-0.2734f,0.1634f,0.0144f,-0.3750f,0.8189f,0.4252f,-0.2760f,0.1653f,0.0000f,-0.4219f,0.8976f,0.0000f,-0.2442f,0.1699f,0.0144f,-0.1250f,0.9055f,0.3937f,-0.2460f,0.1721f,0.0000f,-0.1406f,0.9843f,0.0000f,-0.2034f,0.1723f,0.0144f,-0.0234f,0.9134f,0.3937f,-0.2040f,0.1746f,0.0000f,-0.0313f,0.9921f,0.0000f,-0.1510f,0.1727f,0.0144f,0.0000f,0.9213f,0.3701f,-0.1500f,0.1750f,0.0000f,0.0000f,1.0000f,0.0000f,-0.2894f,0.1300f,0.0216f,-0.4141f,0.0236f,0.9055f,-0.2839f,0.1481f,0.0216f,-0.3438f,0.2677f,0.8898f,-0.2674f,0.1591f,0.0216f,-0.1563f,0.4252f,0.8898f,-0.2400f,0.1647f,0.0216f,-0.0469f,0.4488f,0.8898f,-0.2020f,0.1668f,0.0216f,-0.0078f,0.4409f,0.8898f,-0.1535f,0.1671f,0.0216f,0.0000f,0.5354f,0.8346f,-0.2806f,0.1300f,0.0216f,0.3150f,-0.0234f,0.9449f,-0.2754f,0.1448f,0.0216f,0.2362f,-0.1797f,0.9528f,-0.2601f,0.1538f,0.0216f,0.1339f,-0.3516f,0.9213f,-0.2350f,0.1585f,0.0216f,0.0472f,-0.4141f,0.8976f,-0.2003f,0.1602f,0.0216f,0.0079f,-0.4297f,0.8976f,-0.1565f,0.1604f,0.0216f,0.0000f,-0.3438f,0.9370f,-0.2731f,0.1300f,0.0144f,0.8504f,-0.0938f,0.5118f,-0.2683f,0.1421f,0.0144f,0.6299f,-0.5859f,0.4961f,-0.2540f,0.1495f,0.0144f,0.2677f,-0.8594f,0.4252f,-0.2307f,0.1532f,0.0144f,0.0866f,-0.9063f,0.3937f,-0.1989f,0.1546f,0.0144f,0.0157f,-0.9141f,0.3937f,-0.1590f,0.1548f,0.0144f,0.0000f,-0.9063f,0.4173f,-0.2700f,0.1300f,0.0000f,0.9921f,-0.1172f,0.0000f,-0.2653f,0.1410f,0.0000f,0.7165f,-0.6953f,0.0000f,-0.2514f,0.1476f,0.0000f,0.2913f,-0.9531f,0.0000f,-0.2290f,0.1511f,0.0000f,0.0945f,-0.9922f,0.0000f,-0.1983f,0.1523f,0.0000f,0.0157f,-0.9922f,0.0000f,-0.1600f,0.1525f,0.0000f,0.0000f,-1.0000f,0.0000f,-0.2731f,0.1300f,-0.0144f,0.8504f,-0.0938f,-0.5078f,-0.2683f,0.1421f,-0.0144f,0.6299f,-0.5859f,-0.5000f,-0.2540f,0.1495f,-0.0144f,0.2677f,-0.8594f,-0.4219f,-0.2307f,0.1532f,-0.0144f,0.0866f,-0.9063f,-0.3984f,-0.1989f,0.1546f,-0.0144f,0.0157f,-0.9141f,-0.3906f,-0.1590f,0.1548f,-0.0144f,0.0000f,-0.9063f,-0.4141f,-0.2806f,0.1300f,-0.0216f,0.3150f,-0.0234f,-0.9453f,-0.2754f,0.1448f,-0.0216f,0.2362f,-0.1797f,-0.9531f,-0.2601f,0.1538f,-0.0216f,0.1339f,-0.3516f,-0.9219f,-0.2350f,0.1585f,-0.0216f,0.0472f,-0.4141f,-0.8984f,-0.2003f,0.1602f,-0.0216f,0.0079f,-0.4297f,-0.8984f,-0.1565f,0.1604f,-0.0216f,0.0000f,-0.3438f,-0.9375f,-0.2894f,0.1300f,-0.0216f,-0.4141f,0.0236f,-0.9063f,-0.2839f,0.1481f,-0.0216f,-0.3438f,0.2677f,-0.8906f,-0.2674f,0.1591f,-0.0216f,-0.1563f,0.4252f,-0.8828f,-0.2400f,0.1647f,-0.0216f,-0.0469f,0.4488f,-0.8906f,-0.2020f,0.1668f,-0.0216f,-0.0078f,0.4409f,-0.8906f,-0.1535f,0.1671f,-0.0216f,0.0000f,0.5354f,-0.8359f,-0.2969f,0.1300f,-0.0144f,-0.8750f,0.0472f,-0.4688f,-0.2910f,0.1508f,-0.0144f,-0.7266f,0.5039f,-0.4609f,-0.2734f,0.1634f,-0.0144f,-0.3750f,0.8189f,-0.4219f,-0.2442f,0.1699f,-0.0144f,-0.1250f,0.9055f,-0.3984f,-0.2034f,0.1723f,-0.0144f,-0.0234f,0.9134f,-0.3906f,-0.1510f,0.1727f,-0.0144f,0.0000f,0.9213f,-0.3672f,-0.1910f,0.0131f,0.0144f,-0.4375f,-0.8281f,0.3307f,-0.2298f,0.0337f,0.0144f,-0.4844f,-0.7656f,0.4016f,-0.2302f,0.0311f,0.0000f,-0.5234f,-0.8438f,0.0000f,-0.1900f,0.0100f,0.0000f,-0.4609f,-0.8828f,0.0000f,-0.2596f,0.0560f,0.0144f,-0.6094f,-0.6563f,0.4252f,-0.2611f,0.0539f,0.0000f,-0.6719f,-0.7344f,0.0000f,-0.2805f,0.0798f,0.0144f,-0.7344f,-0.4922f,0.4567f,-0.2829f,0.0780f,0.0000f,-0.8203f,-0.5547f,0.0000f,-0.2928f,0.1046f,0.0144f,-0.8359f,-0.2656f,0.4646f,-0.2958f,0.1035f,0.0000f,-0.9453f,-0.3047f,0.0000f,-0.1935f,0.0206f,0.0216f,-0.2969f,-0.5547f,0.7717f,-0.2289f,0.0398f,0.0216f,-0.2500f,-0.3672f,0.8898f,-0.2559f,0.0613f,0.0216f,-0.2969f,-0.3125f,0.8976f,-0.2747f,0.0840f,0.0216f,-0.3438f,-0.2266f,0.9055f,-0.2858f,0.1072f,0.0216f,-0.3828f,-0.1172f,0.9134f,-0.1965f,0.0294f,0.0216f,0.1260f,0.2126f,0.9606f,-0.2278f,0.0471f,0.0216f,0.2283f,0.3386f,0.9055f,-0.2515f,0.0675f,0.0216f,0.2835f,0.2677f,0.9134f,-0.2679f,0.0891f,0.0216f,0.3150f,0.1811f,0.9291f,-0.2775f,0.1104f,0.0216f,0.3307f,0.0945f,0.9291f,-0.1990f,0.0369f,0.0144f,0.4488f,0.7717f,0.4409f,-0.2269f,0.0533f,0.0144f,0.5433f,0.7244f,0.4094f,-0.2478f,0.0727f,0.0144f,0.6693f,0.5906f,0.4331f,-0.2622f,0.0933f,0.0144f,0.7638f,0.4252f,0.4724f,-0.2705f,0.1130f,0.0144f,0.8346f,0.2362f,0.4882f,-0.2265f,0.0558f,0.0000f,0.6063f,0.7874f,0.0000f,-0.2462f,0.0749f,0.0000f,0.7559f,0.6457f,0.0000f,-0.2598f,0.0951f,0.0000f,0.8740f,0.4724f,0.0000f,-0.2675f,0.1142f,0.0000f,0.9606f,0.2677f,0.0000f,-0.1990f,0.0369f,-0.0144f,0.4488f,0.7717f,-0.4375f,-0.2269f,0.0533f,-0.0144f,0.5433f,0.7244f,-0.4063f,-0.2478f,0.0727f,-0.0144f,0.6693f,0.5906f,-0.4375f,-0.2622f,0.0933f,-0.0144f,0.7638f,0.4252f,-0.4688f,-0.2705f,0.1130f,-0.0144f,0.8346f,0.2362f,-0.4844f,-0.1965f,0.0294f,-0.0216f,0.1260f,0.2126f,-0.9609f,-0.2278f,0.0471f,-0.0216f,0.2283f,0.3386f,-0.9063f,-0.2515f,0.0675f,-0.0216f,0.2835f,0.2677f,-0.9141f,-0.2679f,0.0891f,-0.0216f,0.3150f,0.1811f,-0.9297f,-0.2775f,0.1104f,-0.0216f,0.3307f,0.0945f,-0.9297f,-0.1935f,0.0206f,-0.0216f,-0.2969f,-0.5547f,-0.7734f,-0.2289f,0.0398f,-0.0216f,-0.2500f,-0.3672f,-0.8906f,-0.2559f,0.0613f,-0.0216f,-0.2969f,-0.3125f,-0.8984f,-0.2747f,0.0840f,-0.0216f,-0.3438f,-0.2266f,-0.9063f,-0.2858f,0.1072f,-0.0216f,-0.3828f,-0.1172f,-0.9063f,-0.1910f,0.0131f,-0.0144f,-0.4375f,-0.8281f,-0.3359f,-0.2298f,0.0337f,-0.0144f,-0.4844f,-0.7656f,-0.3984f,-0.2596f,0.0560f,-0.0144f,-0.6094f,-0.6563f,-0.4219f,-0.2805f,0.0798f,-0.0144f,-0.7344f,-0.4922f,-0.4531f,-0.2928f,0.1046f,-0.0144f,-0.8359f,-0.2656f,-0.4688f,0.3238f,0.1900f,0.0120f,0.4567f,-0.6719f,0.5748f,0.2881f,0.1600f,0.0140f,0.6772f,-0.4297f,0.5906f,0.2922f,0.1590f,0.0000f,0.8031f,-0.5938f,0.0000f,0.3300f,0.1900f,0.0000f,0.5118f,-0.8516f,0.0000f,0.2718f,0.1196f,0.0189f,0.8425f,-0.2344f,0.4646f,0.2751f,0.1169f,0.0000f,0.9370f,-0.3203f,0.0000f,0.2579f,0.0771f,0.0248f,0.8110f,-0.3828f,0.4331f,0.2609f,0.0723f,0.0000f,0.8819f,-0.4609f,0.0000f,0.2296f,0.0406f,0.0296f,0.5276f,-0.6797f,0.4882f,0.2318f,0.0338f,0.0000f,0.5906f,-0.8047f,0.0000f,0.1700f,0.0186f,0.0317f,0.3150f,-0.8047f,0.4961f,0.1700f,0.0100f,0.0000f,0.3543f,-0.9297f,0.0000f,0.3089f,0.1900f,0.0180f,0.1890f,-0.1016f,0.9685f,0.2784f,0.1623f,0.0211f,0.2835f,-0.0234f,0.9528f,0.2640f,0.1260f,0.0284f,0.4488f,0.0157f,0.8898f,0.2509f,0.0884f,0.0371f,0.5039f,-0.0859f,0.8504f,0.2245f,0.0570f,0.0444f,0.3228f,-0.2813f,0.8976f,0.1700f,0.0390f,0.0475f,0.1732f,-0.3672f,0.9055f,0.2911f,0.1900f,0.0180f,-0.1719f,0.3780f,0.9055f,0.2667f,0.1651f,0.0211f,-0.2344f,0.3071f,0.9134f,0.2546f,0.1336f,0.0284f,-0.2266f,0.2992f,0.9213f,0.2425f,0.1020f,0.0371f,-0.0859f,0.3307f,0.9370f,0.2184f,0.0765f,0.0444f,-0.0078f,0.2992f,0.9528f,0.1700f,0.0635f,0.0475f,-0.0078f,0.2835f,0.9528f,0.2762f,0.1900f,0.0120f,-0.5078f,0.6535f,0.5512f,0.2570f,0.1674f,0.0140f,-0.6953f,0.4646f,0.5354f,0.2467f,0.1400f,0.0189f,-0.7578f,0.4016f,0.5039f,0.2355f,0.1134f,0.0248f,-0.6406f,0.5591f,0.5118f,0.2133f,0.0929f,0.0296f,-0.3281f,0.7559f,0.5512f,0.1700f,0.0839f,0.0317f,-0.1406f,0.8110f,0.5591f,0.2700f,0.1900f,0.0000f,-0.6719f,0.7323f,0.0000f,0.2529f,0.1683f,0.0000f,-0.8594f,0.5039f,0.0000f,0.2434f,0.1427f,0.0000f,-0.9141f,0.3858f,0.0000f,0.2326f,0.1182f,0.0000f,-0.8047f,0.5906f,0.0000f,0.2111f,0.0998f,0.0000f,-0.4375f,0.8976f,0.0000f,0.1700f,0.0925f,0.0000f,-0.1797f,0.9764f,0.0000f,0.2762f,0.1900f,-0.0120f,-0.5078f,0.6535f,-0.5469f,0.2570f,0.1674f,-0.0140f,-0.6953f,0.4646f,-0.5391f,0.2467f,0.1400f,-0.0189f,-0.7578f,0.4016f,-0.5000f,0.2355f,0.1134f,-0.0248f,-0.6406f,0.5591f,-0.5156f,0.2133f,0.0929f,-0.0296f,-0.3281f,0.7559f,-0.5547f,0.1700f,0.0839f,-0.0317f,-0.1406f,0.8110f,-0.5547f,0.2911f,0.1900f,-0.0180f,-0.1719f,0.3780f,-0.9063f,0.2667f,0.1651f,-0.0211f,-0.2344f,0.3071f,-0.9141f,0.2546f,0.1336f,-0.0284f,-0.2266f,0.2992f,-0.9219f,0.2425f,0.1020f,-0.0371f,-0.0859f,0.3307f,-0.9375f,0.2184f,0.0765f,-0.0444f,-0.0078f,0.2992f,-0.9531f,0.1700f,0.0635f,-0.0475f,-0.0078f,0.2835f,-0.9531f,0.3089f,0.1900f,-0.0180f,0.1890f,-0.1016f,-0.9688f,0.2784f,0.1623f,-0.0211f,0.2835f,-0.0234f,-0.9531f,0.2640f,0.1260f,-0.0284f,0.4488f,0.0157f,-0.8906f,0.2509f,0.0884f,-0.0371f,0.5039f,-0.0859f,-0.8516f,0.2245f,0.0570f,-0.0444f,0.3228f,-0.2813f,-0.8984f,0.1700f,0.0390f,-0.0475f,0.1732f,-0.3672f,-0.9063f,0.3238f,0.1900f,-0.0120f,0.4567f,-0.6719f,-0.5703f,0.2881f,0.1600f,-0.0140f,0.6772f,-0.4297f,-0.5859f,0.2718f,0.1196f,-0.0189f,0.8425f,-0.2344f,-0.4688f,0.2579f,0.0771f,-0.0248f,0.8110f,-0.3828f,-0.4297f,0.2296f,0.0406f,-0.0296f,0.5276f,-0.6797f,-0.4922f,0.1700f,0.0186f,-0.0317f,0.3150f,-0.8047f,-0.4922f,0.3158f,0.1900f,0.0072f,-0.2969f,0.7480f,-0.5781f,0.3277f,0.1951f,0.0077f,-0.2734f,0.8819f,-0.3672f,0.3328f,0.1952f,0.0000f,-0.3125f,0.9449f,0.0000f,0.3200f,0.1900f,0.0000f,-0.3750f,0.9213f,0.0000f,0.3349f,0.1973f,0.0089f,-0.0781f,0.9921f,-0.0313f,0.3408f,0.1976f,0.0000f,-0.0234f,0.9921f,0.0000f,0.3369f,0.1971f,0.0103f,0.6850f,0.3386f,0.6378f,0.3434f,0.1973f,0.0000f,0.9685f,0.2441f,0.0000f,0.3333f,0.1946f,0.0115f,0.4724f,-0.5000f,0.7165f,0.3400f,0.1947f,0.0000f,0.5591f,-0.8203f,0.0000f,0.3059f,0.1900f,0.0108f,-0.0469f,0.2677f,-0.9609f,0.3155f,0.1946f,0.0115f,-0.1328f,0.6614f,-0.7266f,0.3207f,0.1968f,0.0133f,-0.0859f,0.9685f,-0.2031f,0.3213f,0.1966f,0.0155f,0.1654f,0.7087f,0.6772f,0.3174f,0.1943f,0.0173f,0.1811f,0.0709f,0.9764f,0.2941f,0.1900f,0.0108f,0.2598f,-0.2266f,-0.9297f,0.3010f,0.1942f,0.0115f,0.1260f,0.3071f,-0.9375f,0.3038f,0.1962f,0.0133f,0.0000f,0.9213f,-0.3672f,0.3028f,0.1961f,0.0155f,-0.0469f,0.8976f,0.4252f,0.2984f,0.1940f,0.0173f,-0.1094f,0.5512f,0.8189f,0.2842f,0.1900f,0.0072f,0.5669f,-0.6172f,-0.5313f,0.2889f,0.1938f,0.0077f,0.5827f,-0.1563f,-0.7891f,0.2896f,0.1956f,0.0089f,0.2126f,0.8740f,-0.4219f,0.2872f,0.1956f,0.0103f,-0.1563f,0.9528f,0.2441f,0.2825f,0.1937f,0.0115f,-0.3359f,0.8031f,0.4724f,0.2800f,0.1900f,0.0000f,0.6693f,-0.7344f,0.0000f,0.2838f,0.1936f,0.0000f,0.8819f,-0.4609f,0.0000f,0.2837f,0.1954f,0.0000f,0.4961f,0.8583f,0.0000f,0.2807f,0.1954f,0.0000f,-0.2266f,0.9685f,0.0000f,0.2758f,0.1936f,0.0000f,-0.4453f,0.8898f,0.0000f,0.2842f,0.1900f,-0.0072f,0.5669f,-0.6172f,0.5354f,0.2889f,0.1938f,-0.0077f,0.5827f,-0.1563f,0.7874f,0.2896f,0.1956f,-0.0089f,0.2126f,0.8740f,0.4252f,0.2872f,0.1956f,-0.0103f,-0.1563f,0.9528f,-0.2422f,0.2825f,0.1937f,-0.0115f,-0.3359f,0.8031f,-0.4766f,0.2941f,0.1900f,-0.0108f,0.2598f,-0.2266f,0.9370f,0.3010f,0.1942f,-0.0115f,0.1260f,0.3071f,0.9370f,0.3038f,0.1962f,-0.0133f,0.0000f,0.9213f,0.3701f,0.3028f,0.1961f,-0.0155f,-0.0469f,0.8976f,-0.4297f,0.2984f,0.1940f,-0.0173f,-0.1094f,0.5512f,-0.8203f,0.3059f,0.1900f,-0.0108f,-0.0469f,0.2677f,0.9606f,0.3155f,0.1946f,-0.0115f,-0.1328f,0.6614f,0.7244f,0.3207f,0.1968f,-0.0133f,-0.0859f,0.9685f,0.2047f,0.3213f,0.1966f,-0.0155f,0.1654f,0.7087f,-0.6719f,0.3174f,0.1943f,-0.0173f,0.1811f,0.0709f,-0.9766f,0.3158f,0.1900f,-0.0072f,-0.2969f,0.7480f,0.5827f,0.3277f,0.1951f,-0.0077f,-0.2734f,0.8819f,0.3622f,0.3349f,0.1973f,-0.0089f,-0.0781f,0.9921f,0.0315f,0.3369f,0.1971f,-0.0103f,0.6850f,0.3386f,-0.6328f,0.3333f,0.1946f,-0.0115f,0.4724f,-0.5000f,-0.7109f,0.0064f,0.2200f,0.0190f,0.2283f,0.6614f,0.7008f,0.0057f,0.2304f,0.0170f,0.2913f,-0.2422f,0.9213f,0.0000f,0.2304f,0.0179f,0.0000f,-0.2422f,0.9685f,0.0000f,0.2200f,0.0200f,0.0000f,0.6614f,0.7402f,0.0088f,0.2423f,0.0260f,0.2362f,-0.6094f,0.7480f,0.0000f,0.2423f,0.0274f,0.0000f,-0.6094f,0.7874f,0.0115f,0.2535f,0.0340f,0.3071f,-0.0469f,0.9449f,0.0000f,0.2535f,0.0358f,0.0000f,-0.0469f,0.9921f,0.0099f,0.2618f,0.0293f,0.1732f,0.8189f,0.5354f,0.0000f,0.2618f,0.0309f,0.0000f,0.8189f,0.5669f,0.0000f,0.2650f,0.0000f,0.0000f,1.0000f,0.0000f,0.0119f,0.2200f,0.0162f,0.4331f,0.6614f,0.5984f,0.0107f,0.2304f,0.0145f,0.5669f,-0.2422f,0.7795f,0.0163f,0.2423f,0.0222f,0.4567f,-0.6094f,0.6378f,0.0213f,0.2535f,0.0290f,0.5827f,-0.0469f,0.8031f,0.0184f,0.2618f,0.0250f,0.3307f,0.8189f,0.4567f,0.0162f,0.2200f,0.0119f,0.5984f,0.6614f,0.4331f,0.0145f,0.2304f,0.0107f,0.7795f,-0.2422f,0.5669f,0.0222f,0.2423f,0.0163f,0.6378f,-0.6094f,0.4567f,0.0290f,0.2535f,0.0213f,0.8031f,-0.0469f,0.5827f,0.0250f,0.2618f,0.0184f,0.4567f,0.8189f,0.3307f,0.0190f,0.2200f,0.0064f,0.7008f,0.6614f,0.2283f,0.0170f,0.2304f,0.0057f,0.9213f,-0.2422f,0.2913f,0.0260f,0.2423f,0.0088f,0.7480f,-0.6094f,0.2362f,0.0340f,0.2535f,0.0115f,0.9449f,-0.0469f,0.3071f,0.0293f,0.2618f,0.0099f,0.5354f,0.8189f,0.1732f,0.0200f,0.2200f,0.0000f,0.7402f,0.6614f,0.0000f,0.0179f,0.2304f,0.0000f,0.9685f,-0.2422f,0.0000f,0.0274f,0.2423f,0.0000f,0.7874f,-0.6094f,0.0000f,0.0358f,0.2535f,0.0000f,0.9921f,-0.0469f,0.0000f,0.0309f,0.2618f,0.0000f,0.5669f,0.8189f,0.0000f,-0.0190f,0.2200f,0.0064f,-0.7031f,0.6614f,0.2283f,-0.0170f,0.2304f,0.0057f,-0.9219f,-0.2422f,0.2913f,-0.0179f,0.2304f,0.0000f,-0.9688f,-0.2422f,0.0000f,-0.0200f,0.2200f,0.0000f,-0.7422f,0.6614f,0.0000f,-0.0260f,0.2423f,0.0088f,-0.7500f,-0.6094f,0.2362f,-0.0274f,0.2423f,0.0000f,-0.7891f,-0.6094f,0.0000f,-0.0340f,0.2535f,0.0115f,-0.9453f,-0.0469f,0.3071f,-0.0358f,0.2535f,0.0000f,-0.9922f,-0.0469f,0.0000f,-0.0293f,0.2618f,0.0099f,-0.5391f,0.8189f,0.1732f,-0.0309f,0.2618f,0.0000f,-0.5625f,0.8189f,0.0000f,-0.0162f,0.2200f,0.0119f,-0.6016f,0.6614f,0.4331f,-0.0145f,0.2304f,0.0107f,-0.7813f,-0.2422f,0.5669f,-0.0222f,0.2423f,0.0163f,-0.6328f,-0.6094f,0.4567f,-0.0290f,0.2535f,0.0213f,-0.8047f,-0.0469f,0.5827f,-0.0250f,0.2618f,0.0184f,-0.4531f,0.8189f,0.3307f,-0.0119f,0.2200f,0.0162f,-0.4375f,0.6614f,0.5984f,-0.0107f,0.2304f,0.0145f,-0.5625f,-0.2422f,0.7795f,-0.0163f,0.2423f,0.0222f,-0.4609f,-0.6094f,0.6378f,-0.0213f,0.2535f,0.0290f,-0.5859f,-0.0469f,0.8031f,-0.0184f,0.2618f,0.0250f,-0.3281f,0.8189f,0.4567f,-0.0064f,0.2200f,0.0190f,-0.2266f,0.6614f,0.7008f,-0.0057f,0.2304f,0.0170f,-0.2969f,-0.2422f,0.9213f,-0.0088f,0.2423f,0.0260f,-0.2422f,-0.6094f,0.7480f,-0.0115f,0.2535f,0.0340f,-0.3047f,-0.0469f,0.9449f,-0.0099f,0.2618f,0.0293f,-0.1719f,0.8189f,0.5354f,-0.0064f,0.2200f,-0.0190f,-0.2266f,0.6614f,-0.7031f,-0.0057f,0.2304f,-0.0170f,-0.2969f,-0.2422f,-0.9219f,0.0000f,0.2304f,-0.0179f,0.0000f,-0.2422f,-0.9688f,0.0000f,0.2200f,-0.0200f,0.0000f,0.6614f,-0.7422f,-0.0088f,0.2423f,-0.0260f,-0.2422f,-0.6094f,-0.7500f,0.0000f,0.2423f,-0.0274f,0.0000f,-0.6094f,-0.7891f,-0.0115f,0.2535f,-0.0340f,-0.3047f,-0.0469f,-0.9453f,0.0000f,0.2535f,-0.0358f,0.0000f,-0.0469f,-0.9922f,-0.0099f,0.2618f,-0.0293f,-0.1719f,0.8189f,-0.5391f,0.0000f,0.2618f,-0.0309f,0.0000f,0.8189f,-0.5625f,-0.0119f,0.2200f,-0.0162f,-0.4375f,0.6614f,-0.6016f,-0.0107f,0.2304f,-0.0145f,-0.5625f,-0.2422f,-0.7813f,-0.0163f,0.2423f,-0.0222f,-0.4609f,-0.6094f,-0.6328f,-0.0213f,0.2535f,-0.0290f,-0.5859f,-0.0469f,-0.8047f,-0.0184f,0.2618f,-0.0250f,-0.3281f,0.8189f,-0.4531f,-0.0162f,0.2200f,-0.0119f,-0.6016f,0.6614f,-0.4375f,-0.0145f,0.2304f,-0.0107f,-0.7813f,-0.2422f,-0.5625f,-0.0222f,0.2423f,-0.0163f,-0.6328f,-0.6094f,-0.4609f,-0.0290f,0.2535f,-0.0213f,-0.8047f,-0.0469f,-0.5859f,-0.0250f,0.2618f,-0.0184f,-0.4531f,0.8189f,-0.3281f,-0.0190f,0.2200f,-0.0064f,-0.7031f,0.6614f,-0.2266f,-0.0170f,0.2304f,-0.0057f,-0.9219f,-0.2422f,-0.2969f,-0.0260f,0.2423f,-0.0088f,-0.7500f,-0.6094f,-0.2422f,-0.0340f,0.2535f,-0.0115f,-0.9453f,-0.0469f,-0.3047f,-0.0293f,0.2618f,-0.0099f,-0.5391f,0.8189f,-0.1719f,0.0190f,0.2200f,-0.0064f,0.7008f,0.6614f,-0.2266f,0.0170f,0.2304f,-0.0057f,0.9213f,-0.2422f,-0.2969f,0.0260f,0.2423f,-0.0088f,0.7480f,-0.6094f,-0.2422f,0.0340f,0.2535f,-0.0115f,0.9449f,-0.0469f,-0.3047f,0.0293f,0.2618f,-0.0099f,0.5354f,0.8189f,-0.1719f,0.0162f,0.2200f,-0.0119f,0.5984f,0.6614f,-0.4375f,0.0145f,0.2304f,-0.0107f,0.7795f,-0.2422f,-0.5625f,0.0222f,0.2423f,-0.0163f,0.6378f,-0.6094f,-0.4609f,0.0290f,0.2535f,-0.0213f,0.8031f,-0.0469f,-0.5859f,0.0250f,0.2618f,-0.0184f,0.4567f,0.8189f,-0.3281f,0.0119f,0.2200f,-0.0162f,0.4331f,0.6614f,-0.6016f,0.0107f,0.2304f,-0.0145f,0.5669f,-0.2422f,-0.7813f,0.0163f,0.2423f,-0.0222f,0.4567f,-0.6094f,-0.6328f,0.0213f,0.2535f,-0.0290f,0.5827f,-0.0469f,-0.8047f,0.0184f,0.2618f,-0.0250f,0.3307f,0.8189f,-0.4531f,0.0064f,0.2200f,-0.0190f,0.2283f,0.6614f,-0.7031f,0.0057f,0.2304f,-0.0170f,0.2913f,-0.2422f,-0.9219f,0.0088f,0.2423f,-0.0260f,0.2362f,-0.6094f,-0.7500f,0.0115f,0.2535f,-0.0340f,0.3071f,-0.0469f,-0.9453f,0.0099f,0.2618f,-0.0293f,0.1732f,0.8189f,-0.5391f,0.0415f,0.1900f,0.1235f,0.1890f,0.7874f,0.5827f,0.0384f,0.1974f,0.1144f,0.1339f,0.8898f,0.4173f,0.0000f,0.1974f,0.1205f,0.0000f,0.8898f,0.4409f,0.0000f,0.1900f,0.1300f,0.0000f,0.7874f,0.6142f,0.0310f,0.2027f,0.0922f,0.0551f,0.9764f,0.1732f,0.0000f,0.2027f,0.0970f,0.0000f,0.9764f,0.1890f,0.0215f,0.2073f,0.0640f,0.0472f,0.9843f,0.1575f,0.0000f,0.2073f,0.0674f,0.0000f,0.9843f,0.1654f,0.0125f,0.2126f,0.0372f,0.0787f,0.9606f,0.2520f,0.0000f,0.2126f,0.0391f,0.0000f,0.9606f,0.2598f,0.0772f,0.1900f,0.1052f,0.3543f,0.7874f,0.4961f,0.0716f,0.1974f,0.0975f,0.2598f,0.8898f,0.3543f,0.0576f,0.2027f,0.0785f,0.1102f,0.9764f,0.1496f,0.0400f,0.2073f,0.0545f,0.0945f,0.9843f,0.1339f,0.0232f,0.2126f,0.0317f,0.1496f,0.9606f,0.2126f,0.1052f,0.1900f,0.0772f,0.4961f,0.7874f,0.3543f,0.0975f,0.1974f,0.0716f,0.3543f,0.8898f,0.2598f,0.0785f,0.2027f,0.0576f,0.1496f,0.9764f,0.1102f,0.0545f,0.2073f,0.0400f,0.1339f,0.9843f,0.0945f,0.0317f,0.2126f,0.0232f,0.2126f,0.9606f,0.1496f,0.1235f,0.1900f,0.0415f,0.5827f,0.7874f,0.1890f,0.1144f,0.1974f,0.0384f,0.4173f,0.8898f,0.1339f,0.0922f,0.2027f,0.0310f,0.1732f,0.9764f,0.0551f,0.0640f,0.2073f,0.0215f,0.1575f,0.9843f,0.0472f,0.0372f,0.2126f,0.0125f,0.2520f,0.9606f,0.0787f,0.1300f,0.1900f,0.0000f,0.6142f,0.7874f,0.0000f,0.1205f,0.1974f,0.0000f,0.4409f,0.8898f,0.0000f,0.0970f,0.2027f,0.0000f,0.1890f,0.9764f,0.0000f,0.0674f,0.2073f,0.0000f,0.1654f,0.9843f,0.0000f,0.0391f,0.2126f,0.0000f,0.2598f,0.9606f,0.0000f,-0.1235f,0.1900f,0.0415f,-0.5781f,0.7874f,0.1890f,-0.1144f,0.1974f,0.0384f,-0.4219f,0.8898f,0.1339f,-0.1205f,0.1974f,0.0000f,-0.4453f,0.8898f,0.0000f,-0.1300f,0.1900f,0.0000f,-0.6094f,0.7874f,0.0000f,-0.0922f,0.2027f,0.0310f,-0.1797f,0.9764f,0.0551f,-0.0970f,0.2027f,0.0000f,-0.1875f,0.9764f,0.0000f,-0.0640f,0.2073f,0.0215f,-0.1563f,0.9843f,0.0472f,-0.0674f,0.2073f,0.0000f,-0.1641f,0.9843f,0.0000f,-0.0372f,0.2126f,0.0125f,-0.2500f,0.9606f,0.0787f,-0.0391f,0.2126f,0.0000f,-0.2656f,0.9606f,0.0000f,-0.1052f,0.1900f,0.0772f,-0.4922f,0.7874f,0.3543f,-0.0975f,0.1974f,0.0716f,-0.3594f,0.8898f,0.2598f,-0.0785f,0.2027f,0.0576f,-0.1484f,0.9764f,0.1102f,-0.0545f,0.2073f,0.0400f,-0.1328f,0.9843f,0.0945f,-0.0317f,0.2126f,0.0232f,-0.2109f,0.9606f,0.1496f,-0.0772f,0.1900f,0.1052f,-0.3594f,0.7874f,0.4961f,-0.0716f,0.1974f,0.0975f,-0.2578f,0.8898f,0.3543f,-0.0576f,0.2027f,0.0785f,-0.1094f,0.9764f,0.1496f,-0.0400f,0.2073f,0.0545f,-0.0938f,0.9843f,0.1339f,-0.0232f,0.2126f,0.0317f,-0.1484f,0.9606f,0.2126f,-0.0415f,0.1900f,0.1235f,-0.1875f,0.7874f,0.5827f,-0.0384f,0.1974f,0.1144f,-0.1328f,0.8898f,0.4173f,-0.0310f,0.2027f,0.0922f,-0.0547f,0.9764f,0.1732f,-0.0215f,0.2073f,0.0640f,-0.0469f,0.9843f,0.1575f,-0.0125f,0.2126f,0.0372f,-0.0781f,0.9606f,0.2520f,-0.0415f,0.1900f,-0.1235f,-0.1875f,0.7874f,-0.5781f,-0.0384f,0.1974f,-0.1144f,-0.1328f,0.8898f,-0.4219f,0.0000f,0.1974f,-0.1205f,0.0000f,0.8898f,-0.4453f,0.0000f,0.1900f,-0.1300f,0.0000f,0.7874f,-0.6094f,-0.0310f,0.2027f,-0.0922f,-0.0547f,0.9764f,-0.1797f,0.0000f,0.2027f,-0.0970f,0.0000f,0.9764f,-0.1875f,-0.0215f,0.2073f,-0.0640f,-0.0469f,0.9843f,-0.1563f,0.0000f,0.2073f,-0.0674f,0.0000f,0.9843f,-0.1641f,-0.0125f,0.2126f,-0.0372f,-0.0781f,0.9606f,-0.2500f,0.0000f,0.2126f,-0.0391f,0.0000f,0.9606f,-0.2656f,-0.0772f,0.1900f,-0.1052f,-0.3594f,0.7874f,-0.4922f,-0.0716f,0.1974f,-0.0975f,-0.2578f,0.8898f,-0.3594f,-0.0576f,0.2027f,-0.0785f,-0.1094f,0.9764f,-0.1484f,-0.0400f,0.2073f,-0.0545f,-0.0938f,0.9843f,-0.1328f,-0.0232f,0.2126f,-0.0317f,-0.1484f,0.9606f,-0.2109f,-0.1052f,0.1900f,-0.0772f,-0.4922f,0.7874f,-0.3594f,-0.0975f,0.1974f,-0.0716f,-0.3594f,0.8898f,-0.2578f,-0.0785f,0.2027f,-0.0576f,-0.1484f,0.9764f,-0.1094f,-0.0545f,0.2073f,-0.0400f,-0.1328f,0.9843f,-0.0938f,-0.0317f,0.2126f,-0.0232f,-0.2109f,0.9606f,-0.1484f,-0.1235f,0.1900f,-0.0415f,-0.5781f,0.7874f,-0.1875f,-0.1144f,0.1974f,-0.0384f,-0.4219f,0.8898f,-0.1328f,-0.0922f,0.2027f,-0.0310f,-0.1797f,0.9764f,-0.0547f,-0.0640f,0.2073f,-0.0215f,-0.1563f,0.9843f,-0.0469f,-0.0372f,0.2126f,-0.0125f,-0.2500f,0.9606f,-0.0781f,0.1235f,0.1900f,-0.0415f,0.5827f,0.7874f,-0.1875f,0.1144f,0.1974f,-0.0384f,0.4173f,0.8898f,-0.1328f,0.0922f,0.2027f,-0.0310f,0.1732f,0.9764f,-0.0547f,0.0640f,0.2073f,-0.0215f,0.1575f,0.9843f,-0.0469f,0.0372f,0.2126f,-0.0125f,0.2520f,0.9606f,-0.0781f,0.1052f,0.1900f,-0.0772f,0.4961f,0.7874f,-0.3594f,0.0975f,0.1974f,-0.0716f,0.3543f,0.8898f,-0.2578f,0.0785f,0.2027f,-0.0576f,0.1496f,0.9764f,-0.1094f,0.0545f,0.2073f,-0.0400f,0.1339f,0.9843f,-0.0938f,0.0317f,0.2126f,-0.0232f,0.2126f,0.9606f,-0.1484f,0.0772f,0.1900f,-0.1052f,0.3543f,0.7874f,-0.4922f,0.0716f,0.1974f,-0.0975f,0.2598f,0.8898f,-0.3594f,0.0576f,0.2027f,-0.0785f,0.1102f,0.9764f,-0.1484f,0.0400f,0.2073f,-0.0545f,0.0945f,0.9843f,-0.1328f,0.0232f,0.2126f,-0.0317f,0.1496f,0.9606f,-0.2109f,0.0415f,0.1900f,-0.1235f,0.1890f,0.7874f,-0.5781f,0.0384f,0.1974f,-0.1144f,0.1339f,0.8898f,-0.4219f,0.0310f,0.2027f,-0.0922f,0.0551f,0.9764f,-0.1797f,0.0215f,0.2073f,-0.0640f,0.0472f,0.9843f,-0.1563f,0.0125f,0.2126f,-0.0372f,0.0787f,0.9606f,-0.2500f, 8 | }; 9 | 10 | static uint32_t teapot_triangles[] = 11 | { 12 | 0,1,2,0,2,3,1,4,5,1,5,2,4,6,7,4,7,5,6,8,9,6,9,7,8,10,11,8,11,9,12,13,1,12,1,0,13,14,4,13,4,1,14,15,6,14,6,4,15,16,8,15,8,6,16,17,10,16,10,8,18,19,13,18,13,12,19,20,14,19,14,13,20,21,15,20,15,14,21,22,16,21,16,15,22,23,17,22,17,16,24,25,19,24,19,18,25,26,20,25,20,19,26,27,21,26,21,20,27,28,22,27,22,21,28,29,23,28,23,22,30,31,25,30,25,24,31,32,26,31,26,25,32,33,27,32,27,26,33,34,28,33,28,27,34,35,29,34,29,28,36,37,38,36,38,39,37,40,41,37,41,38,40,42,43,40,43,41,42,44,45,42,45,43,44,46,47,44,47,45,48,49,37,48,37,36,49,50,40,49,40,37,50,51,42,50,42,40,51,52,44,51,44,42,52,53,46,52,46,44,54,55,49,54,49,48,55,56,50,55,50,49,56,57,51,56,51,50,57,58,52,57,52,51,58,59,53,58,53,52,60,61,55,60,55,54,61,62,56,61,56,55,62,63,57,62,57,56,63,64,58,63,58,57,64,65,59,64,59,58,3,2,61,3,61,60,2,5,62,2,62,61,5,7,63,5,63,62,7,9,64,7,64,63,9,11,65,9,65,64,66,67,68,66,68,69,67,70,71,67,71,68,70,72,73,70,73,71,72,74,75,72,75,73,74,76,77,74,77,75,78,79,67,78,67,66,79,80,70,79,70,67,80,81,72,80,72,70,81,82,74,81,74,72,82,83,76,82,76,74,84,85,79,84,79,78,85,86,80,85,80,79,86,87,81,86,81,80,87,88,82,87,82,81,88,89,83,88,83,82,90,91,85,90,85,84,91,92,86,91,86,85,92,93,87,92,87,86,93,94,88,93,88,87,94,95,89,94,89,88,39,38,91,39,91,90,38,41,92,38,92,91,41,43,93,41,93,92,43,45,94,43,94,93,45,47,95,45,95,94,96,97,31,96,31,30,97,98,32,97,32,31,98,99,33,98,33,32,99,100,34,99,34,33,100,101,35,100,35,34,102,103,97,102,97,96,103,104,98,103,98,97,104,105,99,104,99,98,105,106,100,105,100,99,106,107,101,106,101,100,108,109,103,108,103,102,109,110,104,109,104,103,110,111,105,110,105,104,111,112,106,111,106,105,112,113,107,112,107,106,114,115,109,114,109,108,115,116,110,115,110,109,116,117,111,116,111,110,117,118,112,117,112,111,118,119,113,118,113,112,69,68,115,69,115,114,68,71,116,68,116,115,71,73,117,71,117,116,73,75,118,73,118,117,75,77,119,75,119,118,120,121,122,120,122,123,121,124,125,121,125,122,124,126,127,124,127,125,126,128,129,126,129,127,128,0,3,128,3,129,130,131,121,130,121,120,131,132,124,131,124,121,132,133,126,132,126,124,133,134,128,133,128,126,134,12,0,134,0,128,135,136,131,135,131,130,136,137,132,136,132,131,137,138,133,137,133,132,138,139,134,138,134,133,139,18,12,139,12,134,140,141,136,140,136,135,141,142,137,141,137,136,142,143,138,142,138,137,143,144,139,143,139,138,144,24,18,144,18,139,145,146,141,145,141,140,146,147,142,146,142,141,147,148,143,147,143,142,148,149,144,148,144,143,149,30,24,149,24,144,150,151,152,150,152,153,151,154,155,151,155,152,154,156,157,154,157,155,156,158,159,156,159,157,158,36,39,158,39,159,160,161,151,160,151,150,161,162,154,161,154,151,162,163,156,162,156,154,163,164,158,163,158,156,164,48,36,164,36,158,165,166,161,165,161,160,166,167,162,166,162,161,167,168,163,167,163,162,168,169,164,168,164,163,169,54,48,169,48,164,170,171,166,170,166,165,171,172,167,171,167,166,172,173,168,172,168,167,173,174,169,173,169,168,174,60,54,174,54,169,123,122,171,123,171,170,122,125,172,122,172,171,125,127,173,125,173,172,127,129,174,127,174,173,129,3,60,129,60,174,175,176,177,175,177,178,176,179,180,176,180,177,179,181,182,179,182,180,181,183,184,181,184,182,183,66,69,183,69,184,185,186,176,185,176,175,186,187,179,186,179,176,187,188,181,187,181,179,188,189,183,188,183,181,189,78,66,189,66,183,190,191,186,190,186,185,191,192,187,191,187,186,192,193,188,192,188,187,193,194,189,193,189,188,194,84,78,194,78,189,195,196,191,195,191,190,196,197,192,196,192,191,197,198,193,197,193,192,198,199,194,198,194,193,199,90,84,199,84,194,153,152,196,153,196,195,152,155,197,152,197,196,155,157,198,155,198,197,157,159,199,157,199,198,159,39,90,159,90,199,200,201,146,200,146,145,201,202,147,201,147,146,202,203,148,202,148,147,203,204,149,203,149,148,204,96,30,204,30,149,205,206,201,205,201,200,206,207,202,206,202,201,207,208,203,207,203,202,208,209,204,208,204,203,209,102,96,209,96,204,210,211,206,210,206,205,211,212,207,211,207,206,212,213,208,212,208,207,213,214,209,213,209,208,214,108,102,214,102,209,215,216,211,215,211,210,216,217,212,216,212,211,217,218,213,217,213,212,218,219,214,218,214,213,219,114,108,219,108,214,178,177,216,178,216,215,177,180,217,177,217,216,180,182,218,180,218,217,182,184,219,182,219,218,184,69,114,184,114,219,220,221,222,220,222,223,221,224,225,221,225,222,224,226,227,224,227,225,226,228,229,226,229,227,228,120,123,228,123,229,230,231,221,230,221,220,231,232,224,231,224,221,232,233,226,232,226,224,233,234,228,233,228,226,234,130,120,234,120,228,235,236,231,235,231,230,236,237,232,236,232,231,237,238,233,237,233,232,238,239,234,238,234,233,239,135,130,239,130,234,240,241,236,240,236,235,241,242,237,241,237,236,242,243,238,242,238,237,243,244,239,243,239,238,244,140,135,244,135,239,245,246,241,245,241,240,246,247,242,246,242,241,247,248,243,247,243,242,248,249,244,248,244,243,249,145,140,249,140,244,250,251,252,250,252,253,251,254,255,251,255,252,254,256,257,254,257,255,256,258,259,256,259,257,258,150,153,258,153,259,260,261,251,260,251,250,261,262,254,261,254,251,262,263,256,262,256,254,263,264,258,263,258,256,264,160,150,264,150,258,265,266,261,265,261,260,266,267,262,266,262,261,267,268,263,267,263,262,268,269,264,268,264,263,269,165,160,269,160,264,270,271,266,270,266,265,271,272,267,271,267,266,272,273,268,272,268,267,273,274,269,273,269,268,274,170,165,274,165,269,223,222,271,223,271,270,222,225,272,222,272,271,225,227,273,225,273,272,227,229,274,227,274,273,229,123,170,229,170,274,275,276,277,275,277,278,276,279,280,276,280,277,279,281,282,279,282,280,281,283,284,281,284,282,283,175,178,283,178,284,285,286,276,285,276,275,286,287,279,286,279,276,287,288,281,287,281,279,288,289,283,288,283,281,289,185,175,289,175,283,290,291,286,290,286,285,291,292,287,291,287,286,292,293,288,292,288,287,293,294,289,293,289,288,294,190,185,294,185,289,295,296,291,295,291,290,296,297,292,296,292,291,297,298,293,297,293,292,298,299,294,298,294,293,299,195,190,299,190,294,253,252,296,253,296,295,252,255,297,252,297,296,255,257,298,255,298,297,257,259,299,257,299,298,259,153,195,259,195,299,300,301,246,300,246,245,301,302,247,301,247,246,302,303,248,302,248,247,303,304,249,303,249,248,304,200,145,304,145,249,305,306,301,305,301,300,306,307,302,306,302,301,307,308,303,307,303,302,308,309,304,308,304,303,309,205,200,309,200,304,310,311,306,310,306,305,311,312,307,311,307,306,312,313,308,312,308,307,313,314,309,313,309,308,314,210,205,314,205,309,315,316,311,315,311,310,316,317,312,316,312,311,317,318,313,317,313,312,318,319,314,318,314,313,319,215,210,319,210,314,278,277,316,278,316,315,277,280,317,277,317,316,280,282,318,280,318,317,282,284,319,282,319,318,284,178,215,284,215,319,320,321,322,320,322,278,321,323,324,321,324,322,323,325,326,323,326,324,325,327,328,325,328,326,327,329,328,310,330,321,310,321,320,330,331,323,330,323,321,331,332,325,331,325,323,332,333,327,332,327,325,333,329,327,305,334,330,305,330,310,334,335,331,334,331,330,335,336,332,335,332,331,336,337,333,336,333,332,337,329,333,338,339,334,338,334,305,339,340,335,339,335,334,340,341,336,340,336,335,341,342,337,341,337,336,342,329,337,245,343,339,245,339,338,343,344,340,343,340,339,344,345,341,344,341,340,345,346,342,345,342,341,346,329,342,347,348,349,347,349,253,348,350,351,348,351,349,350,352,353,350,353,351,352,354,355,352,355,353,354,329,355,290,356,348,290,348,347,356,357,350,356,350,348,357,358,352,357,352,350,358,359,354,358,354,352,359,329,354,285,360,356,285,356,290,360,361,357,360,357,356,361,362,358,361,358,357,362,363,359,362,359,358,363,329,359,364,365,360,364,360,285,365,366,361,365,361,360,366,367,362,366,362,361,367,368,363,367,363,362,368,329,363,278,322,365,278,365,364,322,324,366,322,366,365,324,326,367,324,367,366,326,328,368,326,368,367,328,329,368,369,370,371,369,371,223,370,372,373,370,373,371,372,374,375,372,375,373,374,376,377,374,377,375,376,329,377,265,378,370,265,370,369,378,379,372,378,372,370,379,380,374,379,374,372,380,381,376,380,376,374,381,329,376,260,382,378,260,378,265,382,383,379,382,379,378,383,384,380,383,380,379,384,385,381,384,381,380,385,329,381,386,387,382,386,382,260,387,388,383,387,383,382,388,389,384,388,384,383,389,390,385,389,385,384,390,329,385,253,349,387,253,387,386,349,351,388,349,388,387,351,353,389,351,389,388,353,355,390,353,390,389,355,329,390,391,392,343,391,343,245,392,393,344,392,344,343,393,394,345,393,345,344,394,395,346,394,346,345,395,329,346,235,396,392,235,392,391,396,397,393,396,393,392,397,398,394,397,394,393,398,399,395,398,395,394,399,329,395,230,400,396,230,396,235,400,401,397,400,397,396,401,402,398,401,398,397,402,403,399,402,399,398,403,329,399,404,405,400,404,400,230,405,406,401,405,401,400,406,407,402,406,402,401,407,408,403,407,403,402,408,329,403,223,371,405,223,405,404,371,373,406,371,406,405,373,375,407,373,407,406,375,377,408,375,408,407,377,329,408,409,410,411,409,411,412,410,413,414,410,414,411,413,415,416,413,416,414,415,417,418,415,418,416,417,419,420,417,420,418,421,422,410,421,410,409,422,423,413,422,413,410,423,424,415,423,415,413,424,425,417,424,417,415,425,426,419,425,419,417,427,428,422,427,422,421,428,429,423,428,423,422,429,430,424,429,424,423,430,431,425,430,425,424,431,432,426,431,426,425,433,434,428,433,428,427,434,435,429,434,429,428,435,436,430,435,430,429,436,437,431,436,431,430,437,438,432,437,432,431,439,440,434,439,434,433,440,441,435,440,435,434,441,442,436,441,436,435,442,443,437,442,437,436,443,444,438,443,438,437,445,446,440,445,440,439,446,447,441,446,441,440,447,448,442,447,442,441,448,449,443,448,443,442,449,450,444,449,444,443,451,452,446,451,446,445,452,453,447,452,447,446,453,454,448,453,448,447,454,455,449,454,449,448,455,456,450,455,450,449,457,458,452,457,452,451,458,459,453,458,453,452,459,460,454,459,454,453,460,461,455,460,455,454,461,462,456,461,456,455,463,464,458,463,458,457,464,465,459,464,459,458,465,466,460,465,460,459,466,467,461,466,461,460,467,468,462,467,462,461,412,411,464,412,464,463,411,414,465,411,465,464,414,416,466,414,466,465,416,418,467,416,467,466,418,420,468,418,468,467,469,470,471,469,471,472,470,473,474,470,474,471,473,475,476,473,476,474,475,477,478,475,478,476,477,409,412,477,412,478,479,480,470,479,470,469,480,481,473,480,473,470,481,482,475,481,475,473,482,483,477,482,477,475,483,421,409,483,409,477,484,485,480,484,480,479,485,486,481,485,481,480,486,487,482,486,482,481,487,488,483,487,483,482,488,427,421,488,421,483,489,490,485,489,485,484,490,491,486,490,486,485,491,492,487,491,487,486,492,493,488,492,488,487,493,433,427,493,427,488,153,494,490,153,490,489,494,495,491,494,491,490,495,496,492,495,492,491,496,497,493,496,493,492,497,439,433,497,433,493,498,499,494,498,494,153,499,500,495,499,495,494,500,501,496,500,496,495,501,502,497,501,497,496,502,445,439,502,439,497,503,504,499,503,499,498,504,505,500,504,500,499,505,506,501,505,501,500,506,507,502,506,502,501,507,451,445,507,445,502,508,509,504,508,504,503,509,510,505,509,505,504,510,511,506,510,506,505,511,512,507,511,507,506,512,457,451,512,451,507,513,514,509,513,509,508,514,515,510,514,510,509,515,516,511,515,511,510,516,517,512,516,512,511,517,463,457,517,457,512,472,471,514,472,514,513,471,474,515,471,515,514,474,476,516,474,516,515,476,478,517,476,517,516,478,412,463,478,463,517,518,519,520,518,520,521,519,522,523,519,523,520,522,524,525,522,525,523,524,526,527,524,527,525,526,528,529,526,529,527,530,531,519,530,519,518,531,532,522,531,522,519,532,533,524,532,524,522,533,534,526,533,526,524,534,535,528,534,528,526,536,537,531,536,531,530,537,538,532,537,532,531,538,539,533,538,533,532,539,540,534,539,534,533,540,541,535,540,535,534,542,543,537,542,537,536,543,544,538,543,538,537,544,545,539,544,539,538,545,546,540,545,540,539,546,547,541,546,541,540,548,549,543,548,543,542,549,550,544,549,544,543,550,551,545,550,545,544,551,552,546,551,546,545,552,553,547,552,547,546,554,555,549,554,549,548,555,556,550,555,550,549,556,557,551,556,551,550,557,558,552,557,552,551,558,559,553,558,553,552,560,561,555,560,555,554,561,562,556,561,556,555,562,563,557,562,557,556,563,564,558,563,558,557,564,565,559,564,559,558,566,567,561,566,561,560,567,568,562,567,562,561,568,569,563,568,563,562,569,570,564,569,564,563,570,571,565,570,565,564,572,573,567,572,567,566,573,574,568,573,568,567,574,575,569,574,569,568,575,576,570,575,570,569,576,577,571,576,571,570,521,520,573,521,573,572,520,523,574,520,574,573,523,525,575,523,575,574,525,527,576,525,576,575,527,529,577,527,577,576,578,579,580,578,580,581,579,582,583,579,583,580,582,584,585,582,585,583,584,586,587,584,587,585,586,518,521,586,521,587,588,589,579,588,579,578,589,590,582,589,582,579,590,591,584,590,584,582,591,592,586,591,586,584,592,530,518,592,518,586,593,594,589,593,589,588,594,595,590,594,590,589,595,596,591,595,591,590,596,597,592,596,592,591,597,536,530,597,530,592,598,599,594,598,594,593,599,600,595,599,595,594,600,601,596,600,596,595,601,602,597,601,597,596,602,542,536,602,536,597,603,604,599,603,599,598,604,605,600,604,600,599,605,606,601,605,601,600,606,607,602,606,602,601,607,548,542,607,542,602,608,609,604,608,604,603,609,610,605,609,605,604,610,611,606,610,606,605,611,612,607,611,607,606,612,554,548,612,548,607,613,614,609,613,609,608,614,615,610,614,610,609,615,616,611,615,611,610,616,617,612,616,612,611,617,560,554,617,554,612,618,619,614,618,614,613,619,620,615,619,615,614,620,621,616,620,616,615,621,622,617,621,617,616,622,566,560,622,560,617,623,624,619,623,619,618,624,625,620,624,620,619,625,626,621,625,621,620,626,627,622,626,622,621,627,572,566,627,566,622,581,580,624,581,624,623,580,583,625,580,625,624,583,585,626,583,626,625,585,587,627,585,627,626,587,521,572,587,572,627,628,629,630,628,630,631,629,632,633,629,633,630,632,634,635,632,635,633,634,636,637,634,637,635,636,638,637,639,640,629,639,629,628,640,641,632,640,632,629,641,642,634,641,634,632,642,643,636,642,636,634,643,638,636,644,645,640,644,640,639,645,646,641,645,641,640,646,647,642,646,642,641,647,648,643,647,643,642,648,638,643,649,650,645,649,645,644,650,651,646,650,646,645,651,652,647,651,647,646,652,653,648,652,648,647,653,638,648,654,655,650,654,650,649,655,656,651,655,651,650,656,657,652,656,652,651,657,658,653,657,653,652,658,638,653,659,660,661,659,661,662,660,663,664,660,664,661,663,665,666,663,666,664,665,667,668,665,668,666,667,638,668,669,670,660,669,660,659,670,671,663,670,663,660,671,672,665,671,665,663,672,673,667,672,667,665,673,638,667,674,675,670,674,670,669,675,676,671,675,671,670,676,677,672,676,672,671,677,678,673,677,673,672,678,638,673,679,680,675,679,675,674,680,681,676,680,676,675,681,682,677,681,677,676,682,683,678,682,678,677,683,638,678,631,630,680,631,680,679,630,633,681,630,681,680,633,635,682,633,682,681,635,637,683,635,683,682,637,638,683,684,685,686,684,686,687,685,688,689,685,689,686,688,690,691,688,691,689,690,692,693,690,693,691,692,638,693,694,695,685,694,685,684,695,696,688,695,688,685,696,697,690,696,690,688,697,698,692,697,692,690,698,638,692,699,700,695,699,695,694,700,701,696,700,696,695,701,702,697,701,697,696,702,703,698,702,698,697,703,638,698,704,705,700,704,700,699,705,706,701,705,701,700,706,707,702,706,702,701,707,708,703,707,703,702,708,638,703,662,661,705,662,705,704,661,664,706,661,706,705,664,666,707,664,707,706,666,668,708,666,708,707,668,638,708,709,710,655,709,655,654,710,711,656,710,656,655,711,712,657,711,657,656,712,713,658,712,658,657,713,638,658,714,715,710,714,710,709,715,716,711,715,711,710,716,717,712,716,712,711,717,718,713,717,713,712,718,638,713,719,720,715,719,715,714,720,721,716,720,716,715,721,722,717,721,717,716,722,723,718,722,718,717,723,638,718,724,725,720,724,720,719,725,726,721,725,721,720,726,727,722,726,722,721,727,728,723,727,723,722,728,638,723,687,686,725,687,725,724,686,689,726,686,726,725,689,691,727,689,727,726,691,693,728,691,728,727,693,638,728,729,730,731,729,731,732,730,733,734,730,734,731,733,735,736,733,736,734,735,737,738,735,738,736,737,628,631,737,631,738,739,740,730,739,730,729,740,741,733,740,733,730,741,742,735,741,735,733,742,743,737,742,737,735,743,639,628,743,628,737,744,745,740,744,740,739,745,746,741,745,741,740,746,747,742,746,742,741,747,748,743,747,743,742,748,644,639,748,639,743,749,750,745,749,745,744,750,751,746,750,746,745,751,752,747,751,747,746,752,753,748,752,748,747,753,649,644,753,644,748,754,755,750,754,750,749,755,756,751,755,751,750,756,757,752,756,752,751,757,758,753,757,753,752,758,654,649,758,649,753,759,760,761,759,761,762,760,763,764,760,764,761,763,765,766,763,766,764,765,767,768,765,768,766,767,659,662,767,662,768,769,770,760,769,760,759,770,771,763,770,763,760,771,772,765,771,765,763,772,773,767,772,767,765,773,669,659,773,659,767,774,775,770,774,770,769,775,776,771,775,771,770,776,777,772,776,772,771,777,778,773,777,773,772,778,674,669,778,669,773,779,780,775,779,775,774,780,781,776,780,776,775,781,782,777,781,777,776,782,783,778,782,778,777,783,679,674,783,674,778,732,731,780,732,780,779,731,734,781,731,781,780,734,736,782,734,782,781,736,738,783,736,783,782,738,631,679,738,679,783,784,785,786,784,786,787,785,788,789,785,789,786,788,790,791,788,791,789,790,792,793,790,793,791,792,684,687,792,687,793,794,795,785,794,785,784,795,796,788,795,788,785,796,797,790,796,790,788,797,798,792,797,792,790,798,694,684,798,684,792,799,800,795,799,795,794,800,801,796,800,796,795,801,802,797,801,797,796,802,803,798,802,798,797,803,699,694,803,694,798,804,805,800,804,800,799,805,806,801,805,801,800,806,807,802,806,802,801,807,808,803,807,803,802,808,704,699,808,699,803,762,761,805,762,805,804,761,764,806,761,806,805,764,766,807,764,807,806,766,768,808,766,808,807,768,662,704,768,704,808,809,810,755,809,755,754,810,811,756,810,756,755,811,812,757,811,757,756,812,813,758,812,758,757,813,709,654,813,654,758,814,815,810,814,810,809,815,816,811,815,811,810,816,817,812,816,812,811,817,818,813,817,813,812,818,714,709,818,709,813,819,820,815,819,815,814,820,821,816,820,816,815,821,822,817,821,817,816,822,823,818,822,818,817,823,719,714,823,714,818,824,825,820,824,820,819,825,826,821,825,821,820,826,827,822,826,822,821,827,828,823,827,823,822,828,724,719,828,719,823,787,786,825,787,825,824,786,789,826,786,826,825,789,791,827,789,827,826,791,793,828,791,828,827,793,687,724,793,724,828, 13 | }; -------------------------------------------------------------------------------- /tiny-gizmo-example/tiny-gizmo-example.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tiny-gizmo-example", "tiny-gizmo-example.vcxproj", "{E8595BE1-022E-46B2-9079-A12C655C5E4B}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "glfw3", "third-party\glfw-3.1.2\glfw3.vcxproj", "{BE423E72-28C2-4FB7-9FE1-42AA2F393BBC}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|x64 = Debug|x64 13 | Debug|x86 = Debug|x86 14 | Release|x64 = Release|x64 15 | Release|x86 = Release|x86 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {E8595BE1-022E-46B2-9079-A12C655C5E4B}.Debug|x64.ActiveCfg = Debug|x64 19 | {E8595BE1-022E-46B2-9079-A12C655C5E4B}.Debug|x64.Build.0 = Debug|x64 20 | {E8595BE1-022E-46B2-9079-A12C655C5E4B}.Debug|x86.ActiveCfg = Debug|Win32 21 | {E8595BE1-022E-46B2-9079-A12C655C5E4B}.Debug|x86.Build.0 = Debug|Win32 22 | {E8595BE1-022E-46B2-9079-A12C655C5E4B}.Release|x64.ActiveCfg = Release|x64 23 | {E8595BE1-022E-46B2-9079-A12C655C5E4B}.Release|x64.Build.0 = Release|x64 24 | {E8595BE1-022E-46B2-9079-A12C655C5E4B}.Release|x86.ActiveCfg = Release|Win32 25 | {E8595BE1-022E-46B2-9079-A12C655C5E4B}.Release|x86.Build.0 = Release|Win32 26 | {BE423E72-28C2-4FB7-9FE1-42AA2F393BBC}.Debug|x64.ActiveCfg = Debug|x64 27 | {BE423E72-28C2-4FB7-9FE1-42AA2F393BBC}.Debug|x64.Build.0 = Debug|x64 28 | {BE423E72-28C2-4FB7-9FE1-42AA2F393BBC}.Debug|x86.ActiveCfg = Debug|Win32 29 | {BE423E72-28C2-4FB7-9FE1-42AA2F393BBC}.Debug|x86.Build.0 = Debug|Win32 30 | {BE423E72-28C2-4FB7-9FE1-42AA2F393BBC}.Release|x64.ActiveCfg = Release|x64 31 | {BE423E72-28C2-4FB7-9FE1-42AA2F393BBC}.Release|x64.Build.0 = Release|x64 32 | {BE423E72-28C2-4FB7-9FE1-42AA2F393BBC}.Release|x86.ActiveCfg = Release|Win32 33 | {BE423E72-28C2-4FB7-9FE1-42AA2F393BBC}.Release|x86.Build.0 = Release|Win32 34 | EndGlobalSection 35 | GlobalSection(SolutionProperties) = preSolution 36 | HideSolutionNode = FALSE 37 | EndGlobalSection 38 | EndGlobal 39 | -------------------------------------------------------------------------------- /tiny-gizmo-example/tiny-gizmo-example.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 23 | {be423e72-28c2-4fb7-9fe1-42aa2f393bbc} 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | {E8595BE1-022E-46B2-9079-A12C655C5E4B} 38 | xlab_cpp 39 | 10.0.16299.0 40 | tiny-gizmo-example 41 | 42 | 43 | 44 | Application 45 | true 46 | v141 47 | MultiByte 48 | 49 | 50 | Application 51 | false 52 | v141 53 | true 54 | MultiByte 55 | 56 | 57 | Application 58 | true 59 | v141 60 | MultiByte 61 | 62 | 63 | Application 64 | false 65 | v141 66 | true 67 | MultiByte 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | $(ProjectDir)\build\ 89 | $(ProjectDir)\build\obj\ 90 | 91 | 92 | $(ProjectDir)\build\ 93 | $(ProjectDir)\build\obj\ 94 | 95 | 96 | $(ProjectDir)\build\ 97 | $(ProjectDir)\build\obj\ 98 | 99 | 100 | $(ProjectDir)\build\ 101 | $(ProjectDir)\build\obj\ 102 | 103 | 104 | 105 | Level3 106 | Disabled 107 | true 108 | $(SolutionDir)third-party;$(SolutionDir)third-party\glew;$(SolutionDir)third-party\glfw-3.1.2\include;%(AdditionalIncludeDirectories) 109 | _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) 110 | 111 | 112 | $(SolutionDir)third-party\glew\lib\$(Platform);$(SolutionDir)third-party\fbxsdk\lib\x64\$(Configuration);%(AdditionalLibraryDirectories) 113 | glew32s.lib;opengl32.lib;%(AdditionalDependencies) 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | Level3 123 | Disabled 124 | true 125 | $(SolutionDir)third-party;$(SolutionDir)third-party\glew;$(SolutionDir)third-party\glfw-3.1.2\include;%(AdditionalIncludeDirectories) 126 | _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) 127 | 128 | 129 | $(SolutionDir)third-party\glew\lib\$(Platform);$(SolutionDir)third-party\fbxsdk\lib\x64\$(Configuration);%(AdditionalLibraryDirectories) 130 | glew32s.lib;opengl32.lib;%(AdditionalDependencies) 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | Level3 140 | MaxSpeed 141 | true 142 | true 143 | true 144 | $(SolutionDir)third-party;$(SolutionDir)third-party\glew;$(SolutionDir)third-party\glfw-3.1.2\include;%(AdditionalIncludeDirectories) 145 | _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) 146 | 147 | 148 | true 149 | true 150 | $(SolutionDir)third-party\glew\lib\$(Platform);$(SolutionDir)third-party\fbxsdk\lib\x64\$(Configuration);%(AdditionalLibraryDirectories) 151 | glew32s.lib;opengl32.lib;%(AdditionalDependencies) 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | Level3 161 | MaxSpeed 162 | true 163 | true 164 | true 165 | $(SolutionDir)third-party;$(SolutionDir)third-party\glew;$(SolutionDir)third-party\glfw-3.1.2\include;%(AdditionalIncludeDirectories) 166 | _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) 167 | 168 | 169 | true 170 | true 171 | $(SolutionDir)third-party\glew\lib\$(Platform);$(SolutionDir)third-party\fbxsdk\lib\x64\$(Configuration);%(AdditionalLibraryDirectories) 172 | glew32s.lib;opengl32.lib;%(AdditionalDependencies) 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | -------------------------------------------------------------------------------- /tiny-gizmo-example/tiny-gizmo-example.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {886b3b0e-2a37-489f-b0cf-7ab0efe1bdb1} 6 | 7 | 8 | {0bceb5fb-0b9d-4b04-842b-5da21648b39d} 9 | 10 | 11 | 12 | 13 | 14 | gizmo 15 | 16 | 17 | 18 | 19 | extra 20 | 21 | 22 | extra 23 | 24 | 25 | extra 26 | 27 | 28 | gizmo 29 | 30 | 31 | -------------------------------------------------------------------------------- /tiny-gizmo-example/util.hpp: -------------------------------------------------------------------------------- 1 | // This is free and unencumbered software released into the public domain. 2 | // For more information, please refer to 3 | 4 | #pragma once 5 | 6 | #ifndef tinygizmo_example_util_hpp 7 | #define tinygizmo_example_util_hpp 8 | 9 | #include 10 | #include 11 | 12 | //#define GLEW_STATIC 13 | #define GL_GLEXT_PROTOTYPES 14 | #include "GL/glew.h" 15 | 16 | #define GLFW_INCLUDE_GLU 17 | #include "GLFW/glfw3.h" 18 | 19 | #include "../tiny-gizmo.hpp" 20 | #include "linalg.h" 21 | 22 | /////////////////////////////////// 23 | // Windowing & App Lifecycle // 24 | /////////////////////////////////// 25 | 26 | struct ray { linalg::aliases::float3 origin; linalg::aliases::float3 direction; }; 27 | 28 | struct rect 29 | { 30 | int x0, y0, x1, y1; 31 | int width() const { return x1 - x0; } 32 | int height() const { return y1 - y0; } 33 | linalg::aliases::int2 dims() const { return{ width(), height() }; } 34 | float aspect_ratio() const { return (float)width() / height(); } 35 | }; 36 | 37 | struct camera 38 | { 39 | float yfov, near_clip, far_clip; 40 | linalg::aliases::float3 position; 41 | float pitch, yaw; 42 | linalg::aliases::float4 get_orientation() const { return qmul(rotation_quat(linalg::aliases::float3(0, 1, 0), yaw), rotation_quat(linalg::aliases::float3(1, 0, 0), pitch)); } 43 | linalg::aliases::float4x4 get_view_matrix() const { return mul(rotation_matrix(qconj(get_orientation())), translation_matrix(-position)); } 44 | linalg::aliases::float4x4 get_projection_matrix(const float aspectRatio) const { return linalg::perspective_matrix(yfov, aspectRatio, near_clip, far_clip); } 45 | linalg::aliases::float4x4 get_viewproj_matrix(const float aspectRatio) const { return mul(get_projection_matrix(aspectRatio), get_view_matrix()); } 46 | }; 47 | 48 | // Returns a world-space ray through the given pixel, originating at the camera 49 | ray get_ray_from_pixel(const linalg::aliases::float2 & pixel, const rect & viewport, const camera & cam) 50 | { 51 | const float x = 2 * (pixel.x - viewport.x0) / viewport.width() - 1, y = 1 - 2 * (pixel.y - viewport.y0) / viewport.height(); 52 | const linalg::aliases::float4x4 inv_view_proj = inverse(cam.get_viewproj_matrix(viewport.aspect_ratio())); 53 | const linalg::aliases::float4 p0 = mul(inv_view_proj, linalg::aliases::float4(x, y, -1, 1)), p1 = mul(inv_view_proj, linalg::aliases::float4(x, y, +1, 1)); 54 | return{ cam.position, p1.xyz()*p0.w - p0.xyz()*p1.w }; 55 | } 56 | 57 | class Window 58 | { 59 | GLFWwindow * window; 60 | public: 61 | std::function on_char; 62 | std::function on_key; 63 | std::function on_mouse_button; 64 | std::function on_cursor_pos; 65 | std::function on_drop; 66 | 67 | Window(int width, int height, const char * title) 68 | { 69 | glewExperimental = GL_TRUE; 70 | if (glfwInit() == GL_FALSE) throw std::runtime_error("glfwInit() failed"); 71 | 72 | // Define version and compatibility settings 73 | // this must occur after init and before create window. 74 | glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); 75 | glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); 76 | glfwWindowHint(GLFW_OPENGL_PROFILE,GLFW_OPENGL_CORE_PROFILE); 77 | glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); 78 | glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); 79 | 80 | window = glfwCreateWindow(width, height, title, nullptr, nullptr); 81 | if (!window) throw std::runtime_error("glfwCreateWindow() failed"); 82 | 83 | glfwMakeContextCurrent(window); 84 | 85 | if (GLenum err = glewInit()) 86 | { 87 | throw std::runtime_error(std::string("glewInit() failed - ") + (const char *)glewGetErrorString(err)); 88 | } 89 | 90 | std::cout << "GL_SHADING_LANGUAGE_VERSION: " << glGetString(GL_SHADING_LANGUAGE_VERSION) << std::endl; 91 | 92 | glfwSetCharCallback(window, [](GLFWwindow * window, unsigned int codepoint) { 93 | auto w = (Window *)glfwGetWindowUserPointer(window); if (w->on_char) w->on_char(codepoint); 94 | }); 95 | 96 | glfwSetKeyCallback(window, [](GLFWwindow * window, int key, int, int action, int mods) { 97 | auto w = (Window *)glfwGetWindowUserPointer(window); if (w->on_key) w->on_key(key, action, mods); 98 | }); 99 | 100 | glfwSetMouseButtonCallback(window, [](GLFWwindow * window, int button, int action, int mods) { 101 | auto w = (Window *)glfwGetWindowUserPointer(window); if (w->on_mouse_button) w->on_mouse_button(button, action, mods); 102 | }); 103 | 104 | glfwSetCursorPosCallback(window, [](GLFWwindow * window, double xpos, double ypos) { 105 | auto w = (Window *)glfwGetWindowUserPointer(window); if (w->on_cursor_pos) w->on_cursor_pos(linalg::aliases::float2(linalg::aliases::double2(xpos, ypos))); 106 | }); 107 | 108 | glfwSetDropCallback(window, [](GLFWwindow * window, int numFiles, const char ** paths) { 109 | auto w = (Window *)glfwGetWindowUserPointer(window); if (w->on_drop) w->on_drop(numFiles, paths); 110 | }); 111 | 112 | glfwSetWindowUserPointer(window, this); 113 | } 114 | 115 | ~Window() 116 | { 117 | glfwMakeContextCurrent(window); 118 | glfwDestroyWindow(window); 119 | glfwTerminate(); 120 | } 121 | 122 | Window(const Window &) = delete; 123 | Window(Window &&) = delete; 124 | Window & operator = (const Window &) = delete; 125 | Window & operator = (Window &&) = delete; 126 | 127 | GLFWwindow * get_glfw_window_handle() { return window; }; 128 | bool should_close() const { return !!glfwWindowShouldClose(window); } 129 | int get_window_attrib(int attrib) const { return glfwGetWindowAttrib(window, attrib); } 130 | linalg::aliases::int2 get_window_size() const { linalg::aliases::int2 size; glfwGetWindowSize(window, &size.x, &size.y); return size; } 131 | void set_window_size(linalg::aliases::int2 newSize) { glfwSetWindowSize(window, newSize.x, newSize.y); } 132 | linalg::aliases::int2 get_framebuffer_size() const { linalg::aliases::int2 size; glfwGetFramebufferSize(window, &size.x, &size.y); return size; } 133 | linalg::aliases::float2 get_cursor_pos() const { linalg::aliases::double2 pos; glfwGetCursorPos(window, &pos.x, &pos.y); return linalg::aliases::float2(pos); } 134 | 135 | void swap_buffers() { glfwSwapBuffers(window); } 136 | void close() { glfwSetWindowShouldClose(window, 1); } 137 | }; 138 | 139 | #endif // end tinygizmo_example_util_hpp 140 | -------------------------------------------------------------------------------- /tiny-gizmo.hpp: -------------------------------------------------------------------------------- 1 | // This is free and unencumbered software originally written and released into the public domain by Dimitri Diakopoulos. 2 | // For more information, please refer to 3 | // 4 | // The original code is here: https://github.com/ddiakopoulos/tinygizmo 5 | // and this version is from here: https://github.com/meshula/tinygizmo/tree/really-tiny 6 | 7 | #ifndef tinygizmo_hpp 8 | #define tinygizmo_hpp 9 | 10 | #include // for uint32_t 11 | 12 | namespace tinygizmo 13 | { 14 | // Basic numeric types 15 | 16 | struct v2f { float x, y; }; 17 | struct v3f { float x, y, z; }; 18 | struct v4f { float x, y, z, w; }; 19 | typedef v4f quatf; 20 | struct uint3 { uint32_t x, y, z; }; 21 | struct m44f { v4f x, y, z, w; }; 22 | 23 | // Utility object to be manipulated by the gizmos 24 | 25 | struct rigid_transform 26 | { 27 | rigid_transform() {} 28 | rigid_transform(const quatf& orientation, const v3f& position, const v3f& scale) : orientation(orientation), position(position), scale(scale) {} 29 | rigid_transform(const quatf& orientation, const v3f& position, float scale) : orientation(orientation), position(position), scale{ scale, scale, scale } {} 30 | rigid_transform(const quatf& orientation, const v3f& position) : orientation(orientation), position(position) {} 31 | 32 | quatf orientation{ 0,0,0,1 }; 33 | v3f position{ 0,0,0 }; 34 | v3f scale{ 1,1,1 }; 35 | 36 | bool is_uniform_scale() const { return scale.x == scale.y && scale.x == scale.z; } 37 | m44f matrix() const; 38 | v3f transform_vector(const v3f& vec) const; 39 | v3f transform_point(const v3f& p) const; 40 | v3f detransform_point(const v3f& p) const; 41 | v3f detransform_vector(const v3f& vec) const; 42 | }; 43 | 44 | // input data for the gizmo's calculations 45 | 46 | struct camera_parameters 47 | { 48 | float yfov, near_clip, far_clip; 49 | v3f position; 50 | quatf orientation; 51 | }; 52 | 53 | struct gizmo_application_state 54 | { 55 | bool mouse_left{ false }; // indicates that LMB is pressed 56 | bool modifier_active{ false }; // indicates an active interaction modifier, for example the control key 57 | 58 | float screenspace_scale{ 0.f }; // If > 0.f, the gizmos are drawn scale-invariant with a screenspace value defined here 59 | float snap_translation{ 0.f }; // World-scale units used for snapping translation 60 | float snap_scale{ 0.f }; // World-scale units used for snapping scale 61 | float snap_rotation{ 0.f }; // Radians used for snapping rotation quaternions (i.e. PI/8 or PI/16) 62 | 63 | v2f viewport_size{ 0,0 }; // 3d viewport used to render the view 64 | v3f ray_origin{ 0,0,0 }; // world-space ray origin (i.e. the camera position) 65 | v3f ray_direction{ 0,0,1 }; // world-space ray direction 66 | 67 | camera_parameters cam; // Used for constructing inverse view projection for raycasting onto gizmo geometry 68 | }; 69 | 70 | enum class transform_mode { translate, rotate, scale }; 71 | enum class reference_frame { local, global }; 72 | 73 | class gizmo_context 74 | { 75 | struct gizmo_context_impl; 76 | gizmo_context_impl* impl; 77 | 78 | public: 79 | gizmo_context(); 80 | ~gizmo_context(); 81 | 82 | transform_mode get_mode() const; 83 | void set_mode(transform_mode); 84 | reference_frame get_frame() const; 85 | void set_frame(reference_frame); 86 | 87 | void begin(const gizmo_application_state & state); // Clear geometry buffer and update internal `gizmo_application_state` data 88 | void end(const gizmo_application_state & state); 89 | 90 | // The following functions are to be called between begin and end. 91 | 92 | // Fills index_buffer with faces to draw all gizmos, up to capacity. Returns desired capacity. 93 | // If desired capacity is greater than buffer_capacity, a larger index_buffer should be provided, and faces(...) called again. 94 | // Providing a null pointer for index_buffer, or a zero buffer_capacity is a quick way to discover necessary buffer size. 95 | int triangles(uint32_t* index_buffer, int buffer_capacity); 96 | 97 | // position:v3f, normal::v3f, color::v4f 98 | int vertices(float* vertex_buffer, int stride, int normal_offset, int color_offset, int vertex_capacity); 99 | 100 | // returns true if the gizmo is hovered, or being manipulated. 101 | // call once for every active transform gizmo. 102 | // Any gizmo not named between begin and end will disappear. The manipulation state will be remembered for the next time the gizmo is activated. 103 | bool transform_gizmo(char const* const name, rigid_transform& t); 104 | }; 105 | 106 | } // end namespace tinygizmo; 107 | 108 | #endif // end tinygizmo_hpp 109 | --------------------------------------------------------------------------------